/* FieldNavigator â€” Comprehensive CSS with theme support */

:root {
  --fn-bg: #f8fafc;
  --fn-surface: #ffffff;
  --fn-raised: #f1f5f9;
  --fn-text: #0f172a;
  --fn-text-sub: #334a63;      /* was #475569 — lifted to 8.9:1 on bg */
  --fn-text-muted: #5a6b80;    /* was #94a3b8 (2.3:1, failed AA). 4.7:1 on bg — passes AA normal */
  --fn-border: #e2e8f0;
  --fn-border-sub: #cbd5e1;
  --fn-accent: #1d4ed8;        /* was #2563eb — 7.5:1 on white vs 5.1:1 */
  --fn-accent-hover: #1e40af;  /* was #1d4ed8 */

  /* Status pill colour pairs (light mode) */
  --pill-sch-bg: #dbeafe; --pill-sch-fg: #1e3a8a;   /* was #1d4ed8 — bumped contrast on pill bg */
  --pill-cnf-bg: #d1fae5; --pill-cnf-fg: #065f46;   /* was #047857 — darker for pill text */
  --pill-cmp-bg: #a7f3d0; --pill-cmp-fg: #064e3b;
  --pill-cnc-bg: #e2e8f0; --pill-cnc-fg: #334a63;   /* was #475569 */

  --warn-bg: #fef3c7; --warn-fg: #78350f;            /* was #92400e — darker on warn-bg */

  /* Icon font fallback chain — Radzen 5.9.9 ships its own woff2 declared as
     "Material Symbols", but App.razor also pulls in Google's "Material Symbols
     Outlined". Listing both makes .rzi render whichever face actually loaded. */
  --rz-icon-font-family: "Material Symbols", "Material Symbols Outlined";
}

[data-theme="dark"] {
  --fn-bg: #0f172a;
  --fn-surface: #1e293b;
  --fn-raised: #334155;
  --fn-text: #f1f5f9;
  --fn-text-sub: #cbd5e1;      /* was #94a3b8 — brighter for dark bg */
  --fn-text-muted: #b0bdcd;    /* was #64748b (failed 4.04:1 on raised) — now 5.4:1 on raised */
  --fn-border: #334155;
  --fn-border-sub: #475569;
  --fn-accent: #60a5fa;        /* was #3b82f6 — brighter blue for dark mode accent text */
  --fn-accent-hover: #3b82f6;  /* was #2563eb */

  /* Status pill colour pairs (dark mode) */
  --pill-sch-bg: #1e3a8a; --pill-sch-fg: #bfdbfe;
  --pill-cnf-bg: #064e3b; --pill-cnf-fg: #a7f3d0;
  --pill-cmp-bg: #065f46; --pill-cmp-fg: #ecfdf5;
  --pill-cnc-bg: #334155; --pill-cnc-fg: #cbd5e1;

  --warn-bg: #78350f; --warn-fg: #fde68a;
}

/* Dark-mode contrast overrides: --fn-accent in dark mode is intentionally bright
   for accent text on dark backgrounds, but that same value as a button/avatar
   background fails contrast against white labels. Force the darker brand-blue
   (#1d4ed8) on filled elements so white text holds 6.3:1. */
[data-theme="dark"] .fn-fa-maps-btn,
[data-theme="dark"] .fn-fa-btn--primary-blue,
[data-theme="dark"] .pill--inprogress,
[data-theme="dark"] .fn-fa-up-next,
[data-theme="dark"] .fn-fa-avatar,
[data-theme="dark"] .fn-fa-drawer-avatar {
  background: #1d4ed8;
  border-color: #1d4ed8;
  color: white;
}

[data-theme="dark"] .fn-fa-up-next .fn-fa-up-next-nav-btn {
  background: rgba(255, 255, 255, 0.25);
  border-color: rgba(255, 255, 255, 0.5);
  color: white;
}

[data-theme="dark"] .fn-fa-btn--primary-green,
[data-theme="dark"] .fn-fa-mc-complete-btn {
  background: #047857;
  border-color: #047857;
  color: white;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
}

body {
  font-family: 'IBM Plex Sans', 'Segoe UI', system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--fn-text);
  background-color: var(--fn-bg);
  transition: background-color 0.3s ease, color 0.3s ease;
}

#app {
  height: 100%;
  width: 100%;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-weight: 600;
}

p {
  margin: 0;
}

a {
  color: var(--fn-accent);
  text-decoration: none;
  transition: color 0.2s ease;
}

a:hover {
  color: var(--fn-accent-hover);
}

button {
  font-family: inherit;
  cursor: pointer;
}

/* Shell Layout */

.fn-shell {
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 100%;
  background-color: var(--fn-bg);
}

.fn-topbar {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 0.75rem 1.5rem;
  background-color: var(--fn-surface);
  border-bottom: 1px solid var(--fn-border);
  flex-shrink: 0;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.fn-app-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.fn-app-brand-icon {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  display: block;
}

.fn-app-title {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--fn-text);
  letter-spacing: -0.5px;
}

.fn-topbar-tabs {
  display: flex;
  gap: 0.5rem;
  margin-left: auto;
  flex: 0 0 auto;
}

.fn-topbar-right {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-left: auto;
}

/* v2.8.0a (Lane A) — ProfileBubble dropdown. Replaces the old user-identity chip:
   the avatar opens a popup with name + email/address + role pills + theme toggle
   + Sign out. The theme toggle no longer sits standalone in the topbar — it's only
   reachable via the bubble. The role pills reuse .fn-mock-login-role-pill (defined
   further down in this file). */
.fn-profile-bubble {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.fn-profile-bubble-avatar {
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  border: 1px solid var(--fn-border);
  background: var(--fn-raised);
  color: var(--fn-text);
  font-weight: 600;
  font-size: 0.875rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Hover tint only for the interactive topbar avatar (a <button>), not the static
   panel-header avatar (a <span>). */
button.fn-profile-bubble-avatar:hover {
  background: var(--fn-accent-soft, var(--fn-raised));
}

.fn-profile-bubble-avatar:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

/* Real Entra photo fills the circular avatar (both the topbar bubble and the panel
   header); overflow is clipped to the circle so any aspect ratio crops cleanly. */
.fn-profile-bubble-avatar {
  overflow: hidden;
}

.fn-profile-bubble-avatar-img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

/* Panel header: larger avatar beside the user's name. */
.fn-profile-bubble-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.fn-profile-bubble-avatar--lg {
  width: 2.5rem;
  height: 2.5rem;
  font-size: 1rem;
  flex-shrink: 0;
  cursor: default;
}

.fn-profile-bubble-panel {
  position: absolute;
  top: calc(100% + 0.25rem);
  right: 0;
  min-width: 14rem;
  padding: 0.75rem;
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  z-index: 1000;
}

.fn-profile-bubble-name {
  font-weight: 600;
  color: var(--fn-text);
}

.fn-profile-bubble-email,
.fn-profile-bubble-address {
  color: var(--fn-text-sub);
  font-size: 0.8125rem;
  word-break: break-word;
}

.fn-profile-bubble-roles {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
}

.fn-profile-bubble-theme {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.5rem;
  border-radius: 4px;
  background: transparent;
  border: 1px solid var(--fn-border);
  color: var(--fn-text);
  font-size: 0.875rem;
  cursor: pointer;
  text-align: left;
}

.fn-profile-bubble-theme:hover {
  background: var(--fn-raised);
}

.fn-profile-bubble-signout,
.fn-profile-bubble-signin {
  padding: 0.375rem 0.5rem;
  border-radius: 4px;
  text-decoration: none;
  color: var(--fn-text-sub);
  border: 1px solid var(--fn-border);
  font-size: 0.8125rem;
  text-align: center;
}

.fn-profile-bubble-signout:hover,
.fn-profile-bubble-signin:hover {
  background: var(--fn-raised);
  color: var(--fn-text);
}

.fn-profile-bubble-signout:focus-visible,
.fn-profile-bubble-signin:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

/* v2.8.0d (Lane D) — Settings dropdown. Mirrors the ProfileBubble pattern
   (anchored panel positioned via position:relative on the wrapper, items as
   <button> elements). Lives inside .fn-topbar-tabs alongside the remaining
   nav buttons; visual weight matches a tertiary nav button so it doesn't
   compete with Schedule|Dashboard|Map|Split. */
.fn-settings-dropdown {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.fn-settings-dropdown-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.75rem;
  border-radius: 4px;
  border: 1px solid var(--fn-border);
  background: var(--fn-raised);
  color: var(--fn-text);
  font-size: 0.875rem;
  cursor: pointer;
}

.fn-settings-dropdown-trigger:hover {
  background: var(--fn-accent-soft, var(--fn-raised));
}

.fn-settings-dropdown-trigger:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

.fn-settings-dropdown-caret {
  font-size: 1rem;
  line-height: 1;
}

.fn-settings-dropdown-panel {
  position: absolute;
  top: calc(100% + 0.25rem);
  right: 0;
  min-width: 12rem;
  padding: 0.25rem;
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  z-index: 1000;
}

.fn-settings-dropdown-item {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.5rem;
  border-radius: 4px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--fn-text);
  font-size: 0.875rem;
  cursor: pointer;
  text-align: left;
}

.fn-settings-dropdown-item:hover {
  background: var(--fn-raised);
}

.fn-settings-dropdown-item:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

/* v2.8.6 — main-area restructure. .fn-main-area is now a ROW: the content
   column (schedule grid + bottom panel stacked) on the left, SidePanelHost
   spanning the full vertical height on the right. The bottom panel sits
   beneath the grid only — it no longer stretches under the side panel. */
.fn-main-area {
  display: flex;
  flex-direction: row;
  flex: 1;
  min-height: 0;
}

/* v2.8.6 — content column wrapping @Body (schedule/dashboard/map/etc.) and
   the BottomPanelHost. Stacks vertically; claims the remaining horizontal
   space to SidePanelHost's left. */
.fn-content-column {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  background-color: var(--fn-bg);
}

/* v2.8.6 — body slot inside the content column. Renamed from the previous
   inline-styled flex:1 div; now CSS-driven for predictable measure. */
.fn-content-body {
  flex: 1;
  overflow: auto;
  min-width: 0;
  min-height: 0;
}

/* v2.8.2a (Lane A) — bottom-panel host. ALWAYS visible regardless of focused
   agent or active view (the conditional gate moved off; Sidebar lives here
   uniformly). Height is driven by --fn-bottom-panel-height (default 280px)
   and mutated by panel-resize.js as the user drags the top-edge handle.

   v2.9.4 added a min(..., 35vh) cap as a static safety net because the
   v2.8.14c header removal had taken the resize handle with it; v2.12.1
   restored the handle (top-edge only — no preset chrome), so the cap is
   gone and the JS clamp [80px, innerHeight - 200px] is the live ceiling. */
.fn-bottom-panel-host {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  height: var(--fn-bottom-panel-height, 280px);
  border-top: 1px solid var(--fn-border);
  background-color: var(--fn-surface);
  overflow: hidden;
  transition: background-color 0.3s ease, border-color 0.3s ease;
  position: relative; /* anchor for the top-edge drag handle */
}

.fn-bottom-panel-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.6rem;
  border-bottom: 1px solid var(--fn-border);
  background-color: var(--fn-raised);
  flex-shrink: 0;
}

/* v2.12.1 — top-edge drag handle. Absolute-positioned across the full width
   of the host so the hit area covers the panel boundary; the visible stripe
   is transparent until hover, mirroring the map-pane handle treatment. */
.fn-bottom-panel-drag-handle {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  cursor: ns-resize;
  background: transparent;
  z-index: 5;
  touch-action: none;
}
.fn-bottom-panel-drag-handle:hover,
.fn-bottom-panel-drag-handle:active {
  background: var(--fn-border);
}

/* v2.8.10 — snap presets restyled from filled pills to a segmented-control
   look. Transparent baseline with an accent underline on active so the row
   reads as one cohesive surface alongside the new tab strip + agent caption. */
.fn-bottom-panel-snap-presets {
  display: flex;
  gap: 0.25rem;
  flex-shrink: 0;
}
.fn-bottom-panel-snap-btn {
  font-size: 0.78rem;
  padding: 0.2rem 0.6rem;
  border-radius: 0;
  border: none;
  background: transparent;
  color: var(--fn-text-sub);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.fn-bottom-panel-snap-btn:hover {
  color: var(--fn-text);
}
.fn-bottom-panel-snap-btn.active {
  color: var(--fn-accent);
  border-bottom-color: var(--fn-accent);
  /* Compensate so the row height matches inactive buttons after the 2px border kicks in. */
  padding-bottom: 0.15rem;
}

/* v2.8.10 — agent + day caption in the bottom-panel header bar. Replaces the
   dead sidebar agent chip; muted typography so it reads as panel chrome, not
   an action target. */
.fn-bottom-panel-context {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-right: 0.5rem;
  font-size: 0.78rem;
  color: var(--fn-text-sub);
  flex-shrink: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fn-bottom-panel-context-name {
  font-weight: 600;
  color: var(--fn-text);
}
.fn-bottom-panel-context-sep {
  color: var(--fn-text-sub);
}
.fn-bottom-panel-context-day {
  color: var(--fn-text-sub);
}

.fn-bottom-panel-body {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
}

/* v2.8.2a — SidePanelHost. Lives on the right edge of .fn-content. Expanded
   state renders AgentWeekSummaryPanel at the full ~320px width; collapsed
   state shrinks to a ~28px strip. The chevron is only rendered when an
   agent is focused — see SidePanelHost.razor for the rationale.

   v2.12.1 — expanded width is now user-resizable. --fn-side-panel-width
   drives the expanded state and panel-resize.js mutates it on left-edge
   drag. Transition disabled in the expanded state so the live drag isn't
   smoothed (animation lags the pointer); the collapsed↔expanded toggle
   still animates because it doesn't touch --fn-side-panel-width. */
.fn-side-panel-host {
  flex-shrink: 0;
  border-left: 1px solid var(--fn-border);
  background-color: var(--fn-surface);
  display: flex;
  overflow: hidden;
  transition: width 0.2s ease, background-color 0.3s ease, border-color 0.3s ease;
  position: relative; /* anchor for the left-edge drag handle */
}
.fn-side-panel-host.collapsed {
  width: 28px;
  align-items: center;
  justify-content: center;
}
.fn-side-panel-host.expanded {
  /* v2.8.8 — widened from 320px so the relocated DayDetailPanel's two-column
     layout (visit rows + Admin/Overnight right column, each ~260px) has room.
     v2.12.1 — now driven by --fn-side-panel-width with the v2.8.8 value as
     the default. */
  width: var(--fn-side-panel-width, 480px);
  flex-direction: column;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

/* v2.12.1 — left-edge drag handle (expanded state only — the collapsed
   28px strip has no useful width to negotiate). Mirrors the map-pane
   handle treatment: full-height, transparent until hover, 6px hit area. */
.fn-side-panel-drag-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 6px;
  cursor: ew-resize;
  background: transparent;
  z-index: 5;
  touch-action: none;
}
.fn-side-panel-drag-handle:hover,
.fn-side-panel-drag-handle:active {
  background: var(--fn-border);
}
.fn-side-panel-chevron {
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--fn-text-sub);
  font-size: 1rem;
  line-height: 1;
  padding: 0.4rem 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fn-side-panel-chevron:hover {
  color: var(--fn-accent);
}

/* v2.7.1c — shared CapacityBar primitive (head + bar + foot). Used by
   AgentWeekSummaryPanel for the 2-week summary AND inline route-day chips.
   Colour comes from DayLabels.BandFromPercent so any palette tweak in v2.8+
   flows through automatically. CompactMode strips head/foot. */
.fn-capacity-bar-block {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin-bottom: 0.4rem;
}
.fn-capacity-bar-block--compact {
  margin-bottom: 0;
  gap: 0;
}
.fn-capacity-bar-block-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.75rem;
  color: var(--fn-text-sub);
}
.fn-capacity-bar-block-label {
  font-weight: 500;
}
.fn-capacity-bar-block-pct {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.fn-capacity-bar-block-track {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: var(--fn-raised);
  overflow: hidden;
}
.fn-capacity-bar-block--compact .fn-capacity-bar-block-track {
  height: 3px;
}
.fn-capacity-bar-block-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 3px;
  transition: width 0.3s ease, background 0.15s ease;
}
.fn-capacity-bar-block-foot {
  font-size: 0.7rem;
  color: var(--fn-text-sub);
}

/* v2.7.1c — AgentWeekSummaryPanel. Horizontal layout: identity strip on
   the left, then capacity bars, leave/blockouts, route preview. Each block
   is its own scrollable column (overflow-y:auto) so a long leave list
   doesn't push the route strip off the right edge. */
.fn-agent-summary-panel {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) minmax(180px, 1fr) minmax(180px, 1fr) minmax(280px, 2fr);
  gap: 1rem;
  padding: 0.6rem 1rem;
  height: 100%;
  box-sizing: border-box;
  font-size: 0.85rem;
  color: var(--fn-text);
}

.fn-agent-summary-section-head {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fn-text-sub);
  margin-bottom: 0.4rem;
}

/* Identity strip */
.fn-agent-summary-identity {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-width: 0;
}
.fn-agent-summary-identity-name {
  font-size: 1rem;
  font-weight: 700;
  color: var(--fn-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fn-agent-summary-identity-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  font-size: 0.75rem;
}
.fn-agent-summary-identity-status {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-weight: 600;
}
.fn-agent-summary-identity-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}
.fn-agent-summary-identity-skills {
  color: var(--fn-text-sub);
}
.fn-agent-summary-identity-actions {
  display: flex;
  gap: 0.4rem;
  margin-top: auto;
  align-items: center;
}
.fn-agent-summary-identity-profile {
  flex: 1;
  padding: 0.3rem 0.5rem;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--fn-text);
  cursor: pointer;
  text-align: center;
}
.fn-agent-summary-identity-profile:hover {
  background: var(--fn-surface);
  border-color: var(--fn-accent);
}
.fn-agent-summary-identity-close {
  width: 28px;
  height: 28px;
  border: 1px solid var(--fn-border);
  border-radius: 50%;
  background: var(--fn-raised);
  color: var(--fn-text-sub);
  cursor: pointer;
  font-size: 0.85rem;
  line-height: 1;
}
.fn-agent-summary-identity-close:hover {
  background: var(--fn-surface);
  color: var(--fn-text);
}

/* Capacity column */
.fn-agent-summary-capacity {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Leave + blockouts column */
.fn-agent-summary-leave {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow-y: auto;
}
.fn-agent-summary-leave-row {
  display: flex;
  flex-direction: column;
  padding: 0.25rem 0;
  border-bottom: 1px dashed var(--fn-border);
  font-size: 0.78rem;
}
.fn-agent-summary-leave-row:last-child {
  border-bottom: none;
}
.fn-agent-summary-leave-range {
  font-weight: 600;
  color: var(--fn-text);
}
.fn-agent-summary-leave-reason {
  color: var(--fn-text-sub);
}
.fn-agent-summary-empty {
  font-size: 0.78rem;
  color: var(--fn-text-sub);
  font-style: italic;
}

/* Per-day route strip — horizontal flex of day chips. */
.fn-agent-summary-route {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.fn-agent-summary-route-strip {
  display: flex;
  gap: 0.4rem;
  overflow-x: auto;
  padding-bottom: 0.2rem;
}
.fn-agent-summary-route-day {
  flex: 1;
  min-width: 56px;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.4rem 0.3rem;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  text-align: center;
  font-size: 0.7rem;
}
.fn-agent-summary-route-day-name {
  font-weight: 700;
  color: var(--fn-text-sub);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.fn-agent-summary-route-day-num {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--fn-text);
  line-height: 1;
}
.fn-agent-summary-route-day-visits {
  font-size: 0.7rem;
  color: var(--fn-text-sub);
}

/* v2.8.2a (Lane A) — base Sidebar rules. The legacy border-left + fixed
   width assumed the right-edge column placement; with the panel-swap the
   sidebar lives in the bottom panel (horizontal) or — for any future
   reuse — possibly still in a vertical rail. .fn-sidebar--vertical keeps
   the old behaviour; .fn-sidebar--horizontal flexes to fill the bottom
   panel's available height/width. */
.fn-sidebar {
  background-color: var(--fn-surface);
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.fn-sidebar--vertical {
  flex: 0 0 260px;
  overflow-y: auto;
}

.fn-sidebar--horizontal {
  display: flex;
  flex-direction: row;
  flex: 1;
  min-width: 0;
  overflow: auto;
  gap: 0.5rem;
  padding: 0.25rem 0.5rem;
}

.fn-sidebar.collapsed {
  transform: translateX(100%);
}

/* Schedule Grid */

.fn-schedule-grid {
  --fn-card-col: 152px;
  display: flex;
  flex-direction: column;
  flex: 1;
  /* v2.8.9 finding 3 — overflow: auto here used to add a second scrollbar on top
     of .fn-content-body's. The shell does not need to scroll independently —
     .fn-content-body is the canonical scroll container. Sticky week-header
     (finding 2) also requires overflow:visible here so the sticky ancestor
     resolves to .fn-content-body instead of being trapped by this scroller. */
  overflow: visible;
  /* v2.8.1c — outer padding + inter-row gap halved for a denser layout. */
  padding: 0.5rem;
  gap: 0.25rem;
}

/* v2.6.2c — header + each agent row share the same grid template so columns
   lock-step in split view. Both rows are direct children of .fn-schedule-grid;
   --fn-day-cols is set inline per render via the C# State.ViewWeekDays. */
.fn-date-header,
.fn-agent-row {
  display: grid;
  grid-template-columns: var(--fn-card-col) repeat(var(--fn-day-cols, 5), 1fr);
  /* v2.8.1c — column gap halved (5px → 2px) to densify the grid. */
  gap: 2px;
  min-width: calc(var(--fn-card-col) + 480px);
}

.fn-date-header {
  margin-bottom: 0.5rem;
}

.fn-date-header-spacer {
  /* empty grid cell at column 1 — keeps header columns aligned with agent-card column */
}

.fn-agent-row {
  min-height: 120px;
  align-items: stretch;
}

.fn-date-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  text-align: center;
  /* v2.8.1c — vertical padding halved (0.4rem → 0.2rem) for denser date header. */
  padding: 0.2rem 0.25rem;
  /* v2.6.2j — match .fn-day-tile min-width (line ~326) so header columns and
     agent-row columns resolve to the same widths in narrow viewports (split
     view). Without this, header 1fr shrinks freely while DayTile floors at
     100px → columns drift. */
  min-width: 100px;
  /* v2.7.3d — clickable; hover affordance + active-state when this date drives
     the map's all-agents-day view. */
  cursor: pointer;
  border-radius: 4px;
  transition: background-color 0.12s ease;
}

.fn-date-cell:hover {
  background-color: var(--fn-raised);
}

.fn-date-cell:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: -2px;
}

.fn-date-cell--active {
  background-color: var(--fn-accent-soft, rgba(59, 130, 246, 0.12));
  /* v2.13 — was `inset 0 -2px 0` (a solid blue line on the bottom edge that clashed
     with the grid row below); a full contained ring reads as "selected" without any
     bottom-edge bleed into the adjacent header/grid. */
  box-shadow: inset 0 0 0 1.5px var(--fn-accent);
}

.fn-date-cell-label {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--fn-text-sub);
}

.fn-date-header-cell {
  flex: 1;
  /* v2.8.1c — padding halved (0.5rem → 0.25rem) for denser header rows. */
  padding: 0.25rem;
  text-align: center;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--fn-text-sub);
  background-color: var(--fn-raised);
  border-radius: 6px;
  min-width: 100px;
}

.fn-agent-card {
  flex: 0 0 152px;
  padding: 1rem;
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-left: 4px solid var(--fn-accent);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  transition: all 0.2s ease;
}

.fn-agent-card:hover {
  border-color: var(--fn-border-sub);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.fn-agent-name {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--fn-text);
  word-break: break-word;
  /* v2.6.2 (010): cap to 2 lines with ellipsis; full name lives in title attr. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fn-agent-meta {
  font-size: 0.75rem;
  color: var(--fn-text-muted);
  margin-top: 0.25rem;
}

/* 2026-04-28 â€” agent skill tags. Standard text colour (was inheriting the agent's
   accent which clashed with status-coloured visit chips). */
.fn-agent-tags {
  font-size: 0.7rem;
  color: var(--fn-text-sub);
  margin-top: 0.15rem;
  word-break: break-word;
}

.fn-util-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-top: 0.5rem;
  padding: 0.2rem 0.5rem;
  background-color: var(--fn-raised);
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--fn-accent);
}

/* v2.7.0 (011/014) — 4-band weekly capacity badge. Background is set inline
   from DayLabels.StatusColors; foreground here is white because Under/Over
   (orange) and Review (bright red) and Optimal (emerald) all have low enough
   luminance for white text to clear WCAG AA on the badge's small font size. */
.fn-util-badge--under,
.fn-util-badge--optimal,
.fn-util-badge--over,
.fn-util-badge--review {
  color: #fff;
}

.fn-util-badge .fn-util-pct {
  font-size: 0.85rem;
  line-height: 1;
}

.fn-util-badge .fn-util-label {
  font-size: 0.7rem;
  line-height: 1;
  opacity: 0.92;
}

.fn-day-tiles {
  display: flex;
  flex: 1;
  /* v2.8.1c — inter-tile gap halved (0.5rem → 0.25rem). */
  gap: 0.25rem;
}

.fn-day-tile {
  flex: 1;
  min-width: 100px;
  /* v2.8.1c — padding halved (0.75rem → 0.375rem) for denser tiles. */
  padding: 0.375rem;
  background-color: var(--fn-surface);
  border: 2px solid var(--fn-border);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  position: relative;
  cursor: grab;
  transition: all 0.2s ease;
  overflow: hidden;
}

.fn-day-tile:hover {
  border-color: var(--fn-border-sub);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

/* v2.6.2g (002) — discoverability hint for the right-click "Add visit" menu.
   The handler already works (SchedulerView.OpenEmptyDayContextMenuFromJs) but
   nothing visually signals that cells are right-clickable. Faint centered
   prompt fades in on hover; pointer-events:none so it never blocks the
   contextmenu event itself. v2.8.1c — the data attribute renamed to
   data-day-add-visit (right-click is now eligible on populated days too) but
   the overlay hint stays scoped to empty cells via :not(.fn-day-tile--has-content)
   so it doesn't paint over chips on populated tiles. */
.fn-day-tile[data-day-add-visit="true"] {
  cursor: context-menu;
}

.fn-day-tile[data-day-add-visit="true"]:not(.fn-day-tile--has-content):hover::after {
  content: "+ Right-click to add visit";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  color: var(--fn-text-muted);
  opacity: 0.65;
  pointer-events: none;
  text-align: center;
  padding: 0 0.5rem;
}

.fn-day-tile.selected {
  border-color: var(--fn-accent);
  background-color: var(--fn-raised);
  /* v2.13 — was `0 0 0 3px` (an OUTSET halo that spilled 3px into adjacent tiles and up
     toward the date header); inset keeps the same emphasis contained within the tile. */
  box-shadow: inset 0 0 0 2px rgba(37, 99, 235, 0.12);
}

.fn-day-tile.drag-over {
  background-color: rgba(37, 99, 235, 0.05);
  border-color: var(--fn-accent);
  border-width: 2px;
}

.fn-day-tile.pref-field {
  border-top: 3px solid #10b981;
}

/* Agent-off-day visual indicator. Subtle diagonal stripe + small "off" label.
   Drop is still allowed (soft warning fires in HandleDrop) â€” this is at-a-glance
   only. If the day is also blocked out / a holiday those visualisations land in
   Phase 3; for now the off-day stripe always wins where it fires. */
.fn-day-tile--off-day {
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0,
    transparent 5px,
    rgba(100, 116, 139, 0.28) 5px,
    rgba(100, 116, 139, 0.28) 7px
  );
}

[data-theme="dark"] .fn-day-tile--off-day {
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0,
    transparent 5px,
    rgba(148, 163, 184, 0.32) 5px,
    rgba(148, 163, 184, 0.32) 7px
  );
}

/* Business blockout visual marker â€” red-tinted diagonal stripe distinct from the
   slate NWD stripe. Stripe density mirrors the NWD pattern so the two read as the
   same family at a glance. Soft-warn fires at drop-time regardless of the visual. */
.fn-day-tile--blockout {
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0,
    transparent 5px,
    rgba(220, 38, 38, 0.20) 5px,
    rgba(220, 38, 38, 0.20) 7px
  );
}

/* Compounding NWD + blockout â€” the two stripes don't combine sensibly via the
   single background-image property, so blockout's stripe overrides off-day above
   when both apply. The label hierarchy already shows blockout > NWD; the stripe
   alignment matches. */
.fn-day-tile--off-day.fn-day-tile--blockout {
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0,
    transparent 5px,
    rgba(220, 38, 38, 0.22) 5px,
    rgba(220, 38, 38, 0.22) 7px
  );
}

[data-theme="dark"] .fn-day-tile--blockout {
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0,
    transparent 5px,
    rgba(248, 113, 113, 0.28) 5px,
    rgba(248, 113, 113, 0.28) 7px
  );
}

[data-theme="dark"] .fn-day-tile--off-day.fn-day-tile--blockout {
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0,
    transparent 5px,
    rgba(248, 113, 113, 0.30) 5px,
    rgba(248, 113, 113, 0.30) 7px
  );
}

/* Per-cell leave stripe â€” fires for date-range AgentLeave entries (NOT whole-agent
   OnLeave status, which is signalled at the row level via .fn-agent-row--on-leave).
   Amber diagonal stripe matching the row treatment so the planner reads the two as
   the same family. Drop is still allowed (soft-warn fires in HandleDrop) â€” this is
   at-a-glance only. Blockout's red stripe wins where both apply, mirroring the
   off-day + blockout precedence above. */
.fn-day-tile--leave {
  background-image: repeating-linear-gradient(
    45deg,
    transparent 0,
    transparent 4px,
    rgba(245, 158, 11, 0.22) 4px,
    rgba(245, 158, 11, 0.22) 7px
  );
}

[data-theme="dark"] .fn-day-tile--leave {
  background-image: repeating-linear-gradient(
    45deg,
    transparent 0,
    transparent 4px,
    rgba(252, 211, 77, 0.28) 4px,
    rgba(252, 211, 77, 0.28) 7px
  );
}

/* Off-day labels. Three flavours that may stack independently inside the
   .fn-day-tile-labels flex-column wrapper:
   - .fn-day-tile-nwd-label      : slate/grey, "NWD" (Non-Working Day) per agent work pattern.
   - .fn-day-tile-leave-label    : amber, "Annual Leave" per agent OnLeave status.
   - .fn-day-tile-blockout-label : red, "Blockout" per BusinessBlockout date range.
   When the cell also holds visit chips/travel/overnight (.fn-day-tile--has-content)
   labels fade to 0.5 so chips remain the primary signal but the off-day reasons
   stay readable. The wrapper anchors at top:4px so the badges stack downward; we
   chose a wrapper over hand-tuned top offsets per label so DOM order alone drives
   stacking and so labels can't collide if their heights change. */
.fn-day-tile-labels {
  position: absolute;
  top: 4px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  pointer-events: none;
  z-index: 1;
}

.fn-day-tile-nwd-label,
.fn-day-tile-leave-label,
.fn-day-tile-blockout-label {
  padding: 2px 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: 10px;
  line-height: 1.4;
  white-space: nowrap;
  transition: opacity 0.2s ease;
}

.fn-day-tile-nwd-label {
  color: #475569;
  background-color: rgba(100, 116, 139, 0.15);
  border: 1px solid rgba(100, 116, 139, 0.30);
}

.fn-day-tile-leave-label {
  color: #b45309;
  background-color: rgba(245, 158, 11, 0.18);
  border: 1px solid rgba(245, 158, 11, 0.40);
}

.fn-day-tile-blockout-label {
  color: #b91c1c;
  background-color: rgba(220, 38, 38, 0.15);
  border: 1px solid rgba(220, 38, 38, 0.40);
}

.fn-day-tile--has-content .fn-day-tile-labels {
  opacity: 0.5;
}

[data-theme="dark"] .fn-day-tile-nwd-label {
  color: #cbd5e1;
  background-color: rgba(148, 163, 184, 0.18);
  border-color: rgba(148, 163, 184, 0.35);
}

[data-theme="dark"] .fn-day-tile-leave-label {
  color: #fcd34d;
  background-color: rgba(245, 158, 11, 0.22);
  border-color: rgba(252, 211, 77, 0.40);
}

[data-theme="dark"] .fn-day-tile-blockout-label {
  color: #fca5a5;
  background-color: rgba(220, 38, 38, 0.22);
  border-color: rgba(248, 113, 113, 0.45);
}

/* On-Leave agent row treatment. Overlay a subtle complementary stripe so
   the planner can SEE the visits booked against the agent (for rehoming) but
   the row reads as "do not assign new work". Drag-drop hard block lives in
   SchedulerView.HandleDrop â€” this is presentation only.
   NOTE: previously used opacity: 0.6 on the row; that established a stacking
   context that washed the amber Annual Leave label out to grey (CSS opacity
   compounds and cannot be undone by descendants). The row stripe + per-tile
   leave label now carry the "on leave" signal without dimming. */
.fn-agent-row--on-leave {
  background-image: repeating-linear-gradient(
    45deg,
    transparent 0,
    transparent 4px,
    rgba(245, 158, 11, 0.30) 4px,
    rgba(245, 158, 11, 0.30) 7px
  );
  border-radius: 8px;
}

[data-theme="dark"] .fn-agent-row--on-leave {
  background-image: repeating-linear-gradient(
    45deg,
    transparent 0,
    transparent 4px,
    rgba(252, 211, 77, 0.32) 4px,
    rgba(252, 211, 77, 0.32) 7px
  );
}

.fn-onleave-badge {
  display: inline-block;
  margin-top: 2px;
  padding: 1px 6px;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #b45309;
  background-color: rgba(245, 158, 11, 0.15);
  border: 1px solid rgba(245, 158, 11, 0.35);
  border-radius: 10px;
  line-height: 1.4;
}

[data-theme="dark"] .fn-onleave-badge {
  color: #fcd34d;
  background-color: rgba(245, 158, 11, 0.18);
  border-color: rgba(252, 211, 77, 0.35);
}

.fn-day-tile-content {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1;
  min-height: 0;
}

.fn-status-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.7rem;
  font-weight: 600;
  width: fit-content;
  transition: all 0.2s ease;
}

.fn-status-badge.available {
  background-color: #d1fae5;
  color: #047857;
}

.fn-status-badge.constrained {
  background-color: #fef3c7;
  color: #b45309;
}

.fn-status-badge.unavailable {
  background-color: #fee2e2;
  color: #dc2626;
}

.fn-status-badge.wfh {
  background-color: #dbeafe;
  color: #0284c7;
}

.fn-status-badge.office {
  background-color: #e9d5ff;
  color: #7e22ce;
}

.fn-status-badge.empty {
  background-color: var(--fn-raised);
  color: var(--fn-text-muted);
}

.fn-visit-chip {
  padding: 0.5rem;
  background-color: var(--fn-raised);
  border-left: 3px solid var(--fn-accent);
  border-radius: 4px;
  font-size: 0.8rem;
  color: var(--fn-text);
  cursor: grab;
  transition: all 0.2s ease;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Suppress text selection so click-drag starts an HTML5 drag, not a text-select gesture.
     Without this, the chip's text gets highlighted on mousedown and the drag never starts. */
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}

.fn-visit-chip:hover {
  background-color: rgba(37, 99, 235, 0.1);
  transform: translateX(2px);
}

.fn-visit-chip:active {
  cursor: grabbing;
}

/* --- Visit lifecycle status modifiers (Phase 2c) ----------------------------
   Stack on top of .fn-visit-chip; each modifier overrides the base border /
   background / text decoration to match the spec wireframe states.
   - Scheduled: solid blue border (default â€” uses base .fn-visit-chip).
   - Confirmed: solid green border + check-ring badge inside the chip.
   - Complete : muted green background + âœ“ badge, no border emphasis, not interactive.
   - Cancelled: grey strikethrough on text, muted background, reason on title hover.
   The existing soft-violation âš  corner badge is independent (sits on top via z-index).
   --------------------------------------------------------------------------- */
.fn-visit--scheduled {
  border-left: 3px solid #2563eb;
}

.fn-visit--confirmed {
  border-left: 3px solid #10b981;
  border-top: 1px solid #a7f3d0;
  border-right: 1px solid #a7f3d0;
  border-bottom: 1px solid #a7f3d0;
}

.fn-visit--confirmed .fn-visit-status-icon {
  color: #047857;
}

.fn-visit--complete {
  background-color: #d1fae5 !important;
  border-left: 3px solid #6ee7b7;
  color: #065f46;
  cursor: default;
  opacity: 1 !important;
}

.fn-visit--complete:hover {
  transform: none;
  background-color: #d1fae5 !important;
}

.fn-visit--complete .fn-visit-status-icon {
  color: #047857;
}

.fn-visit--cancelled {
  background-color: #f1f5f9 !important;
  border-left: 3px solid #94a3b8;
  color: #64748b;
  text-decoration: line-through;
  cursor: help;
  opacity: 0.85;
}

.fn-visit--cancelled:hover {
  transform: none;
  background-color: #e2e8f0 !important;
}

/* Tiny inline status icon used inside .fn-visit-chip when Confirmed/Complete. */
.fn-visit-status-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  margin-right: 4px;
  font-weight: 700;
}

/* Dark-mode overrides â€” match the existing pattern where light surfaces invert
   to slate/teal tones rather than retaining the bright Tailwind palette. */
[data-theme="dark"] .fn-visit--scheduled {
  border-left-color: #3b82f6;
}

[data-theme="dark"] .fn-visit--confirmed {
  border-left-color: #34d399;
  border-top-color: #065f46;
  border-right-color: #065f46;
  border-bottom-color: #065f46;
}

[data-theme="dark"] .fn-visit--confirmed .fn-visit-status-icon {
  color: #6ee7b7;
}

[data-theme="dark"] .fn-visit--complete {
  background-color: #064e3b !important;
  /* 2026-04-28 planner feedback: site name was hard to read in muted-green text;
     force white for readability. Status accent comes from background + border. */
  color: #fff;
  border-left-color: #34d399;
}

[data-theme="dark"] .fn-visit--complete:hover {
  background-color: #064e3b !important;
}

[data-theme="dark"] .fn-visit--complete .fn-visit-status-icon {
  color: #6ee7b7;
}

[data-theme="dark"] .fn-visit--cancelled {
  background-color: #1e293b !important;
  /* Same fix as Complete â€” site name was unreadably grey; switch to white and let
     the strikethrough + reduced opacity carry the "cancelled" signal. */
  color: #fff;
  border-left-color: #64748b;
}

[data-theme="dark"] .fn-visit--cancelled:hover {
  background-color: #1e293b !important;
}

/* ─── Phase 4 — WFH/Office chips ───────────────────────────── */
/* DayTile chip blocks: visit-style chip rendered alongside visits.
   Indigo for WFH (matches retired DayLabels.StatusColors["wfh"]); Blue for
   Office. Hover/focus affordances mirror visit chips. Palette aligned with
   .fa-badge--wfh / .fa-badge--office for a unified colour vocabulary across
   planner-side chips and FA-side badges. */
.fn-chip {
    padding: 0.5rem;
    border-radius: 4px;
    font-size: 0.8rem;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    user-select: none;
    display: flex;
    gap: 0.4rem;
    align-items: center;
    transition: filter 120ms ease, transform 120ms ease;
}
.fn-chip--wfh    { background: #ede9fe; border-left: 3px solid #818cf8; color: #4c1d95; }
.fn-chip--office { background: #dbeafe; border-left: 3px solid #60a5fa; color: #1e3a8a; }
.fn-chip:hover { transform: translateX(2px); filter: brightness(0.97); }
.fn-chip:focus-visible { outline: 2px solid #3b82f6; outline-offset: 2px; }
.fn-chip__label    { font-weight: 600; }
.fn-chip__duration { font-size: 0.7rem; opacity: 0.85; }

/* DayDetailPanel chip-list row + add-button header */
.fn-chip-row { display: flex; align-items: center; gap: 0.4rem; padding: 0.4rem 0.5rem; border-radius: 6px; }
.fn-chip-row.fn-chip--wfh    { background: #ede9fe; }
.fn-chip-row.fn-chip--office { background: #dbeafe; }

/* v2.13.0 — day-level affordances (chip-add + overnight toggle) live in a
   single horizontal row below the capacity bar; visit rows split into head /
   times bands. v2.13.1 — duration spinner + reorder/confirm/unassign buttons
   collapsed into the times band (single visit-row line). */
.fn-chip-button-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.5rem 0 0.75rem; }
.fn-chip-button-row__warn { color: #d97706; font-size: 0.75rem; margin-top: 0.25rem; margin-bottom: 0.5rem; }
.fn-visit-row__head { display: flex; align-items: center; gap: 0.5rem; }
.fn-visit-row__head .fn-visit-status-pill { margin-left: auto; }
.fn-visit-row__times { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
/* v2.19 — the day-panel time pickers (visit start/end, WFH chip, office chip) were
   clipping "17:55"/"09:00" style values. The input is width:100% of the picker, but
   Radzen reserves a generous padding-inline-end of calc(1rem + icon-width) (~2.25rem)
   to clear the absolutely-positioned clock trigger, and that (plus the ~90px field cap)
   left too little room for the text. Scoped to the whole panel so every HH:mm picker
   shares the fix: keep enough right padding to clear the icon but trim the surplus, and
   shave the left padding — so the time always shows in full without a much wider field. */
.fn-detail-panel .rz-datepicker > .rz-inputtext {
  padding-inline-start: 0.35rem;
  padding-inline-end: calc(0.4rem + var(--rz-datepicker-trigger-icon-width));
}

/* Dark mode — desaturate the kind-tinted backgrounds, keep the kind hue */
[data-theme="dark"] .fn-chip--wfh,
[data-theme="dark"] .fn-chip-row.fn-chip--wfh    { background: rgba(129,140,248,0.18); border-left-color: #818cf8; color: #c4b5fd; }
[data-theme="dark"] .fn-chip--office,
[data-theme="dark"] .fn-chip-row.fn-chip--office { background: rgba(96,165,250,0.18);  border-left-color: #60a5fa; color: #93c5fd; }

/* Phase 2c â€” dialog component shared layout (CancelVisitDialog, SendBackToBucketDialog). */
.fn-dialog-body {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 0.85rem;
}

.fn-dialog-subtitle {
  font-weight: 600;
  color: var(--fn-text);
  margin-bottom: 0.5rem;
}

.fn-dialog-label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--fn-text-sub);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 0.25rem;
}

.fn-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}

/* Phase 5b â€” three-way "out of cadence window" prompt. Two stacked option cards
   (ShiftAnchor / Override) above a single Cancel button. Cards behave like
   buttons (full-width, hover/focus states) so the choice reads as picking a
   path, not filling a form. */
/* v1c smoke-fix â€” surface the cadence window dates inside the prompt so the
   planner sees when the visit IS due. */
.fn-cadence-prompt-window {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
  margin: 0 0 0.5rem 0;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
}

.fn-cadence-prompt-window-label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fn-text-sub);
}

.fn-cadence-prompt-window-value {
  font-weight: 700;
  color: var(--fn-text);
}

.fn-cadence-prompt-window-target {
  font-size: 0.75rem;
  color: var(--fn-text-sub);
}

.fn-cadence-prompt-options {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0.25rem 0 0.25rem 0;
}

.fn-cadence-prompt-option {
  text-align: left;
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  padding: 0.6rem 0.75rem;
  cursor: pointer;
  color: var(--fn-text);
  transition: border-color 0.12s ease, background-color 0.12s ease, box-shadow 0.12s ease;
}

.fn-cadence-prompt-option:hover {
  border-color: var(--fn-border-sub);
  background-color: var(--fn-bg);
}

.fn-cadence-prompt-option:focus-visible {
  outline: none;
  border-color: var(--fn-accent);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.2);
}

.fn-cadence-prompt-option--primary {
  border-color: var(--fn-accent);
  border-left: 4px solid var(--fn-accent);
}

.fn-cadence-prompt-option--primary:hover {
  border-color: var(--fn-accent-hover);
  background-color: var(--fn-bg);
}

.fn-cadence-prompt-option-title {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--fn-text);
  margin-bottom: 0.15rem;
}

.fn-cadence-prompt-option-sub {
  font-size: 0.75rem;
  color: var(--fn-text-sub);
  line-height: 1.35;
}

/* Phase 7a — disabled-ShiftAnchor row in the cadence prompt. Daily / Weekly /
   Fortnightly cadence types render the option with the same shape but greyed
   out + non-clickable so the dialog control surface stays predictable. The
   sub-text carries the "use Override instead" hint. */
.fn-cadence-prompt-option--disabled {
  opacity: 0.55;
  cursor: not-allowed;
  background-color: var(--fn-bg-muted, var(--fn-bg));
}

.fn-cadence-prompt-option--disabled:hover {
  border-color: var(--fn-border);
  background-color: var(--fn-bg-muted, var(--fn-bg));
}

.fn-cadence-shiftanchor-disabled {
  font-style: italic;
}

/* Phase 5d-4 â€” multi-day route spread preview dialog. Shows a day-by-day plan with
   capacity bars + ordered stop lists + a skipped section + pinned-visit warnings. */
.fn-dialog-hint {
  margin: 0 0 0.75rem 0;
  font-size: 0.8rem;
  color: var(--fn-text-sub);
  line-height: 1.4;
}

.fn-dialog-empty {
  font-size: 0.85rem;
  color: var(--fn-text-sub);
  font-style: italic;
  padding: 1rem 0;
}

.fn-spread-empty-state {
  padding: 0.75rem;
  background: rgba(239, 68, 68, 0.08);
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-radius: 6px;
  font-size: 0.85rem;
  color: var(--fn-text);
}

.fn-spread-day-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.fn-spread-day {
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  padding: 0.5rem 0.6rem;
  background: var(--fn-surface);
}

.fn-spread-day-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.3rem;
  font-size: 0.8rem;
  flex-wrap: wrap;
}

.fn-spread-day-stops-count {
  color: var(--fn-text-sub);
  font-size: 0.75rem;
}

.fn-spread-day-pinned {
  margin-left: auto;
  font-size: 0.7rem;
  padding: 0.1rem 0.4rem;
  background: rgba(245, 158, 11, 0.15);
  color: #b45309;
  border-radius: 999px;
}

[data-theme="dark"] .fn-spread-day-pinned {
  background: rgba(245, 158, 11, 0.25);
  color: #fbbf24;
}

.fn-spread-day-bar {
  height: 4px;
  background: var(--fn-border);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 0.4rem;
}

.fn-spread-day-bar-fill {
  height: 100%;
  background: var(--fn-accent);
}

.fn-spread-day-stops {
  margin: 0;
  padding-left: 1.4rem;
  font-size: 0.78rem;
  color: var(--fn-text);
}

.fn-spread-day-stops li {
  padding: 0.1rem 0;
}

.fn-spread-stop-name {
  font-weight: 500;
}

.fn-spread-stop-sub {
  margin-left: 0.4rem;
  color: var(--fn-text-muted);
  font-size: 0.72rem;
}

.fn-spread-skipped {
  margin: 0.5rem 0 0.75rem 0;
  padding: 0.6rem 0.75rem;
  background: rgba(239, 68, 68, 0.08);
  border: 1px solid rgba(239, 68, 68, 0.25);
  border-radius: 6px;
  font-size: 0.78rem;
}

.fn-spread-skipped-head {
  font-weight: 600;
  margin-bottom: 0.3rem;
  color: #b91c1c;
}

[data-theme="dark"] .fn-spread-skipped-head {
  color: #fca5a5;
}

.fn-spread-skipped ul {
  margin: 0;
  padding-left: 1.2rem;
}

.fn-spread-skipped-msg {
  color: var(--fn-text-muted);
  font-size: 0.72rem;
}

/* SMOKE-016 / v1.0.5 — soft-prompt over-capacity warnings in the route spread
   preview. Amber tone (vs the red of the hard-skip section above) signals
   "will be placed if you confirm" rather than "will be dropped". */
.fn-spread-warnings {
  margin: 0.5rem 0 0.75rem 0;
  padding: 0.6rem 0.75rem;
  background: rgba(245, 158, 11, 0.1);
  border: 1px solid rgba(245, 158, 11, 0.35);
  border-radius: 6px;
  font-size: 0.78rem;
}

.fn-spread-warnings-head {
  font-weight: 600;
  margin-bottom: 0.3rem;
  color: #b45309;
}

[data-theme="dark"] .fn-spread-warnings-head {
  color: #fbbf24;
}

.fn-spread-warnings ul {
  margin: 0;
  padding-left: 1.2rem;
}

.fn-spread-warnings-msg {
  display: block;
  color: var(--fn-text-muted);
  font-size: 0.72rem;
  margin-left: 0.25rem;
}

.fn-spread-warning {
  margin: 0.5rem 0 0.5rem 0;
  padding: 0.5rem 0.75rem;
  background: rgba(245, 158, 11, 0.1);
  border: 1px solid rgba(245, 158, 11, 0.3);
  border-radius: 6px;
  font-size: 0.78rem;
  color: var(--fn-text);
}

/* Status badge used at the top of a visit row in DayDetailPanel. Visually
   echoes the chip colours so the planner sees consistent state across the
   grid + the detail panel. */
.fn-visit-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.7rem;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.fn-visit-status-pill--scheduled {
  background-color: #dbeafe;
  color: #1d4ed8;
}

.fn-visit-status-pill--confirmed {
  background-color: #d1fae5;
  color: #047857;
}

.fn-visit-status-pill--complete {
  background-color: #a7f3d0;
  color: #064e3b;
}

.fn-visit-status-pill--cancelled {
  background-color: #e2e8f0;
  color: #475569;
}

[data-theme="dark"] .fn-visit-status-pill--scheduled {
  background-color: #1e3a8a;
  color: #bfdbfe;
}

[data-theme="dark"] .fn-visit-status-pill--confirmed {
  background-color: #064e3b;
  color: #a7f3d0;
}

[data-theme="dark"] .fn-visit-status-pill--complete {
  background-color: #065f46;
  color: #d1fae5;
}

[data-theme="dark"] .fn-visit-status-pill--cancelled {
  background-color: #334155;
  color: #cbd5e1;
}

.fn-travel-chip {
  padding: 0.35rem 0.5rem;
  background-color: #f0f9ff;
  border-left: 2px solid #0ea5e9;
  border-radius: 3px;
  font-size: 0.75rem;
  color: #0369a1;
  font-style: italic;
}

[data-theme="dark"] .fn-travel-chip {
  background-color: #082f49;
  color: #7dd3fc;
}

.fn-overnight-chip {
  padding: 0.35rem 0.5rem;
  background-color: #f3f0ff;
  border-left: 2px solid #a855f7;
  border-radius: 3px;
  font-size: 0.75rem;
  color: #7e22ce;
}

[data-theme="dark"] .fn-overnight-chip {
  background-color: #3f0f64;
  color: #d8b4fe;
}

/* v2.0a — "trip continues" indicator. Renders on continuation days of a multi-day
   overnight trip (NOT on the trip's first overnight, NOT on the tail). Visually
   sits above the existing Overnight chip; uses a slightly cooler purple-tinted
   amber so it reads as "context" rather than another action chip. */
.fn-trip-continues {
  padding: 0.25rem 0.5rem;
  background-color: #fef3c7;
  border-left: 2px solid #d97706;
  border-radius: 3px;
  font-size: 0.7rem;
  color: #92400e;
  font-style: italic;
}

[data-theme="dark"] .fn-trip-continues {
  background-color: #3f2a08;
  color: #fcd34d;
}

.fn-capacity-bar {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, #10b981 0%, #f59e0b 70%, #ef4444 100%);
  border-radius: 0 0 6px 6px;
}

/* Phase 6.5b — split-day capacity bar. Three contiguous coloured stripes
   (office / travel / site) replace the single linear-gradient bar above when any
   bucket is non-zero. Each segment's width is share-of-total set inline by
   DayTile.razor. The container itself is still positioned absolutely along the
   bottom of the tile; the segments flex left-to-right and clip past 100%. */
.fn-capacity-bar--split {
  background: transparent;
  display: flex;
  flex-direction: row;
  height: 3px;
  width: 100%;
  overflow: hidden;
}

.fn-capacity-bar-segment {
  height: 100%;
  display: block;
}

.fn-capacity-bar-segment--office {
  /* Violet — distinct from agent identity colours; reads as "indoor admin time". */
  background-color: #8b5cf6;
}

.fn-capacity-bar-segment--travel {
  /* Orange — matches the existing travel-chip family used on the FA timeline. */
  background-color: #f59e0b;
}

.fn-capacity-bar-segment--site {
  /* Green — matches the on-track status colour the planner already associates
     with capacity headroom. */
  background-color: #10b981;
}

/* Dark-mode tokens — slightly punchier so the 3-pixel band stays visible against
   the schedule grid's darker tile background. */
[data-theme="dark"] .fn-capacity-bar-segment--office {
  background-color: #a78bfa;
}

[data-theme="dark"] .fn-capacity-bar-segment--travel {
  background-color: #fbbf24;
}

[data-theme="dark"] .fn-capacity-bar-segment--site {
  background-color: #34d399;
}

/* Detail Panel */

.fn-detail-panel {
  padding: 1.5rem;
  background-color: var(--fn-surface);
  border-top: 1px solid var(--fn-border);
  max-height: 300px;
  overflow-y: auto;
}

.fn-detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

.fn-detail-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--fn-text);
}

.fn-timeline {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
  padding: 0.5rem;
  background-color: var(--fn-raised);
  border-radius: 6px;
  height: 40px;
  align-items: center;
  overflow-x: auto;
}

.fn-timeline-segment {
  flex-shrink: 0;
  height: 24px;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 600;
  color: white;
  transition: all 0.2s ease;
}

.fn-timeline-segment.visit {
  background-color: var(--fn-accent);
}

.fn-timeline-segment.travel {
  background-color: #0ea5e9;
}

.fn-timeline-segment.admin {
  background-color: #a855f7;
}

.fn-timeline-segment.break {
  background-color: #6b7280;
}

/* Radzen Component Overrides */

.rz-button {
  font-family: inherit;
  transition: all 0.2s ease;
}

.rz-button.rz-button-md {
  padding: 0.5rem 1rem;
  border-radius: 6px;
}

.rz-button:not(.rz-button-flat) {
  background-color: var(--fn-accent);
  border-color: var(--fn-accent);
  color: white;
}

.rz-button:not(.rz-button-flat):hover:not(:disabled) {
  background-color: var(--fn-accent-hover);
  border-color: var(--fn-accent-hover);
}

.rz-button.rz-button-flat {
  color: var(--fn-accent);
}

.rz-button.rz-button-flat:hover:not(:disabled) {
  background-color: rgba(37, 99, 235, 0.1);
}

.rz-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.rz-card {
  background-color: var(--fn-surface);
  border-color: var(--fn-border);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  border-radius: 8px;
}

.rz-badge {
  border-radius: 12px;
  font-weight: 600;
  font-size: 0.8rem;
}

.rz-dropdown {
  background-color: var(--fn-surface);
  border-color: var(--fn-border);
  color: var(--fn-text);
  border-radius: 6px;
}

.rz-dropdown:focus {
  border-color: var(--fn-accent);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}

.rz-input {
  background-color: var(--fn-surface);
  border-color: var(--fn-border);
  color: var(--fn-text);
  border-radius: 6px;
}

.rz-input:focus {
  border-color: var(--fn-accent);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}

.rz-dialog {
  background-color: var(--fn-surface);
}

.rz-dialog-title {
  color: var(--fn-text);
}

/* Utility Classes */

.fn-flex-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.fn-flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

.fn-gap-sm {
  gap: 0.5rem;
}

.fn-gap-md {
  gap: 1rem;
}

.fn-gap-lg {
  gap: 1.5rem;
}

.fn-text-sm {
  font-size: 0.875rem;
}

.fn-text-xs {
  font-size: 0.75rem;
}

.fn-text-muted {
  color: var(--fn-text-muted);
}

.fn-text-sub {
  color: var(--fn-text-sub);
}

.fn-rounded-sm {
  border-radius: 4px;
}

.fn-rounded-md {
  border-radius: 8px;
}

.fn-rounded-lg {
  border-radius: 12px;
}

.fn-p-xs {
  padding: 0.25rem;
}

.fn-p-sm {
  padding: 0.5rem;
}

.fn-p-md {
  padding: 1rem;
}

.fn-p-lg {
  padding: 1.5rem;
}

.fn-m-0 {
  margin: 0;
}

.fn-shadow-sm {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.fn-shadow-md {
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.fn-cursor-grab {
  cursor: grab;
}

.fn-cursor-grabbing {
  cursor: grabbing;
}

/* Responsive Adjustments */

@media (max-width: 1024px) {
  .fn-topbar {
    padding: 0.5rem 1rem;
    gap: 1rem;
  }

  .fn-app-title {
    font-size: 1.1rem;
  }

  .fn-agent-card {
    flex: 0 0 120px;
  }

  /* Narrow the agent-card column on viewports <1200px (header + agent rows
     share the same column template via --fn-card-col, so changing it once
     keeps columns lock-step). */
  .fn-schedule-grid {
    --fn-card-col: 120px;
  }
}

@media (max-width: 768px) {
  body {
    font-size: 13px;
  }

  .fn-topbar {
    flex-wrap: wrap;
    padding: 0.5rem;
    gap: 0.5rem;
  }

  .fn-topbar-tabs {
    width: 100%;
    gap: 0.25rem;
  }

  .fn-topbar-right {
    width: 100%;
    gap: 0.5rem;
  }

  .fn-schedule-grid {
    padding: 0.5rem;
    gap: 0.25rem;
  }

  .fn-agent-row {
    /* Mobile: opt out of the shared grid and stack vertically. .fn-date-header
       is hidden at this breakpoint so column lock-step doesn't matter. */
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
  }

  .fn-day-tiles {
    flex-direction: column;
  }

  .fn-agent-card {
    flex: 0 0 auto;
    min-height: 60px;
  }

  .fn-date-header,
  .fn-week-header-grid {
    display: none;
  }
}

/* Print Styles */

@media print {
  .fn-topbar,
  .fn-sidebar,
  .rz-dialog,
  button {
    display: none;
  }

  .fn-shell {
    height: auto;
  }

  .fn-schedule-grid {
    padding: 0;
  }
}


/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   FIELD AGENT VIEW  (fa-*)
   All colours reference --fn-* design tokens from :root / [data-theme="dark"]
   â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

/* â”€â”€ Shell layout â”€â”€ */
.fa-shell {
  display: flex;
  flex: 1;
  overflow: hidden;
  background-color: var(--fn-bg);
}

/* â”€â”€ Left Sidebar â”€â”€ */
.fa-sidebar {
  flex: 0 0 232px;
  display: flex;
  flex-direction: column;
  background-color: var(--fn-surface);
  border-right: 1px solid var(--fn-border);
  overflow-y: auto;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.fa-sidebar-hdr {
  padding: 14px 16px;
  border-bottom: 1px solid var(--fn-border);
  flex-shrink: 0;
}

.fa-sidebar-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.3px;
  color: var(--fn-text);
}

.fa-section-label {
  padding: 14px 16px 6px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fn-text-muted);
}

/* â”€â”€ Agent list â”€â”€ */
.fa-agent-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 0 8px;
}

.fa-agent-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 8px;
  border: none;
  background: none;
  border-radius: 6px;
  cursor: pointer;
  width: 100%;
  text-align: left;
  color: var(--fn-text);
  transition: background-color 0.15s ease;
}

.fa-agent-item:hover {
  background-color: var(--fn-raised);
}

.fa-agent-item--active {
  background-color: rgba(37, 99, 235, 0.10);
}

[data-theme="dark"] .fa-agent-item--active {
  background-color: rgba(59, 130, 246, 0.15);
}

.fa-avatar {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
}

.fa-agent-info {
  flex: 1;
  min-width: 0;
}

.fa-agent-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--fn-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fa-agent-sub {
  font-size: 11px;
  color: var(--fn-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fa-check-icon {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 700;
  color: var(--fn-accent);
}

/* â”€â”€ Week tabs â”€â”€ */
.fa-week-tabs {
  display: flex;
  gap: 4px;
  padding: 0 8px;
}

.fa-week-tab {
  flex: 1;
  padding: 5px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  background: none;
  color: var(--fn-text-sub);
  cursor: pointer;
  transition: all 0.15s ease;
  font-family: inherit;
}

.fa-week-tab:hover {
  background-color: var(--fn-raised);
}

.fa-week-tab--active {
  background-color: var(--fn-accent);
  border-color: var(--fn-accent);
  color: #fff;
}

/* v2.13.x — Plusnet quick-launch buttons in the FA sidebar Tools section.
   External links (Consult, Referral) styled to match the week-tab pillbox
   chrome so they read as buttons inside the sidebar. */
.fa-tool-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 0 12px;
}

.fa-tool-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  background: none;
  color: var(--fn-text-sub);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: all 0.15s ease;
}

.fa-tool-btn:hover {
  background-color: var(--fn-raised);
  color: var(--fn-text);
}

.fa-tool-btn:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

.fa-tool-btn-ico {
  opacity: 0.6;
  font-size: 0.9em;
  margin-left: 8px;
}

/* â”€â”€ Main panel â”€â”€ */
.fa-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background-color: var(--fn-bg);
}

/* â”€â”€ Empty / no-agent state â”€â”€ */
.fa-empty-state {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  color: var(--fn-text-muted);
}

.fa-empty-icon  { font-size: 52px; }
.fa-empty-text  { font-size: 14px; }

/* â”€â”€ Day header â”€â”€ */
.fa-day-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  background-color: var(--fn-surface);
  border-bottom: 1px solid var(--fn-border);
  flex-shrink: 0;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.fa-day-header-left {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.fa-day-heading {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.5px;
  color: var(--fn-text);
}

.fa-day-badges {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.fa-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
}

.fa-badge--field    { background-color: #dcfce7; color: #166534; }
.fa-badge--office   { background-color: #dbeafe; color: #1e3a8a; }
.fa-badge--wfh      { background-color: #ede9fe; color: #4c1d95; }
.fa-badge--overnight{ background-color: #fef3c7; color: #92400e; }

[data-theme="dark"] .fa-badge--field     { background-color: rgba(16,185,129,0.18); color: #6ee7b7; }
[data-theme="dark"] .fa-badge--office    { background-color: rgba(59,130,246,0.18);  color: #93c5fd; }
[data-theme="dark"] .fa-badge--wfh       { background-color: rgba(129,140,248,0.18); color: #c4b5fd; }
[data-theme="dark"] .fa-badge--overnight { background-color: rgba(245,158,11,0.18);  color: #fcd34d; }

.fa-day-header-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}

.fa-status-pill {
  padding: 4px 13px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
}

.fa-header-time {
  font-size: 12px;
  color: var(--fn-text-muted);
}

/* â”€â”€ Non-field states (Office / WFH / Empty) â”€â”€ */
.fa-non-field-state {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 32px;
}

.fa-nf-icon  { font-size: 56px; }

.fa-nf-title {
  font-size: 18px;
  font-weight: 600;
  color: var(--fn-text-sub);
}

.fa-nf-sub {
  font-size: 13px;
  color: var(--fn-text-muted);
  text-align: center;
}

/* â”€â”€ Route scroll container â”€â”€ */
.fa-route-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 24px;
  display: flex;
  flex-direction: column;
}

.fa-route-scroll--centered {
  align-items: center;
  justify-content: center;
}

/* â”€â”€ Route timeline wrapper â”€â”€ */
.fa-route-timeline {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 620px;
  margin: 0 auto;
  gap: 0;
}

/* â”€â”€ Waypoints (start & end) â”€â”€ */
.fa-waypoint {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 16px;
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.fa-waypoint-icon {
  font-size: 20px;
  line-height: 1;
  padding-top: 2px;
}

.fa-waypoint-info  { flex: 1; }

.fa-waypoint-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fn-text-muted);
  margin-bottom: 3px;
}

.fa-waypoint-address {
  font-size: 13px;
  font-weight: 500;
  color: var(--fn-text);
}

.fa-waypoint-sub  { color: var(--fn-text-muted); }

.fa-hotel-conf {
  font-size: 11px;
  color: var(--fn-text-muted);
  margin-top: 3px;
}

/* â”€â”€ Travel leg connector â”€â”€ */
.fa-travel-leg {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 20px;
  gap: 0;
}

.fa-tl-line {
  width: 2px;
  height: 14px;
  background-color: var(--fn-border-sub);
}

.fa-tl-line--admin {
  background-color: #818cf8;
  opacity: 0.45;
}

.fa-tl-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 14px;
  background-color: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 999px;
  font-size: 12px;
  color: var(--fn-text-sub);
  white-space: nowrap;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.fa-tl-chip--admin {
  background-color: rgba(129, 140, 248, 0.10);
  border-color: rgba(129, 140, 248, 0.35);
  color: #818cf8;
}

.fa-tl-car      { font-size: 13px; }
.fa-tl-duration { font-weight: 700; color: var(--fn-text); }
.fa-tl-label    { font-size: 11px; color: var(--fn-text-muted); }

/* â”€â”€ Stop card â”€â”€ */
.fa-stop-card {
  position: relative;
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-left: 3px solid #10b981;
  border-radius: 10px;
  overflow: hidden;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.fa-stop-badge {
  position: absolute;
  top: 10px;
  right: 12px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fn-text-muted);
}

.fa-stop-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--fn-border);
}

.fa-stop-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--fn-text);
  padding-right: 64px;  /* clear the stop badge */
}

.fa-stop-sub {
  font-size: 12px;
  color: var(--fn-text-sub);
  margin-top: 2px;
}

.fa-stop-duration-pill {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--fn-text-sub);
  background-color: var(--fn-raised);
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--fn-border);
  white-space: nowrap;
  margin-top: 2px;
}

.fa-stop-body {
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.fa-stop-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.fa-stop-row--notes {
  padding-top: 6px;
  border-top: 1px solid var(--fn-border);
}

.fa-stop-ico {
  font-size: 14px;
  flex-shrink: 0;
  line-height: 1.5;
}

.fa-stop-val {
  font-size: 13px;
  color: var(--fn-text-sub);
  line-height: 1.5;
}

.fa-stop-val--notes {
  color: var(--fn-text-muted);
  font-style: italic;
}

.fa-stop-phone {
  color: var(--fn-text-muted);
}

/* Phase 2c â€” Complete-visit form embedded inside a stop card. */
.fa-stop-status {
  padding: 0 16px 6px;
}

.fa-stop-actions {
  padding: 6px 16px 14px;
  border-top: 1px solid var(--fn-border);
}

.fa-complete-form {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  background: var(--fn-raised);
  border-radius: 8px;
  padding: 0.75rem;
}

.fa-complete-form-title {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--fn-text);
  margin-bottom: 0.25rem;
}

.fa-complete-time-row {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.fa-time-input {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--fn-border);
  border-radius: 4px;
  background: var(--fn-surface);
  color: var(--fn-text);
  font-size: 0.85rem;
}

.fa-complete-error {
  color: #ef4444;
  font-size: 0.75rem;
  margin-top: 0.25rem;
}

.fa-complete-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.4rem;
  margin-top: 0.5rem;
}

.fa-stop-completed {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 8px 16px 14px;
  font-size: 0.8rem;
  color: #047857;
  border-top: 1px solid var(--fn-border);
}

[data-theme="dark"] .fa-stop-completed {
  color: #6ee7b7;
}

.fa-pref-chip {
  display: inline-block;
  padding: 1px 7px;
  background-color: var(--fn-raised);
  border-radius: 4px;
  font-size: 11px;
  color: var(--fn-text-muted);
  text-transform: capitalize;
  border: 1px solid var(--fn-border);
}

.fa-stop-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding-top: 4px;
}

.fa-tag {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: 4px;
}

.fa-tag--ok   { background-color: #dcfce7; color: #166534; }
.fa-tag--warn { background-color: #fee2e2; color: #991b1b; }

[data-theme="dark"] .fa-tag--ok   { background-color: rgba(16,185,129,0.18); color: #6ee7b7; }
[data-theme="dark"] .fa-tag--warn { background-color: rgba(239,68,68,0.18);  color: #fca5a5; }


/* â”€â”€ Capacity footer â”€â”€ */
.fa-cap-footer {
  flex-shrink: 0;
  border-top: 1px solid var(--fn-border);
  background-color: var(--fn-surface);
  padding: 10px 24px 12px;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.fa-cap-bar {
  display: flex;
  height: 6px;
  border-radius: 3px;
  overflow: hidden;
  gap: 2px;
  margin-bottom: 9px;
  background-color: var(--fn-raised);
}

.fa-cap-seg {
  border-radius: 2px;
  min-width: 2px;
}

.fa-cap-seg--rem {
  background-color: var(--fn-raised);
  border: 1px solid var(--fn-border);
}

.fa-cap-legend {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.fa-cap-stat {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--fn-text-sub);
}

.fa-cap-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
}

.fa-cap-remaining {
  margin-left: auto;
  font-size: 12px;
  font-weight: 600;
  color: var(--fn-text-sub);
}

.fa-cap-remaining--over {
  color: #ef4444;
}

/* ------------------------------------------------------------
   Phase 6 smoke fix â€” "Completed today" terminal section.
   Renders Complete + Cancelled visits below the live timeline so the agent
   sees their day's record. Spec rule "Complete and Cancelled visits STAY
   in the day list (terminal but visible â€” muted green âœ“ / grey strikethrough)"
   applied to FA.
   ------------------------------------------------------------ */
.fa-terminal-section {
  padding: 16px 24px 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.fa-terminal-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.fa-terminal-card {
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  padding: 10px 12px;
  background-color: var(--fn-surface);
  border-left: 3px solid var(--fn-text-muted);
}

.fa-terminal-card--complete {
  border-left-color: #10b981;
  opacity: 0.85;
}

.fa-terminal-card--cancelled {
  border-left-color: var(--fn-text-muted);
  opacity: 0.65;
}

.fa-terminal-card--cancelled .fa-terminal-title {
  text-decoration: line-through;
  color: var(--fn-text-sub);
}

.fa-terminal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}

.fa-terminal-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--fn-text);
}

.fa-terminal-sub {
  font-size: 12px;
  color: var(--fn-text-sub);
  margin-bottom: 4px;
}

.fa-terminal-meta {
  font-size: 12px;
  color: var(--fn-text-sub);
}

.fa-terminal-details {
  font-size: 12px;
  color: var(--fn-text-muted);
  font-style: italic;
  margin-top: 4px;
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------------
   Phase 6 smoke fix â€” Field Agent live-notes textarea (ProgressNotes).
   Sits between the Mark-complete button and the outcome form. Save-state pill
   below the textarea so the agent sees when keystrokes have actually persisted â€”
   non-negotiable per BA verdict (don't silently lose data on partial connectivity).
   ------------------------------------------------------------ */
.fa-progress-notes {
  margin: 8px 16px 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.fa-progress-notes-input {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 10px;
  font-size: 14px;
  font-family: inherit;
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  background-color: var(--fn-surface);
  color: var(--fn-text);
  resize: vertical;
  min-height: 64px;
}

.fa-progress-notes-input:focus {
  outline: none;
  border-color: var(--fn-accent);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
}

.fa-progress-notes-meta {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--fn-text-sub);
}

.fa-progress-notes-state {
  font-weight: 500;
}

.fa-progress-notes-state--idle { color: transparent; }
.fa-progress-notes-state--saving { color: var(--fn-text-sub); }
.fa-progress-notes-state--saved { color: #10b981; }
.fa-progress-notes-state--failed { color: #ef4444; font-weight: 600; }

.fa-progress-notes-counter {
  color: var(--fn-text-muted);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------
   Phase 6b â€” Field Agent mobile-first responsive layout

   The desktop layout (sidebar + main) collapses below 768px into a
   stacked column with horizontally scrolling agent + day strips. Stop
   cards become full-width with bigger tap targets so an agent on
   their phone can confirm/complete a visit one-handed.
   ------------------------------------------------------------ */
@media (max-width: 768px) {
  .fa-shell {
    flex-direction: column;
    overflow: auto;
  }

  /* Sidebar collapses into a sticky horizontal strip at the top. */
  .fa-sidebar {
    flex: 0 0 auto;
    flex-direction: column;
    border-right: none;
    border-bottom: 1px solid var(--fn-border);
    overflow: visible;
    position: sticky;
    top: 0;
    z-index: 5;
  }

  .fa-sidebar-hdr {
    padding: 10px 12px;
  }

  /* Agents become a horizontal chip strip â€” tap to switch agent. */
  .fa-agent-list {
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    gap: 6px;
    padding: 8px 12px;
    -webkit-overflow-scrolling: touch;
  }

  .fa-agent-item {
    flex: 0 0 auto;
    min-width: 160px;
    padding: 8px 10px;
  }

  /* Week tabs full-width row. */
  .fa-week-tabs {
    padding: 0 12px;
    gap: 6px;
  }

  /* Main content gets full width + scrollable inside. overflow-x is `clip` rather
     than `hidden` so it visually clips runaway children WITHOUT establishing a new
     scroll container. (The legacy chip-row was a horizontal scroller â€” replaced by
     the day-stepper, which has no overflow concerns. The clip-not-hidden choice
     is preserved as defence-in-depth for any future inner scroll container.)
     Stop-card overflow protection still lives on .fa-stop-card directly. */
  .fa-main {
    flex: 1 1 auto;
    min-width: 0;
    overflow-y: auto;
    overflow-x: clip;
  }

  /* Tighter route-scroll padding on phones so the card has room to breathe. */
  .fa-route-scroll {
    padding: 12px;
  }

  /* Day header stacks vertically on narrow screens. */
  .fa-day-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    padding: 12px;
  }

  .fa-day-header-right {
    width: 100%;
    justify-content: flex-start;
    gap: 8px;
  }

  /* Stop cards full-width, comfortable padding for thumbs. box-sizing + max-width
     pin the card width to the parent so a long site name or duration pill can't
     push the right edge past the viewport (Phase 6 smoke-fix). overflow-x: hidden
     here is now the load-bearing runaway-child guard since the parent .fa-main
     uses overflow-x: clip (which doesn't create a scroll container). */
  .fa-stop-card {
    margin: 8px 0;
    padding: 0;
    box-sizing: border-box;
    max-width: 100%;
    overflow-x: hidden;
  }

  /* Title block must be allowed to shrink below its intrinsic content size,
     otherwise long site names propagate up the flex chain and overflow.
     padding-right: 0 because the stop-badge is already inside the card on mobile. */
  .fa-stop-title {
    min-width: 0;
    padding-right: 12px;
    overflow-wrap: anywhere;
  }

  .fa-stop-header {
    padding: 12px 12px 8px;
    flex-wrap: wrap;
    gap: 8px;
  }

  /* Bigger tap targets â€” Radzen buttons inside the actions row stretch
     to fill the row so a thumb hit is forgiving. */
  .fa-stop-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 12px;
  }

  .fa-stop-actions .rz-button {
    min-height: 44px;
    flex: 1 1 auto;
  }

  .fa-complete-actions {
    flex-wrap: wrap;
    gap: 8px;
  }

  .fa-complete-actions .rz-button {
    min-height: 44px;
    flex: 1 1 auto;
  }

  /* Inline complete form widens to fill the card. */
  .fa-complete-form {
    padding: 10px 0 0 0;
  }

  .fa-complete-time-row {
    flex-direction: column;
    gap: 8px;
  }

  .fa-time-input {
    min-height: 40px;
  }

  /* Travel chip readable on small screens. */
  .fa-travel-leg {
    padding: 4px 12px;
  }

  /* Phone link explicit-block so the whole row is tappable. */
  .fa-stop-phone {
    display: inline-block;
    min-height: 32px;
    padding: 4px 0;
  }
}

/* Even smaller â€” under 480px (tight phone screens). Drops some padding,
   reduces avatar sizes; otherwise inherits the 768px rules. */
@media (max-width: 480px) {
  .fa-stop-card { margin: 6px; padding: 12px; }
  .fa-agent-item { min-width: 140px; }
}

/* ============================================================
   Phase 6.x â€” Field Agent login + 3-week navigation + density
   ============================================================ */

/* â”€â”€ Login shell (full viewport, centred card) â”€â”€ */
.fa-login-shell {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background-color: var(--fn-bg);
  min-height: 100%;
}

.fa-login-card {
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 12px;
  padding: 1.5rem;
  width: 100%;
  max-width: 400px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(15, 23, 42, 0.04);
}

[data-theme="dark"] .fa-login-card {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.25);
}

.fa-login-wordmark {
  display: block;
  width: 100%;
  max-width: 280px;
  height: auto;
  margin: 0 auto 1rem;
}

.fa-login-title {
  font-size: 18px;
  font-weight: 700;
  color: var(--fn-text);
  text-align: center;
  margin-bottom: 0.25rem;
}

.fa-login-sub {
  font-size: 13px;
  color: var(--fn-text-sub);
  text-align: center;
  margin-bottom: 1.25rem;
}

.fa-login-label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--fn-text-sub);
  margin-bottom: 0.4rem;
}

.fa-login-error {
  margin-top: 0.6rem;
  padding: 0.5rem 0.75rem;
  background-color: rgba(239, 68, 68, 0.10);
  border: 1px solid rgba(239, 68, 68, 0.25);
  color: #b91c1c;
  border-radius: 6px;
  font-size: 13px;
}

[data-theme="dark"] .fa-login-error {
  background-color: rgba(239, 68, 68, 0.18);
  color: #fca5a5;
}

/* â”€â”€ Sidebar header layout: title row + Switch user link â”€â”€ */
.fa-sidebar-hdr-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.fa-switch-user {
  background: none;
  border: none;
  padding: 4px 6px;
  font-size: 11px;
  font-family: inherit;
  font-weight: 500;
  color: var(--fn-accent);
  cursor: pointer;
  border-radius: 4px;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.fa-switch-user:hover {
  color: var(--fn-accent-hover);
  background-color: var(--fn-bg);
}

.fa-switch-user:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

/* Signed-in agent chip â€” locked to active state, not clickable. */
.fa-agent-item--signed-in {
  cursor: default;
  margin: 0.5rem 8px 0;
}

.fa-agent-item--signed-in:hover {
  background-color: rgba(37, 99, 235, 0.10);
}

[data-theme="dark"] .fa-agent-item--signed-in:hover {
  background-color: rgba(59, 130, 246, 0.15);
}

/* â”€â”€ Three-tab week range selector â”€â”€ */
.fa-week-tabs--three .fa-week-tab {
  font-size: 11px;
  padding: 6px 4px;
}

@media (max-width: 768px) {
  .fa-week-tabs--three .fa-week-tab {
    min-height: 44px;
    font-size: 12px;
  }
}

/* â”€â”€ Day-stepper (replaces the 2026-04-27 horizontal chip row) â”€â”€
   Three-element row: [â†] anchor [â†’]. Strict per-tab boundaries â€” buttons
   disable when the agent reaches the first or last visible-valid day in
   the active tab's Monâ€“Sun range. No auto-cross to the adjacent tab. */
.fa-day-stepper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 12px 24px;
  background-color: var(--fn-surface);
  border-bottom: 1px solid var(--fn-border);
}

.fa-day-stepper-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  background-color: var(--fn-surface);
  color: var(--fn-text);
  font-size: 18px;
  line-height: 1;
  font-family: inherit;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}

.fa-day-stepper-btn:hover:not([disabled]) {
  background-color: var(--fn-raised);
  border-color: var(--fn-border-sub);
}

.fa-day-stepper-btn:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

.fa-day-stepper-btn[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.fa-day-stepper-anchor {
  flex: 0 0 auto;
  min-width: 140px;
  text-align: center;
  font-size: 15px;
  font-weight: 500;
  color: var(--fn-text);
}

.fa-day-stepper-anchor--today {
  color: var(--fn-accent);
  font-weight: 600;
}

/* â”€â”€ Today summary chip in the day header â”€â”€ */
.fa-day-summary-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.75rem;
  background-color: rgba(37, 99, 235, 0.15);
  color: var(--fn-accent);
  font-size: 13px;
  font-weight: 500;
  border-radius: 999px;
  white-space: nowrap;
}

[data-theme="dark"] .fa-day-summary-chip {
  background-color: rgba(59, 130, 246, 0.22);
  color: #93c5fd;
}

/* â”€â”€ "View this/next week â†’" link inside non-field state â”€â”€ */
.fa-nf-link {
  margin-top: 6px;
  background: none;
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  padding: 8px 14px;
  color: var(--fn-accent);
  cursor: pointer;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  min-height: 44px;
}

.fa-nf-link:hover {
  background-color: var(--fn-raised);
  border-color: var(--fn-border-sub);
}

.fa-nf-link:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

/* Phase 6.x smoke-fix bundle (bug 5): dark-mode contrast â€” accent #3b82f6 on
   raised #334155 only hits ~3.7:1 (WCAG AA fail for normal text). Use the
   high-contrast primary text token in dark mode (resolves to #f1f5f9, ~12:1
   on #334155). Light mode unchanged â€” the accent on flat bg there is fine. */
[data-theme="dark"] .fa-nf-link {
  color: var(--fn-text);
}

/* â”€â”€ Day-stepper mobile tweaks â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
   Stretch the stepper to the full main-panel width and bump the prev/next
   buttons to a 44px tap target (Apple HIG min). The anchor stays centred
   and shrinks slightly so the row fits cleanly on a 375px screen. */
@media (max-width: 768px) {
  .fa-day-stepper {
    padding: 10px 12px;
    width: 100%;
    box-sizing: border-box;
  }
  .fa-day-stepper-btn {
    min-width: 44px;
    min-height: 44px;
  }
  .fa-day-stepper-anchor {
    font-size: 14px;
    min-width: 0;
    flex: 1 1 auto;
  }
}

/* â”€â”€ A11y: focus-visible ring on the agent item â”€â”€ */
.fa-agent-item:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

.fa-week-tab:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

/* v2.8.10 — the duplicated Sidebar-content block (~230 LOC: .fn-sidebar*,
   .fn-sidebar-railtoggle*, .fn-sidebar-subtab*, .fn-sidebar-agent-header*,
   .fn-sites-toolbar, .fn-sites-employer-*, .fn-sidebar-body) was deleted from
   here in v2.8.10 — the canonical copy lives ~3000 LOC below at the second
   "Sidebar content (Phase 3)" marker. Future edits to those classes go there. */
/* =================================================
   Phase 6.x â€” Field Agent login + 3-week navigation + density
   ============================================================ */

/* â”€â”€ Login shell (full viewport, centred card) â”€â”€ */
.fa-login-shell {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background-color: var(--fn-bg);
  min-height: 100%;
}

.fa-login-card {
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 12px;
  padding: 1.5rem;
  width: 100%;
  max-width: 400px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(15, 23, 42, 0.04);
}

[data-theme="dark"] .fa-login-card {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.25);
}

.fa-login-wordmark {
  display: block;
  width: 100%;
  max-width: 280px;
  height: auto;
  margin: 0 auto 1rem;
}

.fa-login-title {
  font-size: 18px;
  font-weight: 700;
  color: var(--fn-text);
  text-align: center;
  margin-bottom: 0.25rem;
}

.fa-login-sub {
  font-size: 13px;
  color: var(--fn-text-sub);
  text-align: center;
  margin-bottom: 1.25rem;
}

.fa-login-label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--fn-text-sub);
  margin-bottom: 0.4rem;
}

.fa-login-error {
  margin-top: 0.6rem;
  padding: 0.5rem 0.75rem;
  background-color: rgba(239, 68, 68, 0.10);
  border: 1px solid rgba(239, 68, 68, 0.25);
  color: #b91c1c;
  border-radius: 6px;
  font-size: 13px;
}

[data-theme="dark"] .fa-login-error {
  background-color: rgba(239, 68, 68, 0.18);
  color: #fca5a5;
}

/* â”€â”€ Sidebar header layout: title row + Switch user link â”€â”€ */
.fa-sidebar-hdr-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.fa-switch-user {
  background: none;
  border: none;
  padding: 4px 6px;
  font-size: 11px;
  font-family: inherit;
  font-weight: 500;
  color: var(--fn-accent);
  cursor: pointer;
  border-radius: 4px;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.fa-switch-user:hover {
  color: var(--fn-accent-hover);
  background-color: var(--fn-bg);
}

.fa-switch-user:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

/* Signed-in agent chip â€” locked to active state, not clickable. */
.fa-agent-item--signed-in {
  cursor: default;
  margin: 0.5rem 8px 0;
}

.fa-agent-item--signed-in:hover {
  background-color: rgba(37, 99, 235, 0.10);
}

[data-theme="dark"] .fa-agent-item--signed-in:hover {
  background-color: rgba(59, 130, 246, 0.15);
}

/* â”€â”€ Three-tab week range selector â”€â”€ */
.fa-week-tabs--three .fa-week-tab {
  font-size: 11px;
  padding: 6px 4px;
}

@media (max-width: 768px) {
  .fa-week-tabs--three .fa-week-tab {
    min-height: 44px;
    font-size: 12px;
  }
}

/* â”€â”€ Day-stepper (replaces the 2026-04-27 horizontal chip row) â”€â”€
   Three-element row: [â†] anchor [â†’]. Strict per-tab boundaries â€” buttons
   disable when the agent reaches the first or last visible-valid day in
   the active tab's Monâ€“Sun range. No auto-cross to the adjacent tab. */
.fa-day-stepper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 12px 24px;
  background-color: var(--fn-surface);
  border-bottom: 1px solid var(--fn-border);
}

.fa-day-stepper-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  background-color: var(--fn-surface);
  color: var(--fn-text);
  font-size: 18px;
  line-height: 1;
  font-family: inherit;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}

.fa-day-stepper-btn:hover:not([disabled]) {
  background-color: var(--fn-raised);
  border-color: var(--fn-border-sub);
}

.fa-day-stepper-btn:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

.fa-day-stepper-btn[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.fa-day-stepper-anchor {
  flex: 0 0 auto;
  min-width: 140px;
  text-align: center;
  font-size: 15px;
  font-weight: 500;
  color: var(--fn-text);
}

.fa-day-stepper-anchor--today {
  color: var(--fn-accent);
  font-weight: 600;
}

/* â”€â”€ Today summary chip in the day header â”€â”€ */
.fa-day-summary-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.75rem;
  background-color: rgba(37, 99, 235, 0.15);
  color: var(--fn-accent);
  font-size: 13px;
  font-weight: 500;
  border-radius: 999px;
  white-space: nowrap;
}

[data-theme="dark"] .fa-day-summary-chip {
  background-color: rgba(59, 130, 246, 0.22);
  color: #93c5fd;
}

/* â”€â”€ "View this/next week â†’" link inside non-field state â”€â”€ */
.fa-nf-link {
  margin-top: 6px;
  background: none;
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  padding: 8px 14px;
  color: var(--fn-accent);
  cursor: pointer;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  min-height: 44px;
}

.fa-nf-link:hover {
  background-color: var(--fn-raised);
  border-color: var(--fn-border-sub);
}

.fa-nf-link:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

/* Phase 6.x smoke-fix bundle (bug 5): dark-mode contrast â€” accent #3b82f6 on
   raised #334155 only hits ~3.7:1 (WCAG AA fail for normal text). Use the
   high-contrast primary text token in dark mode (resolves to #f1f5f9, ~12:1
   on #334155). Light mode unchanged â€” the accent on flat bg there is fine. */
[data-theme="dark"] .fa-nf-link {
  color: var(--fn-text);
}

/* â”€â”€ Day-stepper mobile tweaks â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
   Stretch the stepper to the full main-panel width and bump the prev/next
   buttons to a 44px tap target (Apple HIG min). The anchor stays centred
   and shrinks slightly so the row fits cleanly on a 375px screen. */
@media (max-width: 768px) {
  .fa-day-stepper {
    padding: 10px 12px;
    width: 100%;
    box-sizing: border-box;
  }
  .fa-day-stepper-btn {
    min-width: 44px;
    min-height: 44px;
  }
  .fa-day-stepper-anchor {
    font-size: 14px;
    min-width: 0;
    flex: 1 1 auto;
  }
}

/* â”€â”€ A11y: focus-visible ring on the agent item â”€â”€ */
.fa-agent-item:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

.fa-week-tab:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

/* ------------------------------------------------------------
   Sidebar content (Phase 3)
   v2.8.10 — this is the canonical (and now sole) copy of the Sidebar layout
   rules. The earlier duplicate at line ~3458 was deleted in v2.8.10. The
   .fn-sidebar-railtoggle / .fn-sidebar-subtab / .fn-sidebar-agent-header
   rules below are kept for legacy class lookups in tests but no longer
   render — the live markup uses the .fn-sidebar-tabstrip class added at
   the bottom of this block.
   ------------------------------------------------------------ */

.fn-sidebar {
  display: flex;
  flex-direction: column;
  padding: 0.75rem;
}

/* v2.8.2a (Lane A) — horizontal orientation. v2.8.10 — the Sidebar always
   renders in horizontal mode now (Orientation parameter retired). The
   `.fn-sidebar.fn-sidebar--horizontal` selector still applies because the
   markup keeps both classes for back-compat with downstream selectors. */
.fn-sidebar.fn-sidebar--horizontal {
  /* v2.8.6 — claim the full BottomPanelHost width. A legacy
     `.fn-sidebar { flex: 0 0 300px }` rule further down still wins on
     specificity in horizontal mode without this override. */
  flex: 1 1 auto;
  width: 100%;
  flex-direction: column;
  align-items: stretch;
  padding: 0.5rem 0.75rem;
  gap: 0.4rem;
  overflow-x: hidden;
  overflow-y: hidden;
}
.fn-sidebar.fn-sidebar--horizontal .fn-sidebar-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

/* v2.8.10 — inline tab strip replacing the two-tier vertical button stack
   (the old .fn-sidebar-railtoggle column + .fn-sidebar-subtabs column).
   Three mutually-exclusive pill buttons: Unscheduled · Scheduled · Sites.
   Content-width (not flex:1) so the strip hugs the top-left and the body
   reclaims the remaining horizontal room. */
.fn-sidebar-tabstrip {
  display: flex;
  flex-direction: row;
  gap: 0.25rem;
  margin-bottom: 0.4rem;
  flex-shrink: 0;
}
.fn-sidebar-tabstrip-btn {
  padding: 0.3rem 0.7rem;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--fn-text-sub);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.fn-sidebar-tabstrip-btn:hover {
  color: var(--fn-text);
  border-color: var(--fn-accent);
}
.fn-sidebar-tabstrip-btn.active {
  background: var(--fn-accent);
  color: #fff;
  border-color: var(--fn-accent);
}

/* v2.8.11 — tabstrip + filter input share one row at the top of the panel.
   The tabstrip claims content-width; the filter grows to fill the remainder.
   Replaces the previous arrangement where tabstrip was row 1, filter row 2. */
.fn-sidebar-tabrow {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
  flex-shrink: 0;
}
.fn-sidebar-tabrow > .fn-sidebar-tabstrip {
  margin-bottom: 0;
  flex-shrink: 0;
}

/* v2.13 — bottom panel simplified to the Unscheduled bucket. The tab strip was
   replaced by a single static heading; keep it visually aligned with the old
   tabstrip baseline so the bucket body sits where planners expect. */
.fn-sidebar-heading {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--fn-text-sub);
}

/* v2.8.11 — single-line visit row. Replaces the prior two-line layout
   (site name on line 1, employer · duration · target on line 2). Everything
   inline; meta text truncates with ellipsis when narrow. */
.fn-site-row--compact {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  white-space: nowrap;
  overflow: hidden;
}
.fn-site-row--compact .fn-site-row-name {
  flex: 0 0 auto;
  max-width: 40%;
}
.fn-site-row--compact .fn-site-row-meta {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.78rem;
  color: var(--fn-text-sub);
  overflow: hidden;
  text-overflow: ellipsis;
}
.fn-site-row--compact .fn-site-row-skills {
  flex: 0 0 auto;
  display: inline-flex;
  gap: 2px;
}

/* v2.8.10 — sticky bucket toolbar wraps the filter input + skill chips so they
   stay pinned at the top while the long employer-grouped sites list / bucket
   sections scroll underneath. Anchored to the .fn-sidebar-body scroll context.
   The existing .fn-sites-employer-header sticky uses `top: 0`; bump it to
   `top: 38px` so it doesn't slide UNDER this toolbar (see rule below). */
.fn-sidebar-bucket-toolbar {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--fn-surface);
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--fn-border);
  margin-bottom: 0.4rem;
}
.fn-sidebar-skill-chips {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
  margin-top: 0.35rem;
}

/* v2.7.1b legacy — railtoggle/subtab/agent-header classes retained for any
   surface still referencing them (tests pin retirement of the underlying state
   plumbing, not the CSS itself). Live UI now uses .fn-sidebar-tabstrip above. */
.fn-sidebar-railtoggle {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 0.5rem;
}
.fn-sidebar-railtoggle-btn {
  flex: 1;
  padding: 0.35rem 0.5rem;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--fn-text-sub);
  cursor: pointer;
}
.fn-sidebar-railtoggle-btn.active {
  background: var(--fn-accent);
  color: white;
  border-color: var(--fn-accent);
}

.fn-sidebar-tabs {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--fn-border);
}

.fn-sidebar-tab {
  flex: 1;
  padding: 0.4rem 0.5rem;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--fn-text-sub);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.fn-sidebar-tab:hover {
  color: var(--fn-text);
}

.fn-sidebar-tab.active {
  color: var(--fn-accent);
  border-bottom-color: var(--fn-accent);
}

.fn-sidebar-subtabs {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 0.5rem;
}

.fn-sidebar-subtab {
  flex: 1;
  padding: 0.25rem 0.4rem;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--fn-text-sub);
  cursor: pointer;
}

.fn-sidebar-subtab.active {
  background: var(--fn-accent);
  color: white;
  border-color: var(--fn-accent);
}

/* v2.7.1b — Sites tab top toolbar (filter + Show-inactive toggle). */
.fn-sites-toolbar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.fn-sites-show-inactive {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.75rem;
  color: var(--fn-text-sub);
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}
.fn-sites-show-inactive input {
  margin: 0;
}

/* v2.7.1b — employer subheader inside the Sites grid. Sticky on scroll so
   the planner can scan a long list without losing the current employer.
   v2.8.10 — top bumped to 38px so it slides BENEATH the sticky bucket toolbar
   above instead of overlapping it. 38px ≈ toolbar height + bottom padding. */
.fn-sites-employer-header {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  position: sticky;
  top: 38px;
  background: var(--fn-bg);
  padding: 0.3rem 0.25rem 0.2rem;
  margin-top: 0.4rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--fn-text-sub);
  border-bottom: 1px solid var(--fn-border);
  z-index: 1;
}
.fn-sites-employer-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fn-sites-employer-inactive {
  background: var(--fn-raised);
  color: var(--fn-text-sub);
  font-weight: 500;
}

.fn-sidebar-body {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

/* v2.7.1d — Services section (read-only) inside SiteDetailView. Renders a
   list of recurrences under the "Services" vocabulary. Manage button sits
   to the right of the section title and routes through the existing OnEdit
   callback. */
.fn-services-section-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.3rem;
}
.fn-services-section-manage {
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--fn-border);
  border-radius: 4px;
  padding: 0.15rem 0.5rem;
  font-size: 0.75rem;
  color: var(--fn-accent);
  cursor: pointer;
}
.fn-services-section-manage:hover {
  background: var(--fn-raised);
  border-color: var(--fn-accent);
}
.fn-services-section-empty {
  font-style: italic;
  color: var(--fn-text-sub);
}
.fn-services-section-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.fn-services-section-row {
  display: flex;
  flex-direction: column;
  padding: 0.4rem 0.5rem;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
}
.fn-services-section-row--inactive {
  opacity: 0.6;
}
.fn-services-section-row-label {
  font-weight: 600;
  color: var(--fn-text);
}
.fn-services-section-row-meta {
  font-size: 0.78rem;
  color: var(--fn-text-sub);
  margin-top: 0.1rem;
}
.fn-services-section-inactive-tag {
  margin-left: 0.4rem;
  background: var(--fn-raised);
  color: var(--fn-text-sub);
  font-weight: 500;
}

.fn-site-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.5rem;
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  cursor: grab;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.fn-site-row:hover,
.fn-site-row.active {
  border-color: var(--fn-accent);
  background: var(--fn-raised);
}

.fn-site-row-name {
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--fn-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fn-site-row-sub {
  font-size: 0.72rem;
  color: var(--fn-text-sub);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fn-tag {
  display: inline-block;
  padding: 1px 6px;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 10px;
  font-size: 0.65rem;
  font-weight: 600;
  color: var(--fn-text-sub);
}

.fn-tag-toggle {
  padding: 3px 10px;
  border-radius: 12px;
  border: 1px solid var(--fn-border);
  background: var(--fn-surface);
  color: var(--fn-text-sub);
  font-size: 0.7rem;
  font-weight: 600;
  cursor: pointer;
}

.fn-tag-toggle.active {
  background: var(--fn-accent);
  color: white;
  border-color: var(--fn-accent);
}

.fn-visit-create-form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.fn-avatar-xs {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  color: white;
  font-size: 0.7rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.fn-sidebar {
  flex: 0 0 300px;
}

/* ------------------------------------------------------------
   Agent profile panel (Sidebar overlay)
   ------------------------------------------------------------ */

.fn-agent-profile {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.fn-agent-profile-header {
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--fn-border);
  margin-bottom: 0.5rem;
  flex-shrink: 0;
}

.fn-agent-profile-identity {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.fn-agent-profile-name {
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--fn-text);
  word-break: break-word;
}

.fn-agent-profile-meta {
  display: flex;
  gap: 0.25rem;
  align-items: center;
  margin-top: 0.2rem;
  flex-wrap: wrap;
}

.fn-agent-profile-status {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.fn-agent-profile-status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.fn-agent-profile-close {
  background: transparent;
  border: none;
  color: var(--fn-text-sub);
  font-size: 1rem;
  cursor: pointer;
  padding: 0 0.2rem;
  line-height: 1;
}

.fn-agent-profile-close:hover {
  color: var(--fn-text);
}

.fn-agent-profile-actions {
  display: flex;
  gap: 0.3rem;
}

.fn-agent-profile-body {
  flex: 1;
  overflow-y: auto;
  padding-right: 0.1rem;
}

.fn-agent-profile-section-head {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--fn-text-sub);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0.85rem 0 0.4rem;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid var(--fn-border);
}

.fn-agent-profile-section-head:first-child {
  margin-top: 0.25rem;
}

.fn-agent-profile-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 0.25rem 0;
  border-bottom: 1px solid var(--fn-border);
  gap: 0.5rem;
}

.fn-agent-profile-row-label {
  font-size: 0.72rem;
  color: var(--fn-text-sub);
  flex-shrink: 0;
}

.fn-agent-profile-row-value {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--fn-text);
  text-align: right;
  line-height: 1.4;
  word-break: break-word;
}

.fn-agent-profile-util {
  margin-bottom: 0.5rem;
}

.fn-agent-profile-util-head {
  display: flex;
  justify-content: space-between;
  font-size: 0.72rem;
  color: var(--fn-text-sub);
  margin-bottom: 0.2rem;
}

.fn-agent-profile-util-bar {
  height: 5px;
  background: var(--fn-raised);
  border-radius: 3px;
  overflow: hidden;
}

.fn-agent-profile-util-bar > div {
  height: 100%;
  border-radius: 3px;
  transition: width 0.3s ease;
}

.fn-agent-profile-util-foot {
  font-size: 0.65rem;
  color: var(--fn-text-sub);
  margin-top: 0.1rem;
  text-align: right;
}

.fn-agent-profile-pref-block {
  margin-bottom: 0.5rem;
}

.fn-agent-profile-pref-label {
  font-size: 0.7rem;
  color: var(--fn-text-sub);
  margin-bottom: 0.25rem;
}

.fn-agent-profile-day-row {
  display: flex;
  gap: 0.2rem;
}

.fn-agent-profile-day-chip {
  flex: 1;
  padding: 0.2rem 0;
  border-radius: 3px;
  text-align: center;
  font-size: 0.7rem;
  font-weight: 700;
  background: var(--fn-bg);
  color: var(--fn-text-sub);
  border: 1px solid var(--fn-border);
}

.fn-agent-profile-day-chip.on {
  color: #fff;
}

/* ------------------------------------------------------------
   Drawer + Card grids (Phase 5)
   ------------------------------------------------------------ */

.fn-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.35);
  z-index: 900;
}

.fn-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 440px;
  max-width: 100vw;
  background: var(--fn-surface);
  border-left: 1px solid var(--fn-border);
  box-shadow: -10px 0 30px rgba(0, 0, 0, 0.12);
  display: flex;
  flex-direction: column;
  z-index: 1000;
  animation: fn-drawer-slide 180ms ease-out;
}

@keyframes fn-drawer-slide {
  from { transform: translateX(100%); }
  to   { transform: translateX(0); }
}

.fn-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--fn-border);
  flex-shrink: 0;
}

.fn-drawer-header h3 {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--fn-text);
}

.fn-drawer-close {
  background: transparent;
  border: none;
  font-size: 1.4rem;
  line-height: 1;
  color: var(--fn-text-sub);
  cursor: pointer;
  padding: 0 0.25rem;
}

.fn-drawer-close:hover { color: var(--fn-text); }

.fn-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: 1rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.fn-drawer-footer {
  padding: 0.75rem 1.25rem;
  border-top: 1px solid var(--fn-border);
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
  flex-shrink: 0;
}

.fn-drawer-section {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.fn-drawer-section-title {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--fn-text-sub);
}

.fn-drawer-field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.fn-drawer-field label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--fn-text);
}

.fn-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 0.75rem;
  padding: 1.25rem;
}

.fn-page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--fn-border);
  background: var(--fn-surface);
}

.fn-page-header h2 {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 600;
}

.fn-page-header-meta {
  font-size: 0.8rem;
  color: var(--fn-text-sub);
}

.fn-entity-card {
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  padding: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  transition: border-color 0.15s ease;
}

.fn-entity-card:hover {
  border-color: var(--fn-accent);
}

/* Phase 3 follow-up: site lifecycle border-left stripe matching the status pill.
   Green = Active, Amber = Dormant, Red = Inactive. The 4 px stripe replaces the
   default 1 px left border so the card visual reads as "tagged" without growing. */
.fn-site-card--active {
  border-left: 4px solid #16a34a;
}
.fn-site-card--dormant {
  border-left: 4px solid #d97706;
}
.fn-site-card--inactive {
  border-left: 4px solid #dc2626;
  opacity: 0.85;
}

[data-theme="dark"] .fn-site-card--active {
  border-left-color: #4ade80;
}
[data-theme="dark"] .fn-site-card--dormant {
  border-left-color: #fbbf24;
}
[data-theme="dark"] .fn-site-card--inactive {
  border-left-color: #f87171;
}

.fn-entity-card-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.fn-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: 700;
  flex-shrink: 0;
}

.fn-entity-card-title {
  font-weight: 600;
  color: var(--fn-text);
}

.fn-entity-card-sub {
  font-size: 0.78rem;
  color: var(--fn-text-sub);
}

.fn-entity-card-actions {
  display: flex;
  gap: 0.3rem;
  margin-top: auto;
}

.fn-chip {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 10px;
  border: 1px solid;
  font-size: 0.7rem;
  font-weight: 600;
}

.fn-day-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.2rem;
}

.fn-day-btn {
  padding: 0.3rem;
  border-radius: 6px;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  color: var(--fn-text-sub);
  font-size: 0.72rem;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
}

.fn-day-btn.active {
  background: var(--fn-accent);
  color: white;
  border-color: var(--fn-accent);
}

.fn-color-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.35rem;
}

.fn-color-swatch {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 6px;
  border: 2px solid transparent;
  cursor: pointer;
}

.fn-color-swatch.active {
  border-color: var(--fn-text);
}

.fn-color-swatch[disabled] {
  opacity: 0.35;
  cursor: not-allowed;
}

.fn-card-warn {
  background: #fef3c7;
  color: #78350f;
  border: 1px solid #f59e0b;
  border-radius: 6px;
  padding: 0.5rem 0.6rem;
  font-size: 0.78rem;
}

[data-theme="dark"] .fn-card-warn {
  background: #78350f33;
  color: #fcd34d;
  border-color: #d97706;
}

/* ------------------------------------------------------------
   Kanban (Phase 6)
   ------------------------------------------------------------ */

.fn-kanban {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
  padding: 1.25rem;
  align-items: start;
}

.fn-kanban-col {
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 200px;
}

.fn-kanban-col-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--fn-text);
}

.fn-kanban-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
}

.fn-kanban-count {
  margin-left: auto;
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 10px;
  padding: 0 8px;
  font-size: 0.7rem;
  color: var(--fn-text-sub);
}

.fn-task-card {
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-left: 3px solid #cbd5e1;
  border-radius: 6px;
  padding: 0.6rem 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.fn-task-title {
  font-weight: 600;
  font-size: 0.88rem;
  color: var(--fn-text);
}

.fn-task-desc {
  font-size: 0.78rem;
  color: var(--fn-text-sub);
  white-space: pre-wrap;
}

.fn-task-actions {
  display: flex;
  gap: 0.25rem;
  margin-top: 0.2rem;
}

/* ------------------------------------------------------------
   MapView (Phase 7)
   ------------------------------------------------------------ */

.fn-map-shell {
  display: flex;
  flex-direction: column;
  height: 100%;
  position: relative;
}

.fn-map-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.6rem 0.9rem;
  background: var(--fn-surface);
  border-bottom: 1px solid var(--fn-border);
  align-items: center;
}

.fn-map-toolbar-group {
  display: flex;
  gap: 0.2rem;
  align-items: center;
}

.fn-map-canvas {
  flex: 1;
  width: 100%;
  min-height: 400px;
  background: var(--fn-raised);
}

.fn-map-legend {
  position: absolute;
  bottom: 12px;
  right: 12px;
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  padding: 0.5rem 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.75rem;
  z-index: 500;
  box-shadow: 0 2px 6px rgba(0,0,0,.08);
}

.fn-map-legend-item {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.fn-map-legend-swatch {
  width: 14px;
  height: 14px;
  border-radius: 3px;
}

/* v2.7.3e — initials pill for all-agents-day legend. Mirror the JS-side
   initialsIcon so the legend ↔ marker correspondence is visual. */
.fn-map-legend-initials {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  color: white;
  font-size: 10px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 2px solid white;
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}

.fn-map-legend-day-anchor {
  font-weight: 700;
  font-size: 0.78rem;
  color: var(--fn-text-sub);
  padding-right: 0.5rem;
  border-right: 1px solid var(--fn-border-sub);
  margin-right: 0.25rem;
}

/* ------------------------------------------------------------
   Map pane (v2.8.14) — split view's map column. Sits as a flex
   sibling of .fn-content-column and .fn-side-panel-host so the
   map column lives between SidePanelHost and the right edge of
   the page, full vertical height of .fn-main-area. The previous
   .fn-split-view / .fn-split-left / .fn-split-right rules (which
   boxed map + schedule together inside .fn-content-body) are
   retired.
   ------------------------------------------------------------ */

.fn-map-pane {
  /* v2.8.14b — user-resizable. --fn-map-pane-width starts at 50% of the
     flex container and is updated inline by panel-resize.js when the
     user drags the left-edge handle. flex-grow + shrink both 0 so the
     width is honoured exactly rather than negotiated by sibling flex
     children. The CSS min-width still gates the minimum so cosmetic
     drags below 360px clamp at the same value JS clamps to. */
  flex: 0 0 var(--fn-map-pane-width, 50%);
  min-width: 360px;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--fn-border);
  background: var(--fn-surface);
  overflow: hidden;
  position: relative; /* anchor for the drag handle */
}

.fn-map-pane-drag-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 6px;
  cursor: ew-resize;
  background: transparent;
  z-index: 5;
  /* Touch target: widen the hit area on coarse pointers without showing
     a visually-wider stripe. */
  touch-action: none;
}

.fn-map-pane-drag-handle:hover,
.fn-map-pane-drag-handle:active {
  background: var(--fn-border);
}

/* --- v2.14.0 map markers + stacked-visit list --------------------------- */

/* The shared "host" element used by numberIcon + initialsIcon. The white ring
   + circular shape + drop-shadow were inlined per-icon in mapview.js prior to
   v2.14.0; they're hoisted here so a single rule can also position the corner
   stack-badge with `position:relative`. */
.fn-map-num-host {
  position: relative;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid white;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  color: white;
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* v2.14.1 — unscheduled-visit marker host. Hoisted from the inline-styled
   divIcon HTML so position:relative anchors the corner stack-badge when
   multiple unscheduled visits share a site. Outline colour is set inline
   via border-color to encode urgency (red/amber/grey). */
.fn-map-q-host {
  position: relative;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid #9ca3af;
  background: #9ca3af;
  color: white;
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Corner count badge — only rendered by mapview.js when 2+ visits share a
   site on the same day. Clue to the planner that clicking the marker opens
   a list rather than a single visit's hover card. */
.fn-map-stack-badge {
  position: absolute;
  top: -6px;
  right: -8px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  background: #111827;
  color: white;
  border: 2px solid white;
  border-radius: 9px;
  font-size: 10px;
  font-weight: 700;
  line-height: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

.fn-map-visit-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.fn-map-visit-list__sub {
  font-size: 0.75rem;
  color: var(--fn-text-sub, #6b7280);
}

.fn-map-visit-list__rows {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.fn-map-visit-list__row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px;
  border: 1px solid var(--fn-border, #e5e7eb);
  border-radius: 6px;
  background: var(--fn-raised, #ffffff);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  font-size: 0.85rem;
  color: inherit;
}

.fn-map-visit-list__row:hover {
  background: var(--fn-hover, #f3f4f6);
  border-color: var(--fn-accent, #2563eb);
}

.fn-map-visit-list__row:focus-visible {
  outline: 2px solid var(--fn-accent, #2563eb);
  outline-offset: 1px;
}

.fn-map-visit-list__row-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.fn-map-visit-list__agent {
  font-weight: 600;
}

.fn-map-visit-list__row-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.75rem;
  color: var(--fn-text-sub, #6b7280);
}

.fn-map-visit-list__code {
  font-family: ui-monospace, SFMono-Regular, monospace;
  letter-spacing: 0.02em;
}

/* v2.14.1 — date hint per row (e.g. "Sched 12 May" / "Target 12 May") */
.fn-map-visit-list__date {
  color: var(--fn-text-sub, #6b7280);
}

/* v2.14.1 — "Unscheduled" pill replaces the status pill when ScheduledDate is null.
   Same visual weight as the status pills but a neutral grey so the planner
   can tell at a glance the row is a placeholder, not an agent-scheduled visit. */
.fn-map-visit-list__unsched {
  padding: 2px 8px;
  background: #f3f4f6;
  color: #4b5563;
  border: 1px solid #d1d5db;
  border-radius: 9999px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* --- Phase 3c admin UI -------------------------------------------------- */

/* Public-holiday pill on the day header. Sits next to the date-num text;
   short ("PH") with a tooltip carrying the holiday name + state codes. */
.fn-holiday-badge {
  display: inline-block;
  margin-left: 4px;
  padding: 1px 6px;
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #f59e0b;
  border-radius: 4px;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  vertical-align: middle;
  cursor: help;
}

[data-theme="dark"] .fn-holiday-badge {
  background: rgba(245, 158, 11, 0.18);
  color: #fbbf24;
  border-color: #b45309;
}

/* Per-agent leave row inside the AgentModal Leave section. */
.fn-leave-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.5rem;
  background: var(--fn-surface-alt, #f9fafb);
  border: 1px solid var(--fn-border);
  border-radius: 4px;
}

.fn-leave-row-dates {
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--fn-text);
}

.fn-leave-row-reason {
  color: var(--fn-text-sub);
  font-size: 0.78rem;
}

.fn-leave-add-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.4rem;
  margin-top: 0.6rem;
  padding-top: 0.5rem;
  border-top: 1px dashed var(--fn-border);
}

/* Phase 6.5a â€” per-weekday work pattern grid in AgentModal. 5 columns:
   Day | Works | Travel | Overnight | Office. */
.fn-workpattern-grid {
  display: grid;
  grid-template-columns: 3rem 4rem 1fr 1fr 4rem;
  gap: 0.3rem 0.5rem;
  align-items: center;
  font-size: 0.8rem;
}

.fn-workpattern-grid-head {
  font-weight: 600;
  font-size: 0.72rem;
  color: var(--fn-text-sub);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-bottom: 1px solid var(--fn-border);
  padding-bottom: 0.25rem;
}

.fn-workpattern-grid-day {
  font-weight: 600;
  color: var(--fn-text);
}

.fn-workpattern-grid-cell {
  display: flex;
  align-items: center;
  justify-content: flex-start;
}

/* Tristate (null / true / false) toggle group â€” three small pill buttons. */
.fn-pref-tri {
  display: inline-flex;
  border: 1px solid var(--fn-border);
  border-radius: 4px;
  overflow: hidden;
}

.fn-pref-tri-btn {
  background: transparent;
  border: 0;
  padding: 0.2rem 0.5rem;
  font-size: 0.85rem;
  cursor: pointer;
  color: var(--fn-text-sub);
  border-right: 1px solid var(--fn-border);
  min-width: 1.8rem;
  line-height: 1.2;
}

.fn-pref-tri-btn:last-child {
  border-right: 0;
}

.fn-pref-tri-btn:hover {
  background: var(--fn-raised);
  color: var(--fn-text);
}

.fn-pref-tri-btn--active {
  background: var(--fn-accent);
  color: var(--fn-on-accent, #fff);
  font-weight: 600;
}

.fn-pref-tri-btn--active.fn-pref-tri-btn--yes {
  background: #15803d;
  color: #fff;
}

.fn-pref-tri-btn--active.fn-pref-tri-btn--no {
  background: #b91c1c;
  color: #fff;
}

.fn-pref-tri-btn:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 1px;
}

/* Conflicts dialog body â€” list of visits that the new leave overlaps. */
.fn-leave-conflicts-list {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  max-height: 240px;
  overflow-y: auto;
  margin: 0.5rem 0;
}

.fn-leave-conflict-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--fn-border);
  border-radius: 4px;
}

.fn-leave-conflict-name {
  font-weight: 600;
  font-size: 0.88rem;
  color: var(--fn-text);
}

.fn-leave-conflict-sub {
  font-size: 0.75rem;
  color: var(--fn-text-sub);
}

.fn-leave-conflict-status {
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.fn-leave-conflict-status--scheduled {
  background: #dbeafe;
  color: #1d4ed8;
}

.fn-leave-conflict-status--confirmed {
  background: #dcfce7;
  color: #15803d;
}

[data-theme="dark"] .fn-leave-conflict-status--scheduled {
  background: rgba(59, 130, 246, 0.2);
  color: #93c5fd;
}

[data-theme="dark"] .fn-leave-conflict-status--confirmed {
  background: rgba(16, 185, 129, 0.2);
  color: #6ee7b7;
}

/* Site dormancy banner â€” shown at the top of SiteModal when the working site
   is still dormant. Calls out the activate-site escape hatch for the seed flow. */
.fn-dormant-banner {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.7rem 0.8rem;
  background: #fef3c7;
  border: 1px solid #f59e0b;
  border-radius: 6px;
  margin-bottom: 0.5rem;
}

.fn-dormant-banner-text {
  flex: 1;
  font-size: 0.82rem;
  line-height: 1.4;
  color: #78350f;
}

[data-theme="dark"] .fn-dormant-banner {
  background: rgba(245, 158, 11, 0.15);
  border-color: #b45309;
}

[data-theme="dark"] .fn-dormant-banner-text {
  color: #fcd34d;
}

/* Admin landing screen â€” three stacked sections with simple tables. */
.fn-admin-grid {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: 1.25rem;
}

.fn-admin-section {
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.fn-admin-section h3 {
  margin: 0 0 0.25rem 0;
  font-size: 1rem;
  font-weight: 600;
}

.fn-admin-empty {
  font-size: 0.82rem;
  color: var(--fn-text-sub);
  font-style: italic;
}

.fn-admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.fn-admin-table th,
.fn-admin-table td {
  text-align: left;
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid var(--fn-border);
}

.fn-admin-table th {
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fn-text-sub);
  background: var(--fn-surface-alt, transparent);
}

.fn-admin-add-row {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  padding-top: 0.5rem;
  border-top: 1px dashed var(--fn-border);
  flex-wrap: wrap;
}

.fn-admin-status {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.fn-admin-status--active {
  background: #dcfce7;
  color: #15803d;
}

.fn-admin-status--inactive {
  background: #fee2e2;
  color: #b91c1c;
}

/* v2.0b — dormant variant for sites that haven't had their first confirmed
   visit yet (Site.IsDormant=true && IsActive=true). Amber tint distinguishes
   from both green (active) and red (deactivated). */
.fn-admin-status--dormant {
  background: #fef3c7;
  color: #92400e;
}

[data-theme="dark"] .fn-admin-status--dormant {
  background: rgba(234, 179, 8, 0.2);
  color: #fde047;
}

[data-theme="dark"] .fn-admin-status--active {
  background: rgba(16, 185, 129, 0.2);
  color: #6ee7b7;
}

[data-theme="dark"] .fn-admin-status--inactive {
  background: rgba(239, 68, 68, 0.2);
  color: #fca5a5;
}

/* v2.0b — EmployerDetailView. Read-only summary surface; v2.0e promoted from
   an AdminView dialog into an inline component embedded in EmployersView's
   master/detail flow. Lists all sites under one employer with status counts
   + per-site next/last visit dates. */
.fn-employer-detail-toolbar {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}

.fn-employer-detail-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 0.75rem;
}

.fn-employer-detail-status {
  margin-top: 0.4rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.fn-employer-detail-counts {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  align-items: flex-start;
}

.fn-employer-count {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 500;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  color: var(--fn-text-sub);
}

.fn-employer-count--active {
  background: #d1fae5;
  color: #065f46;
  border-color: #10b981;
}

.fn-employer-count--dormant {
  background: #fef3c7;
  color: #92400e;
  border-color: #d97706;
}

.fn-employer-count--deactivated {
  background: #fee2e2;
  color: #991b1b;
  border-color: #ef4444;
}

[data-theme="dark"] .fn-employer-count--active {
  background: rgba(16, 185, 129, 0.18);
  color: #6ee7b7;
  border-color: rgba(16, 185, 129, 0.4);
}

[data-theme="dark"] .fn-employer-count--dormant {
  background: rgba(234, 179, 8, 0.18);
  color: #fde047;
  border-color: rgba(234, 179, 8, 0.4);
}

[data-theme="dark"] .fn-employer-count--deactivated {
  background: rgba(239, 68, 68, 0.18);
  color: #fca5a5;
  border-color: rgba(239, 68, 68, 0.4);
}

.fn-employer-detail-notes {
  margin-top: 0.75rem;
  padding: 0.6rem 0.75rem;
  background: var(--fn-raised);
  border-left: 2px solid var(--fn-border);
  border-radius: 0 4px 4px 0;
}

.fn-employer-detail-notes-label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fn-text-sub);
  margin-bottom: 0.2rem;
}

.fn-employer-detail-notes-body {
  font-size: 0.85rem;
  color: var(--fn-text);
  white-space: pre-wrap;
}

/* ----- v2.8.1a Lane A: schedule week header (single-row: nav + date cells + hamburger) ---- */

.fn-week-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0rem;
  background: var(--fn-raised, #f8fafc);
  border: 1px solid var(--fn-border, #e2e8f0);
  border-radius: 8px;
  margin-bottom: 0.5rem;
  /* v2.8.9 finding 2 — pin the day header at the top of .fn-content-body so it
     stays visible as the planner scrolls down the agent list. Sticky resolves
     to the nearest scrolling ancestor; .fn-schedule-grid's overflow was
     flipped to visible (finding 3) so this sticks against .fn-content-body. */
  position: sticky;
  top: 0;
  z-index: 2;
}

/* Inner grid mirrors `.fn-date-header, .fn-agent-row` column template so the
   nav cluster sits in the card column and date cells line up with day-tile columns. */
.fn-week-header-grid {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: var(--fn-card-col) repeat(var(--fn-day-cols, 5), 1fr);
  gap: 5px;
  align-items: center;
}

.fn-week-header-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  min-width: 0;
}

.fn-week-header-month {
  font-weight: 600;
  white-space: nowrap;
  font-size: 0.95rem;
}

.fn-week-header-tail {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

/* Schedule toolbar menu — hamburger trigger + popup panel. */
.fn-schedule-toolbar-menu {
  position: relative;
}

.fn-schedule-toolbar-menu-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--fn-border, #e2e8f0);
  border-radius: 6px;
  cursor: pointer;
  color: var(--fn-text, #0f172a);
}

.fn-schedule-toolbar-menu-trigger:hover {
  background: var(--fn-raised, #f1f5f9);
}

.fn-schedule-toolbar-menu-trigger:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

.fn-schedule-toolbar-menu-panel {
  position: absolute;
  top: calc(100% + 6px);
  /* v2.14 — menu trigger now sits at the far-left of the week header (card column),
     so the panel must open rightward (left:0) into the viewport. Previously right:0
     anchored it to the trigger's right edge and it spilled off-screen to the left. */
  left: 0;
  z-index: 30;
  min-width: 240px;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.75rem;
  background: var(--fn-surface, #fff);
  border: 1px solid var(--fn-border, #e2e8f0);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
}

.fn-schedule-toolbar-menu-row {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.fn-schedule-toolbar-menu-label {
  font-size: 0.75rem;
  color: var(--fn-text-sub, #64748b);
  font-weight: 600;
}

.fn-schedule-toolbar-menu-item {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  color: var(--fn-text, #0f172a);
}

.fn-schedule-toolbar-menu-item:hover {
  background: var(--fn-raised, #f1f5f9);
}

.fn-schedule-toolbar-menu-item:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: -2px;
}

/* ----- Phase 4b: schedule shell + filters rail + bucket sections --------- */

.fn-schedule-shell {
  display: flex;
  flex-direction: row;
  flex: 1;
  min-width: 0;
  gap: 0.5rem;
  /* v2.8.15: safety net for hover popovers. The visit-chip rich preview is
     absolutely positioned and escapes its day-tile (which flips overflow:
     hidden→visible on hover, see .fn-day-tile:has(...) elsewhere). Without
     a containing clip the popover near the right/bottom edge of the grid
     pushes the viewport, causing layout jitter. fn-hover-flip.js picks the
     correct inward variant per chip; this clip catches anything it misses. */
  overflow: hidden;
}

.fn-schedule-shell > .fn-schedule-grid {
  flex: 1;
  min-width: 0;
}

.fn-filters-rail {
  flex: 0 0 220px;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0.75rem 0.5rem 0.75rem 0.75rem;
  border-right: 1px solid var(--fn-border);
  background: var(--fn-surface);
  overflow-y: auto;
}

.fn-filters-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.fn-filters-title {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--fn-text);
}

.fn-filters-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.4rem;
  height: 1.2rem;
  padding: 0 0.4rem;
  border-radius: 999px;
  background: var(--fn-accent);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
}

.fn-filters-clear-all,
.fn-filters-clear {
  background: transparent;
  border: none;
  color: var(--fn-text-sub);
  font-size: 0.72rem;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
}

.fn-filters-clear-all:hover,
.fn-filters-clear:hover {
  color: var(--fn-accent);
}

.fn-filters-group {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.fn-filters-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.fn-filters-group-label {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--fn-text-sub);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.fn-filters-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

.fn-filters-empty {
  font-size: 0.72rem;
  color: var(--fn-text-sub);
  font-style: italic;
}

/* Soft-dim agent rows when skill filter is active and they hold none. The dim is
   non-destructive â€” the row still renders and is interactable. */
.fn-agent-row--skill-dim {
  opacity: 0.45;
  filter: saturate(0.7);
}

/* Bucket section accordion */
.fn-bucket-section {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  background: var(--fn-surface);
  margin-bottom: 0.5rem;
}

.fn-bucket-section--footer {
  margin-top: 0.5rem;
  border-style: dashed;
}

/* v2.8.10 — gap bumped 0.4rem → 0.6rem so the chevron / title / subtitle / count
   badge sit further apart; the subtitle no longer claims `flex:1`, freeing the
   count badge to anchor cleanly via its existing `margin-left:auto`. */
.fn-bucket-section-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.45rem 0.6rem;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  width: 100%;
  font-family: inherit;
}

.fn-bucket-section-head:hover {
  background: var(--fn-raised);
}

.fn-bucket-section-chev {
  display: inline-block;
  width: 0.9rem;
  color: var(--fn-text-sub);
  font-size: 0.7rem;
}

.fn-bucket-section-title {
  font-weight: 700;
  font-size: 0.8rem;
  color: var(--fn-text);
}

.fn-bucket-section-sub {
  font-size: 0.7rem;
  color: var(--fn-text-sub);
  margin-left: 0.25rem;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fn-bucket-section-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  height: 1.2rem;
  padding: 0 0.4rem;
  border-radius: 999px;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  color: var(--fn-text-sub);
  font-size: 0.7rem;
  font-weight: 700;
  margin-left: auto;
}

.fn-bucket-section-count--overdue {
  background: rgba(239, 68, 68, 0.15);
  border-color: rgba(239, 68, 68, 0.4);
  color: #b91c1c;
}

[data-theme="dark"] .fn-bucket-section-count--overdue {
  background: rgba(239, 68, 68, 0.25);
  color: #fca5a5;
  border-color: rgba(239, 68, 68, 0.5);
}

.fn-bucket-section-body {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.4rem 0.5rem 0.5rem;
  border-top: 1px solid var(--fn-border);
}

.fn-bucket-empty {
  font-size: 0.75rem;
  color: var(--fn-text-sub);
  font-style: italic;
  padding: 0.25rem 0.1rem;
}

/* Phase 5c â€” Routes section. The whole row is the drag handle (mirrors fn-site-row);
   inside the row a tiny chevron button toggles the inline stops list. The chevron
   button stops drag bubbling so it stays a click target instead of starting a drag. */
.fn-route-row {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.45rem 0.5rem;
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  cursor: grab;
}

.fn-route-row:hover {
  border-color: var(--fn-accent);
}

.fn-route-row-head {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.fn-route-row-toggle {
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  width: 1.1rem;
  height: 1.1rem;
  font-size: 0.75rem;
  color: var(--fn-text-sub);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.fn-route-row-toggle:hover {
  color: var(--fn-text);
}

.fn-route-row-name {
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--fn-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fn-route-row-sub {
  font-size: 0.72rem;
  color: var(--fn-text-sub);
}

.fn-route-row-stops {
  margin: 0.25rem 0 0 1.5rem;
  padding: 0;
  list-style: decimal;
  font-size: 0.75rem;
  color: var(--fn-text-sub);
}

.fn-route-row-stops li {
  padding: 0.1rem 0;
}

.fn-route-row-stop-name {
  color: var(--fn-text);
}

.fn-route-row-stop-sub {
  color: var(--fn-text-muted);
  font-size: 0.7rem;
  margin-left: 0.3rem;
}

.fn-bucket-blockout {
  display: flex;
  flex-direction: column;
  padding: 0.3rem 0.4rem;
  border-left: 3px solid var(--fn-accent);
  background: var(--fn-raised);
  border-radius: 4px;
}

.fn-bucket-blockout-range {
  font-size: 0.74rem;
  font-weight: 700;
  color: var(--fn-text);
}

.fn-bucket-blockout-reason {
  font-size: 0.72rem;
  color: var(--fn-text-sub);
}

/* ------------------------------------------------------------
   Phase 4c â€” hover popovers (visit chips + capacity bars)
   ------------------------------------------------------------
   Pure CSS: an .fn-hover-anchor wraps the trigger, and an
   .fn-hover-popover sibling holds the content. The popover stays
   pointer-events:none so it never consumes drag, click, or
   dragstart events. transition-delay gives a 400ms hover lag so
   the planner can scan chips quickly without flicker.
   --------------------------------------------------------------- */
.fn-hover-anchor {
  position: relative;
}

.fn-hover-popover {
  position: absolute;
  z-index: 50;
  min-width: 240px;
  max-width: 320px;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-2px);
  transition: opacity 120ms ease 0ms, visibility 0ms linear 120ms, transform 120ms ease 0ms;
}

.fn-hover-anchor:hover > .fn-hover-popover {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition: opacity 120ms ease 400ms, visibility 0ms linear 400ms, transform 120ms ease 400ms;
}

/* Anchor variants â€” keep popover fully on-screen relative to the
   chip's likely placement on the grid. */
.fn-hover-popover--right {
  left: calc(100% + 8px);
  top: 0;
}

.fn-hover-popover--left {
  right: calc(100% + 8px);
  top: 0;
}

.fn-hover-popover--top {
  bottom: calc(100% + 8px);
  left: 0;
}

/* v2.8.15 — combined corner variants for chips near the bottom of the grid.
   fn-hover-flip.js applies these when the chip lacks vertical room below;
   horizontal half matches whichever side has room (right-flush by default,
   left when the chip is also near the right edge). */
.fn-hover-popover--top-right {
  bottom: calc(100% + 8px);
  left: 0;
}

.fn-hover-popover--top-left {
  bottom: calc(100% + 8px);
  right: 0;
}

/* Default fallback — a bare .fn-hover-popover (no directional modifier) sits
   to the right of the chip, matching the historical --right behaviour. The JS
   replaces this with the correct variant on first hover; the safety-net
   overflow: hidden on .fn-schedule-shell keeps the bare default from jutting
   during the very first paint before JS runs. */
.fn-hover-popover:not(.fn-hover-popover--right):not(.fn-hover-popover--left):not(.fn-hover-popover--top):not(.fn-hover-popover--top-right):not(.fn-hover-popover--top-left):not(.fn-hover-popover--sidebar) {
  left: calc(100% + 8px);
  top: 0;
}

.fn-hover-popover--compact {
  min-width: 200px;
}

/* Sidebar variant â€” popover anchors BELOW the row and matches the row's
   horizontal extent (left:0; right:0). Crucially, it never extends past
   the row horizontally, so the sidebar's width stays steady on hover.
   Vertical extension can still happen â€” see scrollbar-gutter below for
   why that no longer causes a width flicker either. */
.fn-hover-popover--sidebar {
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  min-width: 0;
  max-width: none;
}

.fn-hover-card {
  background: var(--fn-surface);
  color: var(--fn-text);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  box-shadow: 0 6px 24px rgba(15, 23, 42, 0.18);
  padding: 0.65rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 0.78rem;
  line-height: 1.35;
}

.fn-hover-card-head {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--fn-border);
}

.fn-hover-card-title {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--fn-text);
}

.fn-hover-card-sub {
  font-size: 0.72rem;
  color: var(--fn-text-sub);
}

/* v4 â€” visit short-code surfaces. Locked to pure black (light) / pure white (dark)
   regardless of chip status colour â€” planner feedback 2026-04-28: high-contrast
   identifier text is the priority, even if it stands out against status-coloured
   chip bodies. Strong weight + monospace for legibility. */
.fn-hover-card-shortcode {
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 0.75rem;
  font-weight: 700;
  color: #000;
  letter-spacing: 0.04em;
}

[data-theme="dark"] .fn-hover-card-shortcode {
  color: #fff;
}

.fn-visit-shortcode {
  display: inline-block;
  padding-left: 0.45rem;
  margin-left: 0.2rem;
  border-left: 1px solid currentColor;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #000;
}

[data-theme="dark"] .fn-visit-shortcode {
  color: #fff;
}

/* v2.8.10 — margin-right tightened slightly so the short-code badge sits closer
   to its site name without running into it; the existing 0.45rem read as a gap. */
.fn-bucket-shortcode {
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 0.72rem;
  font-weight: 700;
  color: #000;
  margin-right: 0.35rem;
  letter-spacing: 0.04em;
}

[data-theme="dark"] .fn-bucket-shortcode {
  color: #fff;
}

/* v4 â€” Visit history table inside SiteModal */
.fn-visit-history-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
}

.fn-visit-history-table th {
  text-align: left;
  font-weight: 600;
  color: var(--fn-text-sub);
  padding: 0.35rem 0.4rem;
  border-bottom: 1px solid var(--fn-border);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.fn-visit-history-table td {
  padding: 0.35rem 0.4rem;
  border-bottom: 1px solid var(--fn-border);
  vertical-align: top;
}

.fn-visit-history-table tr:hover td {
  background: var(--fn-raised);
}

.fn-visit-history-code {
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-weight: 600;
  white-space: nowrap;
}

/* v1b â€” Allowed-days picker (SiteModal). Day chips toggle bits in Site.AllowedDays. */
.fn-allowed-days {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.fn-allowed-day-chip {
  min-width: 44px;
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  background: var(--fn-surface);
  color: var(--fn-text-sub);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.fn-allowed-day-chip:hover {
  background: var(--fn-raised);
}

.fn-allowed-day-chip--on {
  background: var(--fn-accent);
  border-color: var(--fn-accent);
  color: #fff;
}

.fn-allowed-day-chip--on:hover {
  background: var(--fn-accent);
  filter: brightness(1.05);
}

.fn-allowed-day-chip:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

.fn-hover-card-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.fn-hover-card-row--block {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
}

.fn-hover-card-label {
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fn-text-sub);
}

.fn-hover-card-value {
  font-size: 0.78rem;
  color: var(--fn-text);
}

.fn-hover-card-value--note {
  white-space: normal;
  font-style: italic;
  color: var(--fn-text-sub);
}

.fn-hover-card-value--muted {
  font-style: italic;
  color: var(--fn-text-sub);
}

/* v1b â€” soft-warn highlight on hover-card values (e.g. AllowedDays mismatch). */
.fn-hover-card-value--warn {
  color: var(--fn-danger, #dc2626);
  font-weight: 600;
}

/* v1c â€” Sites tab bulk-ops toolbar (multi-select + bulk activate/deactivate). */
.fn-bulk-toolbar {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.5rem;
  margin-bottom: 0.4rem;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  flex-wrap: wrap;
}

.fn-bulk-count {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--fn-text-sub);
  margin-right: 0.2rem;
}

/* SMOKE-007 (v1.0.6) — inline Undo banner shown for 6s after a successful bulk
   deactivate. Replaces the Radzen toast path that the 5.x renderer silently
   dropped (NotificationMessage.Click is a 6.x-only feature). */
.fn-undo-banner {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.5rem;
  margin-bottom: 0.4rem;
  background: color-mix(in srgb, var(--fn-success, #2ea44f) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--fn-success, #2ea44f) 35%, transparent);
  border-radius: 6px;
  font-size: 0.8125rem;
}

.fn-undo-banner-text {
  flex: 1;
  color: var(--fn-text);
}

.fn-bulk-selectall {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.25rem 0.4rem;
  margin-bottom: 0.3rem;
  font-size: 0.75rem;
  color: var(--fn-text-sub);
}

.fn-site-row--selected {
  background: var(--fn-raised);
  border-left: 3px solid var(--fn-accent);
}

/* v1c â€” "Navigate to site" deep-link, FA stop card only (smoke-fix: planner
   doesn't need it). Opens Google Maps in a new tab; mobile OS routes to native. */
.fa-stop-navigate {
  color: var(--fn-accent);
  font-weight: 600;
  font-size: 0.85rem;
  text-decoration: none;
}

.fa-stop-navigate:hover {
  text-decoration: underline;
}

.fa-stop-navigate:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

.fn-hover-card-meta {
  font-size: 0.72rem;
  color: var(--fn-text-sub);
  margin-left: auto;
}

.fn-hover-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem;
}

.fn-hover-card-list {
  margin: 0;
  padding-left: 1rem;
  font-size: 0.78rem;
  color: var(--fn-text);
}

.fn-hover-card-list li {
  margin-bottom: 0.1rem;
}

/* Phase 4c â€” agent profile polish: empty-state placeholder for
   skills + work pattern. Italic + muted matches the existing
   .fn-bucket-empty treatment. */
.fn-agent-profile-empty {
  font-size: 0.75rem;
  color: var(--fn-text-sub);
  font-style: italic;
}

/* Phase 4c â€” escape the day-tile's overflow:hidden on hover so the
   visit-chip popover can extend outside the tile bounds. :has() lets
   us flip overflow only while a chip-anchor is hovered, leaving the
   default clipping in place when no popover is being shown. */
.fn-day-tile:has(.fn-hover-anchor:hover) {
  overflow: visible;
}

/* Same trick for the agent card (weekly util tooltip) and the
   sidebar bucket rows. The day-tile rule above covers chips on the
   grid; this rule covers the AgentCard's util-badge popover. */
.fn-agent-card:has(.fn-hover-anchor:hover) {
  overflow: visible;
}

/* Sidebar popover stays inside the row's horizontal extent (see the
   .fn-hover-popover--sidebar rule above), so we don't need to flip
   .fn-sidebar / .fn-sidebar-body overflow during hover. We DO need
   the scrollbar gutter permanently reserved on the body, otherwise:
     1. body overflow-y:auto with scrollbar-not-yet-shown
     2. user hovers a row, popover renders below
     3. popover extends past body height â†’ scrollbar appears
     4. scrollbar consumes ~17px of inner width â†’ row narrows
     5. on un-hover, popover collapses â†’ scrollbar disappears â†’ row widens
   That sequence is the flicker the user reported. scrollbar-gutter:
   stable reserves the gutter column whether or not the bar is shown,
   so steps 4â€“5 become no-ops and the body width stays constant. */
.fn-sidebar-body {
  scrollbar-gutter: stable;
}

/* Phase 6.x Step 6 â€” subtle pulse on the next-actionable Confirmed card.
   Pulses border-color only (not box-shadow â†’ too heavy on mobile;
   not opacity â†’ confuses the status pill). The static border-left
   on .fa-stop-card already provides a non-motion affordance, so when
   prefers-reduced-motion is set we leave the card visually unchanged.
   color-mix referencing var(--fn-accent) keeps light + dark themes
   correct without an explicit dark-mode override. */
@keyframes fa-pulse-border {
  0%, 100% { border-left-color: var(--fn-accent); }
  50% { border-left-color: color-mix(in srgb, var(--fn-accent) 40%, transparent); }
}

@media (prefers-reduced-motion: no-preference) {
  .fa-stop-card--pulse {
    animation: fa-pulse-border 2s ease-in-out infinite;
  }
}

/* Phase 7c-1 (Wave 1) â€” Global search dialog. Hosted via DialogService.OpenAsync
   so the outer chrome (RadzenDialog window + close button) comes from Radzen;
   these rules style the inner content (input, group headers, result rows). */
.fn-search-dialog {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 200px;
  max-height: 60vh;
  overflow: hidden;
}

.fn-search-input {
  width: 100%;
  padding: 0.6rem 0.75rem;
  font-size: 0.95rem;
  font-family: inherit;
  color: var(--fn-text);
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.fn-search-input:focus {
  border-color: var(--fn-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--fn-accent) 20%, transparent);
}

.fn-search-input::placeholder {
  color: var(--fn-text-muted);
}

.fn-search-empty {
  padding: 1.25rem 0.5rem;
  text-align: center;
  font-size: 0.85rem;
  color: var(--fn-text-muted);
}

.fn-search-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 0.4rem;
}

.fn-search-group-header {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--fn-text-sub);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.25rem 0.4rem;
}

.fn-search-result {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  cursor: pointer;
  background-color: transparent;
  border: 1px solid transparent;
  transition: background-color 0.1s ease, border-color 0.1s ease;
}

.fn-search-result:hover,
.fn-search-result--active {
  background-color: var(--fn-raised);
  border-color: var(--fn-border);
}

.fn-search-result--active {
  border-color: var(--fn-accent);
}

.fn-search-result-primary {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--fn-text);
}

.fn-search-result-secondary {
  font-size: 0.78rem;
  color: var(--fn-text-sub);
}

/* Dark-mode tweaks â€” the variables already invert most of the palette, but the
   active-row accent halo benefits from a denser background contrast in dark. */
[data-theme="dark"] .fn-search-input {
  background-color: var(--fn-raised);
}

[data-theme="dark"] .fn-search-result:hover,
[data-theme="dark"] .fn-search-result--active {
  background-color: color-mix(in srgb, var(--fn-accent) 15%, var(--fn-surface));
}

/* ---------------------------------------------------------------------------
   Phase 6.5c — Overnight override dialog. Shown when a multi-day route spread
   triggers either the system NoOvernightDayDefault rule or a per-agent
   OvernightAllowed=false preference. Two-button (Override / Cancel) with an
   optional planner note that gets appended to the RouteSpread audit row.
   --------------------------------------------------------------------------- */
.fn-overnight-dialog {
  /* Inherits .fn-dialog-body padding/typography; this rule reserves a hook for
     dialog-specific spacing tweaks without breaking the shared dialog frame. */
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.fn-overnight-dialog-warn {
  background: rgba(245, 158, 11, 0.10);            /* amber-500 @ 10% */
  border: 1px solid rgba(245, 158, 11, 0.40);
  border-radius: 6px;
  padding: 0.6rem 0.75rem;
  margin-bottom: 0.25rem;
  color: var(--fn-text);
}

.fn-overnight-dialog-warn .fn-dialog-warn-list {
  margin: 0.4rem 0 0 1.1rem;
  padding: 0;
  font-size: 0.85rem;
  line-height: 1.45;
}

.fn-overnight-dialog-warn .fn-dialog-warn-list li {
  margin: 0.15rem 0;
}

[data-theme="dark"] .fn-overnight-dialog-warn {
  /* Dark palette pushes the amber tint further toward yellow so the contrast
     against --fn-raised stays legible without washing the message text out. */
  background: rgba(251, 191, 36, 0.12);            /* amber-400 @ 12% */
  border-color: rgba(251, 191, 36, 0.45);
}

/* Phase 7c-2/3 (Wave 2) — CSV import dialog. Hosted via DialogService so the
   outer chrome comes from Radzen; these rules style the inner content (file
   picker, preview table, action buttons). Uses --fn-* tokens so dark mode
   inverts cleanly. */
.fn-import-dialog {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 600px;
  max-height: 70vh;
  overflow: hidden;
}

.fn-import-summary {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  padding: 0.5rem 0.6rem;
  background-color: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  font-size: 0.85rem;
}

.fn-import-summary-hint {
  display: block;
  margin-top: 0.25rem;
  color: var(--fn-text-sub);
  font-size: 0.78rem;
}

.fn-import-summary-actions {
  flex-shrink: 0;
}

.fn-import-template-link {
  color: var(--fn-accent);
  text-decoration: underline;
  font-size: 0.85rem;
}

.fn-import-template-link:hover {
  color: var(--fn-accent-hover);
}

.fn-import-picker {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0.6rem;
  border: 1px dashed var(--fn-border-sub);
  border-radius: 6px;
  background-color: var(--fn-surface);
}

.fn-import-picker-filename {
  font-size: 0.85rem;
  color: var(--fn-text-sub);
}

.fn-import-empty {
  padding: 1.25rem 0.5rem;
  text-align: center;
  font-size: 0.85rem;
  color: var(--fn-text-muted);
}

.fn-import-header-errors {
  padding: 0.6rem 0.75rem;
  background-color: color-mix(in srgb, #ef4444 12%, var(--fn-surface));
  border: 1px solid #ef4444;
  border-radius: 6px;
  font-size: 0.85rem;
  color: var(--fn-text);
}

.fn-import-header-errors ul {
  margin: 0.4rem 0 0 1rem;
  padding: 0;
}

.fn-import-counts {
  display: flex;
  flex-direction: row;
  gap: 0.5rem;
  font-size: 0.8rem;
}

.fn-import-count {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-weight: 600;
}

.fn-import-count--ok {
  background-color: color-mix(in srgb, #10b981 18%, var(--fn-surface));
  color: #047857;
}

.fn-import-count--err {
  background-color: color-mix(in srgb, #ef4444 18%, var(--fn-surface));
  color: #b91c1c;
}

.fn-import-table-wrap {
  overflow: auto;
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  max-height: 320px;
}

.fn-import-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}

.fn-import-table th,
.fn-import-table td {
  padding: 0.35rem 0.5rem;
  border-bottom: 1px solid var(--fn-border);
  text-align: left;
  vertical-align: top;
  color: var(--fn-text);
}

.fn-import-table th {
  background-color: var(--fn-raised);
  font-weight: 600;
  color: var(--fn-text-sub);
  position: sticky;
  top: 0;
}

.fn-import-row--error td {
  background-color: color-mix(in srgb, #ef4444 10%, var(--fn-surface));
  color: var(--fn-text);
}

.fn-import-buttons {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.fn-import-picker-options {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.5rem 0;
}

[data-theme="dark"] .fn-import-count--ok {
  color: #6ee7b7;
}

[data-theme="dark"] .fn-import-count--err {
  color: #fca5a5;
}

[data-theme="dark"] .fn-import-row--error td {
  background-color: color-mix(in srgb, #ef4444 22%, var(--fn-surface));
}

/* ---------------------------------------------------------------------------
   v1c.2 — Right-panel week-grouped Visits view. Mirrors the fn-bucket-section
   accordion grammar so the planner sees a familiar shape, but uses dedicated
   classes so future tweaks don't bleed into the Sites-mode bucket. Header is
   a real <button> when the week is toggleable; the Overdue header uses the
   .fn-week-section-header--static modifier (no hover, no cursor:pointer).
   --------------------------------------------------------------------------- */
.fn-week-section {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  background: var(--fn-surface);
  margin-bottom: 0.5rem;
}

.fn-week-section-collapsed {
  /* Visual cue that the section is closed - slightly muted background so a
     long list of collapsed weeks doesn't compete with the open one for
     attention. The body is gone; this rule colours the header strip. */
  background: var(--fn-raised);
}

.fn-week-section-header {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.6rem;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  width: 100%;
  font-family: inherit;
}

.fn-week-section-header:hover {
  background: var(--fn-raised);
}

.fn-week-section-header--static {
  cursor: default;
}

.fn-week-section-header--static:hover {
  background: transparent;
}

.fn-week-section-chevron {
  display: inline-block;
  width: 0.9rem;
  color: var(--fn-text-sub);
  font-size: 0.7rem;
}

.fn-week-section-title {
  font-weight: 700;
  font-size: 0.8rem;
  color: var(--fn-text);
}

.fn-week-section-sub {
  font-size: 0.7rem;
  color: var(--fn-text-sub);
  margin-left: 0.25rem;
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fn-week-section-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  height: 1.2rem;
  padding: 0 0.4rem;
  border-radius: 999px;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  color: var(--fn-text-sub);
  font-size: 0.7rem;
  font-weight: 700;
  margin-left: auto;
}

.fn-week-section-count--overdue {
  background: rgba(239, 68, 68, 0.15);
  border-color: rgba(239, 68, 68, 0.4);
  color: #b91c1c;
}

[data-theme="dark"] .fn-week-section-count--overdue {
  background: rgba(239, 68, 68, 0.25);
  color: #fca5a5;
  border-color: rgba(239, 68, 68, 0.5);
}

.fn-week-section-body {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.4rem 0.5rem 0.5rem;
  border-top: 1px solid var(--fn-border);
}

[data-theme="dark"] .fn-week-section-collapsed {
  /* In dark mode --fn-raised is already lighter than --fn-surface; no extra
     tweak needed beyond the variable swap, but pin a rule here for future
     tuning without searching for the selector. */
  background: var(--fn-raised);
}

/* ============================================================
   Phase 7d-mock — MockLoginPage (Wave 3)
   ============================================================
   Cookie-issuing /login surface. Plain HTML <form> per user row
   posts to /api/mock-login which calls SignInAsync. Real-IdP
   swap replaces these rows with a single "Sign in with X" button.
   ============================================================ */

.fn-mock-login-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100%;
  padding: 1.5rem;
  background-color: var(--fn-bg);
}

.fn-mock-login-card {
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 12px;
  padding: 1.5rem;
  width: 100%;
  max-width: 480px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(15, 23, 42, 0.04);
}

[data-theme="dark"] .fn-mock-login-card {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.25);
}

.fn-mock-login-title {
  margin: 0 0 0.25rem;
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--fn-text);
}

.fn-mock-login-subtitle {
  margin: 0 0 1.25rem;
  font-size: 0.875rem;
  color: var(--fn-text-sub);
}

.fn-mock-login-empty {
  margin: 0;
  padding: 1rem;
  background-color: var(--fn-bg);
  border: 1px dashed var(--fn-border);
  border-radius: 8px;
  font-size: 0.875rem;
  color: var(--fn-text-sub);
  text-align: center;
}

.fn-mock-login-user-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.fn-mock-login-form {
  margin: 0;
  display: block;
}

.fn-mock-login-user-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  width: 100%;
  padding: 0.75rem 1rem;
  background-color: var(--fn-bg);
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  font-size: 0.875rem;
  color: var(--fn-text);
  transition: background-color 0.12s ease, border-color 0.12s ease;
}

.fn-mock-login-user-row:hover {
  background-color: var(--fn-surface);
  border-color: var(--fn-accent);
}

.fn-mock-login-user-row:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}

.fn-mock-login-user-name {
  font-weight: 600;
  color: var(--fn-text);
}

.fn-mock-login-user-email {
  font-size: 0.8125rem;
  color: var(--fn-text-sub);
}

.fn-mock-login-user-roles {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.25rem;
}

.fn-mock-login-role-pill {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  background-color: color-mix(in srgb, var(--fn-accent) 15%, transparent);
  color: var(--fn-accent);
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

[data-theme="dark"] .fn-mock-login-user-row {
  background-color: color-mix(in srgb, var(--fn-bg) 80%, var(--fn-surface));
}

[data-theme="dark"] .fn-mock-login-user-row:hover {
  background-color: var(--fn-surface);
}

/* --- Phase 7d-2: audit retention admin section -----------------------------
   Subtle accent on the audit retention row so it visually groups its SelectBar
   + status text + last-purge count together within the broader admin grid.
   --------------------------------------------------------------------------- */
.fn-admin-audit-section {
  /* No new shape — inherits .fn-admin-section. The class is attached so future
     styling tweaks (and bUnit selectors in tests) have a stable hook. */
}

[data-theme="dark"] .fn-admin-audit-section {
  /* Reserved — light/dark palette already covered by the parent .fn-admin-section. */
}

/* --- Phase 7d-3: a11y polish — visit chip keyboard focus ring ---------------
   Visit chips are now keyboard-focusable (tabindex="0" + onkeydown). Surface a
   high-contrast outline when keyboard-focused so the planner can see which chip
   Enter/Space will activate. :focus-visible avoids the ring on mouse-click users.
   --------------------------------------------------------------------------- */
.fn-visit-chip:focus-visible {
  outline: 2px solid var(--fn-accent, #2563eb);
  outline-offset: 2px;
  /* Slight inner highlight for chips with a coloured left-border, so the ring
     never visually competes with the status border. */
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
}

[data-theme="dark"] .fn-visit-chip:focus-visible {
  outline-color: #60a5fa;
  box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.25);
}

/* --- Phase 7d-3: screen-reader-only context menu host -----------------------
   The Radzen context menu builds its DOM at runtime under the cursor — those
   nodes can't carry role="menu"/role="menuitem" markers. We render a parallel
   off-screen menu host inside SchedulerView so assistive tech sees the menu
   semantics. Visually clipped but still in the accessibility tree.
   --------------------------------------------------------------------------- */
.fn-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;
}
/* ----------------------------------------------------------------------- */
/* Phase 8 — Operational dashboard                                          */
/* ----------------------------------------------------------------------- */
/* Four tiles in a 2x2 grid (1x4 on narrow viewports). Card style mirrors  */
/* the existing entity-card pattern (border + raised surface + accent on   */
/* the value). Threshold colours route through --fn-* tokens so dark mode  */
/* inherits without needing a separate [data-theme=dark] block per tile.   */

.fn-dashboard-shell {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1rem 1.25rem;
  min-width: 0;
}

.fn-dashboard-header {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.fn-dashboard-title {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--fn-text);
  margin: 0;
}

.fn-dashboard-subtitle {
  font-size: 0.825rem;
  color: var(--fn-text-sub);
  margin: 0;
}

.fn-dashboard-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

@media (max-width: 720px) {
  .fn-dashboard-grid {
    grid-template-columns: 1fr;
  }
}

.fn-dashboard-tile {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-left: 4px solid var(--fn-accent);
  border-radius: 8px;
  padding: 1rem 1.1rem;
  min-height: 120px;
  transition: border-color 0.12s ease;
}

.fn-dashboard-tile:hover {
  border-color: var(--fn-border-sub);
}

.fn-dashboard-tile-value {
  font-size: 2.25rem;
  font-weight: 700;
  color: var(--fn-text);
  line-height: 1.05;
}

.fn-dashboard-tile-label {
  font-size: 0.825rem;
  color: var(--fn-text-sub);
}

/* v2.7.6f (SMOKE-2_7-003 / -004) — clickable drill-in tiles. The Overdue tile
   and the 017 weekly band tiles get a pointer cursor + slightly stronger hover
   border so the planner sees them as actionable. The existing .fn-dashboard-tile
   hover already nudges the border colour; --clickable tightens the affordance. */
.fn-dashboard-tile--clickable,
.fn-dashboard-band-tile--clickable {
  cursor: pointer;
  user-select: none;
}
.fn-dashboard-tile--clickable:hover,
.fn-dashboard-band-tile--clickable:hover {
  background-color: var(--fn-surface-hover, var(--fn-surface));
  border-color: var(--fn-accent, var(--fn-border-sub));
}
.fn-dashboard-tile--clickable:focus-visible,
.fn-dashboard-band-tile--clickable:focus-visible {
  outline: 2px solid var(--fn-accent);
  outline-offset: 2px;
}
.fn-dashboard-band-tile--expanded {
  background-color: var(--fn-surface-hover, var(--fn-surface));
  border-color: var(--fn-accent);
}

.fn-dashboard-panel--overdue-drill,
.fn-dashboard-band-drill {
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  padding: 0.85rem 1rem;
  margin-top: 0.5rem;
}

/* Threshold-coloured completion tile. The colour applies to the BIG number
   (and the left accent) so the eye lands on the colour cue. */
.fn-dashboard-tile-color--green {
  border-left-color: #16a34a;
}
.fn-dashboard-tile-color--green .fn-dashboard-tile-value {
  color: #16a34a;
}

.fn-dashboard-tile-color--amber {
  border-left-color: #d97706;
}
.fn-dashboard-tile-color--amber .fn-dashboard-tile-value {
  color: #d97706;
}

.fn-dashboard-tile-color--red {
  border-left-color: #dc2626;
}
.fn-dashboard-tile-color--red .fn-dashboard-tile-value {
  color: #dc2626;
}

[data-theme="dark"] .fn-dashboard-tile-color--green {
  border-left-color: #22c55e;
}
[data-theme="dark"] .fn-dashboard-tile-color--green .fn-dashboard-tile-value {
  color: #4ade80;
}

[data-theme="dark"] .fn-dashboard-tile-color--amber {
  border-left-color: #f59e0b;
}
[data-theme="dark"] .fn-dashboard-tile-color--amber .fn-dashboard-tile-value {
  color: #fbbf24;
}

[data-theme="dark"] .fn-dashboard-tile-color--red {
  border-left-color: #ef4444;
}
[data-theme="dark"] .fn-dashboard-tile-color--red .fn-dashboard-tile-value {
  color: #f87171;
}

/* Capacity-heat list — one row per over-capacity agent, with util% on the
   right. List is ungrid'd so the tile collapses cleanly on a narrow grid. */
.fn-dashboard-hot-agent-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin-top: 0.4rem;
}

.fn-dashboard-hot-agent-row {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.82rem;
  padding: 0.2rem 0.4rem;
  background-color: var(--fn-raised);
  border-radius: 4px;
}

.fn-dashboard-hot-agent-name {
  color: var(--fn-text);
  font-weight: 600;
}

.fn-dashboard-hot-agent-pct {
  color: var(--fn-text-sub);
  font-variant-numeric: tabular-nums;
}

/* v2.7.2a — week selector. Sits between header and grid. Q18: no Min/Max on
   the picker, so chevrons can scroll arbitrarily into past/future weeks. */
.fn-dashboard-week-selector {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* v2.7.2b — capacity-status counts panel. Five bands across active agents,
   weekly or daily slice. Colour-keyed by DayLabels.StatusColors so palette
   changes flow through. */
.fn-dashboard-panel {
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  padding: 1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.fn-dashboard-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.fn-dashboard-panel-title {
  font-size: 1rem;
  font-weight: 700;
  color: var(--fn-text);
  margin: 0;
}

.fn-dashboard-band-row {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0.6rem;
}

@media (max-width: 720px) {
  .fn-dashboard-band-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.fn-dashboard-band-tile {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.55rem 0.7rem;
  background-color: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-left: 4px solid transparent;
  border-radius: 6px;
}

.fn-dashboard-band-tile-value {
  font-size: 1.5rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}

.fn-dashboard-band-tile-label {
  font-size: 0.78rem;
  color: var(--fn-text-sub);
}

.fn-dashboard-band-tile--compact {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 0.3rem 0.5rem;
  gap: 0.4rem;
}

.fn-dashboard-band-tile--compact .fn-dashboard-band-tile-value {
  font-size: 0.95rem;
}

.fn-dashboard-band-tile--compact .fn-dashboard-band-tile-label {
  font-size: 0.7rem;
}

.fn-dashboard-daily-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.5rem;
}

@media (max-width: 1100px) {
  .fn-dashboard-daily-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  .fn-dashboard-daily-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.fn-dashboard-daily-col {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.fn-dashboard-daily-col-head {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--fn-text-sub);
  text-align: center;
  padding-bottom: 0.15rem;
  border-bottom: 1px solid var(--fn-border-sub);
}

/* v2.7.2d — unscheduled-for-week list. One row per visit, three columns. */
.fn-dashboard-unscheduled-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.fn-dashboard-unscheduled-row {
  display: grid;
  grid-template-columns: 2fr 2fr 1fr;
  gap: 0.5rem;
  padding: 0.3rem 0.5rem;
  background-color: var(--fn-raised);
  border-radius: 4px;
  font-size: 0.82rem;
  align-items: center;
}

.fn-dashboard-unscheduled-site {
  color: var(--fn-text);
  font-weight: 600;
}

.fn-dashboard-unscheduled-employer {
  color: var(--fn-text-sub);
}

.fn-dashboard-unscheduled-target {
  color: var(--fn-text-sub);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* v2.7.2e — travel-heavy badge + drill-in. Lives inside the capacity-heat
   tile's hot-agent list. Badge is a button (clickable for drill-in). */
.fn-dashboard-travel-heavy-badge {
  background: transparent;
  border: 1px solid #d97706;
  color: #d97706;
  border-radius: 4px;
  padding: 0 0.35rem;
  font-size: 0.72rem;
  cursor: pointer;
  margin-left: 0.4rem;
}

.fn-dashboard-travel-heavy-badge:hover {
  background-color: rgba(217, 119, 6, 0.08);
}

.fn-dashboard-travel-breakdown {
  background-color: var(--fn-surface);
  border: 1px solid var(--fn-border-sub);
  border-radius: 4px;
  padding: 0.4rem;
  margin-top: 0.2rem;
}

.fn-dashboard-travel-breakdown-table {
  width: 100%;
  font-size: 0.78rem;
  border-collapse: collapse;
}

.fn-dashboard-travel-breakdown-table th {
  text-align: left;
  font-weight: 600;
  color: var(--fn-text-sub);
  padding: 0.15rem 0.35rem;
  border-bottom: 1px solid var(--fn-border-sub);
}

.fn-dashboard-travel-breakdown-table td {
  padding: 0.15rem 0.35rem;
  font-variant-numeric: tabular-nums;
  color: var(--fn-text);
}

/* ----- v2.1: site detail (page-level master/detail child under EmployersView) ---- */

.fn-site-detail {
  padding: 0.5rem 0.25rem 1.5rem 0.25rem;
}

.fn-site-detail-toolbar {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}

.fn-site-detail-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
}

.fn-site-detail-header-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.fn-site-detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: 1rem;
}

@media (max-width: 900px) {
  .fn-site-detail-grid {
    grid-template-columns: 1fr;
  }
}

.fn-site-detail-left,
.fn-site-detail-right {
  min-width: 0;
}

.fn-site-detail-section {
  margin-bottom: 1rem;
}

.fn-site-detail-section-title {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fn-text-sub);
  margin-bottom: 0.3rem;
  font-weight: 600;
}

.fn-site-detail-field {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin-bottom: 0.5rem;
}

.fn-site-detail-field-label {
  font-size: 0.7rem;
  color: var(--fn-text-sub);
}

.fn-site-detail-field-value {
  font-size: 0.9rem;
  color: var(--fn-text);
  white-space: pre-wrap;
}

.fn-site-visits-section {
  margin-bottom: 1.25rem;
}

.fn-site-visits-section-title {
  font-size: 0.95rem;
  font-weight: 600;
  margin: 0 0 0.4rem 0;
  color: var(--fn-text);
}

.fn-admin-table tbody tr.fn-admin-table-row--clickable {
  cursor: pointer;
}

.fn-admin-table tbody tr.fn-admin-table-row--clickable:hover {
  background: var(--fn-raised);
}

/* v2.2 — SiteModal service-streams (recurrences) editor */
.fn-recurrence-row {
    border: 1px solid var(--fn-border);
    border-radius: 6px;
    padding: 0.5rem 0.6rem;
    margin-bottom: 0.4rem;
    background: var(--fn-surface);
}
.fn-recurrence-row--inactive {
    opacity: 0.55;
}
.fn-recurrence-row-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.fn-recurrence-label {
    font-weight: 600;
    min-width: 3rem;
}
.fn-recurrence-meta {
    font-size: 0.78rem;
    color: var(--fn-text-sub);
    flex: 1;
}
.fn-recurrence-actions {
    display: flex;
    gap: 0.25rem;
    margin-left: auto;
}
.fn-recurrence-edit-form,
.fn-recurrence-add-form {
    margin-top: 0.5rem;
    padding-top: 0.4rem;
    border-top: 1px solid var(--fn-border);
}

/* v2.3 — FA site upcoming visits (#5.1) */
.fa-site-upcoming { padding: 0.5rem 0.75rem; border-top: 1px solid #f0f0f0; }
.fa-site-upcoming-label { font-size: 0.7rem; font-weight: 600; color: #6b7280; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.35rem; }
.fa-site-upcoming-row { display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem 0.5rem; padding: 0.25rem 0; }
.fa-site-upcoming-date { font-size: 0.78rem; color: #374151; font-weight: 600; }
.fa-site-upcoming-attendees { display: flex; gap: 0.2rem; }
.fa-site-upcoming-agent { font-size: 0.78rem; color: #374151; }
.fa-site-upcoming-multiday { font-size: 0.7rem; color: #6b7280; font-style: italic; padding: 0 0.35rem; border-radius: 4px; background: #f3f4f6; }

/* v2.14.0 — FA last visits at this site (rear-view counterpart to upcoming) */
.fa-site-last { padding: 0.5rem 0.75rem; border-top: 1px solid #f0f0f0; }
.fa-site-last-label { font-size: 0.7rem; font-weight: 600; color: #6b7280; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.35rem; }
.fa-site-last-row { display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem 0.5rem; padding: 0.25rem 0; }
.fa-site-last-date { font-size: 0.78rem; color: #374151; font-weight: 600; }
.fa-site-last-agent { font-size: 0.78rem; color: #374151; }
.fa-site-last-multiday { font-size: 0.7rem; color: #6b7280; font-style: italic; padding: 0 0.35rem; border-radius: 4px; background: #f3f4f6; }
.fa-site-last-details { width: 100%; font-size: 0.78rem; color: #6b7280; padding-left: 0.2rem; line-height: 1.35; }

/* v2.14.0 — linked-group badge row on the current stop card. Renders a chip per
   condition: multi-day (date range + Day N of M) and/or co-visit (agent names). */
.fa-stop-linked { display: flex; flex-wrap: wrap; gap: 0.35rem 0.5rem; padding: 0.25rem 0.75rem 0.5rem; }
.fa-stop-linked-chip { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.2rem 0.5rem; border-radius: 999px; font-size: 0.72rem; font-weight: 500; border: 1px solid #e5e7eb; background: #f9fafb; color: #374151; }
.fa-stop-linked-chip--multiday { background: #eef2ff; border-color: #c7d2fe; color: #3730a3; }
.fa-stop-linked-chip--multiagent { background: #ecfdf5; border-color: #a7f3d0; color: #065f46; }
.fa-stop-linked-ico { line-height: 1; }

/* v2.14.0 — placeholder for blank contact fields (always-shown contact rows) */
.fa-stop-val--placeholder { color: #9ca3af; font-style: italic; }

/* v2.14.0 — planner-notes row (visit-level notes from Lane B dialog) */
.fa-stop-row--planner-notes { background: #fef9c3; border-left: 3px solid #facc15; padding-left: 0.4rem; }

/* v2.3 — FA others here today (#5.3) */
.fa-others-today { padding: 0.5rem 0.75rem; border-top: 1px solid #f0f0f0; }
.fa-others-today-label { font-size: 0.7rem; font-weight: 600; color: #6b7280; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.35rem; }
.fa-others-today-agents { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.5rem; }
.fa-others-today-name { font-size: 0.78rem; color: #374151; }
.fa-others-today-empty { font-size: 0.78rem; color: #9ca3af; font-style: italic; }

/* v2.3 — mini avatar for co-attendees */
.fa-mini-avatar { display: inline-flex; align-items: center; justify-content: center; width: 1.4rem; height: 1.4rem; border-radius: 50%; font-size: 0.55rem; font-weight: 700; color: #fff; flex-shrink: 0; }

/* v2.3 — email link in stop card */
.fa-stop-email { color: #2563eb; text-decoration: none; }
.fa-stop-email:hover { text-decoration: underline; }

/* v2.4 — 6-column work-pattern grid variant used by AgentProfilePanel sidebar.
   Adds the WFH (IsWfhDay) column and compresses widths to fit the narrower panel. */
.fn-workpattern-grid--profile {
  /* v2.13 — read-only, text headers (Works / Travel / O'night / Office / WFH). Day column
     stays fixed; the five attribute columns share the rest evenly so the words fit. */
  grid-template-columns: 2.6rem repeat(5, 1fr);
  font-size: 0.75rem;
}

.fn-workpattern-grid--profile .fn-workpattern-grid-head,
.fn-workpattern-grid--profile .fn-workpattern-grid-cell {
  justify-content: center;
  text-align: center;
  font-size: 0.68rem;
}

/* Compact tri-state buttons for the sidebar profile panel. */
.fn-pref-tri--sm .fn-pref-tri-btn {
  padding: 0 0.2rem;
  min-width: 1.2rem;
  font-size: 0.7rem;
}

/* v2.4 — edit/done toggle used in AgentProfilePanel skill section. */
.fn-agent-profile-edit-toggle {
  font-size: 0.72rem;
  color: var(--fn-accent);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
}
.fn-agent-profile-edit-toggle:hover {
  color: var(--fn-accent-hover, var(--fn-accent));
}

/* v2.4 — 6-column work-pattern grid for AgentModal (adds WFH column). */
.fn-workpattern-grid--wfh {
  grid-template-columns: 3rem 4rem 1fr 1fr 4rem 4rem;
}

/* v2.8.4bc — Routes list + editor. Additive only; no existing rule touched. */
.fn-routes-view-row {
  cursor: default;
}
.fn-route-editor {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.fn-route-editor-grid {
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: 0.5rem 0.75rem;
  align-items: center;
}
.fn-route-editor-stop-list {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-height: 2rem;
}
.fn-route-stop-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.6rem;
  background: var(--fn-surface, #fff);
  border: 1px solid var(--fn-border, #e5e7eb);
  border-radius: 4px;
  cursor: grab;
}
.fn-route-stop-row:active {
  cursor: grabbing;
}
.fn-route-stop-row--dragging {
  opacity: 0.55;
  border-style: dashed;
}
.fn-route-stop-row-handle {
  font-size: 1.1rem;
  color: var(--fn-text-sub, #6b7280);
}
.fn-route-stop-row-order {
  font-weight: 600;
  width: 1.5rem;
  text-align: right;
}
.fn-route-stop-row-body {
  flex: 1;
  min-width: 0;
}
.fn-route-stop-row-title {
  font-weight: 500;
}
.fn-route-stop-row-sub {
  font-size: 0.78rem;
  color: var(--fn-text-sub, #6b7280);
}
.fn-route-stop-row-time {
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
  color: var(--fn-text-sub, #6b7280);
}

/* v2.8.8 — DayDetailPanel hosted inside SidePanelHost. The base .fn-detail-panel
   rule upstream is tuned for an inline tail under the schedule grid (heavy
   1.5rem padding, max-height:300px cap, border-top divider). Inside the
   480px-wide side panel column those choices fight: the height cap clips the
   visit list, the top border draws a stray rule, and the padding eats the
   already-tight column. Scoped overrides only — DayDetailPanel itself is
   untouched. */
.fn-side-panel-host.expanded .fn-detail-panel {
  padding: 0.75rem 0.75rem 1rem;
  border-top: none;
  max-height: none;
  height: 100%;
  box-sizing: border-box;
}

/* v2.8.7 — VisitDetailsDialog styling. The v2.8.3b agent created the
   markup classes but never added CSS; the Details tab rendered as raw
   stacked label/value pairs. These rules are additive only; the existing
   .fn-dialog-* / .fn-dialog-body rules upstream still own the dialog shell. */
.fn-visit-details-dialog {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-height: min(80vh, 720px);
  min-height: 0;
}

/* v2.8.14 — sticky header with always-visible X. The Radzen DialogService
   doesn't paint a close button by default; the dialog owns the title + X so
   the planner has a one-click exit even with a long Edit form. */
.fn-vd-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0 0.1rem 0.25rem 0.1rem;
  border-bottom: 1px solid var(--fn-border);
  flex-shrink: 0;
}
.fn-vd-header-title {
  flex: 1;
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--fn-text);
}
.fn-vd-close {
  width: 1.75rem;
  height: 1.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--fn-text);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 4px;
}
.fn-vd-close:hover,
.fn-vd-close:focus-visible {
  background: var(--fn-raised);
  outline: none;
}

/* v2.9.4 — cap VisitDetailsDialog overall height at 85vh so the dialog
   never falls off the viewport when many sections render (linked group
   summary, v2.9.3 per-day Extend agent rows, etc.). The dialog has no
   intrinsic max-height by default, so Radzen auto-sizes it to the natural
   content height — which exceeds short laptop viewports.

   Targeted via :has() so we don't need to thread CssClass through the
   seven callsites that OpenAsync<VisitDetailsDialog>. :has() is supported
   in all evergreen browsers (Chrome 105+, Edge 105+, Safari 15.4+,
   Firefox 121+) — well within the dev/target matrix. */
.rz-dialog:has(.fn-vd-scroll) {
  max-height: 85vh;
  display: flex;
  flex-direction: column;
}
.rz-dialog:has(.fn-vd-scroll) > .rz-dialog-content {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* v2.11.1 — extend the v2.9.4 flex chain through Radzen's <RadzenTabs> DOM so
   .fn-vd-scroll (inside the active tab) actually constrains and scrolls.
   Without this, .rz-tabview sizes to content as a non-flex child of
   .fn-visit-details-dialog, .rz-tabview-panels never gets a constrained
   height, .fn-vd-scroll's flex:1 no-ops, and the Edit tab's bottom sections
   (FA progress notes + the dialog action bar) get clipped by .rz-dialog-content
   overflow:hidden. Scoped to .fn-visit-details-dialog — Routes + Admin tabs
   unaffected. */
.fn-visit-details-dialog .rz-tabview {
  flex: 1;
  min-height: 0;
}
.fn-visit-details-dialog .rz-tabview-panels {
  flex: 1;
  min-height: 0;
}

/* v2.8.14 — per-tab scroll container so the tab strip pins to the dialog top
   and only the active tab's body scrolls. */
.fn-vd-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0.25rem 0.1rem;
}

/* v2.8.15 — Details-tab Site / Employer value cells: name text + inline
   open-in-new icon. Replaces the v2.8.14 actions row above the grid. */
.fn-vd-value--with-link {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  white-space: normal;
}
.fn-vd-value--with-link > span {
  flex: 1;
  min-width: 0;
}

/* v2.8.14 — Edit-tab Planned-time single-line row. */
.fn-vd-time-row {
  align-items: center;
}
.fn-vd-time-sep {
  color: var(--fn-text-sub);
  font-size: 0.8rem;
  padding: 0 0.1rem;
}
.fn-vd-time-error {
  color: var(--fn-danger, #dc2626);
  font-size: 0.75rem;
  margin-top: 0.25rem;
}

/* Pin the dialog action bar — flex column above hands it the bottom slot. */
.fn-vd-actions {
  flex-shrink: 0;
}

/* Details tab — two-column grid with a label column and a flexible value
   column. Each row is a flex pair so long values can wrap cleanly without
   forcing the label column to grow. */
.fn-visit-details-grid {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  background: var(--fn-surface);
  overflow: hidden;
}
.fn-vd-detail-row {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.6rem 0.85rem;
  border-bottom: 1px solid var(--fn-border);
}
.fn-vd-detail-row:last-child {
  border-bottom: none;
}
.fn-vd-detail-label {
  flex: 0 0 140px;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--fn-text-sub);
  line-height: 1.4;
}
.fn-vd-detail-value {
  flex: 1;
  min-width: 0;
  font-size: 0.86rem;
  color: var(--fn-text);
  line-height: 1.45;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Edit tab — grouped titled sections. Each section is a card; inside,
   .fn-vd-row is the flex row of inputs/buttons. */
.fn-visit-details-edit {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.fn-vd-section {
  border: 1px solid var(--fn-border);
  border-radius: 6px;
  background: var(--fn-surface);
  padding: 0.6rem 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.fn-vd-section-title {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--fn-text-sub);
}
.fn-vd-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* Status pill — subtle background tint so the current Status reads as a
   tag rather than raw text next to the action buttons. */
.fn-vd-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: var(--fn-raised);
  color: var(--fn-text);
  font-size: 0.78rem;
  font-weight: 500;
  border: 1px solid var(--fn-border);
}

/* Read-only mirror block for FA progress notes inside the Edit tab. */
.fn-vd-readonly-block {
  padding: 0.5rem 0.65rem;
  background: var(--fn-raised);
  border: 1px solid var(--fn-border);
  border-radius: 4px;
  font-size: 0.82rem;
  color: var(--fn-text);
  white-space: pre-wrap;
  min-height: 2.5rem;
}

/* History tab — the table itself reuses .fn-admin-table; the wrapper just
   needs to scroll on overflow so long histories don't stretch the dialog. */
.fn-visit-details-history {
  max-height: 24rem;
  overflow: auto;
}


/* ---- v2.8.9 finding 4 + 5 — DayDetailPanel sequence + per-leg travel ---- */

/* Travel strip rendered between sequence rows. Muted background distinguishes
   it visually from visit/office rows. Home-leg variant gets a subtle accent
   so the home anchors stand out from inter-visit legs. */
.fn-travel-strip {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.6rem;
  font-size: 0.78rem;
  color: var(--fn-text-sub, #64748b);
  background: var(--fn-bg, transparent);
  border: 1px dashed var(--fn-border, #e2e8f0);
  border-radius: 6px;
  margin: 0 1.25rem;
}

.fn-travel-strip--home {
  border-style: solid;
  background: rgba(59, 130, 246, 0.06);
}

.fn-travel-strip__time {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--fn-text, #0f172a);
}

/* Sequence rows share a common gutter so visit + office rows align. */
.fn-sequence-row {
  /* visit row already styled inline (background:raised, padding) — this hook
     exists for future restyles and for tests asserting on the sequence shape. */
}

/* v2.8.14 — pop-out window shell (MapPopoutLayout). Spans the full pop-out
   viewport so MapView's internal .fn-map-shell / .fn-map-canvas can fill it
   without the planner chrome that MainLayout normally wraps Body in. */
.fn-map-popout-shell {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--fn-bg);
}
.fn-map-popout-shell > .fn-map-shell {
  flex: 1;
  min-height: 0;
}

/* v2.9.0-c — multi-agent / multi-day linked-group UI ------------------------ */

/* Small link glyph appended to a visit chip when the row is part of a linked
   group. Sized to match the existing short-code badge so the chip line stays
   compact. */
.fn-visit-link-icon {
  display: inline-block;
  margin-left: 0.25rem;
  font-size: 10px;
  line-height: 1;
  opacity: 0.85;
}

/* Sibling-list chip buttons in the VisitDetailsDialog Details tab "Linked
   group" section + the Edit tab "sibling notice" block. Clickable; opens the
   referenced visit in the dialog. */
.fn-vd-linked-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.fn-linked-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  padding: 0.15rem 0.4rem;
  border: 1px solid var(--rz-base-300, #ccc);
  border-radius: 4px;
  background: var(--rz-base-100, #f5f5f5);
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 11px;
  cursor: pointer;
}

.fn-linked-chip:hover:not(:disabled) {
  background: var(--rz-base-200, #eee);
}

.fn-linked-chip:disabled {
  cursor: default;
  opacity: 0.65;
}

.fn-linked-chip--self {
  border-color: var(--rz-primary, #2196f3);
  background: var(--rz-primary-light, #e3f2fd);
}

/* ============================================================================
   FA Mobile — shared cross-component rules (Phase 1, Foundation)
   Scoped rules for individual screens live in each component's .razor.css file.
   Only rules consumed by TWO OR MORE downstream screens live here.
   ============================================================================ */

/* Status pills — shared across Today list, Visit detail, Overview day cards */
.pill {
  display: inline-flex;
  font-size: 9.5px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.pill--scheduled {
  background: var(--pill-sch-bg);
  color: var(--pill-sch-fg);
}

.pill--confirmed {
  background: var(--pill-cnf-bg);
  color: var(--pill-cnf-fg);
}

.pill--complete {
  background: var(--pill-cmp-bg);
  color: var(--pill-cmp-fg);
}

.pill--cancelled {
  background: var(--pill-cnc-bg);
  color: var(--pill-cnc-fg);
}

/* Unscheduled — muted neutral (future cadence placeholder, not yet committed) */
.pill--unscheduled {
  background: #eef1f5;
  color: #64748b;
}

[data-theme="dark"] .pill--unscheduled {
  background: #2a2f3a;
  color: #9aa4b2;
}

.pill--warn {
  background: var(--warn-bg);
  color: var(--warn-fg);
}

/* In-progress status pill — animated pulsing dot */
.pill--inprogress {
  background: var(--fn-accent);
  color: white;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
}

.pill--inprogress::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: white;
  animation: fn-fa-livepulse 1.4s ease-in-out infinite;
}

@keyframes fn-fa-livepulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.85); }
}

/* Visit row — shared between Today list and Overview day cards (min 60px tap target) */
.fn-fa-visit-row {
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 14px;
  padding: 12px 14px;
  display: grid;
  grid-template-columns: 58px 1fr auto;
  gap: 12px;
  align-items: center;
  min-height: 60px;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
}

.fn-fa-visit-row.featured {
  border-color: var(--fn-accent);
  box-shadow: 0 0 0 1px var(--fn-accent);
}

.fn-fa-visit-row__time-col {
  text-align: center;
}

.fn-fa-visit-row__time-main {
  font-size: 17px;
  font-weight: 600;
  color: var(--fn-text);
  line-height: 1.1;
}

.fn-fa-visit-row__time-dur {
  font-size: 11px;
  color: var(--fn-text-muted);
  margin-top: 2px;
}

.fn-fa-visit-row__site-col {
  min-width: 0;
}

.fn-fa-visit-row__site-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--fn-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fn-fa-visit-row__site-sub {
  font-size: 12px;
  color: var(--fn-text-sub);
  margin-top: 1px;
}

.fn-fa-visit-row__site-emp {
  font-size: 11px;
  color: var(--fn-text-muted);
  margin-top: 1px;
}

.fn-fa-visit-row__right-col {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}

.fn-fa-visit-row.complete .fn-fa-visit-row__site-name {
  color: var(--fn-text-sub);
}

.fn-fa-visit-row.cancelled {
  opacity: 0.7;
}

.fn-fa-visit-row.cancelled .fn-fa-visit-row__site-name {
  text-decoration: line-through;
  color: var(--fn-text-muted);
}

.fn-fa-visit-row__chev {
  color: var(--fn-text-muted);
  font-size: 18px;
  line-height: 1;
}

/* Travel leg — thin separator between consecutive visit rows */
.fn-fa-travel-leg {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px 6px 30px;
  font-size: 11px;
  color: var(--fn-text-muted);
}

.fn-fa-travel-leg::before {
  content: "";
  width: 2px;
  height: 18px;
  background: var(--fn-border-sub);
  border-radius: 1px;
  margin-right: 4px;
}

/* FA Mobile body background (set by FAMobileShell via .fa-mobile-active class on body) */
body.fa-mobile-active {
  background: var(--fn-bg);
}

/* Menu drawer — shared across all FA screens via FAMobileShell/FAMenuDrawer */
.fn-fa-menu-scrim {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0, 0, 0, 0.42);
  z-index: 200;
}

.fn-fa-menu-drawer {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: 290px;
  background: var(--fn-surface);
  z-index: 201;
  display: flex;
  flex-direction: column;
  box-shadow: 4px 0 30px rgba(0, 0, 0, 0.18);
  overflow-y: auto;
  transform: translateX(0);
  transition: transform 0.22s ease;
}

.fn-fa-drawer-profile {
  padding: 16px 16px 18px;
  border-bottom: 1px solid var(--fn-border);
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
}

.fn-fa-drawer-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--fn-accent);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 15px;
  flex-shrink: 0;
}

.fn-fa-drawer-profile-info {
  flex: 1;
  min-width: 0;
}

.fn-fa-drawer-profile-name {
  font-size: 15px;
  font-weight: 700;
  color: var(--fn-text);
}

.fn-fa-drawer-profile-sub {
  font-size: 12px;
  color: var(--fn-text-sub);
  margin-top: 1px;
}

.fn-fa-drawer-profile-chev {
  color: var(--fn-text-muted);
  font-size: 18px;
}

.fn-fa-drawer-section {
  padding: 8px 0 10px;
  border-bottom: 1px solid var(--fn-border);
}

.fn-fa-drawer-section:last-child {
  border-bottom: 0;
}

.fn-fa-drawer-section-lbl {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fn-text-muted);
  font-weight: 700;
  padding: 8px 16px 4px;
}

/* min-height 44px per tap-target rule (WCAG 2.5.5 / iOS HIG) */
.fn-fa-drawer-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 11px 16px;
  min-height: 44px;
  font-size: 14px;
  color: var(--fn-text);
  text-decoration: none;
  cursor: pointer;
  background: none;
  border: none;
  width: 100%;
  text-align: left;
  font-family: inherit;
}

.fn-fa-drawer-item:hover {
  background: var(--fn-raised);
}

.fn-fa-drawer-item.active {
  background: var(--fn-raised);
  border-left: 3px solid var(--fn-accent);
  padding-left: 13px;
  font-weight: 600;
}

.fn-fa-drawer-item__ico {
  font-size: 16px;
  width: 22px;
  text-align: center;
  color: var(--fn-text-sub);
}

.fn-fa-drawer-item.active .fn-fa-drawer-item__ico {
  color: var(--fn-accent);
}

.fn-fa-drawer-item__lbl {
  flex: 1;
}

.fn-fa-drawer-item__ext {
  font-size: 12px;
  color: var(--fn-text-muted);
}

.fn-fa-drawer-item__badge {
  background: var(--fn-accent);
  color: white;
  font-size: 10px;
  font-weight: 700;
  padding: 1px 8px;
  border-radius: 999px;
}

/* ==============================================================================
   FA MOBILE — migrated from Blazor scoped CSS to global rules

   2026-05-14 v2.15.8 — this project doesn't use Blazor CSS isolation (no
   .razor.css files outside FA Mobile existed pre-v2.15.0). The component-level
   .razor.css files added by the FA Mobile rebuild were silently inactive
   because <link rel="stylesheet" href="FieldNavigator.styles.css" /> was never
   added to App.razor (and adding it would have required Foundation to also
   namespace every existing planner-side rule via scoped attrs).

   This block concatenates the 7 .razor.css files into app.css under their
   own class-prefix namespaces (.fn-fa-, .fat-, .fao-, .fvd-, .facbs-,
   .fn-fa-mc__). No selector collisions with existing planner rules.
   ============================================================================== */


/* ---- FAMobileShell.razor.css ---- */
/* FA Mobile Shell — scoped styles */

.offline-pill-slot {
    /* Phase 7 — collapses to zero height when neither pill nor detail panel renders.
       When the pill is present, it pushes the top bar down naturally (no fixed
       positioning — we want the chrome to flow with the document so layout-shift
       lighthouse warnings stay clean). */
}

/* Offline-status pill — renders only when offline OR queue is non-empty.
   Stretches edge-to-edge so it's unmistakable in the field. 44px min height
   to satisfy the FA Mobile tap-target rule. */
.fn-fa-offline-pill {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 44px;
    padding: 8px 14px;
    background: var(--fn-accent);
    color: white;
    font-weight: 600;
    font-size: 13px;
    border: 0;
    border-radius: 0;
    cursor: pointer;
    text-align: center;
    line-height: 1.3;
}

.fn-fa-offline-pill:hover {
    background: var(--fn-accent-hover, var(--fn-accent));
}

.fn-fa-offline-pill__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.18);
    font-size: 12px;
    line-height: 1;
}

.fn-fa-offline-pill__text {
    /* Text already conveys the offline state — no decorative emoji. */
}

/* Detail panel — slides down from the pill. Stays in normal flow so screen
   readers walk it in order; tap on the close button or another tap on the
   pill collapses it. */
.fn-fa-offline-detail {
    background: var(--fn-surface);
    border-bottom: 1px solid var(--fn-border);
    padding: 12px 14px;
}

.fn-fa-offline-detail__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
    font-size: 13px;
    color: var(--fn-text);
}

.fn-fa-offline-detail__close {
    background: transparent;
    border: 0;
    color: var(--fn-text-sub);
    font-size: 20px;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    cursor: pointer;
    line-height: 1;
}

.fn-fa-offline-detail__close:hover {
    background: var(--fn-raised);
}

.fn-fa-offline-detail__empty {
    margin: 0 0 8px;
    font-size: 12px;
    color: var(--fn-text-sub);
}

.fn-fa-offline-detail__list {
    list-style: none;
    margin: 0 0 8px;
    padding: 0;
    max-height: 200px;
    overflow-y: auto;
}

.fn-fa-offline-detail__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 0;
    border-bottom: 1px solid var(--fn-border);
    font-size: 12px;
}

.fn-fa-offline-detail__item:last-child {
    border-bottom: 0;
}

.fn-fa-offline-detail__kind {
    color: var(--fn-text);
    font-weight: 500;
}

.fn-fa-offline-detail__age {
    color: var(--fn-text-muted);
    font-size: 11px;
}

.fn-fa-offline-detail__actions {
    display: flex;
    gap: 8px;
}

.fn-fa-offline-detail__btn {
    flex: 1;
    min-height: 44px;
    border-radius: 8px;
    border: 1px solid var(--fn-border);
    background: var(--fn-surface);
    color: var(--fn-text);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
}

.fn-fa-offline-detail__btn:hover:not(:disabled) {
    background: var(--fn-raised);
}

.fn-fa-offline-detail__btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.fn-fa-offline-detail__btn--retry {
    background: var(--fn-accent);
    color: white;
    border-color: var(--fn-accent);
}

.fn-fa-offline-detail__btn--retry:hover:not(:disabled) {
    background: var(--fn-accent-hover, var(--fn-accent));
}

.fn-fa-offline-detail__btn--clear {
    border-color: var(--fn-border);
    color: var(--fn-text-sub);
}

.fn-fa-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    width: 100%;
    background: var(--fn-bg);
    position: relative;
    overflow-x: hidden;
}

/* Top bar: hamburger left | centered title-stack | avatar right */
.fn-fa-top-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 14px 12px;
    flex-shrink: 0;
}

.fn-fa-icon-btn {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--fn-surface);
    border: 1px solid var(--fn-border);
    color: var(--fn-text);
    font-size: 20px;
    flex-shrink: 0;
    cursor: pointer;
    /* 44px minimum tap target — the 40px visual is padded by the parent's gap */
    padding: 0;
    line-height: 1;
}

.fn-fa-icon-btn--menu {
    font-weight: 400;
}

.fn-fa-icon-btn:hover {
    background: var(--fn-raised);
}

.fn-fa-title-stack {
    flex: 1;
    text-align: center;
    min-width: 0;
    padding: 0 10px;
}

.fn-fa-title-stack__main {
    font-size: 14px;
    font-weight: 600;
    color: var(--fn-text);
}

.fn-fa-title-stack__sub {
    font-size: 11px;
    color: var(--fn-text-muted);
    margin-top: 1px;
}

/* Profile avatar (right side of top bar) */
.fn-fa-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--fn-accent);
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 13px;
    letter-spacing: 0.02em;
    flex-shrink: 0;
    border: 2px solid var(--fn-surface);
    overflow: hidden;
}

/* Entra/Azure profile photo filling the round FA avatars (top-bar + drawer profile row). */
.fn-fa-avatar .fn-fa-avatar-img,
.fn-fa-drawer-avatar .fn-fa-avatar-img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    display: block;
}

.fn-fa-drawer-avatar {
    overflow: hidden;
}

.fn-fa-shell-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

/* ---- FAMenuDrawer.razor.css ---- */
/* FA Menu Drawer — scoped styles.
   The overlay positioning rules (.fn-fa-menu-drawer, .fn-fa-menu-scrim)
   and section/item base rules live in app.css as shared FA mobile rules.
   This file contains only drawer-specific overrides. */

/* Ensure the drawer scrollbar doesn't overlap content on narrow phones */
.fn-fa-menu-drawer {
    scrollbar-width: thin;
    scrollbar-color: var(--fn-border-sub) transparent;
}

/* ---- FAToday.razor.css ---- */
/* ============================================================================
   FAToday.razor.css — scoped CSS for the Today screen.
   Shared rules (pill, fn-fa-visit-row, fn-fa-travel-leg) live in app.css.
   Only Today-specific patterns are defined here.
   ============================================================================ */

/* ── Day stepper ──────────────────────────────────────────────────────────── */

.fat-stepper {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px 8px;
}

.fat-stepper__btn {
  /* 44×44 minimum tap target (iOS HIG / WCAG 2.5.5 AAA) */
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  line-height: 1;
  background: none;
  border: none;
  color: var(--fn-text);
  cursor: pointer;
  border-radius: 10px;
  transition: background 0.12s;
}

.fat-stepper__btn:hover {
  background: var(--fn-border);
}

.fat-stepper__label {
  font-size: 16px;
  font-weight: 600;
  color: var(--fn-text);
}

/* ── Stats band ──────────────────────────────────────────────────────────── */

.fat-stats-band {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  padding: 4px 16px 12px;
}

.fat-stat-tile {
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 14px;
  padding: 10px 8px;
  text-align: center;
}

.fat-stat-tile__val {
  font-size: 22px;
  font-weight: 700;
  color: var(--fn-text);
  line-height: 1.1;
}

.fat-stat-tile__lbl {
  font-size: 10px;
  font-weight: 600;
  color: var(--fn-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-top: 2px;
}

/* ── Progress dots ───────────────────────────────────────────────────────── */

.fat-progress-dots {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 16px 10px;
  flex-wrap: wrap;
}

.fat-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  pointer-events: none; /* decorative — never a tap target */
}

.fat-dot--scheduled  { background: var(--fn-border-sub, #cbd5e1); }
.fat-dot--confirmed  { background: var(--fn-accent); }
.fat-dot--complete   { background: #22c55e; }
.fat-dot--inprogress {
  background: var(--fn-accent);
  animation: fat-dot-pulse 1.4s ease-in-out infinite;
}

@keyframes fat-dot-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.45; transform: scale(0.8); }
}

/* ── Visit list container ────────────────────────────────────────────────── */

.fat-visit-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0 16px;
}

/* Spacing between visit rows and travel legs */
.fat-visit-list .fn-fa-visit-row {
  margin-bottom: 2px;
}

.fat-visit-list .fn-fa-travel-leg {
  margin-bottom: 2px;
}

/* ── Up-next banner ──────────────────────────────────────────────────────── */

.fat-banner {
  margin: 14px 16px 0;
  border-radius: 18px;
  padding: 16px;
}

.fat-banner--upnext {
  background: var(--fn-accent);
  color: white;
}

.fat-banner__label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  opacity: 0.8;
  margin-bottom: 4px;
}

.fat-banner__heading {
  font-size: 18px;
  font-weight: 700;
  line-height: 1.2;
}

.fat-banner__sub {
  font-size: 13px;
  opacity: 0.85;
  margin-top: 2px;
}

.fat-banner__time {
  font-size: 14px;
  font-weight: 600;
  opacity: 0.9;
  margin-top: 6px;
}

.fat-banner__action {
  margin-top: 14px;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 20px;
  background: rgba(255,255,255,0.2);
  border: 1px solid rgba(255,255,255,0.35);
  color: white;
  font-size: 14px;
  font-weight: 600;
  border-radius: 12px;
  cursor: pointer;
  transition: background 0.12s;
}

.fat-banner__action:hover {
  background: rgba(255,255,255,0.32);
}

/* ── Day-complete banner ─────────────────────────────────────────────────── */

.fat-banner--complete {
  background: #dcfce7;
  color: #14532d;
  border: 1px solid #bbf7d0;
}

[data-theme="dark"] .fat-banner--complete {
  background: #14532d;
  color: #bbf7d0;
  border-color: #065f46;
}

/* ── End-of-day travel strip ─────────────────────────────────────────────── */

.fat-eod-strip {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 14px 16px 0;
  padding: 12px 16px;
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 14px;
  font-size: 14px;
  color: var(--fn-text-sub);
}

/* Start-of-day variant sits ABOVE the visit list, so it needs a bottom gap the
   end-of-day strip (last element on screen) doesn't. */
.fat-eod-strip--sod {
  margin-bottom: 10px;
}

/* Expandable variant (drive-to-hotel with address/confirmation) stacks a
   clickable header row above a details panel. */
.fat-eod-strip--expandable {
  flex-direction: column;
  align-items: stretch;
}

.fat-eod-strip__head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.fat-eod-strip--expandable .fat-eod-strip__head {
  cursor: pointer;
}

.fat-eod-strip__icon {
  font-size: 18px;
  line-height: 1;
}

.fat-eod-strip__text {
  font-weight: 500;
}

.fat-eod-strip__chevron {
  margin-left: auto;
  font-size: 13px;
  color: var(--fn-text-muted);
  line-height: 1;
}

.fat-eod-strip__details {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-top: 10px;
  padding-left: 28px; /* align under the text, past the leading emoji */
  border-top: 1px solid var(--fn-border);
}

.fat-eod-strip__detail {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-weight: 400;
}

.fat-eod-strip__detail-icon {
  font-size: 15px;
  line-height: 1.3;
  flex-shrink: 0;
}

/* ── Empty states ────────────────────────────────────────────────────────── */

.fat-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 40px 24px;
  gap: 8px;
}

.fat-empty-state__heading {
  font-size: 18px;
  font-weight: 600;
  color: var(--fn-text);
}

.fat-empty-state__sub {
  font-size: 14px;
  color: var(--fn-text-muted);
}

.fat-empty-state__actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 16px;
  width: 100%;
  max-width: 280px;
}

.fat-empty-state__action-btn {
  /* 44px minimum height */
  min-height: 44px;
  padding: 0 20px;
  background: var(--fn-accent);
  color: white;
  font-size: 15px;
  font-weight: 600;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  transition: background 0.12s;
}

.fat-empty-state__action-btn:hover {
  background: var(--fn-accent-hover);
}

/* ── Bottom padding so last element breathes above safe area ─────────────── */

.fn-fa-shell-body {
  padding-bottom: env(safe-area-inset-bottom, 16px);
}

/* ---- FAOverview.razor.css ---- */
/* ──────────────────────────────────────────────────────────────────────────
   FA Mobile — Overview week view (Phase 5, Worktree D)
   Scoped via Blazor CSS isolation: every rule targets only FAOverview.razor.
   Reuses shared tokens: --fn-accent, --fn-border, --fn-bg, --fn-text-sub,
   --fn-text-muted, --fn-raised defined in app.css.
   ────────────────────────────────────────────────────────────────────────── */

/* ── Week stepper ────────────────────────────────────────────────────────── */

.fao-stepper {
    display: flex;
    align-items: center;
    gap: 0;
    padding: 12px 8px 8px;
}

.fao-stepper__btn {
    min-width: 44px;
    min-height: 44px;
    background: none;
    border: none;
    border-radius: 8px;
    font-size: 1.5rem;
    color: var(--fn-accent, #1d4ed8);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.fao-stepper__btn:hover {
    background: var(--fn-accent-hover-bg, rgba(29, 78, 216, 0.08));
}

.fao-stepper__center {
    flex: 1;
    text-align: center;
}

.fao-stepper__range {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--fn-text, #0f172a);
}

.fao-stepper__sub {
    font-size: 0.78rem;
    color: var(--fn-text-muted, #5a6b80);
    margin-top: 2px;
}

/* ── 2×2 Stat grid ───────────────────────────────────────────────────────── */

.fao-stat-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    padding: 4px 16px 12px;
}

.fao-stat-tile {
    background: var(--fn-card, #fff);
    border: 1px solid var(--fn-border, #e2e8f0);
    border-radius: 12px;
    padding: 14px 12px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.fao-stat-tile__val {
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--fn-text, #0f172a);
    line-height: 1.1;
}

.fao-stat-tile__lbl {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--fn-text-muted, #5a6b80);
}

.fao-stat-tile__sub {
    font-size: 0.78rem;
    color: var(--fn-text-sub, #334a63);
    margin-top: 2px;
}

/* ── Day-by-day card list ────────────────────────────────────────────────── */

.fao-day-list {
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: 0 16px 32px;
}

/* ── Day card ────────────────────────────────────────────────────────────── */

.fao-day-card {
    background: var(--fn-card, #fff);
    border: 1px solid var(--fn-border, #e2e8f0);
    border-radius: 12px;
    margin-bottom: 8px;
    overflow: hidden;
}

.fao-day-card--dim {
    opacity: 0.6;
}

.fao-day-card--today {
    border-color: var(--fn-accent, #1d4ed8);
    box-shadow: 0 0 0 1px var(--fn-accent, #1d4ed8);
}

.fao-day-card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 14px;
}

.fao-day-card__weekday {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--fn-text, #0f172a);
}

.fao-day-card__tag {
    font-size: 0.72rem;
    font-weight: 600;
    padding: 3px 8px;
    border-radius: 20px;
    background: var(--fn-raised, #f1f5f9);
    color: var(--fn-text-sub, #334a63);
    white-space: nowrap;
}

.fao-day-card__tag--today {
    background: var(--fn-accent, #1d4ed8);
    color: #fff;
}

/* ── Visit rows inside a day card ───────────────────────────────────────── */

.fao-day-card__visits {
    border-top: 1px solid var(--fn-border, #e2e8f0);
    padding: 4px 0;
}

.fao-visit-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px;
}

.fao-visit-row--past {
    color: var(--fn-text-sub, #334a63);
}

.fao-visit-row__icon {
    font-size: 1.1rem;
    color: var(--fn-text-muted, #5a6b80);
    flex-shrink: 0;
    line-height: 1;
}

.fao-visit-row__body {
    flex: 1;
    min-width: 0;
}

.fao-visit-row__site {
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--fn-text, #0f172a);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.fao-visit-row__sub {
    font-size: 0.75rem;
    color: var(--fn-text-muted, #5a6b80);
}

/* Co-agents on the same linked group ("with Ben Lucas, Myplus 5"). */
.fao-visit-row__with {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 2px;
    font-size: 0.75rem;
    color: var(--fn-accent, #2563eb);
}

.fao-visit-row__with-icon {
    font-size: 0.875rem;
    flex-shrink: 0;
}

.fao-visit-row__time {
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    color: var(--fn-text-sub, #334a63);
    flex-shrink: 0;
}

/* ── Overnight strip (between consecutive day cards) ────────────────────── */

.fao-overnight-strip {
    background: var(--fn-raised, #f1f5f9);
    border: 1px solid var(--fn-border, #e2e8f0);
    border-radius: 20px;
    padding: 7px 14px;
    margin-bottom: 8px;
    font-size: 0.8rem;
    color: var(--fn-text-sub, #334a63);
}

.fao-overnight-strip__head {
    display: flex;
    align-items: center;
    gap: 8px;
}

.fao-overnight-strip--expandable .fao-overnight-strip__head {
    cursor: pointer;
}

.fao-overnight-strip__icon {
    font-size: 1rem;
    color: var(--fn-accent, #1d4ed8);
    line-height: 1;
}

.fao-overnight-strip__text {
    font-weight: 500;
}

.fao-overnight-strip__chevron {
    font-size: 1.1rem;
    color: var(--fn-text-muted, #5a6b80);
    line-height: 1;
    margin-left: auto;
}

.fao-overnight-strip__details {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 8px;
    padding-top: 8px;
    padding-left: 24px; /* align under the text, past the moon icon */
    border-top: 1px solid var(--fn-border, #e2e8f0);
}

.fao-overnight-strip__detail {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    color: var(--fn-text-sub, #334a63);
}

.fao-overnight-strip__detail-icon {
    font-size: 0.95rem;
    color: var(--fn-text-muted, #5a6b80);
    line-height: 1.3;
    flex-shrink: 0;
}

/* ── Dark mode overrides ─────────────────────────────────────────────────── */

[data-theme="dark"] .fao-stat-tile,
[data-theme="dark"] .fao-day-card {
    background: var(--fn-card, #1e293b);
    border-color: var(--fn-border, #334155);
}

[data-theme="dark"] .fao-overnight-strip {
    background: var(--fn-raised, #0f172a);
    border-color: var(--fn-border, #334155);
}

[data-theme="dark"] .fao-overnight-strip__details {
    border-top-color: var(--fn-border, #334155);
}

/* ---- FAVisitDetail.razor.css ---- */
/* ─── FAVisitDetail scoped styles ──────────────────────────────────────────── */

/* ── Local app bar (secondary bar inside the shell body) ───────────────────── */
.fvd-app-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--fn-border);
    background: var(--fn-surface);
}

.fvd-app-bar__back {
    min-width: 44px;
    min-height: 44px;
    padding: 0 8px;
    background: none;
    border: none;
    color: var(--fn-accent);
    font: inherit;
    font-size: 15px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 2px;
}

.fvd-app-bar__back:hover {
    color: var(--fn-accent-hover);
}

.fvd-app-bar__crumb {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}

.fvd-app-bar__crumb-date {
    font-size: 13px;
    color: var(--fn-text-sub);
    font-weight: 500;
}

.fvd-app-bar__shortcode {
    font-family: 'IBM Plex Mono', 'Courier New', monospace;
    font-size: 11px;
    color: var(--fn-text-muted);
    letter-spacing: 0.03em;
}

.fvd-app-bar__overflow {
    min-width: 44px;
    min-height: 44px;
    padding: 0 8px;
    background: none;
    border: none;
    color: var(--fn-text-sub);
    font: inherit;
    font-size: 18px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ── Status row ─────────────────────────────────────────────────────────────── */
.fvd-status-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
}

/* ── Badges (linked group, window override) ─────────────────────────────────── */
.fvd-badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
}

.fvd-badge--linked {
    background: var(--fn-raised);
    color: var(--fn-text-sub);
    border: 1px solid var(--fn-border);
}

.fvd-badge--warn {
    background: var(--warn-bg);
    color: var(--warn-fg);
}

/* Tappable variant — the linked-group badge is a button that opens the members sheet. */
.fvd-badge--tappable {
    font-family: inherit;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    gap: 4px;
}

.fvd-badge--tappable::after {
    content: "\203A"; /* › — hints the badge is tappable */
    font-weight: 700;
    opacity: 0.65;
}

.fvd-badge--tappable:hover {
    background: var(--fn-border);
}

.fvd-badge--tappable:active {
    transform: scale(0.97);
}

/* Pulsing dot for in-progress pill */
.fvd-pill-pulse {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: currentColor;
    margin-right: 6px;
    animation: fvd-pulse 1.5s ease-in-out infinite;
}

@keyframes fvd-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.5; transform: scale(0.85); }
}

/* ── Cards (shared) ─────────────────────────────────────────────────────────── */
.fvd-card {
    background: var(--fn-surface);
    border: 1px solid var(--fn-border);
    border-radius: 12px;
    margin: 0 16px 12px;
    overflow: hidden;
}

/* ── Site card ───────────────────────────────────────────────────────────────── */
.fvd-site-card__header {
    padding: 14px 16px 10px;
    border-bottom: 1px solid var(--fn-border);
}

.fvd-site-card__name {
    font-size: 17px;
    font-weight: 600;
    color: var(--fn-text);
    line-height: 1.3;
}

.fvd-site-card__employer {
    font-size: 13px;
    color: var(--fn-text-sub);
    margin-top: 2px;
}

.fvd-site-card__notes-tag {
    display: inline-block;
    margin-top: 6px;
    padding: 2px 8px;
    background: var(--fn-raised);
    border-radius: 999px;
    font-size: 12px;
    color: var(--fn-text-sub);
}

/* Rows inside the site card */
.fvd-site-card__row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--fn-border);
}

.fvd-site-card__row:last-child {
    border-bottom: none;
}

.fvd-site-card__icon {
    flex-shrink: 0;
    font-size: 16px;
    margin-top: 1px;
}

/* Address row */
.fvd-site-card__address-row {
    align-items: center;
}

.fvd-site-card__address {
    flex: 1;
    font-size: 14px;
    color: var(--fn-text);
}

.fvd-site-card__maps-btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 60px;
    min-height: 36px;
    padding: 6px 14px;
    background: var(--fn-accent);
    color: #fff;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
}

.fvd-site-card__maps-btn:hover {
    background: var(--fn-accent-hover);
}

/* Contact row */
.fvd-site-card__contact {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.fvd-site-card__contact-name {
    font-size: 14px;
    font-weight: 500;
    color: var(--fn-text);
}

.fvd-site-card__contact-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.fvd-contact-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-height: 36px;
    padding: 6px 14px;
    background: var(--fn-raised);
    border: 1px solid var(--fn-border);
    border-radius: 8px;
    color: var(--fn-text);
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
}

.fvd-contact-btn:hover {
    background: var(--fn-border);
}

.fvd-contact-btn__icon {
    font-size: 14px;
}

/* Access notes accordion */
.fvd-access-notes {
    flex: 1;
}

.fvd-access-notes__toggle {
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    font-size: 14px;
    color: var(--fn-text-sub);
    cursor: pointer;
    line-height: 1.5;
}

.fvd-access-notes__more {
    color: var(--fn-accent);
    font-size: 13px;
}

/* ── Time card ───────────────────────────────────────────────────────────────── */
.fvd-time-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0;
}

.fvd-time-cell {
    padding: 12px 16px;
    border-right: 1px solid var(--fn-border);
}

.fvd-time-cell:last-child {
    border-right: none;
}

.fvd-time-cell__lbl {
    font-size: 11px;
    font-weight: 600;
    color: var(--fn-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 4px;
}

.fvd-time-cell__val {
    font-size: 16px;
    font-weight: 600;
    color: var(--fn-text);
}

.fvd-time-card__meta {
    padding: 10px 16px;
    border-top: 1px solid var(--fn-border);
    font-size: 13px;
    color: var(--fn-text-sub);
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.fvd-time-card__meta--inprogress {
    color: var(--fn-accent);
}

.fvd-time-card__started {
    font-weight: 500;
}

.fvd-time-card__elapsed {
    color: var(--fn-text-sub);
}

/* ── Planner notes card ──────────────────────────────────────────────────────── */
.fvd-planner-notes-card {
    padding: 12px 16px;
}

.fvd-planner-notes-card__lbl {
    font-size: 11px;
    font-weight: 600;
    color: var(--fn-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 6px;
}

.fvd-planner-notes-card__text {
    font-size: 14px;
    color: var(--fn-text-sub);
    font-style: italic;
    line-height: 1.5;
    white-space: pre-wrap;
}

/* ── Site visit history cards ──────────────────────────────────────────────────
   Two separate collapsible cards (Upcoming + Visit history) listing other jobs at
   this site. Own rows are tappable; cross-agent rows are read-only (dimmed, no chevron). */
.fvd-visit-history-card {
    padding: 0;
}

.fvd-visit-history-card__header {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 13px 16px;
    background: none;
    border: none;
    cursor: pointer;
    text-align: left;
}

.fvd-visit-history-card__lbl {
    flex: 1;
    font-size: 11px;
    font-weight: 600;
    color: var(--fn-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.fvd-visit-history-card__count {
    font-size: 12px;
    font-weight: 600;
    color: var(--fn-text-sub);
    background: var(--fn-surface-hover, rgba(100, 116, 139, 0.14));
    border-radius: 10px;
    padding: 1px 8px;
    min-width: 20px;
    text-align: center;
}

.fvd-visit-history-card__chev {
    color: var(--fn-text-muted);
    font-size: 18px;
    line-height: 1;
    transition: transform 0.15s ease;
}

.fvd-visit-history-card__chev--open {
    transform: rotate(90deg);
}

.fvd-visit-history-card__body {
    padding-bottom: 4px;
}

.fvd-visit-history__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 16px;
    border-top: 1px solid var(--fn-border);
}

.fvd-visit-history__row--mine {
    cursor: pointer;
}

.fvd-visit-history__row--mine:hover {
    background: var(--fn-surface-hover, rgba(37, 99, 235, 0.06));
}

.fvd-visit-history__row--other {
    opacity: 0.72;
}

.fvd-visit-history__row-when {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.fvd-visit-history__date {
    font-size: 14px;
    font-weight: 600;
    color: var(--fn-text);
}

.fvd-visit-history__time {
    font-size: 12px;
    color: var(--fn-text-sub);
    margin-top: 1px;
}

.fvd-visit-history__row-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.fvd-visit-history__agent {
    font-size: 12px;
    color: var(--fn-text-sub);
    max-width: 96px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fvd-visit-history__chev {
    color: var(--fn-text-muted);
    font-size: 18px;
    line-height: 1;
}

/* ── Progress notes card ─────────────────────────────────────────────────────── */
.fvd-progress-notes-card {
    padding: 12px 16px;
}

.fvd-progress-notes-card__lbl {
    font-size: 11px;
    font-weight: 600;
    color: var(--fn-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 6px;
}

.fvd-progress-notes-card__textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--fn-border);
    border-radius: 8px;
    background: var(--fn-raised);
    color: var(--fn-text);
    font: inherit;
    font-size: 14px;
    line-height: 1.5;
    resize: vertical;
    min-height: 80px;
}

.fvd-progress-notes-card__textarea:focus {
    outline: none;
    border-color: var(--fn-accent);
}

.fvd-progress-notes-card__footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 6px;
}

.fvd-progress-notes-card__charcount {
    font-size: 12px;
    color: var(--fn-text-muted);
}

.fvd-progress-notes-card__hint {
    font-size: 12px;
    color: var(--fn-text-muted);
}

/* ── Action bar ──────────────────────────────────────────────────────────────── */
.fvd-action-bar {
    position: sticky;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: var(--fn-surface);
    border-top: 1px solid var(--fn-border);
    margin-top: 8px;
}

.fvd-action-bar__tool-btn {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 56px;
    min-height: 52px;
    padding: 6px 10px;
    background: var(--fn-raised);
    border: 1px solid var(--fn-border);
    border-radius: 10px;
    color: var(--fn-text-sub);
    font-size: 11px;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
}

.fvd-action-bar__tool-btn:hover {
    background: var(--fn-border);
}

.fvd-action-bar__tool-icon {
    font-size: 18px;
}

.fvd-action-bar__primary {
    flex: 2;
    min-height: 48px;
    padding: 12px 20px;
    border: none;
    border-radius: 10px;
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    text-align: center;
}

.fvd-action-bar__primary--confirm,
.fvd-action-bar__primary--checkin {
    background: var(--fn-accent);
    color: #fff;
}

.fvd-action-bar__primary--confirm:hover,
.fvd-action-bar__primary--checkin:hover {
    background: var(--fn-accent-hover);
}

.fvd-action-bar__primary--complete {
    background: #059669;
    color: #fff;
}

.fvd-action-bar__primary--complete:hover {
    background: #047857;
}

/* ── Completed footer ────────────────────────────────────────────────────────── */
.fvd-completed-footer {
    text-align: center;
    padding: 16px;
    font-size: 14px;
    font-weight: 500;
    color: var(--fn-text-sub);
    border-top: 1px solid var(--fn-border);
    background: var(--fn-surface);
    margin-top: 8px;
}

/* ── Not found ───────────────────────────────────────────────────────────────── */
.fvd-not-found {
    padding: 40px 16px;
    text-align: center;
    color: var(--fn-text-sub);
    display: flex;
    flex-direction: column;
    gap: 16px;
    align-items: center;
}

/* ---- FAConcurrentBlockSheet.razor.css ---- */
/* ─── FAConcurrentBlockSheet scoped styles ──────────────────────────────────── */

/* Full-screen overlay scrim */
.facbs-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    z-index: 200;
    /* Animate in from below */
    animation: facbs-slide-up 0.22s ease-out;
}

@keyframes facbs-slide-up {
    from { opacity: 0; transform: translateY(40px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Sheet itself */
.facbs-sheet {
    width: 100%;
    max-width: 480px;
    background: var(--fn-surface);
    border-radius: 20px 20px 0 0;
    padding: 24px 24px 36px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    text-align: center;
}

/* Warning icon */
.facbs-sheet__icon {
    font-size: 32px;
    color: var(--warn-fg);
    margin-bottom: 4px;
}

/* Heading */
.facbs-sheet__heading {
    font-size: 16px;
    font-weight: 600;
    color: var(--fn-text);
}

/* Site name (prominent) */
.facbs-sheet__site-name {
    font-size: 18px;
    font-weight: 700;
    color: var(--fn-text);
}

/* Started time */
.facbs-sheet__started {
    font-size: 14px;
    color: var(--fn-text-sub);
}

/* Message */
.facbs-sheet__message {
    font-size: 14px;
    color: var(--fn-text-sub);
    margin-top: 4px;
    margin-bottom: 12px;
}

/* Action buttons */
.facbs-sheet__actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
}

.facbs-sheet__go-btn {
    min-height: 48px;
    padding: 12px 20px;
    background: var(--fn-accent);
    color: #fff;
    border: none;
    border-radius: 10px;
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    width: 100%;
}

.facbs-sheet__go-btn:hover {
    background: var(--fn-accent-hover);
}

.facbs-sheet__cancel-btn {
    min-height: 44px;
    padding: 10px 20px;
    background: none;
    border: 1px solid var(--fn-border);
    border-radius: 10px;
    font: inherit;
    font-size: 15px;
    color: var(--fn-text-sub);
    cursor: pointer;
    width: 100%;
}

.facbs-sheet__cancel-btn:hover {
    background: var(--fn-raised);
}

/* ---- FALinkedGroupSheet.razor ---- */
/* FA Mobile — read-only linked-group members sheet. Reuses the FAConcurrentBlockSheet
   bottom-sheet shape (overlay + slide-up + rounded top), styled as a scrollable list. */
.falg-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    z-index: 200;
    animation: facbs-slide-up 0.22s ease-out;
}

.falg-sheet {
    width: 100%;
    max-width: 480px;
    background: var(--fn-surface);
    border-radius: 20px 20px 0 0;
    padding: 20px 20px 28px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    max-height: 80vh;
}

.falg-sheet__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.falg-sheet__title {
    font-size: 17px;
    font-weight: 700;
    color: var(--fn-text);
}

.falg-sheet__close {
    background: none;
    border: none;
    font-size: 26px;
    line-height: 1;
    color: var(--fn-text-sub);
    cursor: pointer;
    padding: 0 4px;
}

.falg-sheet__body {
    display: flex;
    flex-direction: column;
    gap: 18px;
    overflow-y: auto;
}

.falg-section {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.falg-section__label {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--fn-text-sub);
}

.falg-day {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 6px;
}

.falg-day__date {
    font-size: 13px;
    font-weight: 600;
    color: var(--fn-text);
}

.falg-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.falg-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 12px;
    border: 1px solid var(--fn-border);
    border-radius: 10px;
    background: var(--fn-raised);
}

.falg-row--self {
    border-color: var(--fn-accent);
}

.falg-row__agent {
    font-size: 15px;
    color: var(--fn-text);
}

.falg-row__you {
    font-size: 11px;
    font-weight: 600;
    color: var(--fn-accent);
    background: var(--fn-surface);
    border: 1px solid var(--fn-accent);
    border-radius: 999px;
    padding: 2px 8px;
}

.falg-sheet__done {
    min-height: 44px;
    padding: 10px 20px;
    background: none;
    border: 1px solid var(--fn-border);
    border-radius: 10px;
    font: inherit;
    font-size: 15px;
    color: var(--fn-text-sub);
    cursor: pointer;
    width: 100%;
}

.falg-sheet__done:hover {
    background: var(--fn-raised);
}

/* ---- FAMarkCompleteDialog.razor.css ---- */
/* FA Mobile Phase 4 — Mark Complete Dialog scoped styles.
   Sheet-specific rules only; pill, section-label, and textarea base
   styles come from Foundation's shared app.css. */

/* ── Top bar ───────────────────────────────────────────────────── */
.fn-fa-mc__top-bar {
    display: flex;
    align-items: center;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--fn-border);
    background: var(--fn-bg);
    position: sticky;
    top: 0;
    z-index: 10;
}

.fn-fa-mc__cancel-btn {
    background: none;
    border: none;
    color: var(--fn-accent);
    font-size: 1rem;
    padding: 0.25rem 0;
    cursor: pointer;
    min-width: 44px;
    min-height: 44px;
    text-align: left;
}

.fn-fa-mc__title {
    flex: 1;
    text-align: center;
    font-weight: 600;
    font-size: 1rem;
    color: var(--fn-text);
}

.fn-fa-mc__top-spacer {
    min-width: 44px;
}

/* ── Visit summary card ─────────────────────────────────────────── */
.fn-fa-mc__summary-card {
    background: var(--fn-raised);
    border: 1px solid var(--fn-border);
    border-radius: 0.75rem;
    padding: 0.875rem 1rem;
    margin: 0.75rem 1rem;
}

.fn-fa-mc__site-name {
    font-weight: 600;
    font-size: 1.05rem;
    color: var(--fn-text);
}

.fn-fa-mc__site-meta {
    font-size: 0.875rem;
    color: var(--fn-text-sub);
    margin-top: 0.25rem;
}

.fn-fa-mc__codes {
    display: flex;
    gap: 0.75rem;
    margin-top: 0.5rem;
}

.fn-fa-mc__shortcode {
    font-family: monospace;
    font-size: 0.8rem;
    background: var(--fn-bg);
    border: 1px solid var(--fn-border);
    border-radius: 0.25rem;
    padding: 0.1rem 0.4rem;
    color: var(--fn-text-sub);
}

.fn-fa-mc__date {
    font-size: 0.875rem;
    color: var(--fn-text-sub);
}

/* ── Section label ──────────────────────────────────────────────── */
.fn-fa-mc__section-label {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--fn-text-muted);
    padding: 0.5rem 1rem 0.25rem;
    text-transform: uppercase;
}

/* ── Two-cell time grid ─────────────────────────────────────────── */
.fn-fa-mc__time-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
    padding: 0.25rem 1rem 0.75rem;
}

.fn-fa-mc__time-cell {
    background: var(--fn-raised);
    border: 1px solid var(--fn-border);
    border-radius: 0.75rem;
    padding: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.fn-fa-mc__time-label {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--fn-text-sub);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.fn-fa-mc__time-input {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--fn-text);
    border: none;
    background: transparent;
    padding: 0;
    width: 100%;
    cursor: pointer;
    min-height: 44px;
}

.fn-fa-mc__time-input:focus {
    outline: 2px solid var(--fn-accent);
    outline-offset: 2px;
    border-radius: 0.25rem;
}

.fn-fa-mc__time-hint {
    font-size: 0.7rem;
    color: var(--fn-text-muted);
}

/* v2.17.0 — actual-start/end date pickers inside Mark Complete sheet. Date row sits
   under the time input; the +Nd badge sits inline with the end-date when end > start. */
.fn-fa-mc__date-input {
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--fn-text);
    border: 1px solid var(--fn-border, rgba(0, 0, 0, 0.12));
    background: transparent;
    padding: 0.25rem 0.5rem;
    border-radius: 0.375rem;
    margin-top: 0.25rem;
    width: 100%;
    cursor: pointer;
    min-height: 36px;
}

.fn-fa-mc__date-input:focus {
    outline: 2px solid var(--fn-accent);
    outline-offset: 2px;
}

.fn-fa-mc__date-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.fn-fa-mc__date-row .fn-fa-mc__date-input {
    flex: 1 1 auto;
}

.fn-fa-mc__crossday-badge {
    flex: 0 0 auto;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--fn-warning, #b45309);
    background: var(--fn-warning-bg, rgba(245, 158, 11, 0.15));
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    line-height: 1.2;
    white-space: nowrap;
}

/* ── Duration card ──────────────────────────────────────────────── */
.fn-fa-mc__duration-card {
    background: var(--fn-raised);
    border: 1px solid var(--fn-border);
    border-radius: 0.75rem;
    padding: 0.875rem 1rem;
    margin: 0 1rem 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.fn-fa-mc__duration-label {
    font-size: 0.875rem;
    color: var(--fn-text-sub);
    flex: 1;
}

.fn-fa-mc__duration-value {
    font-weight: 700;
    font-size: 1.1rem;
    color: var(--fn-text);
}

/* Diff pills: red = over planned, green = under planned */
.fn-fa-mc__diff-pill {
    font-size: 0.75rem;
    font-weight: 600;
    border-radius: 999px;
    padding: 0.15rem 0.6rem;
}

.fn-fa-mc__diff-pill--over {
    background: #fee2e2;
    color: #991b1b;
}

.fn-fa-mc__diff-pill--under {
    background: #dcfce7;
    color: #15803d;
}

/* ── Notes textarea ─────────────────────────────────────────────── */
.fn-fa-mc__notes-textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 0.75rem;
    margin: 0.25rem 1rem 0.75rem;
    width: calc(100% - 2rem);
    border: 1px solid var(--fn-border);
    border-radius: 0.75rem;
    background: var(--fn-raised);
    color: var(--fn-text);
    font-size: 0.9rem;
    resize: vertical;
    font-family: inherit;
    min-height: 80px;
}

.fn-fa-mc__notes-textarea:focus {
    outline: 2px solid var(--fn-accent);
    outline-offset: 1px;
}

/* ── Outcome: visit type (single-line, mirrors the notes textarea chrome) ── */
.fn-fa-mc__visittype-input {
    box-sizing: border-box;
    padding: 0.75rem;
    margin: 0.25rem 1rem 0.75rem;
    width: calc(100% - 2rem);
    border: 1px solid var(--fn-border);
    border-radius: 0.75rem;
    background: var(--fn-raised);
    color: var(--fn-text);
    font-size: 0.9rem;
    font-family: inherit;
    min-height: 44px;
}

.fn-fa-mc__visittype-input:focus {
    outline: 2px solid var(--fn-accent);
    outline-offset: 1px;
}

/* ── Warning callout ────────────────────────────────────────────── */
.fn-fa-mc__warn-callout {
    background: #fffbeb;
    border: 1px solid #f59e0b;
    border-radius: 0.75rem;
    padding: 0.75rem 1rem;
    margin: 0 1rem 0.75rem;
    font-size: 0.85rem;
    color: #78350f;
    line-height: 1.5;
}

/* ── Cross-day confirmation ─────────────────────────────────────── */
.fn-fa-mc__crossday-confirm {
    background: #fffbeb;
    border: 1px solid #f59e0b;
    border-radius: 0.75rem;
    padding: 0.875rem 1rem;
    margin: 0 1rem 0.75rem;
}

.fn-fa-mc__crossday-msg {
    font-size: 0.875rem;
    color: #78350f;
    margin-bottom: 0.75rem;
}

.fn-fa-mc__crossday-actions {
    display: flex;
    gap: 0.5rem;
}

.fn-fa-mc__crossday-cancel-btn,
.fn-fa-mc__crossday-confirm-btn {
    flex: 1;
    min-height: 44px;
    border-radius: 0.5rem;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    border: none;
}

.fn-fa-mc__crossday-cancel-btn {
    background: var(--fn-bg);
    border: 1px solid var(--fn-border);
    color: var(--fn-text);
}

.fn-fa-mc__crossday-confirm-btn {
    background: var(--fn-accent);
    color: #fff;
}

/* ── Complete button ────────────────────────────────────────────── */
.fn-fa-mc__complete-btn {
    display: block;
    width: calc(100% - 2rem);
    margin: 0 1rem 1rem;
    min-height: 52px;
    background: #16a34a;
    color: #fff;
    font-size: 1rem;
    font-weight: 700;
    border: none;
    border-radius: 0.75rem;
    cursor: pointer;
    letter-spacing: 0.01em;
}

.fn-fa-mc__complete-btn:hover {
    background: #15803d;
}

.fn-fa-mc__complete-btn:focus {
    outline: 3px solid #16a34a;
    outline-offset: 2px;
}

/* ── Validation error ────────────────────────────────────────────── */
.fn-fa-mc__error {
    background: #fee2e2;
    border: 1px solid #f87171;
    border-radius: 0.5rem;
    padding: 0.6rem 1rem;
    margin: 0 1rem 0.75rem;
    font-size: 0.875rem;
    color: #991b1b;
}

/* ══════════════════════════════════════════════════════════════════
   v2.13.x — Plusnet on-site form pages (/consult/{id}, /referral/{id})
   ══════════════════════════════════════════════════════════════════ */

/* Full-page layout */
.fn-plusnet-page {
    min-height: 100vh;
    background: var(--fn-bg, #f3f4f6);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 2rem 1rem;
}

.fn-plusnet-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    font-size: 1rem;
    color: var(--fn-text-sub, #6b7280);
}

/* Card */
.fn-plusnet-card {
    background: #fff;
    border-radius: 12px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
    width: 100%;
    max-width: 760px;
    padding: 1.75rem 2rem 2rem;
}

/* Header */
.fn-plusnet-header {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.fn-plusnet-back {
    background: none;
    border: none;
    color: var(--fn-accent, #2563eb);
    font-size: 0.9rem;
    cursor: pointer;
    padding: 0;
}

.fn-plusnet-back:hover { text-decoration: underline; }

.fn-plusnet-title {
    font-size: 1.5rem;
    font-weight: 700;
    margin: 0;
    color: var(--fn-text, #111827);
}

/* Auto-fill context banner */
.fn-plusnet-context {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1.5rem;
    background: var(--fn-raised, #f9fafb);
    border: 1px solid var(--fn-border, #e5e7eb);
    border-radius: 8px;
    padding: 0.75rem 1rem;
    margin-bottom: 1.5rem;
    font-size: 0.875rem;
    color: var(--fn-text-sub, #6b7280);
}

.fn-plusnet-ctx-item strong { color: var(--fn-text, #111827); }

/* Error */
.fn-plusnet-error {
    background: #fee2e2;
    border: 1px solid #f87171;
    border-radius: 8px;
    padding: 0.65rem 1rem;
    margin-bottom: 1rem;
    font-size: 0.875rem;
    color: #991b1b;
}

/* Amber — submission saved locally but the immediate +Net sync didn't land (parked or failed).
   Distinct from the red validation error: this is a warning, the data is safe and will sync. */
.fn-plusnet-warning {
    background: #fef3c7;
    border: 1px solid #f59e0b;
    border-radius: 8px;
    padding: 0.65rem 1rem;
    margin-bottom: 1rem;
    font-size: 0.875rem;
    color: #92400e;
}

/* Form grid */
.fn-plusnet-form { display: flex; flex-direction: column; gap: 1rem; }

.fn-plusnet-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

.fn-plusnet-row--full { grid-template-columns: 1fr; }

.fn-plusnet-field { display: flex; flex-direction: column; gap: 4px; }
.fn-plusnet-field--full { width: 100%; }

.fn-plusnet-label {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--fn-text, #111827);
}

.fn-plusnet-req { color: #ef4444; margin-left: 2px; }
.fn-plusnet-opt { font-weight: 400; color: var(--fn-text-sub, #6b7280); }

.fn-plusnet-input,
.fn-plusnet-select,
.fn-plusnet-textarea {
    width: 100%;
    box-sizing: border-box;
    border: 1px solid var(--fn-border, #d1d5db);
    border-radius: 6px;
    padding: 0.5rem 0.75rem;
    font-size: 0.9rem;
    color: var(--fn-text, #111827);
    background: #fff;
    outline: none;
    transition: border-color 0.15s;
}

.fn-plusnet-input:focus,
.fn-plusnet-select:focus,
.fn-plusnet-textarea:focus {
    border-color: var(--fn-accent, #2563eb);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}

.fn-plusnet-select { appearance: auto; }
.fn-plusnet-textarea { resize: vertical; min-height: 90px; }

/* Action buttons */
.fn-plusnet-actions {
    display: flex;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 0.5rem;
}

.fn-plusnet-btn {
    padding: 0.55rem 1.5rem;
    border-radius: 6px;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    border: none;
    transition: background 0.15s, opacity 0.15s;
}

.fn-plusnet-btn--primary {
    background: #2563eb;
    color: #fff;
}

.fn-plusnet-btn--primary:hover { background: #1d4ed8; }

.fn-plusnet-btn--secondary {
    background: var(--fn-raised, #f3f4f6);
    color: var(--fn-text, #374151);
    border: 1px solid var(--fn-border, #d1d5db);
}

.fn-plusnet-btn--secondary:hover { background: var(--fn-border, #e5e7eb); }

/* ── Per-visit Consult / Referral action row (FieldAgentView stop cards) ── */
.fa-stop-plusnet {
    display: flex;
    gap: 0.5rem;
    padding: 0.5rem 0 0.25rem;
    flex-wrap: wrap;
}

.fa-plusnet-btn {
    padding: 0.3rem 0.9rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    border: 1px solid var(--fn-accent, #2563eb);
    background: transparent;
    color: var(--fn-accent, #2563eb);
    transition: background 0.15s, color 0.15s;
}

.fa-plusnet-btn:hover {
    background: var(--fn-accent, #2563eb);
    color: #fff;
}

/* ── VisitDetailsDialog Plusnet tab ── */
.fn-vd-plusnet { padding: 0; }

.fn-vd-plusnet-section { margin-bottom: 1.5rem; }

.fn-vd-plusnet-heading {
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--fn-text-sub, #6b7280);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.5rem 0 0.4rem;
    border-bottom: 1px solid var(--fn-border, #e5e7eb);
    margin-bottom: 0.5rem;
}

/* Mobile responsiveness */
@media (max-width: 600px) {
    .fn-plusnet-row { grid-template-columns: 1fr; }
    .fn-plusnet-card { padding: 1.25rem 1rem 1.5rem; }
}

/* ── No-access page (v2.18.0) ─────────────────────────────────────────────
   Standalone full-page state shown by NoAccessPage.razor (MinimalLayout, no
   planner chrome). All colours via theme tokens so light/dark both work. */
.fn-noaccess {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background-color: var(--fn-bg);
    color: var(--fn-text);
}

.fn-noaccess-card {
    width: 100%;
    max-width: 30rem;
    background: var(--fn-surface);
    border: 1px solid var(--fn-border);
    border-radius: 12px;
    padding: 2.25rem 2rem;
    text-align: center;
    box-shadow: 0 10px 30px rgba(15, 23, 42, 0.08);
}

.fn-noaccess-icon {
    width: 3.5rem;
    height: 3.5rem;
    margin: 0 auto 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--fn-accent-soft, var(--fn-raised, #eef2ff));
    color: var(--fn-accent);
}

.fn-noaccess-icon .rzi { font-size: 1.9rem; }

.fn-noaccess-title {
    margin: 0 0 0.75rem;
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--fn-text);
}

.fn-noaccess-body {
    margin: 0 0 0.5rem;
    color: var(--fn-text-sub);
    line-height: 1.5;
}

.fn-noaccess-hint {
    margin: 0 0 1.5rem;
    color: var(--fn-text-muted);
    font-size: 0.9rem;
}

.fn-noaccess-actions {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.fn-noaccess-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.65rem 1.1rem;
    border-radius: 6px;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.fn-noaccess-btn-primary {
    background: var(--fn-accent);
    color: #ffffff;
}

.fn-noaccess-btn-primary:hover { background: var(--fn-accent-hover); }

.fn-noaccess-btn-secondary {
    background: transparent;
    color: var(--fn-text);
    border-color: var(--fn-border-sub);
}

.fn-noaccess-btn-secondary:hover { background: var(--fn-raised, rgba(15, 23, 42, 0.04)); }

.fn-noaccess-btn:focus-visible { outline: 2px solid var(--fn-accent); outline-offset: 2px; }

/* ---- FAHistory.razor ---- */
/* ──────────────────────────────────────────────────────────────────────────
   FA Mobile — Visit history screen (/field/history).
   Reuses the shared fn-fa-visit-row row card + pill idiom; only the summary
   strip and day-group scaffolding are new. All colours use theme-aware tokens
   (--fn-surface / --fn-border / --fn-text*) so dark mode needs no overrides.
   ────────────────────────────────────────────────────────────────────────── */

.fah-summary {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin: 12px 16px;
    padding: 14px 12px;
    background: var(--fn-surface);
    border: 1px solid var(--fn-border);
    border-radius: 14px;
}

.fah-summary__stat {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}

.fah-summary__val {
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--fn-text);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.fah-summary__lbl {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--fn-text-muted);
}

.fah-summary__divider {
    width: 1px;
    align-self: stretch;
    background: var(--fn-border);
}

.fah-list {
    display: flex;
    flex-direction: column;
    padding: 0 16px 32px;
}

.fah-day-group {
    margin-bottom: 16px;
}

.fah-day-header {
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--fn-text-muted);
    padding: 4px 2px 8px;
}

.fah-day-group .fn-fa-visit-row {
    margin-bottom: 8px;
}

/* ---- FAProfile.razor ---- */
/* ──────────────────────────────────────────────────────────────────────────
   FA Mobile — Profile screen (/profile). Read-only self view.
   Theme-aware tokens throughout; no dark-mode overrides required.
   ────────────────────────────────────────────────────────────────────────── */

.fap-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 8px;
    padding: 24px 16px 16px;
}

.fap-avatar {
    width: 72px;
    height: 72px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

/* Entra/Azure profile photo filling the profile-page avatar. */
.fap-avatar--photo {
    overflow: hidden;
    background: transparent;
}

.fap-avatar .fap-avatar-img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    display: block;
}

.fap-header__name {
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--fn-text);
}

.fap-header__meta {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.85rem;
    color: var(--fn-text-sub);
}

.fap-status {
    font-weight: 600;
}

.fap-status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.fap-header__sep {
    color: var(--fn-text-muted);
}

.fap-section {
    padding: 8px 16px 0;
}

.fap-section__head {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fn-text-muted);
    padding: 12px 2px 8px;
}

.fap-card {
    background: var(--fn-surface);
    border: 1px solid var(--fn-border);
    border-radius: 14px;
    overflow: hidden;
}

.fap-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 14px;
}

.fap-row + .fap-row {
    border-top: 1px solid var(--fn-border);
}

.fap-row__label {
    font-size: 0.85rem;
    color: var(--fn-text-sub);
    flex-shrink: 0;
}

.fap-row__value {
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--fn-text);
    text-align: right;
    min-width: 0;
    word-break: break-word;
}

.fap-empty {
    padding: 14px;
    font-size: 0.85rem;
    color: var(--fn-text-muted);
}

.fap-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.fap-tag {
    font-size: 0.8rem;
    font-weight: 500;
    padding: 5px 12px;
    border-radius: 20px;
    background: var(--fn-raised);
    color: var(--fn-text-sub);
}

.fap-leave-row {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 12px 14px;
}

.fap-leave-row + .fap-leave-row {
    border-top: 1px solid var(--fn-border);
}

.fap-leave-row__dates {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--fn-text);
    font-variant-numeric: tabular-nums;
}

.fap-leave-row__reason {
    font-size: 0.8rem;
    color: var(--fn-text-muted);
}

.fap-signout {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 48px;
    margin: 12px 0 32px;
    padding: 0 20px;
    background: var(--fn-surface);
    border: 1px solid var(--fn-border);
    border-radius: 12px;
    font-size: 0.95rem;
    font-weight: 600;
    color: #b91c1c;
    cursor: pointer;
    transition: background 0.12s;
}

.fap-signout:hover {
    background: var(--fn-raised);
}

.fap-signout__icon {
    font-size: 1.1rem;
    line-height: 1;
}

[data-theme="dark"] .fap-signout {
    color: #f87171;
}

/* ------------------------------------------------------------------------
   2026-07-15 — AgentProfilePanel read-only polish + wider shared edit drawer.
   The base .fn-agent-profile and .fn-drawer rules are DUPLICATED earlier in
   this file (two copies each). Rather than edit both copies, these EOF
   overrides win the cascade unambiguously.
   ------------------------------------------------------------------------ */

/* (3) Side panel content was flush to the rail edges — give it breathing room.
   The host (.fn-side-panel-host) has no padding of its own, so this is additive. */
.fn-agent-profile {
  padding: 0.75rem 1rem 1rem;
}

/* (2) The shared AgentModal drawer was 440px — too narrow for the 6-column
   work-pattern grid (the WFH column clipped). Widen it, capped to the viewport. */
.fn-drawer {
  width: min(600px, 100vw);
}

/* ------------------------------------------------------------------------
   2026-07-17 (v2.14) — week header collapsed back to a SINGLE row. v2.13 split it
   into two stacked rows because the nav was crushed inside the 152px card column;
   dropping the month/year label (each date cell already shows its month) frees
   enough room to fit the chevrons + Today (icon-only) + hamburger in that column
   again. The header is now a grid whose template MIRRORS .fn-agent-row
   (card-col + repeat(day-cols,1fr), 2px gap, same min-width), so the date cells
   stay locked to the day-tile columns below during horizontal scroll. Base
   .fn-week-header* rules are duplicated earlier in this file → these EOF overrides
   win the cascade.
   ------------------------------------------------------------------------ */
.fn-week-header {
  display: grid;
  grid-template-columns: var(--fn-card-col) repeat(var(--fn-day-cols, 5), 1fr);
  gap: 2px;
  align-items: center;
  min-width: calc(var(--fn-card-col) + 480px);
}
/* Nav cluster occupies the agent-card column; keep it a tight single row so the
   chevrons, Today icon and hamburger all fit within ~152px. */
.fn-week-header-nav {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem;
  min-width: 0;
}

/* ------------------------------------------------------------------------
   v2.20 - Radzen DataGrid house skin (.fn-grid) + detail card (.fn-detail-card)

   EmployerDetailView and SiteDetailView were the last detail surfaces still
   rendering hand-rolled <table class="fn-admin-table"> / .fn-visit-history-table
   markup with no paging or sorting. They now use RadzenDataGrid; this block is
   the shared skin that makes a Radzen grid read as part of the app rather than
   as a stock Material widget. These are the FIRST RadzenDataGrid / RadzenCard
   usages in the codebase - keep new grids on .fn-grid so the look stays in
   one place.

   Themed by REDECLARING Radzen's own --rz-grid-* custom properties scoped to
   .fn-grid, rather than by out-specifying its rules. Radzen's theme applies them
   from selectors like `.rz-grid-table thead th` (0,1,2) and
   `.rz-grid-table td .rz-cell-data` (0,2,2); a plain `.fn-grid th` override loses
   that fight, and escalating the selector just breaks again on the next release.
   Overriding the variable wins wherever Radzen chooses to apply it.

   Values come from the --fn-* tokens, so light and dark track the app palette
   automatically alongside the rz-theme-dark stylesheet that theme.js toggles.
   Without this the grid keeps Radzen dark's near-black (#1e1e1e) chrome, which
   reads as a hole punched in the app's navy (--fn-surface) card.
   ------------------------------------------------------------------------ */

.fn-grid {
  /* Frame — the containing .fn-detail-card draws the border, so the grid's own
     background and shadow drop out and it sits ON the card surface. */
  --rz-grid-background-color: transparent;
  --rz-grid-shadow: none;
  --rz-grid-border-radius: 0;

  /* Header band */
  --rz-grid-header-background-color: var(--fn-raised);
  --rz-grid-header-sorted-background-color: var(--fn-raised);
  --rz-grid-header-color: var(--fn-text-sub);
  --rz-grid-header-font-size: 0.72rem;
  --rz-grid-header-font-weight: 600;
  --rz-grid-header-text-transform: uppercase;
  --rz-grid-header-cell-padding: 0.4rem 0.5rem;

  /* Body cells — matches .fn-admin-table's density and near-black text. */
  --rz-grid-cell-color: var(--fn-text);
  --rz-grid-cell-font-size: 0.85rem;
  --rz-grid-cell-padding: 0.4rem 0.5rem;
  --rz-grid-cell-border: 1px solid var(--fn-border);
  --rz-grid-bottom-cell-border: 1px solid var(--fn-border);
  --rz-grid-hover-background-color: var(--fn-raised);
  --rz-grid-hover-color: var(--fn-text);

  /* Filter row + pager */
  --rz-grid-filter-background-color: transparent;
  --rz-grid-foot-background-color: transparent;

  font-size: 0.85rem;
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--fn-surface);
}

/* Radzen paints the scroll wrapper and table separately from the variables
   above; clear them so the card surface shows through the whole grid. */
.fn-grid .rz-data-grid-data,
.fn-grid .rz-grid-table,
.fn-grid tbody tr,
.fn-grid tbody tr > td {
  background: transparent;
}

/* Letter-spacing has no --rz-* variable, so it stays a rule — scoped to the
   header LABEL only. Radzen's sort/filter affordances are Material Symbols
   ligatures (literal text like "arrow_upward" resolved by the font); applying
   text-transform to their container breaks the ligature and leaks the raw token
   into the header. Hence the .rzi reset below — belt and braces. */
.fn-grid th .rz-column-title-content {
  letter-spacing: 0.04em;
}

.fn-grid .rzi,
.fn-grid input,
.fn-grid .rz-dropdown {
  text-transform: none;
  letter-spacing: normal;
}

.fn-grid tbody tr:last-child td {
  border-bottom: none;
}

.fn-grid tbody tr:hover > td {
  background: var(--fn-raised);
}

/* Row-level drill-in. Anchored on the data-* hooks that RowRender splats onto
   the <tr> rather than a class: Radzen computes the row's class attribute
   itself, so a class supplied through RowRenderEventArgs.Attributes is not a
   reliable hook. The same attributes are what the bUnit tests select on. */
.fn-grid tbody tr[data-site-id],
.fn-grid tbody tr[data-visit-id] {
  cursor: pointer;
}

.fn-grid .rz-paginator {
  background: var(--fn-surface);
  border-top: 1px solid var(--fn-border);
  padding: 0.3rem 0.5rem;
  font-size: 0.78rem;
}

/* Panel wrapper for the employer/site detail surfaces. Mirrors .fn-admin-section
   so a RadzenCard sits flush with the app's existing panels instead of carrying
   the Material theme's own elevation and radius. */
.fn-detail-card {
  background: var(--fn-surface);
  border: 1px solid var(--fn-border);
  border-radius: 8px;
  box-shadow: none;
  margin-bottom: 1rem;
}

/* A grid inside a card must not double up on frames - the card already draws
   the outer border, so the grid drops its own. */
.fn-detail-card .fn-grid {
  border: none;
  border-radius: 0;
  background: transparent;
}

/* Section heading + CTA row that sits above a grid inside a card. */
.fn-detail-card-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
