/* ============================================================
   theme-ff.css — DSP Portal "Freedom-Forever" B&W re-skin.
   Loaded AFTER styles.css so it wins by cascade order.
   Strategy: the portal is driven by a CSS design-token system,
   so we re-theme the whole app by overriding the color/shadow
   tokens from dark → flat black & white (light), and neutralize
   the dark animated background layers. NO structural or JS
   changes live here — purely visual. Locked direction:
   utilitarian enterprise, black & white only, one signal color
   (red) reserved for true urgency (clawbacks/errors).
   ============================================================ */

:root {
  /* surfaces + ink */
  --bg:            #f6f7f9;
  --bg-deep:       #ffffff;
  --ink:           #16181d;
  --ink-soft:      #565a62;
  --ink-faint:     #6b6f76; /* ff381 (P2-04): was #8a8d94 (3.3:1, AA fail at 10-12px) → 4.9:1 */
  --ink-dim:       rgba(0, 0, 0, 0.5);

  /* hairlines */
  --line:          #e4e5e9;
  --line-strong:   rgba(0, 0, 0, 0.16);
  --line-bright:   rgba(0, 0, 0, 0.30);

  /* cards + controls */
  --card-bg:       #ffffff;
  --card-bg-hover: #f7f7f9;
  --control-bg:    #ffffff;
  --control-bg-focus: #ffffff;

  /* accent → grayscale (no colored accent; black is the accent) */
  --accent-blue:        rgba(0, 0, 0, 0.55);
  --accent-blue-strong: #111111;
  --accent-blue-bg:     linear-gradient(180deg, #1c1c1c 0%, #111111 100%);

  /* Columbia-blue signature accent — a light, deliberate touch on selected/active
     states + focus so the B&W shell reads as ours, not a stock template. */
  --col-blue:      #6CACE4;
  --col-blue-deep: #3E84C0;
  --col-blue-soft: #E8F2FB;

  /* status: keep red for urgency only; mute the rest toward grayscale */
  --error:   #b42318;
  --success: #1f7a44;
  --warning: #7a5d00;

  /* brand "metal" gradients → solid near-black (B&W) */
  --gradient-silver:   linear-gradient(180deg, #1a1a1a 0%, #333333 100%);
  --gradient-platinum: linear-gradient(135deg, #111111 0%, #444444 50%, #111111 100%);
  --gradient-card-edge: linear-gradient(135deg, rgba(0,0,0,0.10), rgba(0,0,0,0.03));

  /* shadows → light-theme soft */
  --shadow-flat:    0 1px 2px rgba(0, 0, 0, 0.06);
  --shadow-soft:    0 4px 12px -4px rgba(0, 0, 0, 0.10), 0 1px 2px rgba(0, 0, 0, 0.06);
  --shadow-lifted:  0 12px 28px -10px rgba(0, 0, 0, 0.14), 0 4px 8px -4px rgba(0, 0, 0, 0.08);
  --shadow-deep:    0 24px 60px -20px rgba(0, 0, 0, 0.18), 0 8px 24px -12px rgba(0, 0, 0, 0.10);
  --shadow-edge:    inset 0 1px 0 rgba(255, 255, 255, 0.7);
  --shadow-pressed: inset 0 1px 4px rgba(0, 0, 0, 0.10);

  /* focus rings → grayscale */
  --ring-soft:    0 0 0 3px rgba(0, 0, 0, 0.08);
  --ring-medium:  0 0 0 3px rgba(0, 0, 0, 0.14);
  --ring-strong:  0 0 0 3px rgba(0, 0, 0, 0.26);

  /* leaderboard sticky tints → light */
  --lb-sticky-bg:        #ffffff;
  --lb-sticky-bg-gold:   #f4efe0;
  --lb-sticky-bg-silver: #eef0f2;
  --lb-sticky-bg-bronze: #f3ebe2;
  --lb-sticky-bg-me:     #eef2f8;

  /* font → Roboto (enterprise/MUI feel per locked direction).
     ff381 (P2-01c): --font-mono joins the pair — styles.css's token still said
     'Geist Mono' (~220 consuming rules), so a normal session mixed FOUR faces. */
  --font-display: 'Roboto', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-body:    'Roboto', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono:    'Roboto Mono', 'SF Mono', Menlo, Consolas, monospace;
}

/* base surface */
html, body { background: var(--bg) !important; color: var(--ink); }

/* ff380 (P1-10): iOS zooms the whole viewport when a focused input's font-size
   is under 16px — the FF-era 13-14px search/date/form inputs made every list
   search "jump" and often left the screen stuck zoomed. Touch devices get 16px
   on every text-entry control; desktop (fine pointer) keeps the compact sizes.
   Same rule the login form already applies (.auth-field input). */
@media (pointer: coarse) {
  .ff-search input,
  .ff-topfilter .inp input,
  .ff-adminview-search,
  .ff-date input,
  .ffs-field input,
  .ffs-field select,
  .ffs-field textarea,
  .ff-dispo-card .dm-note,
  #ffCommActions select,
  .lh-input,
  .dsp-edit-search {
    font-size: 16px !important;
  }
}

/* The topbar has a HARDCODED dark glass bg rgba(8,10,18,.72) that the tokens
   don't reach → make it the FF white frosted bar with dark contents. */
.portal-topbar { background: #fff !important; border-bottom: 1px solid var(--line) !important; }
.portal-topbar-wordmark { color: var(--ink) !important; }
.portal-topbar-btn { background: #fff !important; border: 1px solid var(--line) !important; color: var(--ink) !important; }
.portal-topbar-btn:hover { background: #f5f5f5 !important; }
.portal-topbar-btn .portal-topbar-btn-label { color: var(--ink) !important; }
.portal-topbar-btn svg { color: var(--ink-soft) !important; }
.topbar-preview { background: #fff !important; border: 1px solid var(--line) !important; color: var(--ink) !important; }
.topbar-preview-label { color: var(--ink) !important; }

/* (orb/particle hide rule deleted ff381 — the markup itself is gone, DC-05.) */

/* selection → grayscale */
::selection    { background: rgba(0, 0, 0, 0.12); color: var(--ink); }
::-moz-selection { background: rgba(0, 0, 0, 0.12); color: var(--ink); }

/* The silver/platinum gradient-text treatment → solid near-black so hero
   numbers + headings read as crisp B&W instead of metallic-on-dark. */
.text-silver, .text-platinum {
  background: none !important;
  -webkit-text-fill-color: #16181d !important;
  color: #16181d !important;
  animation: none !important;
}

/* The chiseled "obsidian" card edge → a clean hairline border on white. */
.card-depth::before { background: var(--gradient-card-edge) !important; }

/* Inputs/selects: ensure dark-on-light, not light-on-dark, even where a rule
   hardcoded a near-black text color for the dark theme. */
input, select, textarea { color: var(--ink); }
input::placeholder, textarea::placeholder { color: var(--ink-faint); }

/* The brand burst mark is a WHITE png (built for dark bg) → invert to black so
   it's visible on the light shell. Covers topbar, auth hero, and any usage. */
.portal-topbar-burst,
.auth-hero-burst,
img[src*="logo-burst-white"] { filter: invert(1); }

/* Wordmarks + hero/auth titles used metallic gradient text on dark → force
   crisp solid ink so they read on white. */
.portal-topbar-wordmark,
.auth-hero-meta,
.auth-hero-tagline,
.app-welcome-name {
  background: none !important;
  -webkit-text-fill-color: var(--ink) !important;
  color: var(--ink) !important;
}
.auth-hero-meta, .auth-hero-tagline { color: var(--ink-soft) !important; -webkit-text-fill-color: var(--ink-soft) !important; }

/* The "sick" silver sweep Nathaniel liked on the Sign-in title — kept, but
   re-tuned for the LIGHT shell: dark ink text with a silver highlight gliding
   left→right across it (readable + premium, pure B&W). */
.auth-title, .auth-title .shimmer, .auth-hero-wordmark {
  background: linear-gradient(100deg, #16181d 0%, #16181d 38%, #b9bcc4 47%, #eef0f3 50%, #b9bcc4 53%, #16181d 62%, #16181d 100%) !important;
  background-size: 240% 100% !important;
  -webkit-background-clip: text !important;
          background-clip: text !important;
  -webkit-text-fill-color: transparent !important;
  color: transparent !important;
  animation: ffSheen 3.6s ease-in-out infinite !important;
}
@keyframes ffSheen { 0% { background-position: 140% 0; } 100% { background-position: -40% 0; } }
/* Even with Reduce Motion on, keep a static silver highlight so it never looks flat black. */
@media (prefers-reduced-motion: reduce){ .auth-title, .auth-title .shimmer, .auth-hero-wordmark { animation: none !important; background-position: 50% 0 !important; } }

/* Decorative glows/halos behind the logo read as gray smudges on white → hide. */
.auth-hero-burst-halo, .auth-hero-glow { display: none !important; }

/* Sign-in PRIMARY action = solid black (FF primary button), not outlined. */
.auth-submit { background: #111 !important; color: #fff !important; border: none !important; box-shadow: none !important; }
.auth-submit:hover { background: #000 !important; }
.auth-submit .auth-submit-label, .auth-submit span { color: #fff !important; }
/* Secondary auth links (switch method / apply to join) were too faint on white. */
.auth-switch-link, .auth-card a:not(.auth-submit), .auth-secondary { color: #2f2f33 !important; font-weight: 500; }
.auth-switch-link:hover, .auth-card a:not(.auth-submit):hover { color: #000 !important; }

/* The legacy giant "Welcome back / Nathaniel." greeting hero is NOT in the FF
   prototype — the identity lives in the topbar instead (see .ff-user). Hide it. */
.app-welcome { display: none !important; }

/* The floating "PORTAL · 2026" meta now overlaps the topbar search → hide it. */
.portal-topbar-meta { display: none !important; }

/* Topbar user dropdown (avatar + name + role + caret → menu), like the prototype. */
.portal-topbar-actions { position: relative; }
.ff-user { display: flex; align-items: center; gap: 9px; padding: 5px 8px 5px 6px; background: none; border: none; border-radius: 9px; cursor: pointer; font-family: inherit; }
.ff-user:hover { background: #f4f5f7; }
.ff-user-av { width: 36px; height: 36px; border-radius: 50%; background: #111; color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 11px; letter-spacing: .06em; flex: 0 0 auto; }
.ff-user-txt { display: flex; flex-direction: column; line-height: 1.15; text-align: left; }
.ff-user-nm { font-weight: 700; font-size: 13px; color: var(--ink); }
.ff-user-rl { font-size: 11px; font-weight: 700; color: var(--ink-soft); letter-spacing: .06em; text-transform: uppercase; }
.ff-user-caret { color: var(--ink-faint); flex: 0 0 auto; }

.ff-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 70; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 18px 44px -14px rgba(0,0,0,.3); padding: 6px; min-width: 240px; }
.ff-menu[hidden] { display: none; }
.ff-menu-item { display: block; width: 100%; text-align: left; background: none; border: none; font-family: inherit; font-size: 13px; color: var(--ink); padding: 10px 12px; border-radius: 7px; cursor: pointer; }
.ff-menu-item:hover { background: #f4f5f7; }
.ff-menu-signout { color: #b42318; font-weight: 500; }
.ff-menu-sec { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint); padding: 8px 12px 4px; }
.ff-menu-div { height: 1px; background: var(--line2, #eee); margin: 5px 4px; }
.ff-menu-admin { padding: 0 6px 2px; }
.ff-menu-admin .topbar-preview { width: 100%; background: #fff !important; border: 1px solid var(--line) !important; border-radius: 7px; }

/* old standalone topbar controls now live in the dropdown → hide them + the eye emoji */
.portal-topbar-btn-invite, .portal-topbar-btn-signout { display: none !important; }
.topbar-preview-eye { display: none !important; }
.topbar-preview { display: none !important; }   /* Admin View moved into the user dropdown */
.ff-menu { min-width: 300px; max-width: calc(100vw - 24px); max-height: calc(100vh - 80px); overflow-y: auto; }

/* Admin View — searchable rep picker inside the user dropdown */
.ff-adminview { padding: 2px 6px 4px; }
.ff-adminview-search { width: 100%; border: 1px solid var(--line); border-radius: 7px; padding: 8px 11px; font-family: inherit; font-size: 13px; color: var(--ink); margin-bottom: 6px; }
.ff-adminview-list { max-height: 340px; overflow-y: auto; -webkit-overflow-scrolling: touch; display: flex; flex-direction: column; gap: 2px; padding-right: 2px; }
.ff-adminview-rep { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; width: 100%; text-align: left; background: none; border: none; font-family: inherit; padding: 9px 11px; border-radius: 7px; cursor: pointer; }
.ff-av-name { font-size: 13px; font-weight: 500; color: var(--ink); line-height: 1.35; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.ff-av-div { font-size: 11px; color: var(--ink-soft); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.ff-adminview-rep:hover { background: #f4f5f7; }
.ff-adminview-rep.is-current { background: #111; }
.ff-adminview-rep.is-current .ff-av-name, .ff-adminview-rep.is-current .ff-av-div { color: #fff; }
.ff-adminview-empty { font-size: 12px; color: var(--ink-faint); padding: 8px 11px; }
.ff-adminview-state { font-size: 12px; color: var(--ink-soft); padding: 4px 11px 8px; display: flex; align-items: center; gap: 8px; }
.ff-adminview-exit { background: #111; color: #fff; border: none; border-radius: 6px; padding: 4px 9px; font-size: 12px; cursor: pointer; }

/* ===========================================================================
   FIX black-on-black: the B&W re-skin flipped --accent-blue-bg to a BLACK
   gradient, but these "selected / primary" fills kept color:var(--ink) → dark
   text on a black fill (invisible): Add-a-Lead + edit Save buttons, the Day/
   Month toggle, segmented tabs, and the selected calendar day. Pin them to a
   flat black fill + WHITE text. The flat (opaque) fill also stops the Light
   Guardian's Phase-2 from re-darkening the text; the classes are allowlisted
   (FFG_ALLOW) so Phase-1 won't whitewash them. (.lh-tl-appt day-view blocks are
   already a readable white card via the rule further down — left untouched.)
   =========================================================================== */
.lh-save-btn, .lh-lead-save, .lh-viewer-btn,
.lh-seg.is-active, .lh-calmode-seg.is-active,
.lh-cal-cell.is-sel {
  background: #111 !important; background-image: none !important;
  border-color: #111 !important; color: #fff !important;
}
.lh-save-btn .lh-save-label,
.lh-cal-cell.is-sel .lh-cal-num { color: #fff !important; }
.lh-cal-cell.is-sel .lh-cal-dot { background: #fff !important; }

/* ── No frosted glass anywhere ───────────────────────────────────────────
   backdrop-filter: blur() composites a GPU layer that paints BLACK for one
   frame (iOS Safari especially) before settling, and janks the open animation —
   the source of the "flash black / choppy" on dropdowns + popovers. The flat
   theme uses SOLID surfaces, not frosted glass, so kill it portal-wide. Every
   surface keeps its own solid background; nothing relies on the blur. */
*, *::before, *::after { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }

/* Appointment reschedule — badge (card + detail), history trail, focused form */
/* Softer, refined chip — was a harsh solid-black pill that popped on the clean card. */
.lh-resched-badge { display: inline-flex; align-items: center; margin-left: 8px; padding: 1px 8px; border-radius: 999px; background: rgba(0,0,0,0.055); color: var(--ink-soft, #565a62); border: 1px solid var(--line, #e4e5e9); font-size: 11px; font-weight: 500; white-space: nowrap; vertical-align: middle; }
/* Unified History <details> — every lead's Notes + Appt History + Follow-Up History
   merged, newest first, collapsed by default ("accessible but not forcing you to read").
   Arrow-toggle styling mirrors the existing .lh-fu-untracked <details> for consistency. */
.lh-history { margin: 2px 0 14px; border: 1px solid var(--line, #e3e5e9); border-radius: 10px; padding: 10px 12px; background: var(--card-bg, #fff); }
.lh-history summary { cursor: pointer; font-size: 13px; font-weight: 700; color: var(--ink-soft, #565a62); list-style: none; }
.lh-history summary::-webkit-details-marker { display: none; }
.lh-history summary::before { content: '▸'; display: inline-block; width: 12px; margin-right: 4px; transition: transform .15s var(--ease-soft, ease); }
.lh-history[open] summary::before { transform: rotate(90deg); }
.lh-history-count { font-weight: 500; color: var(--ink-faint); }
.lh-history-body { margin-top: 8px; max-height: 220px; overflow-y: auto; }
.lh-history-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px; padding: 6px 0; font-size: 13px; border-top: 1px solid var(--line, #eee); }
.lh-history-row:first-child { border-top: none; }
.lh-history-tag { flex: 0 0 auto; padding: 1px 7px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }
.lh-history-tag-notes { background: rgba(0,0,0,0.06); color: var(--ink-soft, #565a62); }
.lh-history-tag-appt { background: rgba(24,100,180,0.1); color: #1a5fa8; }
.lh-history-tag-followup { background: rgba(180,130,24,0.12); color: #946200; }
.lh-history-text { flex: 1 1 160px; min-width: 0; color: var(--ink, #15171c); word-break: break-word; white-space: pre-wrap; }
.lh-history-when { flex: 0 0 auto; color: var(--ink-faint); white-space: nowrap; }
.lh-reschedule .lh-resched-cur { font-size: 13px; color: var(--ink-soft, #444); line-height: 1.55; margin-bottom: 2px; }
.lh-reschedule .lh-resched-cur b { color: var(--ink, #111); font-size: 15px; }
.lh-reschedule .lh-resched-note { font-size: 12px; color: var(--ink-faint); margin: 2px 0 4px; }
/* Black primary (your theme's primary color), consistent with .ff-btn-pri etc. The
   "flash" was the frosted-glass backdrop-filter nearby, now killed portal-wide. */
/* ff381 (P2-12): now class="ff-btn-pri lh-lead-reschedule" in the template - the class
   stays for the JS selector; only the padding delta remains local. */
.lh-lead-reschedule { padding: 8px 14px; }
.lh-lead-reschedule:hover { background: #000; }
/* "Reschedule appt…" entry in the disposition dropdown — set apart as an action. */
.lux-select-option.lh-resched-opt { border-top: 1px solid var(--line, #e3e5e9); margin-top: 4px; padding-top: 9px; font-weight: 500; }

/* Follow-Ups tab — sectioned card grid (Overdue / Due today / Upcoming / Needs a date),
   plus a separate de-emphasized "Not yet tracked" suggestion list below (.lh-fu-untracked). */
.lh-fu-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 16px; }
.lh-fu-search { flex: 1 1 220px; min-width: 160px; max-width: 320px; }
/* Mine/Everyone — visually mirrors .lh-lvtabs/.lh-lvtab (Upcoming/Past on My Leads) under
   distinct class names, since that class is wired document-wide and would otherwise hijack clicks. */
.lh-fu-scope-tabs { display: inline-flex; gap: 4px; padding: 4px; border-radius: var(--r-pill, 999px); background: var(--control-bg, #f1f2f5); border: 1px solid var(--line, #e3e5e9); }
.lh-fu-scope-btn { appearance: none; border: 0; cursor: pointer; padding: 7px 16px; border-radius: var(--r-pill, 999px); font: inherit; font-size: 13px; font-weight: 500; color: var(--ink-soft, #565a62); background: transparent; }
.lh-fu-scope-btn:hover { color: var(--ink, #15171c); }
.lh-fu-scope-btn.is-active { background: var(--card-bg, #fff); color: var(--ink, #15171c); box-shadow: 0 1px 3px rgba(0,0,0,.28); }
.lh-followups { display: flex; flex-direction: column; gap: 22px; }
.lh-fu-section-h { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft, #565a62); margin-bottom: 10px; }
.lh-fu-count { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: rgba(0,0,0,0.07); color: var(--ink, #15171c); font-size: 11px; font-weight: 700; }
.lh-fu-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
.lh-fu-card { background: var(--card-bg, #fff); border: 1px solid var(--line, #e3e5e9); border-radius: 10px; padding: 12px 16px; display: flex; flex-direction: column; gap: 4px; }
.lh-fu-card-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.lh-fu-name { font-weight: 500; font-size: 14px; color: var(--ink, #15171c); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lh-fu-card-meta { font-size: 12px; color: var(--ink-soft, #565a62); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lh-fu-card-due { font-size: 12px; color: var(--ink-faint); }
.lh-fu-date { font-weight: 500; color: var(--ink, #15171c); }
.lh-fu-log-btn { align-self: flex-start; margin-top: 6px; }
.lh-fu-pill { display: inline-flex; align-items: center; padding: 1px 8px; border-radius: 999px; font-size: 11px; font-weight: 700; white-space: nowrap; flex: 0 0 auto; }
.lh-fu-pill.lh-fu-hot { background: rgba(180,35,24,0.1); color: #b42318; }
.lh-fu-pill.lh-fu-warm { background: rgba(180,130,24,0.12); color: #946200; }
.lh-fu-pill.lh-fu-cold { background: rgba(0,0,0,0.06); color: var(--ink-soft, #565a62); }
/* "Not yet tracked" — deliberately the LEAST visually important thing on the tab (dashed
   border, muted/tinted, collapsed by default) so it reads as suggestions, never confusable
   with the real (rated or dated) follow-ups above it. */
.lh-fu-untracked { margin-top: 10px; border: 1px dashed var(--line, #d8dade); border-radius: 12px; padding: 12px 14px; background: rgba(0,0,0,0.015); }
.lh-fu-untracked summary { cursor: pointer; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-faint); list-style: none; }
.lh-fu-untracked summary::-webkit-details-marker { display: none; }
.lh-fu-untracked summary::before { content: '▸'; display: inline-block; width: 12px; margin-right: 4px; transition: transform .15s var(--ease-soft, ease); }
.lh-fu-untracked[open] summary::before { transform: rotate(90deg); }
.lh-fu-untracked-hint { font-size: 12px; color: var(--ink-faint); margin: 8px 0 12px; line-height: 1.5; }
.lh-fu-untracked .lh-fu-card { opacity: .82; }

/* Uniform date-range control — identical across Projects / Pipeline / Leaderboard / Commissions */
.ff-daterange { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ff-daterange .ff-dr-pills { flex: 0 0 auto; }
.ff-daterange .ff-date { display: flex; flex-direction: column; gap: 3px; }
.ff-daterange .ff-date label { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); font-weight: 700; }
.ff-daterange .ff-date input[type="date"] { height: 38px; border: 1px solid var(--line, #e3e5e9); border-radius: 6px; padding: 0 9px; font-size: 13px; background: var(--card-bg, #fff); color: var(--ink, #15171c); }
@media (max-width: 559px) {
  .ff-daterange { width: 100%; }
  .ff-daterange .ff-dr-pills { width: 100%; display: flex; flex-wrap: wrap; }
  .ff-daterange .ff-date { flex: 1 1 45%; }
  .ff-daterange .ff-date input[type="date"] { width: 100%; }
}

/* Toasts were dark-on-dark on the white theme (color:var(--ink) on a near-black
   bg) → unreadable. White text on the dark toast; colored status icons stay. */
.toast { color: #fff !important; }

/* (Removed 2026-07-11: the old Leads Hub card overrides — forced padding/gap,
   column meta, and the 150px chip cap. The Day Ledger layout in styles.css
   owns row geometry now; these !important rules fought its grid on mobile.) */

/* Per-file Delete on lead cards (destructive → red). Link fills, Save+Delete sit right. */
.lh-filerow { justify-content: flex-start !important; }
.lh-filerow .lh-filelink { flex: 1 1 auto; }
.lh-filedel { flex: 0 0 auto; padding: 4px 12px; min-height: 32px; display: inline-flex; align-items: center; background: #fff; border: 1px solid var(--line); border-radius: 6px; color: #b91c1c; font-size: 13px; font-weight: 500; cursor: pointer; font-family: inherit; }
.lh-filedel:hover { background: #fef2f2; border-color: #dc2626; color: #dc2626; }

/* Honest state strip on converted panels (loading/error/permission) — the legacy state
   elements are hidden by the .ff-converted rule, so ffShowState_ injects this instead. */
.ff-state { display: flex; align-items: center; gap: 12px; margin: 10px 0 14px; padding: 10px 14px; background: #fff; border: 1px solid var(--line); border-radius: 10px; font-size: 14px; color: var(--ink-soft); }
.ff-state.is-error { border-color: #dc2626; color: #b91c1c; background: #fef2f2; }
.ff-state .ff-state-retry { flex: 0 0 auto; margin-left: auto; }

/* Outbox "Syncing N changes…" — shows when writes are queued waiting on signal */
.ff-outbox-badge { position: fixed; left: calc(16px + env(safe-area-inset-left, 0px)); bottom: 16px; z-index: 1250; display: inline-flex; align-items: center; gap: 8px; background: #111; color: #fff; padding: 8px 14px; border-radius: 999px; font-size: 13px; font-weight: 500; box-shadow: 0 6px 22px -6px rgba(0,0,0,.45); }
.ff-outbox-badge[hidden] { display: none; }
.ff-outbox-badge::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--col-blue); animation: ffOutboxPulse 1.4s ease-in-out infinite; }
@keyframes ffOutboxPulse { 0%{box-shadow:0 0 0 0 rgba(108,172,228,.6)} 70%{box-shadow:0 0 0 7px rgba(108,172,228,0)} 100%{box-shadow:0 0 0 0 rgba(108,172,228,0)} }

/* Admin preview EXIT bar — pinned at the TOP, just under the topbar, so it's
   always visible (iOS Safari hides bottom-fixed bars behind its toolbar). */
/* z 39 (ff380): BELOW the topbar (desktop z 40) so the avatar menu / search
   results dropdowns paint over the banner, above all page content + the rail. */
.ff-preview-banner { position: fixed; left: 0; right: 0; top: var(--portal-topbar-h, 64px); z-index: 39; background: #111; color: #fff; display: flex; align-items: center; justify-content: center; gap: 14px; padding: 9px 16px; font-size: 14px; box-shadow: 0 8px 22px -10px rgba(0,0,0,.45); }
.ff-preview-banner[hidden] { display: none; }
.ff-pvb-txt { color: #fff; }
.ff-pvb-txt b { font-weight: 700; }
.ff-pvb-exit { background: #fff; color: #111; border: none; border-radius: 6px; padding: 7px 16px; font-weight: 500; font-size: 13px; cursor: pointer; flex: 0 0 auto; }
.ff-pvb-exit:hover { background: #eee; }
/* Push the content down so the bar never covers the first row. */
body.ff-previewing .app-stage { margin-top: 46px; }

/* Install Map modal — shows the service-territory map image */
.ff-imap-ov { position: fixed; inset: 0; z-index: 1200; display: flex; align-items: center; justify-content: center; padding: 20px; background: rgba(0,0,0,.55); }
.ff-imap-ov[hidden] { display: none; }
.ff-imap-card { background: #fff; border-radius: 12px; max-width: 560px; width: 100%; max-height: 90vh; overflow: hidden; display: flex; flex-direction: column; box-shadow: 0 24px 60px -12px rgba(0,0,0,.5); }
.ff-imap-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--line); }
.ff-imap-title { font-weight: 700; font-size: 15px; color: var(--ink); }
.ff-imap-x { width: 32px; height: 32px; border: 1px solid var(--line); border-radius: 50%; background: #fff; font-size: 20px; line-height: 1; cursor: pointer; color: #444; flex: 0 0 auto; }
.ff-imap-x:hover { background: #f5f5f5; }
.ff-imap-body { overflow: auto; background: #222; display: flex; justify-content: center; }
.ff-imap-img { display: block; max-width: 100%; height: auto; }
.ff-imap-foot { padding: 14px 18px; border-top: 1px solid var(--line); display: flex; justify-content: flex-end; }
@media (max-width: 559px) { .ff-imap-ov { padding: 0; align-items: flex-end; } .ff-imap-card { max-width: 100%; border-radius: 14px 14px 0 0; max-height: 92vh; } }

/* Address autocomplete (Google Places .pac-container) — the legacy dark theme
   left it black-on-black on the white FF shell. Flip to a clean white dropdown
   with readable text + a Columbia-blue accent. Appended to <body> → global. */
.pac-container {
  background: #fff !important; border: 1px solid var(--line) !important;
  border-radius: 10px !important; box-shadow: 0 14px 36px -10px rgba(0,0,0,.28) !important;
  padding: 6px !important; margin-top: 6px !important; font-family: inherit !important;
}
.pac-item {
  color: #6b7280 !important; padding: 11px 12px !important; border-radius: 8px !important;
  border-top: none !important; font-size: 14px !important; line-height: 1.4 !important;
}
.pac-item:hover, .pac-item-selected { background: var(--col-blue-soft) !important; }
.pac-item-query { color: #14171c !important; font-size: 14px !important; }   /* street — dark, readable */
.pac-matched { color: var(--col-blue-deep) !important; font-weight: 700 !important; }

/* Topbar global customer search */
.ff-topfilter { position: relative; }
.ff-topfilter .inp input { border: none; outline: none; background: none; font-family: inherit; font-size: 14px; color: var(--ink); width: 100%; min-width: 0; }
.ff-search-results { position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 70; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 16px 40px -12px rgba(0,0,0,.28); padding: 5px; max-height: 360px; overflow-y: auto; }
.ff-search-results[hidden] { display: none; }
.ff-search-row { display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left; background: none; border: none; font-family: inherit; padding: 9px 12px; border-radius: 7px; cursor: pointer; }
.ff-search-row:hover { background: #f4f5f7; }
.ff-search-cust { font-weight: 500; font-size: 14px; color: var(--ink); }
.ff-search-sub { font-size: 12px; color: var(--ink-soft); }
.ff-search-empty { font-size: 12px; color: var(--ink-faint); padding: 10px 12px; }
.ff-topfilter .sel { cursor: pointer; border: none; border-right: 1px solid var(--line); font-family: inherit; }
.ff-scope-menu { position: absolute; top: calc(100% + 6px); left: 0; z-index: 71; background: #fff; border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 16px 40px -12px rgba(0,0,0,.28); padding: 5px; min-width: 150px; }
.ff-scope-menu[hidden] { display: none; }
.ff-scope-opt { display: block; width: 100%; text-align: left; background: none; border: none; font-family: inherit; font-size: 13px; color: var(--ink); padding: 8px 11px; border-radius: 6px; cursor: pointer; }
.ff-scope-opt:hover { background: #f4f5f7; }
.ff-scope-opt.is-on { font-weight: 700; background: #f1f1f1; }

/* CRITICAL: the search bar had overflow:hidden (to clip its rounded corners),
   which also clipped the scope + results dropdowns to zero height → invisible.
   Make it visible and round the inner edges instead so dropdowns can hang below. */
.portal-topbar .ff-topfilter { overflow: visible !important; }
.ff-topfilter .sel { border-radius: 6px 0 0 6px; }
.ff-topfilter .inp { border-radius: 0 6px 6px 0; overflow: hidden; }

/* Commissions admin "Viewing pay for [rep]" filter — relocated into the FF head. */
#ffCommActions .commissions-rep-filter { display: flex; align-items: center; gap: 8px; }
#ffCommActions .commissions-rep-filter-label { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
#ffCommActions .commissions-rep-filter-select { border: 1px solid var(--line); border-radius: 6px; padding: 7px 28px 7px 10px; font-family: inherit; font-size: 13px; background: #fff; color: var(--ink); }
/* The OPTION list too — styles.css's old dark theme paints options #15151a,
   which with light-skin ink = dark-on-dark: the dropdown opened as a solid
   black box (owner caught it 2026-06-12). Light scheme, everywhere it renders. */
.commissions-rep-filter-select option { background: #fff !important; color: #111 !important; }
@media (max-width:820px){ #ffCommActions .commissions-rep-filter-label { display:none; } }

@media (max-width: 820px){ .ff-user-txt { display: none; } .ff-user-caret { display: none; } }

/* ============================================================
   FF ICON RAIL — repositions the existing .app-tabs into a thin
   left icon rail that expands on hover (desktop) / opens as a
   drawer (mobile). `.app-tab` + `data-tab` are untouched, so
   setActiveTab + every injected tab keep working. JS adds the
   per-tab icon (.rail-ico) and the mobile hamburger wiring.
   ============================================================ */
/* ff381 (P2-09/P2-14): the old `padding-left:60px` left content FLUSH against the
   rail hairline (<=1180px) and permanently off-center (60 left vs ~36 right at 1440).
   The rail is cleared by MARGIN (which also centers past 1300px); the padding goes
   back to being a real, symmetric gutter. Safe-area for landscape-notch PWAs. */
@media (min-width: 821px) {
  .app-stage {
    padding-left: calc(clamp(20px, 3vw, 36px) + env(safe-area-inset-left, 0px));
    margin-left: max(calc(60px + env(safe-area-inset-left, 0px)), calc((100% - 1180px) / 2));
    margin-right: auto;
  }
}

.app-tabs {
  position: fixed !important;
  left: 0;
  top: var(--portal-topbar-h, 64px);
  bottom: 0;
  width: calc(60px + env(safe-area-inset-left, 0px));
  z-index: 60;
  display: flex !important;
  flex-direction: column !important;
  align-items: stretch !important;
  gap: 2px;
  margin: 0 !important;
  padding: 8px 0 8px env(safe-area-inset-left, 0px) !important;
  background: var(--bg-deep);
  border-right: 1px solid var(--line);
  /* Scrollable when the menu is taller than the viewport (so Home up top is always
     reachable), but the scrollbar is hidden — just hover + scroll. overscroll-behavior
     keeps the scroll INSIDE the nav so it never scrolls the page behind it. */
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  /* A thin, ALWAYS-VISIBLE scrollbar when the menu overflows — so it's obvious you can scroll
     (a hidden bar was the past attempt that left items stranded). `thin` reserves real layout
     space on Chrome/Edge/Firefox, unlike an overlay bar that only flashes while scrolling. */
  scrollbar-width: thin;
  scrollbar-color: rgba(0,0,0,.26) transparent;
  white-space: nowrap;
  transition: width var(--motion-base, .22s) var(--ease, ease), box-shadow var(--motion-base, .22s) ease;
}
.app-tabs:hover { width: 238px; box-shadow: 8px 0 28px -10px rgba(0,0,0,.18); }
/* Chrome/Safari/Edge: a slim, subtle scrollbar so overflow is reachable AND obvious. */
.app-tabs::-webkit-scrollbar { width: 6px; }
.app-tabs::-webkit-scrollbar-track { background: transparent; }
.app-tabs::-webkit-scrollbar-thumb { background: rgba(0,0,0,.18); border-radius: 4px; }
.app-tabs::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,.32); }

.app-stage .app-tabs .app-tab {
  display: flex !important;
  flex-direction: row !important;
  align-items: center;
  justify-content: flex-start;
  gap: 15px;
  width: 100%;
  height: 42px;
  min-height: 42px;
  padding: 0 19px !important;
  margin: 0 !important;
  border: none !important;
  border-radius: 0 !important;
  background: none !important;
  color: var(--ink-faint) !important;
  position: relative;
  cursor: pointer;
  box-shadow: none !important;
  transition: background var(--motion-instant, .12s) ease, color var(--motion-instant, .12s) ease;
}
.app-tab .rail-ico { flex: 0 0 auto; width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; }
.app-tab .app-tab-label {
  font-size: 14px; font-weight: 500; letter-spacing: 0;
  opacity: 0; transition: opacity var(--motion-instant, .12s) ease;
}
.app-tabs:hover .app-tab-label { opacity: 1; }
.app-stage .app-tabs .app-tab:hover { background: var(--card-bg-hover) !important; color: var(--ink-soft) !important; }
.app-stage .app-tabs .app-tab[aria-selected="true"] { color: var(--ink) !important; background: #f1f1f1 !important; }
.app-stage .app-tabs .app-tab[aria-selected="true"]::before {
  content: ""; position: absolute; left: 0; top: 7px; bottom: 7px; width: 3px;
  background: var(--col-blue); border-radius: 0 3px 3px 0;
}
.app-tab-badge { margin-left: auto; }

/* Submit-a-Project rail item (an external link, injected by JS) */
.app-tab.ff-ext { text-decoration: none; }

/* hamburger + drawer overlay (hidden on desktop) */
.ff-burger { display: none; }
/* The overlay starts AT the drawer's right edge (left:266px) so it physically
   cannot cover the drawer tabs — taps always reach the tabs, never the overlay.
   (z-index alone failed: the rail sits in a stacking context below the overlay.) */
.ff-drawer-ov { display: none; position: fixed; top: var(--portal-topbar-h, 64px); right: 0; bottom: 0; left: 266px; background: rgba(0,0,0,.42); z-index: 54; }
.ff-drawer-ov.show { display: block; }
.app-tabs.ff-open { z-index: 70 !important; }

/* ===== phone / small tablet: rail → off-canvas drawer ===== */
@media (max-width: 820px) {
  .app-stage { padding-left: 16px !important; padding-right: 16px !important; }   /* symmetric gutter — no more off-center */
  /* Topbar stays one solid bar ON TOP; the drawer opens BELOW it so the
     centered wordmark is never split across the drawer's edge. */
  .portal-topbar { z-index: 75 !important; }
  .app-tabs {
    top: var(--portal-topbar-h, 64px) !important;
    width: 266px !important;
    padding-top: 12px !important;
    padding-bottom: env(safe-area-inset-bottom, 0px) !important;
    transform: translateX(-101%) !important;
    transition: transform var(--motion-base, .22s) var(--ease, ease);
    box-shadow: none;
    overflow-y: auto;
  }
  .app-tabs.ff-open { transform: translateX(0) !important; box-shadow: 10px 0 30px -8px rgba(0,0,0,.4); }
  .app-stage .app-tabs .app-tab { height: 50px; min-height: 50px; }
  .app-tab .app-tab-label { opacity: 1; }
  .ff-burger {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; border: 1px solid var(--line); border-radius: 8px;
    background: var(--card-bg); color: var(--ink); cursor: pointer; flex: 0 0 auto;
    margin-right: 4px;
  }
}

/* ============================================================
   FF PANEL COMPONENTS — the prototype's actual building blocks
   (KPI cards, filter toolbar, dense data grid). Panels are
   rebuilt onto these (ff-* prefixed so they never collide with
   the legacy panel CSS). Mirrors _brand-mockups exactly.
   ============================================================ */
.ff-head { display:flex; align-items:center; justify-content:space-between; gap:14px; margin-bottom:8px; }
.ff-title { font-size:22px; font-weight:500; color:var(--ink); }
.ff-scope { font-size:13px; color:var(--ink-soft); margin-bottom:16px; display:inline-flex; align-items:center; gap:8px; }
.ff-scope .pin { width:6px; height:6px; border-radius:50%; background:var(--col-blue); flex:0 0 auto; }
.ff-actions { display:flex; gap:10px; flex:0 0 auto; }
.ff-btn-out { border:1px solid #bdbdbd; background:#fff; color:#222; font-weight:500; font-size:13px; padding:8px 14px; border-radius:6px; cursor:pointer; font-family:inherit; white-space:nowrap; display:inline-flex; align-items:center; gap:7px; text-decoration:none; }
.ff-btn-out:hover { background:#f5f5f5; }
.ff-btn-pri { border:none; background:#111; color:#fff; font-weight:500; font-size:13px; padding:9px 16px; border-radius:6px; cursor:pointer; font-family:inherit; white-space:nowrap; text-decoration:none; display:inline-flex; align-items:center; }
.ff-btn-pri:hover { background:#000; }
/* ff381 (P2-12): the ONE sanctioned small-button size - reuse, never mint new paddings. */
.ff-btn-sm { padding:5px 12px; font-size:12px; }

.ff-stats { display:grid; grid-template-columns:repeat(3,1fr); gap:12px; margin-bottom:24px; }
.ff-scard { background:#fff; border:1px solid var(--line); border-radius:8px; padding:20px 16px; text-align:center; }
.ff-scard.sel { border:1.5px solid var(--col-blue); box-shadow:0 0 0 3px var(--col-blue-soft); }
.ff-scard .n { font-size:34px; font-weight:500; letter-spacing:-.01em; line-height:1; color:var(--ink); font-variant-numeric:tabular-nums; }
.ff-scard .c { margin-top:8px; font-size:12px; font-weight:500; color:var(--ink-soft); }
/* Period caption — small, muted, uppercase: the time scope lives here, never
   joined into the label with a dash (enterprise stat-card anatomy). */
.ff-scard .s { margin-top:4px; font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-faint); }
/* 4-card KPI rows (Projects/Pipeline, owner 2026-07-03): ONE row on desktop,
   2x2 from tablet down — "one row or two rows on mobile view", never a 4-stack.
   The mobile block's row-flex .ff-scard styling is built for full-width stacked
   cards and crams at half width, so ff-stats4 cards keep the centered stat look
   (the two-class selectors outrank the mobile block's single-class rules). */
.ff-stats.ff-stats4 { grid-template-columns:repeat(4,1fr); }
@media (max-width:1080px){ .ff-stats.ff-stats4 { grid-template-columns:repeat(2,1fr); } }
@media (max-width:820px){
  .ff-stats.ff-stats4 { grid-template-columns:repeat(2,1fr); gap:10px; }
  .ff-stats4 .ff-scard { display:block; text-align:center; padding:14px 10px; }
  .ff-stats4 .ff-scard .n { font-size:24px; }
  .ff-stats4 .ff-scard .c { margin-top:6px; font-size:12px; }
}

/* Columbia-blue focus rings — accent + accessibility on every editable field */
.ff-search input:focus, .ff-date input:focus, .ff-topfilter .inp:focus, .ff-topfilter .sel:focus,
.broadcasts-textarea:focus, .broadcasts-rep-search:focus, .lh-input:focus,
input[type="search"]:focus, input[type="date"]:focus, input[type="tel"]:focus, input[type="time"]:focus {
  outline: none !important; border-color: var(--col-blue) !important;
  box-shadow: 0 0 0 3px rgba(108,172,228,.22) !important;
}

/* The old dark theme left `color-scheme: dark` on form controls (~12 spots in
   styles.css), making native date/time pickers render DARK on the white app. Force
   light on every control so all native pickers look right on phone/iPad/desktop. */
input, select, textarea { color-scheme: light !important; }

/* Appointment time → uniform scroll-to-pick dropdown (phone/iPad/desktop). Inherits
   field size from context (.lh-field select = 46px / .lh-input = 42px) so it matches
   its neighbors; we add white fill, pointer, + the Columbia focus ring. */
.lh-timeselect { cursor: pointer; background-color: #fff !important; }
.lh-timeselect:focus { outline: none !important; border-color: var(--col-blue) !important; box-shadow: 0 0 0 3px rgba(108,172,228,.22) !important; }

/* Announcements: flat, clean buttons (replace the glossy gradients that looked off) */
.broadcasts-new-btn {
  background:#fff !important; background-image:none !important; border:1px solid var(--col-blue) !important;
  color:var(--col-blue-deep) !important; box-shadow:none !important; border-radius:6px !important;
  font-family:inherit !important; font-weight:500 !important;
}
.broadcasts-new-btn:hover, .broadcasts-new-btn:focus-visible {
  background:var(--col-blue-soft) !important; transform:none !important; box-shadow:none !important; border-color:var(--col-blue-deep) !important;
}
.broadcasts-new-btn svg { color:var(--col-blue-deep) !important; }
.broadcasts-send-btn {
  background:#111 !important; background-image:none !important; border:1px solid #111 !important;
  color:#fff !important; box-shadow:none !important; border-radius:6px !important; font-family:inherit !important;
}
.broadcasts-send-btn .broadcasts-send-label { color:#fff !important; }
.broadcasts-send-btn:hover:not(:disabled), .broadcasts-send-btn:focus-visible:not(:disabled) {
  background:#000 !important; transform:none !important; box-shadow:none !important; border-color:#000 !important;
}
.broadcasts-send-btn:disabled { background:#e9eaec !important; border-color:#e9eaec !important; opacity:1 !important; }
.broadcasts-send-btn:disabled .broadcasts-send-label { color:#9aa0a6 !important; }

.ff-filters { display:flex; align-items:flex-end; gap:12px; flex-wrap:wrap; margin-bottom:16px; }
.ff-search { display:flex; align-items:center; gap:9px; border:1px solid var(--line); border-radius:6px; padding:0 13px; height:38px; width:260px; max-width:100%; background:#fff; color:var(--ink-faint); }
.ff-search input { border:none; outline:none; background:none; font-family:inherit; font-size:14px; color:var(--ink); width:100%; }
.ff-pills { display:inline-flex; border:1px solid var(--line); border-radius:6px; overflow:hidden; }
.ff-pills button { background:#fff; border:none; border-right:1px solid var(--line); font-family:inherit; font-size:13px; font-weight:500; color:var(--ink-soft); padding:8px 14px; cursor:pointer; }
.ff-pills button:last-child { border-right:none; }
/* ff381 (P2-08): one control height on the grid toolbars - search 38, dates 38, pills 38 */
.ff-filters .ff-pills, .ff-daterange .ff-pills { height:38px; align-items:stretch; }
.ff-filters .ff-pills button, .ff-daterange .ff-pills button { padding:0 14px; }
/* Active filter pill — ocean-blue outline (inset ring, since .ff-pills clips overflow). */
.ff-pills button.on { background: var(--col-blue-soft, #E8F2FB); color: var(--col-blue-deep, #2E7AB8); box-shadow: inset 0 0 0 1.6px var(--col-blue-deep, #2E7AB8); font-weight: 500; }
.ff-date { display:flex; flex-direction:column; gap:5px; min-width:148px; }
.ff-date label { font-size:11px; font-weight:700; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.06em; }
.ff-date input { border:1px solid var(--line); border-radius:6px; padding:0 11px; height:38px; font-family:inherit; font-size:13px; background:#fff; color:#444; }

.ff-grid { background:#fff; border:1px solid var(--line); border-radius:8px; overflow:hidden; }
.ff-gwrap { overflow-x:auto; }
.ff-grid table { width:100%; border-collapse:collapse; }
.ff-grid thead th { text-align:left; font-size:11px; font-weight:700; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.06em; padding:11px 14px; border-bottom:1px solid var(--line); white-space:nowrap; }
.ff-grid thead th.c, .ff-grid tbody td.c { text-align:center; }
.ff-grid tbody td { padding:12px 14px; border-bottom:1px solid var(--line2,#eee); font-size:13px; color:#2a2a2a; font-variant-numeric:tabular-nums; white-space:nowrap; }
.ff-grid tbody tr:hover { background:#fafafa; }
.ff-grid td.nm { font-weight:500; color:var(--ink); }
.ff-grid td.muted { color:var(--ink-faint); }
.ff-dot { display:inline-block; width:8px; height:8px; border-radius:50%; background:var(--ink-faint); margin-right:7px; vertical-align:middle; flex:0 0 auto; }
.ff-dot.o { background:#fff; border:1.5px solid var(--ink-faint); }
.ff-dot.h { background:var(--ink-faint); }
/* status colors: Progressing = yellow, Funded/Installed = green, Cancelled = red */
.ff-st-yellow .ff-dot { background:#eab308 !important; border:none !important; }
.ff-st-green  .ff-dot { background:#16a34a !important; border:none !important; }
.ff-st-red    .ff-dot { background:#dc2626 !important; border:none !important; }
td.ff-st-yellow { color:#a16207 !important; }
td.ff-st-green  { color:#15803d !important; }
td.ff-st-red    { color:#b91c1c !important; }
/* Status color-coding — Progressing = blue, Funded = green, Cancelled = red (dot + text). */
.ff-st-blue .ff-dot { background:#2563eb !important; border:none !important; }
td.ff-st-blue   { color:#1d4ed8 !important; }
.stage.ff-st-blue  { color:#1d4ed8; }
.stage.ff-st-green { color:#15803d; }
.stage.ff-st-red   { color:#b91c1c; }
.ff-pager { display:flex; align-items:center; justify-content:flex-end; gap:18px; padding:11px 16px; color:var(--ink-soft); font-size:13px; }
.ff-pager button { border:1px solid var(--line-strong,#ddd); background:#fff; border-radius:6px; min-width:32px; height:30px; font-size:16px; line-height:1; color:var(--ink,#111); cursor:pointer; }
.ff-pager select { border:1px solid var(--line-strong,#ddd); background:#fff; border-radius:6px; height:30px; padding:0 8px; font-size:13px; color:var(--ink,#111); cursor:pointer; }
/* Editable Setter/Closer cells: a PERSISTENT dotted underline — the old cue was
   cursor+hover-halo+title, all three invisible on touch (owner 2026-07-02: his
   manager on an iPhone had no idea the cells were tappable). */
.dsp-editable { text-decoration: underline dotted rgba(0,0,0,.4); text-underline-offset: 3px; }
/* Resources FEATURED billboard (the DSP Store card): full-width inverted-black
   hero in the same monochrome billboard language as the leaderboard podium #1,
   with a floating product shelf (real storefront shots). Sheet-driven — any item
   with Badge 'STORE'/'FEATURED' (or a Shopify URL) renders here instead of the
   card grid. Selectors scoped under #ffResources so no legacy rule can outrank
   them (the unstyled-white-card incident, 2026-07-03). */
#ffResources .ff-rfeature { display:flex; align-items:center; justify-content:space-between; gap:22px;
  background:#111 radial-gradient(120% 160% at 88% -20%, rgba(255,255,255,.14), rgba(255,255,255,0) 55%);
  color:#fff; border-radius:14px; padding:26px 28px; margin:4px 0 24px;
  text-decoration:none; border:1px solid #000; overflow:hidden; position:relative;
  transition:transform .18s ease, box-shadow .18s ease; }
#ffResources .ff-rfeature:hover { transform:translateY(-2px); box-shadow:0 18px 36px -16px rgba(0,0,0,.55); }
#ffResources .ff-rf-main { min-width:0; }
#ffResources .ff-rf-eyebrow { font-size:11px; font-weight:700; letter-spacing:.2em; text-transform:uppercase; color:#c9c3b4; }
#ffResources .ff-rf-title { font-size:clamp(24px,3.6vw,32px); font-weight:700; letter-spacing:-.015em; margin-top:5px; color:#fff; line-height:1.1; }
#ffResources .ff-rf-desc { font-size:14px; color:#d9d9d9; margin-top:7px; max-width:52ch; line-height:1.55; }
#ffResources .ff-rf-cta { display:inline-block; margin-top:16px; background:#fff; color:#111; font-weight:700; font-size:14px;
  padding:11px 22px; border-radius:999px; white-space:nowrap; transition:background .15s ease; }
#ffResources .ff-rfeature:hover .ff-rf-cta { background:#ececec; }
/* Product shelf: three overlapping white tiles, slight scatter — straighten on hover. */
#ffResources .ff-rf-shelf { flex:0 0 auto; display:flex; align-items:center; padding-right:6px; }
#ffResources .ff-rf-tile { width:96px; height:96px; border-radius:12px; background:#fff; overflow:hidden;
  box-shadow:0 10px 24px -8px rgba(0,0,0,.6); border:1px solid rgba(255,255,255,.28);
  transition:transform .22s ease; }
#ffResources .ff-rf-tile img { width:100%; height:100%; object-fit:cover; display:block; }
/* ff380: a 404'd shelf image hides its tile via the AUTHORED class (delegated
   error listener + module set) — no inline onerror mutating the billboard. */
#ffResources .ff-rf-tile.is-dead { display:none; }
#ffResources .ff-rf-tile.t1 { transform:rotate(-5deg) translateY(4px); z-index:1; }
#ffResources .ff-rf-tile.t2 { transform:rotate(3deg) translateY(-6px); margin-left:-16px; z-index:2; }
#ffResources .ff-rf-tile.t3 { transform:rotate(-2deg) translateY(6px); margin-left:-16px; z-index:3; }
#ffResources .ff-rfeature:hover .ff-rf-tile { transform:rotate(0) translateY(0); }
@media (max-width:640px){
  #ffResources .ff-rfeature { flex-direction:column; align-items:flex-start; padding:22px 20px 24px; gap:16px; }
  #ffResources .ff-rf-cta { align-self:stretch; text-align:center; display:block; }
  #ffResources .ff-rf-shelf { align-self:center; padding:2px 0 0; }
  #ffResources .ff-rf-tile { width:84px; height:84px; }
}
@media (prefers-reduced-motion: reduce){
  #ffResources .ff-rfeature, #ffResources .ff-rf-tile, #ffResources .ff-rf-cta { transition:none; }
}

/* ── ff381 (P3-01): HOME BILLBOARD HERO — the front door's ONE focal point.
   Same inverted-black recipe as .ff-rfeature (the one sanctioned rich surface);
   the rep's own rank + week are the product shot. Allowlisted in ffLightGuard. */
.ff-hbill { display:flex; align-items:center; justify-content:space-between; gap:22px;
  background:#111 radial-gradient(120% 160% at 88% -20%, rgba(255,255,255,.14), rgba(255,255,255,0) 55%);
  color:#fff; border-radius:14px; padding:24px 28px; margin:4px 0 16px;
  border:1px solid #000; overflow:hidden; position:relative; }
.ff-hb-main { min-width:0; }
.ff-hb-eyebrow { font-size:11px; font-weight:700; letter-spacing:.2em; text-transform:uppercase; color:#c9c3b4; }
.ff-hb-title { font-size:clamp(24px,3.6vw,32px); font-weight:700; letter-spacing:-.015em; margin-top:5px; color:#fff; line-height:1.1; }
.ff-hb-sub { font-size:14px; color:#d9d9d9; margin-top:7px; }
.ff-hb-side { flex:0 0 auto; text-align:right; }
.ff-hb-rank { font-size:clamp(34px,4.5vw,44px); font-weight:700; letter-spacing:-.01em; line-height:1; color:#fff; font-variant-numeric:tabular-nums; }
.ff-hb-cap { font-family:var(--font-mono); font-size:11px; font-weight:500; letter-spacing:.06em; text-transform:uppercase; color:#c9c3b4; margin-top:8px; white-space:nowrap; }
@media (max-width:640px){
  .ff-hbill { flex-direction:column; align-items:flex-start; gap:14px; padding:20px; }
  .ff-hb-side { text-align:left; }
}

/* Quiet KPI minis under the hero (value + label + muted uppercase caption). */
.ff-hminis { display:grid; grid-template-columns:repeat(3,1fr); gap:12px; margin-bottom:24px; }
.ff-hmini { background:#fff; border:1px solid var(--line); border-radius:10px; padding:12px 16px; }
.ff-hmini .n { font-size:20px; font-weight:500; letter-spacing:-.01em; color:var(--ink); font-variant-numeric:tabular-nums; line-height:1.2; }
.ff-hmini .c { font-size:12px; font-weight:500; color:var(--ink-soft); margin-top:2px; }
.ff-hmini .s { font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-faint); margin-top:2px; }
@media (max-width:640px){ .ff-hminis { gap:8px; } .ff-hmini { padding:10px 12px; } }

/* Recent-activity row: 30px black monogram disc + name/meta (real data as the
   decoration). .min0 lets the name ellipsize inside the flex row. */
.ff-lrow-l { display:flex; align-items:center; gap:12px; min-width:0; }
.ff-lrow-l .min0, .ff-lrow .min0, .ff-cust-cell .min0 { min-width:0; }
.lh-avatar.ffmono { background:#111; }
/* ff381 sweep: monogram discs are B&W portal-wide — the calendar's red discs
   were decorative red, and red is reserved for true urgency (design law). */
.lh-avatar { background:#111 !important; }

/* ff381 (P3-07): broadcasts inbox — sender monogram + blue rail (inset
   shadow: zero layout shift). ff387: the rail now means UNREAD when the
   backend tracks reads (@292); on @291 it falls back to "new today". One
   signal color: blue = new. Weight rides along on the sender name. */
.broadcasts-row-inbox { display:flex; gap:12px; align-items:flex-start; }
.broadcasts-row-inbox .bc-av { margin-top:2px; }
.broadcasts-row-inbox .bc-main { min-width:0; flex:1; }
.broadcasts-row-inbox.is-unread { box-shadow: inset 3px 0 0 var(--col-blue); }
.broadcasts-row-inbox.is-unread .broadcasts-row-sender { font-weight:700; }

/* ff387: announcement cards clamp to 4 lines + an explicit open affordance;
   tapping the card opens the full message in a .rqo sheet. */
.broadcasts-row[data-bc-i] { cursor:pointer; }
.bc-clamp { display:-webkit-box; -webkit-line-clamp:4; -webkit-box-orient:vertical; overflow:hidden; }
.bc-view-more { margin-top:6px; font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-soft); }
.broadcasts-row[data-bc-i]:hover .bc-view-more { color:var(--ink); }

/* Full-message sheet (rides the .rqo overlay mechanics; content-fit). */
.bc-msg-panel { max-width:560px; }
.bc-msg-meta { display:flex; justify-content:space-between; align-items:baseline; gap:12px; }
.bc-msg-sender { font-weight:700; color:var(--ink); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bc-msg-when { font-family:var(--font-mono); font-size:11px; letter-spacing:.06em; color:var(--ink-faint); flex:0 0 auto; }
.bc-msg-body { font-size:15px; line-height:1.6; color:var(--ink); overflow-wrap:break-word; word-break:break-word; padding-bottom:18px; }
.bc-msg-body a { color:var(--ink); text-decoration:underline; }
.bc-msg-read { font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-soft); border-top:1px solid var(--line); padding-top:10px; padding-bottom:14px; }

/* ff381 (P3-05): advance payoff progress — 3px black fill on a hairline track.
   The debt visibly shrinking, B&W-pure. */
.ff-payprog { display:block; height:3px; background:var(--line); border-radius:2px; margin-top:8px; overflow:hidden; max-width:320px; }
.ff-payprog i { display:block; height:100%; background:#111; border-radius:2px; }

/* ── ff381 (P3-03): designed empty state — invitation + next action. */
.ff-empty { text-align:center; padding:40px 20px; background:#fff; border:1px dashed var(--line-strong); border-radius:10px; margin:8px 0 16px; }
.ff-empty svg { width:32px; height:32px; color:#c9cbd0; }
.ff-empty .t { font-size:15px; font-weight:700; color:var(--ink); margin-top:10px; }
.ff-empty .s { font-size:13px; color:var(--ink-soft); margin-top:4px; line-height:1.5; max-width:46ch; margin-left:auto; margin-right:auto; }
.ff-empty .a { margin-top:14px; }

/* Follow-Ups card: Convert + Log actions side by side; History dropdown tucked
   under them (lean by default — expands on demand). */
.lh-fu-card-actions { display:flex; gap:8px; margin-top:10px; }
.lh-fu-card-actions .ff-btn-pri, .lh-fu-card-actions .ff-btn-out { flex:1 1 0; }
.lh-fu-cardhist { margin-top:8px; }
.lh-fu-cardhist > summary { font-size:12px; color:var(--ink-soft,#666); }
.ff-pager button:hover:not(:disabled) { background:var(--card-bg-hover,#f4f4f4); }
.ff-pager button:disabled { opacity:.35; cursor:default; }
.ff-coperniq { color:var(--ink-faint); text-decoration:none; display:inline-flex; align-items:center; gap:5px; font-size:12px; }
.ff-coperniq:hover { color:var(--ink); }

/* A converted panel hides ALL its legacy children; only the injected FF block
   (id starts with "ff") shows. One rule covers every panel. */
.ff-converted > *:not([id^="ff"]) { display:none !important; }

/* podium ranks + totals (leaderboard / team) */
.ff-rk { display:inline-flex; align-items:center; justify-content:center; width:26px; height:26px; border-radius:50%; font-weight:700; font-size:12px; font-variant-numeric:tabular-nums; }
/* Metallic medal chips: gold / silver / bronze (match the podium; dark text = legible). */
.ff-rk.r1 { background:linear-gradient(135deg,#f7e08f,#e7c052 55%,#caa531); color:#3a2d05; box-shadow:inset 0 0 0 1px rgba(255,255,255,.5); }
.ff-rk.r2 { background:linear-gradient(135deg,#f1f4f8,#cfd5de 55%,#b4bcc7); color:#2c313a; box-shadow:inset 0 0 0 1px rgba(255,255,255,.6); }
.ff-rk.r3 { background:linear-gradient(135deg,#eecaa1,#d6a071 55%,#bd8154); color:#2a1808; box-shadow:inset 0 0 0 1px rgba(255,255,255,.45); }
.ff-rk.rn { color:var(--ink-faint); font-weight:500; }
.ff-grid tr.podium td { background:#fcfcfc; }
.ff-grid tr.podium td.nm { font-weight:700; }
/* The metallic rank CHIP alone marks the top-3 — no extra colored row edge (keeps the
   chip area clean; the colored edge was crowding the chip at the card corner). */
.ff-grid tr.totalrow td { border-top:2px solid var(--line); font-weight:700; background:#fafafa; color:#111; }
.ff-youtag { font-size:10px; font-weight:700; letter-spacing:.06em; background:#111; color:#fff; border-radius:10px; padding:2px 7px; margin-left:8px; vertical-align:middle; }

/* ── Leaderboard: resizable columns + expandable division → reps ───────────────
   table-layout:fixed honors the per-column <col> widths; .ff-gwrap scrolls sideways
   when the total runs past the screen. DESKTOP only — the ≤820px card layout below
   resets width and hides the resize handles, so mobile is untouched. */
.ff-grid table.ff-lbtable { table-layout: fixed; width: max-content; min-width: 100%; }
.ff-grid table.ff-lbtable th { position: relative; }
.ff-grid table.ff-lbtable th .ff-th-l { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ff-grid table.ff-lbtable td.nm { overflow: hidden; text-overflow: ellipsis; }
.ff-colres { position: absolute; top: 0; right: 0; width: 11px; height: 100%; cursor: col-resize; z-index: 3; touch-action: none; }
.ff-colres::after { content: ""; position: absolute; top: 25%; bottom: 25%; right: 4px; width: 2px; border-radius: 2px; background: transparent; transition: background .12s; }
.ff-colres:hover::after, .ff-colres.is-drag::after { background: var(--col-blue, #6CACE4); }
.ff-grid table.ff-lbtable tr.ff-lbdiv { cursor: pointer; }
.ff-grid table.ff-lbtable tr.ff-lbdiv:hover td { background: #f6f8fa; }
.ff-grid table.ff-lbtable tr.ff-lbdiv.is-open td { background: #eef4fb; }
.ff-lbcaret { display: inline-block; width: 14px; margin-right: 2px; color: var(--ink-faint); font-size: 10px; }
.ff-lbcaret-empty { visibility: hidden; }
.ff-grid table.ff-lbtable tr.ff-lbsub td { background: #fafbfc; font-size: 13px; }
.ff-grid table.ff-lbtable tr.ff-lbsub td.nm { padding-left: 30px; color: var(--ink-soft, #565a62); font-weight: 500; }
@media (max-width: 820px) {
  .ff-colres { display: none; }
  /* ── Leaderboard mobile: a clean per-rank CARD (overrides the generic table
     stack) so all 8 columns read cleanly on a phone. Rank + name lead the card;
     the six stats sit in a value-over-label grid below a hairline. ── */
  .ff-grid table.ff-lbtable { width:100%; min-width:0; }
  .ff-grid table.ff-lbtable tbody tr {
    display:flex; flex-wrap:wrap; align-items:center; column-gap:12px; row-gap:11px;
    border:1px solid var(--line); border-radius:10px; padding:13px 15px; margin:0 0 10px; background:#fff;
  }
  .ff-grid table.ff-lbtable tbody td { display:block; border:none; padding:0; margin:0; text-align:left; white-space:normal; }
  .ff-grid table.ff-lbtable tbody td::before { display:none; }
  .ff-grid table.ff-lbtable tbody td:empty { display:none; }
  /* top line: rank chip + name (caret + YOU tag ride along) */
  .ff-grid table.ff-lbtable tbody td:first-child { order:0; flex:0 0 38px; display:flex; align-items:center; }
  .ff-grid table.ff-lbtable tbody td:first-child:empty { display:none; }   /* sub-rows + total: no empty rank gutter */
  .ff-grid table.ff-lbtable tbody td:first-child .ff-rk { width:30px; height:30px; font-size:13px; }
  .ff-grid table.ff-lbtable tbody td.nm { order:1; flex:1 1 0; min-width:0; font-size:16px; font-weight:700; overflow:hidden; text-overflow:ellipsis; }
  /* hairline that forces the stats onto their own line(s) */
  .ff-grid table.ff-lbtable tbody tr::before { content:""; order:2; flex:0 0 100%; height:1px; background:var(--line2,#eee); margin:1px 0 0; }
  /* six stats in an EXACT 3-per-row grid: value over a small caps label */
  .ff-grid table.ff-lbtable tbody td.c { order:3; flex:0 0 calc((100% - 24px) / 3); font-size:15px; font-weight:700; color:var(--ink); font-variant-numeric:tabular-nums; line-height:1.15; }
  .ff-grid table.ff-lbtable tbody td.c::before { display:block; content:attr(data-label); font-size:10px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-faint); margin-bottom:1px; }
  /* nested rep rows under an expanded division — indented + tinted */
  .ff-grid table.ff-lbtable tbody tr.ff-lbsub { margin-left:13px; border-left:3px solid var(--line); background:#fafbfc; }
  .ff-grid table.ff-lbtable tbody tr.ff-lbsub td.nm { padding-left:0; font-weight:500; }
  /* no colored card edge on mobile — the metallic rank chip alone marks the top-3 (clean) */
  .ff-grid table.ff-lbtable tbody tr.totalrow { background:#fafafa; }
  .ff-grid table.ff-lbtable tbody tr.totalrow td.nm { font-weight:700; }
}

/* list rows (commissions / advances) */
.ff-lrow { display:flex; align-items:center; justify-content:space-between; background:#fff; border:1px solid var(--line); border-radius:8px; padding:12px 16px; margin-bottom:8px; gap:12px; }
.ff-lrow .nm { font-weight:500; font-size:14px; color:var(--ink); }
.ff-lrow .meta { font-size:12px; color:var(--ink-soft); margin-top:3px; }
.ff-lrow .right { display:flex; align-items:center; gap:16px; }
.ff-amt { font-weight:500; font-variant-numeric:tabular-nums; font-size:15px; color:var(--ink); }
.ff-tag { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; padding:3px 9px; border:1px solid var(--line); border-radius:20px; color:var(--ink-soft); white-space:nowrap; }
.ff-tag.solid { background:#111; color:#fff; border-color:#111; }
.ff-tag.red { color:#b42318; border-color:#f3c0bb; background:#fff6f5; }

/* Pipeline data-quality call-out — "N projects missing a setter / closer" with
   per-side Review buttons that filter the list to the unattributed rows. Built
   on .ff-lrow + .ff-tag.red + .ff-btn-out, so it inherits the responsive
   restack for free. Red is restrained to the count chip (reserved-urgency rule);
   the active "Show all" button goes solid black to signal the live filter. */
.ffq-callout { align-items:flex-start; }
.ffq-left { display:flex; flex-direction:column; gap:9px; width:100%; }
.ffq-eyebrow { display:inline-flex; align-items:center; gap:7px; font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:var(--ink-soft); }
.ffq-eyebrow .pin { width:6px; height:6px; border-radius:50%; background:var(--col-blue); flex:0 0 auto; }
.ffq-items { display:flex; flex-wrap:wrap; align-items:center; gap:10px 26px; }
.ffq-item { display:inline-flex; align-items:center; gap:9px; }
.ffq-lbl { font-size:13px; color:var(--ink-soft); }
.ffq-item .ff-btn-out { padding:5px 11px; font-size:12px; }
.ffq-item .ff-btn-out.is-on { background:#111; color:#fff; border-color:#111; }
@media (max-width:820px){
  .ffq-items { width:100%; gap:12px; }
  /* keep chip · label · button grouped left so the button doesn't drift to a
     lopsided far-right gutter on narrow phones with single-digit counts */
  .ffq-item { flex:1 1 100%; justify-content:flex-start; }
}

/* hero stat (commissions / advances) */
.ff-hero { background:#fff; border:1px solid var(--line); border-radius:10px; padding:20px 24px; margin-bottom:16px; }
.ff-hero .hl { font-size:11px; font-weight:700; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.06em; }
.ff-hero .hv { font-size:34px; font-weight:500; letter-spacing:-.01em; margin-top:6px; font-variant-numeric:tabular-nums; line-height:1; color:var(--ink); }
/* Negative money (clawbacks, deductions, negative balances) reads RED everywhere
   in Commissions + Advances — overrides .ff-amt / .hv ink color. */
.ff-neg, .ff-amt.ff-neg, .ff-hero .hv.ff-neg { color:#dc2626 !important; }

/* Pipeline: homeowner address + phone as a clean sub-line under the customer.
   ff381 (P3-06): 24px black monogram disc before the name — real data as the
   decoration (reuses .lh-avatar-sm + .ffmono). */
.ff-cust-cell { display:flex; align-items:center; gap:10px; min-width:0; }
.ff-grid td.nm .ff-cust-nm { font-weight: 500; }
.ff-grid td.nm .ff-cust-meta { font-size: 12px; color: var(--ink-faint); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 260px; }
/* Editable Setter / Closer cells — dotted underline + pointer affordance */
.ff-grid td.dsp-edit-setter, .ff-grid td.dsp-edit-closer {
  cursor: pointer; text-decoration: underline; text-decoration-style: dotted;
  text-underline-offset: 3px; text-decoration-color: #c4c4c4;
}
.ff-grid td.dsp-edit-setter:hover, .ff-grid td.dsp-edit-closer:hover { background: #f3f3f3; text-decoration-color: #111; }
.ff-grid td.dsp-edit-ok { background: #ecfdf3 !important; }
.ff-grid td.dsp-edit-saving { opacity: .55; }
@media (max-width: 820px) {
  .ff-grid td.nm .ff-cust-meta { max-width: none; white-space: normal; }
}
.ff-hero .hs { font-size:13px; color:var(--ink-faint); margin-top:8px; }
.ff-grouphd { font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-faint); margin:24px 0 8px; }
/* one-line plain-language descriptor under a Resources category header */
.ff-groupsub { font-size:13px; color:var(--ink-soft); line-height:1.5; max-width:640px; margin:-4px 0 12px; }

/* resources link cards — ff381 (P3-02): designed objects. 44px doc-type icon
   tile + left-aligned body + domain chip (the real destination as the detail);
   hover = the billboard's 2px black top edge + 1px lift. */
/* ff387 (owner: "resource cards even better"): the category cards join the
   Requests-card design language — 40px BLACK icon tile (the type glyph is the
   decoration, per the Lavender bar), equal card heights per grid row with the
   meta line pinned to the bottom edge, and the same hover lift. rc-tile is
   allowlisted in ffLightGuard (FFG_ALLOW). */
.ff-rgrid { display:grid; grid-template-columns:repeat(auto-fill,minmax(238px,1fr)); gap:12px; margin-bottom:6px; align-items:stretch; }
.ff-rcard { background:#fff; border:1px solid var(--line); border-radius:10px; padding:16px; text-decoration:none; display:flex; align-items:stretch; gap:12px; text-align:left; transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.ff-rcard:hover { transform:translateY(-2px); border-color:#c9cbd0; box-shadow:0 14px 28px -14px rgba(0,0,0,.35); }
.ff-rcard:focus-visible { outline:2px solid #111; outline-offset:2px; }
.rc-tile { flex:0 0 40px; width:40px; height:40px; border-radius:10px; background:#111; color:#fff; display:inline-flex; align-items:center; justify-content:center; align-self:flex-start; }
.rc-tile svg { width:20px; height:20px; }
.rc-body { min-width:0; display:flex; flex-direction:column; flex:1 1 auto; }
.ff-rcard .rt { display:block; font-size:15px; font-weight:700; margin-bottom:4px; color:var(--ink); }
.ff-rcard .rd { display:block; font-size:13px; color:var(--ink-soft); line-height:1.5; }
.rc-meta { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:auto; padding-top:10px; }
.ff-rcard .rtype { font-size:11px; font-weight:700; letter-spacing:.06em; color:var(--ink-faint); text-transform:uppercase; display:inline-block; }
.rc-dom { font-family:var(--font-mono); font-size:10px; font-weight:500; color:var(--ink-faint); border:1px solid var(--line); border-radius:999px; padding:2px 8px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%; }
/* Dimmed WITH intent: dashed frame + gray tile says "reserved", not "broken". */
.ff-rcard.is-soon { opacity:.6; border-style:dashed; }
.ff-rcard.is-soon:hover { transform:none; box-shadow:none; border-color:var(--line); }
.ff-rcard.is-soon .rc-tile { background:#f0f0f2; color:var(--ink-faint); }
/* ff381 (P2-16): highlight chip — was inline non-token blues in main.js. */
/* ff387: highlight pill RESTRAINED — quiet soft-blue chip, no border chrome,
   micro-label type. One signal color, never louder than the title. */
.rhl { display:inline-block; align-self:flex-start; margin-top:8px; font-size:10px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--col-blue-deep); background:var(--col-blue-soft); border:none; padding:3px 8px; border-radius:999px; line-height:1.35; }

/* ── Pay Estimator (ff304) — inline private calculator in the Commissions tab.
   Reuses the .calc-* skeleton; these scoped rules re-skin the few dark-hardcoded
   bits to the FF B&W palette (Columbia-blue accent only; red stays reserved). */
.ff-payest { margin:6px 0 18px; }
.ff-payest-scope { font-size:13px; color:var(--ink-soft); margin:-4px 0 10px; }
.ff-est-note { display:flex; gap:9px; padding:12px 14px; background:#fff; border:1px solid var(--line); border-left:3px solid var(--col-blue); border-radius:8px; margin:0 0 14px; font-size:13px; line-height:1.55; color:var(--ink-soft); }
.ff-est-note strong { color:var(--ink); font-weight:700; }
.ff-est-note-plain { border-left-color:var(--line); }
#ffPayEst .calc-role-opt.is-selected { background:var(--col-blue-soft); border-color:var(--col-blue); color:var(--col-blue-deep); }
#ffPayEst .calc-role-opt.is-selected .calc-role-pct { color:var(--col-blue-deep); }
#ffPayEst .calc-input-wrap:focus-within { border-color:var(--col-blue); box-shadow:0 0 0 3px rgba(108,172,228,.22); }
#ffPayEst .calc-step.is-final .calc-step-val { -webkit-text-fill-color:var(--ink); background:none; color:var(--ink); }
.ff-est-hero { margin:14px 0; }
.ff-est-charthd { margin-top:16px; }
.ff-est-chartwrap { max-height:300px; overflow-y:auto; border:1px solid var(--line); border-radius:9px; }
#ffEstChart { width:100%; border-collapse:collapse; }
#ffEstChart thead th { position:sticky; top:0; z-index:1; background:#fff; text-align:left; font-size:11px; font-weight:700; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.06em; padding:9px 14px; border-bottom:1px solid var(--line); }
#ffEstChart thead th:last-child { text-align:right; }
#ffEstChart tbody td { padding:7px 14px; border-bottom:1px solid #eef0f2; font-size:13px; font-variant-numeric:tabular-nums; color:var(--ink); }
#ffEstChart tbody td:last-child { text-align:right; font-weight:500; }
#ffEstChart tbody tr.is-current td { background:var(--col-blue-soft); box-shadow:inset 0 0 0 1.5px var(--col-blue-deep); font-weight:700; color:var(--col-blue-deep); }

/* ============================================================
   ANNOUNCEMENTS COMPOSER + INBOX — built for the dark theme, so
   many labels/details went faint or transparent on the light shell.
   Force every text element in the broadcasts panel to readable ink.
   ============================================================ */
#panelBroadcasts { color: var(--ink); }
/* The composer + invite popover are HARDCODED dark panels (bgL=10/14) → whitewash. */
.broadcasts-compose, #broadcastsCompose,
.broadcasts-compose-header, .broadcasts-compose-footer, .broadcasts-compose-body,
.invite-popover-card { background: #fff !important; }
.broadcasts-compose-header, .broadcasts-compose-footer { border-color: var(--line) !important; }
/* Composer text — UNSCOPED (the composer is #broadcastsCompose, a sibling of
   #panelBroadcasts, so #panelBroadcasts-scoped rules don't reach it). */
.broadcasts-compose-title, .broadcasts-preview-body, .broadcasts-preview-title { color: var(--ink) !important; }
.broadcasts-section-label, .broadcasts-filter-label, .broadcasts-audience-count { color: #555 !important; }
.broadcasts-audience-detail, .broadcasts-preview-meta, .broadcasts-row-meta { color: #6b6b6b !important; }
.broadcasts-audience-name, .broadcasts-audience-row, .broadcasts-audience-row * { color: var(--ink) !important; }
.broadcasts-audience-row .broadcasts-audience-detail { color: #6b6b6b !important; }
/* Final safety net: force any transparent/near-transparent text in the composer
   to readable, regardless of class. */
.broadcasts-compose [style], .broadcasts-compose * { }
.broadcasts-audience-count { color: #555 !important; opacity: 1 !important; }

/* ============================================================
   LEADS HUB sub-nav — the original is a segmented "pill" control whose
   active segment (or sliding thumb) became a solid black blob under the
   B&W reskin, swallowing the label. Force clean UNDERLINE tabs like the
   prototype: gray inactive, dark + bottom-border active. No filled pill.
   ============================================================ */
.lh-subnav { display: flex !important; gap: 2px !important; align-items: stretch !important; background: none !important; box-shadow: none !important; border: none !important; border-bottom: 1px solid var(--line) !important; border-radius: 0 !important; padding: 0 !important; }
.lh-subnav::before, .lh-subnav::after, .lh-subnav-thumb, .lh-seg-thumb, .lh-seg::before, .lh-seg::after { display: none !important; background: none !important; box-shadow: none !important; }
.lh-seg { background: none !important; border: none !important; box-shadow: none !important; border-radius: 0 !important; color: var(--ink-soft) !important; font-weight: 500 !important; font-size: 14px !important; padding: 10px 15px !important; margin: 0 !important; border-bottom: 2px solid transparent !important; cursor: pointer; }
.lh-seg:hover { color: var(--ink) !important; }
.lh-seg.is-active, .lh-seg[aria-selected="true"] { background: none !important; color: var(--ink) !important; border-bottom: 2px solid var(--col-blue) !important; }

/* ============================================================
   LEAD DETAIL SHEET — clean modal. The ORIGINAL .lh-cals-panel already centers
   (absolute + translate(-50%,-50%) on desktop, bottom-sheet on mobile), so we
   DON'T touch positioning — only restyle the surface + the X, and give it a
   fixed header + scrolling body. Opacity-only fade so we never fight the
   centering transform.
   ============================================================ */
.lh-leadsheet { position: fixed !important; inset: 0 !important; z-index: 1200 !important; display: flex !important; align-items: center !important; justify-content: center !important; padding: 20px !important; }
.lh-leadsheet[hidden] { display: none !important; }
#lhLeadSheetBackdrop, .lh-leadsheet .lh-cals-backdrop { position: absolute !important; inset: 0 !important; background: rgba(0,0,0,.42) !important; cursor: pointer; transform: none !important; }
.lh-leadsheet-panel {
  position: relative !important;
  left: auto !important; top: auto !important; right: auto !important; bottom: auto !important;
  transform: none !important; margin: 0 !important; z-index: 1 !important;
  width: 100% !important; max-width: 560px !important;
  max-height: 88vh !important; max-height: 88dvh !important;   /* dvh = mobile-toolbar-safe */
  background: #fff !important;
  border: 1px solid var(--line) !important;
  border-radius: 14px !important;
  padding: 0 !important;
  overflow: hidden !important;
  display: flex !important;
  flex-direction: column;
  gap: 0 !important;
  box-shadow: 0 30px 70px -20px rgba(0,0,0,.4) !important;
  animation: ffSheetFade .16s ease;
}
.lh-leadsheet-panel .lh-cals-head { background: #fff; border-bottom: 1px solid var(--line); padding: 15px 18px; display: flex; align-items: center; justify-content: space-between; font-weight: 500; font-size: 16px; color: var(--ink); flex: 0 0 auto; }
.lh-leadsheet-panel .lh-viewer-close { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; background: #f4f5f7; border: 1px solid var(--line); color: var(--ink); font-size: 15px; line-height: 1; cursor: pointer; flex: 0 0 auto; padding: 0; }
.lh-leadsheet-panel .lh-viewer-close:hover { background: #e8e8ea; }
/* min-height:0 is THE fix — without it a flex child won't shrink below its content, so
   the body never scrolls and the whole panel overflows the screen (header cut off). */
.lh-leadsheet-body { overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding: 14px 18px 18px; flex: 1 1 auto; min-height: 0; }
@keyframes ffSheetFade { from { opacity: 0; } to { opacity: 1; } }
@media (max-width: 559px){
  .lh-leadsheet { align-items: flex-end !important; padding: 0 !important; }
  .lh-leadsheet-panel { max-width: none !important; border-radius: 18px 18px 0 0 !important; max-height: 92vh !important; max-height: 92dvh !important; padding-bottom: env(safe-area-inset-bottom, 0px) !important; }
}

/* ============================================================
   "SHOW CALENDARS" SHEET — same clean-modal pattern as the lead sheet above.
   The ORIGINAL .lh-cals-panel used absolute + translate(-50%,-50%) centering,
   which (under the FF app-shell) let the panel overflow its containing block so
   the header + X clipped off the top of the screen and the sheet couldn't be
   closed. Reuse the proven flex-center + position:relative + dvh + PINNED header
   + internally-scrolling list pattern. ID-scoped so the lead sheet is untouched.
   ============================================================ */
#lhCalsSheet { position: fixed !important; inset: 0 !important; z-index: 1200 !important; display: flex !important; align-items: center !important; justify-content: center !important; padding: 20px !important; }
#lhCalsSheet[hidden] { display: none !important; }
#lhCalsSheet .lh-cals-backdrop { position: absolute !important; inset: 0 !important; background: rgba(0,0,0,.42) !important; cursor: pointer; transform: none !important; }
#lhCalsSheet .lh-cals-panel {
  position: relative !important;
  left: auto !important; top: auto !important; right: auto !important; bottom: auto !important;
  transform: none !important; margin: 0 !important; z-index: 1 !important;
  width: 100% !important; max-width: 460px !important;
  max-height: 88vh !important; max-height: 88dvh !important;   /* dvh = mobile-toolbar-safe */
  background: #fff !important;
  border: 1px solid var(--line) !important;
  border-radius: 14px !important;
  padding: 0 !important;
  overflow: hidden !important;       /* the LIST scrolls, not the panel */
  display: flex !important;
  flex-direction: column;
  gap: 0 !important;
  box-shadow: 0 30px 70px -20px rgba(0,0,0,.4) !important;
  animation: ffSheetFade .16s ease;
}
/* Pinned header (Show Calendars + X) — never scrolls away, X always reachable. */
#lhCalsSheet .lh-cals-head { background: #fff; border-bottom: 1px solid var(--line); padding: 15px 18px; display: flex; align-items: center; justify-content: space-between; font-weight: 500; font-size: 16px; color: var(--ink); flex: 0 0 auto; }
#lhCalsSheet .lh-viewer-close { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; background: #f4f5f7; border: 1px solid var(--line); color: var(--ink); font-size: 15px; line-height: 1; cursor: pointer; flex: 0 0 auto; padding: 0; }
#lhCalsSheet .lh-viewer-close:hover { background: #e8e8ea; }
/* Search + All row also pinned. */
#lhCalsSheet .lh-cals-search { flex: 0 0 auto; margin: 12px 18px 0; width: auto; }
#lhCalsSheet .lh-cals-all { flex: 0 0 auto; margin: 8px 18px 0; }
/* min-height:0 is THE fix — lets this flex child shrink so the LIST scrolls
   instead of the whole panel overflowing the screen. */
#lhCalsSheet .lh-cals-list { overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding: 8px 18px 18px; flex: 1 1 auto; min-height: 0; }
@media (max-width: 559px){
  #lhCalsSheet { align-items: flex-end !important; padding: 0 !important; }
  #lhCalsSheet .lh-cals-panel { max-width: none !important; border-radius: 18px 18px 0 0 !important; max-height: 92vh !important; max-height: 92dvh !important; padding-bottom: env(safe-area-inset-bottom, 0px) !important; }
}

/* Calendar appointment blocks were solid black with faded text → clean white
   cards with a black left accent + readable dark text. */
.lh-tl-appt { background: #fff !important; border: 1px solid var(--line) !important; border-left: 3px solid #111 !important; border-radius: 6px !important; color: var(--ink) !important; box-shadow: 0 2px 6px -2px rgba(0,0,0,.12); padding: 5px 8px !important; overflow: hidden; }
.lh-tl-appt-time { color: var(--ink) !important; font-weight: 500 !important; }
.lh-tl-appt-name { color: var(--ink) !important; }
.lh-tl-appt-addr { color: var(--ink-soft) !important; }
.lh-tl-appt:hover { background: #fafafa !important; }
/* Lead detail modal / sheet → white surface, dark text */
.lh-detail, .lh-card-detail, [class*="lh-detail-"] { background: #fff !important; color: var(--ink) !important; }
.lh-detail .lh-detail-label, .lh-detail dt, [class*="lh-detail"] [class*="label"] { color: var(--ink-soft) !important; }

/* disposition note modal (result dispositions → note → SMS setter + sheet log) */
.ff-dispo-ov { position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:80; display:flex; align-items:center; justify-content:center; padding:18px; }
.ff-dispo-ov[hidden] { display:none; }
.ff-dispo-card { background:#fff; border-radius:14px; padding:22px; width:100%; max-width:440px; box-shadow:0 30px 70px -20px rgba(0,0,0,.5); }
.ff-dispo-card .dm-title { font-weight:500; font-size:16px; color:var(--ink); }
.ff-dispo-card .dm-sub { font-size:13px; color:var(--ink-soft); margin:5px 0 15px; line-height:1.45; }
.ff-dispo-card .dm-label { font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-soft); }
.ff-dispo-card .dm-req { color:#b42318; }
.ff-dispo-card .dm-note { width:100%; border:1px solid var(--line); border-radius:8px; padding:10px 12px; font-family:inherit; font-size:14px; margin:7px 0 14px; resize:vertical; color:var(--ink); }
.ff-dispo-card .dm-actions { display:flex; gap:10px; }
@media (max-width:820px){ .ff-dispo-card .dm-actions { flex-direction:column-reverse; } .ff-dispo-card .dm-actions .ff-btn-pri, .ff-dispo-card .dm-actions .ff-btn-out { width:100%; text-align:center; } }

/* ============================================================
   EMBEDDED SUBMIT A PROJECT overlay (replaces submit.* subdomain).
   ============================================================ */
.ffs-overlay { position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:90; display:flex; align-items:flex-start; justify-content:center; padding:24px 16px; overflow:auto; overscroll-behavior:contain; }
.ffs-overlay[hidden] { display:none; }
.ffs-panel { background:#fff; border-radius:14px; width:100%; max-width:780px; box-shadow:0 30px 80px -24px rgba(0,0,0,.5); display:flex; flex-direction:column; max-height:calc(100vh - 48px); }
.ffs-head { display:flex; align-items:center; justify-content:space-between; padding:18px 22px; border-bottom:1px solid var(--line); }
.ffs-title { font-size:18px; font-weight:500; color:var(--ink); }
.ffs-close { background:none; border:none; font-size:24px; line-height:1; color:var(--ink-soft); cursor:pointer; padding:0 4px; }
.ffs-body { padding:20px 22px 22px; overflow:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch; }
.ffs-grid { display:grid; grid-template-columns:1fr 1fr; gap:15px 18px; }
.ffs-field { display:flex; flex-direction:column; gap:6px; }
.ffs-field.ffs-full { grid-column:1 / -1; }
.ffs-field > label { font-size:11px; font-weight:700; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.06em; }
.ffs-req { color:#b42318; }
.ffs-field input, .ffs-field select, .ffs-field textarea { min-height:44px; border:1px solid var(--line); border-radius:6px; padding:10px 12px; font-family:inherit; font-size:14px; background:#fff; color:var(--ink); width:100%; }
.ffs-field input::placeholder, .ffs-field textarea::placeholder { color:#bbb; }
/* Date is short data — keep it a compact field, not a full-width box. It's
   type=date, so tapping already opens the native date picker (iPad/phone/desktop). */
.ffs-field input[type="date"] { max-width:220px; }
.ffs-field textarea { min-height:84px; resize:vertical; }
.ffs-locked { border:1px solid var(--line2,#eee); background:#fafafa; border-radius:6px; padding:10px 12px; color:#666; font-size:14px; }
.ffs-check { display:flex; align-items:center; gap:9px; cursor:pointer; font-size:14px; color:#333; font-weight:500; text-transform:none; letter-spacing:0; }
.ffs-check input { width:16px; height:16px; accent-color:#111; }
.ffs-fine { font-size:13px; color:var(--ink-soft); margin:14px 0 0; line-height:1.5; }
.ffs-foot { display:flex; align-items:center; gap:12px; margin-top:18px; flex-wrap:wrap; }
.ffs-status { font-size:13px; color:var(--ink-soft); }
.ffs-status.ffs-err { color:#b42318; font-weight:500; }
.ffs-confirm { text-align:center; padding:14px 6px 8px; }
.ffs-mark { width:46px; height:46px; border-radius:50%; background:#111; color:#fff; display:inline-flex; align-items:center; justify-content:center; font-size:22px; margin-bottom:12px; }
.ffs-confirm h3 { font-size:18px; font-weight:500; color:var(--ink); margin-bottom:8px; }
.ffs-confirm p { font-size:14px; color:var(--ink-soft); line-height:1.55; max-width:460px; margin:0 auto 14px; }
.ffs-summary { background:#fafafa; border:1px solid var(--line2,#eee); border-radius:8px; padding:13px 16px; text-align:left; font-size:13px; color:#333; margin:0 auto 16px; max-width:460px; line-height:1.7; }
.ffs-tron { display:inline-flex; align-items:center; gap:8px; text-decoration:none; margin-right:10px; }
@media (max-width:820px){
  .ffs-overlay { padding:0; }
  .ffs-panel { max-width:none; min-height:100vh; min-height:100dvh; border-radius:0; max-height:none; }
  .ffs-head { padding:calc(14px + env(safe-area-inset-top,0px)) 16px 14px; position:sticky; top:0; background:#fff; z-index:1; }
  .ffs-body { padding:16px 16px calc(24px + env(safe-area-inset-bottom,0px)); }
  .ffs-grid { grid-template-columns:1fr; }
  .ffs-foot .ff-btn-pri, .ffs-foot .ff-btn-out { flex:1; text-align:center; }
}

@media (max-width:820px){ .ff-lrow { flex-direction:column; align-items:stretch; } .ff-lrow .right { justify-content:space-between; } }

/* TOPBAR filter bar (field-select + search), prototype-style */
.portal-topbar .ff-topfilter {
  display:flex; align-items:stretch; height:38px; margin-left:14px;
  border:1px solid var(--line); border-radius:6px; overflow:hidden; width:460px; max-width:40vw; background:#fff;
}
.ff-topfilter .sel { display:flex; align-items:center; gap:8px; padding:0 12px; background:#f7f7f7; border-right:1px solid var(--line); color:#444; font-weight:500; white-space:nowrap; font-size:13px; }
.ff-topfilter .inp { display:flex; align-items:center; gap:8px; padding:0 12px; flex:1; color:var(--ink-faint); font-size:13px; }
@media (max-width:1100px){ .portal-topbar .ff-topfilter { width:320px; } }
@media (max-width:820px){ .portal-topbar .ff-topfilter { display:none; } }

@media (max-width:820px){
  .ff-stats { grid-template-columns:1fr; gap:10px; }
  .ff-scard { text-align:left; display:flex; align-items:center; justify-content:space-between; padding:15px 16px; }
  .ff-scard .n { font-size:26px; } .ff-scard .c { margin-top:0; }
  .ff-search { width:100%; }
  .ff-filters .ff-pills { flex:1 1 100%; }
  .ff-filters .ff-date { flex:1 1 calc(50% - 6px); }
  .ff-grid table, .ff-grid thead, .ff-grid tbody, .ff-grid tr, .ff-grid td { display:block; width:100%; }
  .ff-grid thead { display:none; }
  .ff-grid tbody tr { border:1px solid var(--line); border-radius:9px; margin:0 0 11px; padding:5px 0; }
  .ff-grid tbody td { border:none; padding:8px 15px; white-space:normal; display:flex; justify-content:space-between; gap:16px; text-align:right; }
  .ff-grid tbody td::before { content:attr(data-label); color:var(--ink-faint); font-size:11px; text-transform:uppercase; letter-spacing:.06em; font-weight:700; text-align:left; }
  .ff-grid td.nm { font-size:15px; font-weight:500; text-align:left; }
  .ff-grid td.nm::before { display:none; }
}

/* ============================================================
   LUX-SELECT (the portal's branded dropdown) — FLASH-BLACK FIX.
   ROOT CAUSE: base styles.css paints .lux-select-menu with a HARDCODED
   near-black surface (rgba(12,14,22,.96)) + heavy blue-tinted shadow +
   backdrop-blur. On the white FF theme that surface was only corrected at
   RUNTIME by the Light Guardian (a setTimeout(...,90) MutationObserver
   pass) — so the menu painted DARK on frame 1, then flipped white ~90ms
   later: the "flash black, then white" the owner reported.
   FIX: give the menu (and its parts) a STATIC flat-white surface in CSS so
   it paints its final B&W look on the FIRST frame, every time, with no
   dependence on JS. Also neutralizes the off-brand blue accents to B&W and
   makes the trigger/scrollbar states visible on white.
   ============================================================ */
.lux-select-menu {
  background: #fff !important;
  background-image: none !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  border: 1px solid var(--line) !important;
  border-radius: 10px !important;
  box-shadow: 0 16px 40px -14px rgba(0, 0, 0, 0.28) !important;
}
/* Options: dark ink on white; flat gray hover/selected (no blue). */
.lux-select-option { color: var(--ink-soft) !important; }
.lux-select-option:hover { background: #f1f1f3 !important; color: var(--ink) !important; }
.lux-select-option[aria-selected="true"] {
  background: #f1f1f3 !important; color: var(--ink) !important; font-weight: 500 !important;
}
.lux-select-option[aria-selected="true"]:hover { background: #e9e9ec !important; }
/* Trigger: subtle gray hover/open (the base rgba(255,255,255,.05) is invisible
   on a white control) and a neutral B&W open border (was blue-tinted). */
.lux-select-trigger { background: #fff !important; color: var(--ink) !important; }
.lux-select-trigger:hover,
.lux-select-trigger:focus-visible { background: #f7f7f9 !important; border-color: var(--line-strong) !important; }
/* Day Ledger: a Confirmed appointment's chip goes solid ink — the one
   deliberate dark chip in the hub (exempt from the white forcing above). */
.lh2-row[data-current="Confirmed"] .lh-disp .lux-select-trigger,
.lh2-row[data-current="Confirmed"] .lh-disp .lux-select-trigger:hover,
.lh2-row[data-current="Confirmed"] .lh-disp .lux-select-trigger:focus-visible {
  background: var(--ink) !important; color: #fff !important; border-color: var(--ink) !important;
}
.lux-select.is-open .lux-select-trigger {
  background: #f7f7f9 !important; border-color: var(--line-bright) !important;
}
/* Menu scrollbar thumb was white-on-white (invisible) → dark on the light menu. */
.lux-select-menu { scrollbar-color: rgba(0, 0, 0, 0.18) transparent !important; }
.lux-select-menu::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.18) !important; }
.lux-select-menu::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.30) !important; }

/* Pipeline inline Setter/Closer edit popover — the LAST legacy dark-glass dropdown.
   It's appended to <body> (outside #appStage), so the Light Guardian never reaches it;
   flip it to the same white pattern as .lux-select-menu/.ff-scope-menu above. */
.dsp-edit-popover {
  background: #fff !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  border: 1px solid var(--line) !important;
  box-shadow: 0 16px 40px -14px rgba(0, 0, 0, 0.28) !important;
  font-family: inherit !important;   /* drop the dead 'Geist' hardcode */
}
.dsp-edit-option { color: var(--ink-soft) !important; }
.dsp-edit-option:hover, .dsp-edit-option:focus { background: #f1f1f3 !important; color: var(--ink) !important; }
.dsp-edit-option.is-current { color: var(--ink) !important; background: #f1f1f3 !important; font-weight: 500 !important; }
.dsp-edit-searchable .dsp-edit-search {
  background: #fff !important;
  border: 1px solid var(--line) !important;
  color: var(--ink) !important;
}
.dsp-edit-searchable .dsp-edit-search:focus { border-color: var(--line-strong) !important; }
.dsp-edit-empty { color: var(--ink-soft) !important; }
.dsp-edit-list { scrollbar-color: rgba(0, 0, 0, 0.18) transparent !important; }
.dsp-edit-list::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.18) !important; }
/* Tap highlight (iOS Safari) — kill the translucent flash on touch. */
.lux-select-trigger, .lux-select-option { -webkit-tap-highlight-color: transparent; }

/* ============================================================
   MOBILE PASS (2026-07-02) — verified fixes from the phone audit.
   Phones are the reps' PRIMARY device; each rule below closes a
   confirmed defect (owner: "awful on the mobile version").
   ============================================================ */

/* Leads Hub sub-nav: labels were ellipsizing to "My Le… / Add a… / Follow…"
   for closers (4 tabs > 390px row). Tabs keep natural width; the row swipes
   sideways like every mobile tab bar. */
.lh-subnav { overflow-x: auto !important; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.lh-subnav::-webkit-scrollbar { display: none; }
.lh-subnav .lh-seg { flex: 0 0 auto !important; }
@media (max-width: 430px) {
  .lh-subnav .lh-seg { padding: 10px 11px !important; }   /* a closer's 4 tabs fit 390px+ without scrolling */
}

/* Outbox "Syncing…" badge: respect the iOS home-indicator zone, and sit UNDER
   open bottom-sheets (z 1200) instead of covering their action rows — it
   reappears the moment the sheet closes. */
.ff-outbox-badge { bottom: calc(16px + env(safe-area-inset-bottom, 0px)); z-index: 1150; }

/* Install-territory map sheet: same dvh + safe-area treatment its sibling
   sheets already have — the footer button sat behind the Safari toolbar. */
@media (max-width: 559px) {
  .ff-imap-card { max-height: 92vh; max-height: 92dvh; padding-bottom: env(safe-area-inset-bottom, 0px); }
}

/* Admin preview banner: text ellipsizes instead of wrapping (a wrapped banner
   grew past the hardcoded content offset and covered the first KPI row); the
   offset itself is now measured live into --ff-pvb-h by ffShowPreviewBanner. */
.ff-pvb-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.ff-previewing .app-stage { margin-top: var(--ff-pvb-h, 46px); }
/* The icon rail is FIXED under the topbar — while previewing, drop it below the
   banner too, or its first icons (Home) sit underneath the black strip
   (owner 2026-07-02: "I dont like this Home overlay"). */
body.ff-previewing .app-tabs { top: calc(var(--portal-topbar-h, 64px) + var(--ff-pvb-h, 46px)); }

/* Touch targets ≥44px on phones (invisible hit-area growth — visual size kept):
   the burger is the ONLY nav opener on mobile at 38px; the Submit form's close X
   was ~32×28 on the money form; sheet close X's were 32px; month-nav arrows 36px. */
@media (max-width: 820px) {
  .ff-burger { width: 44px; height: 44px; }
  .ffs-close { padding: 10px 14px; margin: -10px -14px -10px 0; }
  .lh-leadsheet-panel .lh-viewer-close, #lhCalsSheet .lh-viewer-close { width: 44px; height: 44px; }
  .lh-cal-nav { min-width: 44px; min-height: 44px; }
  .lh-fu-log-btn { min-height: 44px; display: inline-flex; align-items: center; }
  .tab-searchbar-clear { min-width: 44px; min-height: 44px; }
  .lux-select-option { min-height: 44px; display: flex; align-items: center; }
}

/* iOS input auto-zoom: Safari zooms the whole page when a focused control's
   font-size is under 16px — the single biggest "portal feels broken on my
   phone" trigger. Every text-entry control gets 16px at phone widths. */
@media (max-width: 820px) {
  input[type="text"], input[type="search"], input[type="tel"], input[type="email"],
  input[type="number"], input[type="date"], input[type="time"], input[type="password"],
  select, textarea { font-size: 16px !important; }
}

/* Disposition/reschedule/follow-up modal card: cap to the visual viewport and
   scroll inside — on small phones with the keyboard up, the Save row could sit
   off-screen with no way to reach it. */
@media (max-width: 820px) {
  .ff-dispo-card { max-height: 86vh; max-height: 86dvh; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
}

/* ── Commissions mobile sanitization (owner screenshot, 2026-07-02) ──
   The generic ≤820px KPI-row layout (number left, label right) breaks on the
   money tiles' LONG labels ("Pending · project pay not yet paid") — they crammed
   beside the number. Money tiles stack instead. And the header row now wraps so
   the admin/manager rep picker can never push past the screen edge. */
@media (max-width: 820px) {
  .ff-head { flex-wrap: wrap; }
  .ff-actions { flex-wrap: wrap; max-width: 100%; }
  #ffCommActions .commissions-rep-filter-select { max-width: 46vw; }
}

/* ── Topbar elevation (owner 2026-07-02, the "cut in half" header) ──
   The legacy border-bottom is the DARK theme's white-alpha line — invisible on the
   white FF bar, so scrolled content sliced through with no visual layering. A real
   hairline always; a soft shadow only while scrolled (added/removed by main.js). */
.portal-topbar { border-bottom: 1px solid var(--line) !important; }
.portal-topbar.is-scrolled { box-shadow: 0 6px 18px -12px rgba(0, 0, 0, 0.28); }
@media (prefers-reduced-motion: no-preference) {
  .portal-topbar { transition: box-shadow .18s ease; }
}

/* ── Ghost skeletons — cold/slow loads look like THIS portal filling in ──
   Injected by ffSkel_ under the loading strip; removed the instant real data paints. */
.ff-skel { padding-top: 6px; }
.ff-skel .sk { position: relative; overflow: hidden; background: #eceef0; border-radius: 8px; }
.ff-skel .sk::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.65), transparent);
  transform: translateX(-100%);
  animation: ffSkelShimmer 1.3s ease-in-out infinite;
}
@keyframes ffSkelShimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .ff-skel .sk::after { animation: none; } }
.ff-skel .sk-title { width: 38%; max-width: 220px; height: 26px; margin-bottom: 16px; }
.ff-skel .sk-cards { display: flex; gap: 12px; margin-bottom: 16px; }
.ff-skel .sk-card { flex: 1; height: 76px; }
.ff-skel .sk-bar { height: 40px; margin-bottom: 14px; }
.ff-skel .sk-row { height: 58px; margin-bottom: 10px; }
/* ff380 (P1-16): per-panel ghost shapes — hero for Commissions/Advances,
   taller podium cards for Leaderboard — so the skeleton morphs into the
   screen it becomes instead of a generic 3-card grid. */
.ff-skel .sk-hero { height: 118px; margin-bottom: 16px; }
.ff-skel .sk-pod .sk-card { height: 128px; }
@media (max-width: 820px) { .ff-skel .sk-cards { flex-direction: column; } .ff-skel .sk-card { height: 58px; } .ff-skel .sk-pod .sk-card { height: 72px; } }

/* Quick Follow-Up modal cleanup (owner 2026-07-02): the resizable notes box
   overlapped Save/Cancel. Fixed height, no manual resize, real breathing room. */
.ff-dispo-card .dm-note, .ff-dispo-card textarea { resize: none; max-height: 140px; }
.ff-dispo-card .dm-actions { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); display: flex; gap: 10px; }

/* ============================================================
   COMMISSIONS REDESIGN (2026-07-02, approved mockup) -- role-shaped
   money screen. New pieces only: the "Owed to you" / "Outstanding to
   reps" hero, the two mini tiles, the red advance strip, the amber
   HELD strip inside deal cards, section-header subtotals, the black
   admin scope chip, tap-to-expand notes (details/summary -- never
   title= tooltips), deduction rows and the section-jump pill group.
   Reuses existing tokens (var(--line), .ff-lrow, .ff-pills, the
   comm-deal card geometry in styles.css). Nothing here animates, so
   prefers-reduced-motion is satisfied by construction.
   ============================================================ */
/* ff381 (P3-04): the money hero goes billboard — the ONE number a rep opens
   this screen for, on the sanctioned inverted-black surface (same recipe as
   .ff-rfeature). Allowlisted in ffLightGuard. Red money reads #ff8a80 on black
   (the dark-safe red); the red advance strip sits on white below for urgency. */
.comm-hero { background: #111 radial-gradient(120% 160% at 88% -20%, rgba(255,255,255,.14), rgba(255,255,255,0) 55%); border: 1px solid #000; box-shadow: none; border-radius: 14px; padding: 20px 24px; margin-bottom: 10px; }
.comm-hero .hl { font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: #c9c3b4; }
.comm-hero .hn { font-size: 34px; font-weight: 500; letter-spacing: -.01em; line-height: 1.15; margin-top: 4px; font-variant-numeric: tabular-nums; color: #fff; }
.comm-hero .hs { font-size: 12px; color: #d9d9d9; margin-top: 4px; }
.comm-hero .hn.ff-neg { color: #ff8a80 !important; }
/* Mini tiles: label always UNDER the number (phone-first -- owner reviews at 390px). */
.comm-duo { display: flex; gap: 10px; margin: 0 0 10px; }
.comm-mini { flex: 1 1 0; min-width: 0; background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 12px; }
.comm-mini .n { font-size: 20px; font-weight: 500; font-variant-numeric: tabular-nums; color: var(--ink, #16171a); }
.comm-mini .c { font-size: 12px; font-weight: 500; color: var(--ink-soft); margin-top: 2px; }
.comm-mini-sub { display: block; font-size: 11px; color: var(--ink-faint); margin-top: 1px; font-variant-numeric: tabular-nums; }
/* ff381: the separate muted uppercase period caption (stat-card anatomy). */
.comm-mini-cap { display: block; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint); margin-top: 2px; }
/* Red advance strip -- exists ONLY while a balance is open. */
.comm-owe-strip { background: #fef2f2; border: 1px solid #f3c8c8; color: #b91c1c; border-radius: 10px; padding: 9px 13px; font-size: 13px; font-weight: 700; margin-bottom: 10px; }
.comm-owe-strip span { font-weight: 400; color: #8a4444; }
/* Amber HELD strip inside a deal card -- a calm labeled process state, not red panic. */
.comm-held-strip { margin-top: 9px; background: #fdf6e7; border: 1px solid #ecd9ae; color: #8a5a10; border-radius: 8px; padding: 7px 11px; font-size: 12px; line-height: 1.5; }
.comm-held-strip b { letter-spacing: .06em; }
/* Section headers with a right-aligned subtotal of exactly the cards below. */
.ff-grouphd.comm-grouphd { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.comm-gh-sum { font-size: 12px; letter-spacing: 0; text-transform: none; color: var(--ink-soft, #555); font-weight: 500; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Black admin scope chip in the header scope line (mockup: ADMIN + ALL REPS). */
.comm-chip-scope { display: inline-block; background: #111; color: #fff; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; padding: 2px 9px; border-radius: 999px; }
/* Tap-to-expand notes (details/summary like .lh-history) -- phones can't hover. */
.comm-note { margin-top: 4px; }
.comm-note summary { cursor: pointer; list-style: none; font-size: 12px; font-weight: 500; color: var(--col-blue-deep, #2E7AB8); -webkit-tap-highlight-color: transparent; }
.comm-note summary::-webkit-details-marker { display: none; }
.comm-note summary::after { content: ' \25B8'; }
.comm-note[open] summary::after { content: ' \25BE'; }
.comm-note-body { margin-top: 5px; font-size: 13px; color: var(--ink-soft, #555); white-space: pre-wrap; word-break: break-word; }
.comm-note-inline { font-size: 12px; color: var(--ink-soft, #555); margin-top: 3px; overflow-wrap: anywhere; }
/* Deduction/advance/cancellation rows: keep the text column from being crushed
   by the money column inside .ff-lrow. */
.ff-lrow .comm-lrow-main { flex: 1 1 auto; min-width: 0; }
/* Section-jump pills (Advances / Subcontract) read as a DIFFERENT control from
   the status pills: gray fill + small caps; the active one goes solid black. */
.ff-pills.comm-secpills button { background: #f4f4f5; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.ff-pills.comm-secpills button.on { background: #111; color: #fff; box-shadow: none; }
/* Manager "Viewing pay for" picker slot -- sits between "Team pay" and the controls. */
@media (max-width: 430px) {
  .comm-hero .hn { font-size: 26px; }
  .comm-duo { gap: 8px; }
  .comm-mini .n { font-size: 18px; }
}

/* ═════════ REQUESTS CENTER (ff379) — rq-* prefixed, B&W utilitarian ═════════ */
/* HERO STRIP: the viewer's live context as ONE focal number — same inverted-
   black billboard language as the Resources store card, kept compact + calm. */
.rq-hero { display: flex; align-items: center; justify-content: space-between; gap: 22px;
  background: #111 radial-gradient(120% 160% at 88% -20%, rgba(255,255,255,.12), rgba(255,255,255,0) 55%);
  color: #fff; border: 1px solid #000; border-radius: 14px; padding: 20px 24px; margin: 4px 0 6px; overflow: hidden; }
.rq-hero-eyebrow { font-size: 11px; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: #c9c3b4; }
.rq-hero-n { font-size: clamp(28px, 4vw, 38px); font-weight: 700; letter-spacing: -.015em; line-height: 1.05; margin-top: 6px; color: #fff; font-variant-numeric: tabular-nums; }
.rq-hero-c { font-size: 14px; font-weight: 500; color: #d9d9d9; margin-top: 4px; }
.rq-hero-s { font-size: 12px; color: #9b9b9b; margin-top: 3px; }
.rq-hero-side { display: flex; gap: 26px; flex: 0 0 auto; padding-right: 4px; }
.rq-hero-mini .n { font-size: 18px; font-weight: 500; color: #fff; font-variant-numeric: tabular-nums; }
.rq-hero-mini .c { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #9b9b9b; margin-top: 3px; }
/* ACTION CARD ROW: one opener per request type — icon tile, title, one-line
   promise, "Start request" affordance. Tapping opens the pop-out overlay.
   ff387: the cards read as ONE designed unit — grid rows stretch every card
   to the tallest sibling, the text column fills the card, and the go-row pins
   to the bottom edge so all affordances sit on one baseline. */
.rq-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; margin-bottom: 6px; align-items: stretch; }
.rq-action { display: flex; flex-direction: row; align-items: stretch; gap: 14px; min-width: 0; text-align: left;
  background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 15px 16px;
  font-family: inherit; cursor: pointer; transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.rq-action:hover { transform: translateY(-2px); border-color: #c9cbd0; box-shadow: 0 14px 28px -14px rgba(0,0,0,.35); }
.rq-action:focus-visible { outline: 2px solid #111; outline-offset: 2px; }
.rq-action-ico { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px;
  background: #111; color: #fff; border-radius: 10px; flex: 0 0 auto; align-self: flex-start; }
.rq-action-tx { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.rq-action-t { font-weight: 700; font-size: 15px; color: var(--ink); }
.rq-action-d { font-size: 13px; color: var(--ink-soft); line-height: 1.45; margin-top: 4px; }
.rq-action-go { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: var(--ink); margin-top: auto; padding-top: 13px; }
.rq-action.is-off { opacity: .8; cursor: default; }
.rq-action.is-off:hover { transform: none; box-shadow: none; border-color: var(--line); }
/* Disabled card: quiet LIGHT tile — the black tile is the live-action signal
   (same grammar as .ff-rcard.is-soon). */
.rq-action.is-off .rq-action-ico { background: #f0f0f2; color: var(--ink-faint); }
.rq-action.is-off .rq-action-t, .rq-action.is-off .rq-action-go { color: var(--ink-soft); }
.rq-drafttag { background: #f1f1f3; border-color: var(--line); color: #555; }
@media (prefers-reduced-motion: reduce) { .rq-action { transition: none; } }
/* POP-OUT OVERLAY FORMS (.rqo-*): the Submit-a-Project (.ffs-*) mechanics —
   centered card on desktop, full-height sheet on mobile, body scrolls. */
.rqo-ov { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 90; display: flex; align-items: flex-start; justify-content: center; padding: 24px 16px; overflow: auto; overscroll-behavior: contain; }
.rqo-ov[hidden] { display: none; }
.rqo-panel { background: #fff; border-radius: 14px; width: 100%; max-width: 620px; box-shadow: 0 30px 80px -24px rgba(0,0,0,.5); display: flex; flex-direction: column; max-height: calc(100vh - 48px); }
.rqo-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 22px; border-bottom: 1px solid var(--line); flex: 0 0 auto; }
.rqo-title { font-size: 18px; font-weight: 500; color: var(--ink); }
.rqo-close { background: none; border: none; font-size: 24px; line-height: 1; color: var(--ink-soft); cursor: pointer; padding: 0 4px; }
/* ONE flex rhythm for everything inside a request sheet: every block (intro,
   fields, grids, confirm panels, fine print) breathes 14px apart — no more
   0px seams between a field and the next label (owner 2026-07-03: the Cost
   label sat ON the deal input). Hidden blocks take no space. */
.rqo-body { padding: 18px 22px 10px; overflow: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; display: flex; flex-direction: column; gap: 14px; }
.rqo-body .rq-sub, .rqo-body .rq-field, .rqo-body .rq-grid, .rqo-body .rq-confirm, .rqo-body .rq-fineprint { margin: 0; }
.rqo-sub { font-size: 13px; color: var(--ink-soft); line-height: 1.5; margin-bottom: 14px; }
.rqo-foot { padding: 14px 22px 18px; border-top: 1px solid var(--line); flex: 0 0 auto; }
.rqo-foot .rq-err { margin: 0 0 10px; }
.rqo-footrow { display: flex; align-items: center; gap: 14px; }
.rqo-footrow .ff-btn-pri { min-height: 44px; }
.rqo-note { font-size: 13px; color: var(--ink-soft); }
/* Layer order: the deal-search picker and the blocking failed state ride
   .ff-dispo-ov (z 80) but must sit ABOVE an open form overlay (z 90). */
/* The picker anchors high-but-below-the-notch (a search-first sheet wants the
   keyboard; dvh cap keeps it clear of both the status bar and the keyboard —
   owner 2026-07-03: it "shot up" under the clock when opened). Calm entrance. */
#rqPickerOv { z-index: 95; align-items: flex-start; padding: max(14px, env(safe-area-inset-top, 14px)) 14px 14px; }
#rqPickerOv .rq-pk-card { animation: rqPkIn .16s ease-out; max-height: min(72vh, 640px); max-height: min(68dvh, 640px); }
@keyframes rqPkIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { #rqPickerOv .rq-pk-card { animation: none; } }
.rq-pk-spin { display: inline-block; width: 13px; height: 13px; border: 2px solid var(--line); border-top-color: var(--ink); border-radius: 50%; margin-right: 8px; vertical-align: -2px; animation: rqPkSpin .7s linear infinite; }
@keyframes rqPkSpin { to { transform: rotate(360deg); } }
#rqFailedOv { z-index: 96; }
@media (max-width: 640px) {
  /* Content-fit BOTTOM SHEET (owner 2026-07-03: a 3-field form marooned atop a
     full-height sheet = unintentional void; use the .ff-imap-card pattern).
     The sheet rises from the bottom and holds exactly its content, capped at
     92dvh — long forms scroll inside .rqo-body, short forms end where they end. */
  .rqo-ov { padding: 0; align-items: flex-end; }
  .rqo-panel { max-width: none; width: 100%; border-radius: 14px 14px 0 0; max-height: 92vh; max-height: 92dvh; }
  .rqo-head { padding: 14px 16px; position: sticky; top: 0; background: #fff; z-index: 1; }
  .rqo-body { padding: 16px 16px 6px; }
  .rqo-foot { padding: 12px 16px calc(18px + env(safe-area-inset-bottom, 0px)); }
  .rqo-footrow { flex-direction: column; align-items: stretch; }
  .rqo-footrow .ff-btn-pri { width: 100%; justify-content: center; }
  .rqo-note { text-align: center; }
}
/* For-Rep type-to-search combobox (the .dsp-edit-searchable pattern, inline):
   input filters, dropdown lists matches, pick becomes a chip with a clear x. */
.rq-repsel { position: relative; min-width: 0; }
.rq-repchip { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; min-height: 44px;
  border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; background: #f7f7f9;
  font-family: inherit; font-size: 16px; color: var(--ink); cursor: pointer; text-align: left; }
.rq-repchip:hover { background: #f1f1f3; }
.rq-repchip-nm { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rq-repchip-x { font-size: 20px; line-height: 1; color: var(--ink-soft); flex: 0 0 auto; }
.rq-repdd { position: absolute; top: calc(100% + 5px); left: 0; right: 0; z-index: 6; background: #fff;
  border: 1px solid var(--line-strong, #bdbdbd); border-radius: 10px; box-shadow: 0 18px 40px -16px rgba(0,0,0,.4);
  max-height: 262px; overflow-y: auto; }
.rq-repdd-item { display: block; width: 100%; text-align: left; background: none; border: none; border-bottom: 1px solid var(--line);
  padding: 10px 12px; min-height: 44px; font-family: inherit; cursor: pointer; }
.rq-repdd-item:last-child { border-bottom: none; }
.rq-repdd-item:hover { background: #f7f7f9; }
.rq-repdd-item .nm { display: block; font-size: 14px; font-weight: 500; color: var(--ink); }
.rq-repdd-item .sub { display: block; font-size: 12px; color: var(--ink-soft); margin-top: 2px; }
.rq-repdd-empty { padding: 12px; font-size: 12px; color: var(--ink-soft); text-align: center; }
/* Designed empty states: an invitation, not a bare row. */
.rq-empty { background: #fff; border: 1px dashed var(--line-strong, #bdbdbd); border-radius: 10px; padding: 24px 20px; text-align: center; }
.rq-empty-t { font-weight: 700; font-size: 15px; color: var(--ink); }
.rq-empty-d { font-size: 13px; color: var(--ink-soft); line-height: 1.5; margin-top: 5px; max-width: 46ch; margin-left: auto; margin-right: auto; }
.rq-empty-go { margin-top: 14px; min-height: 40px; }
/* Proof-of-life highlight on a just-submitted row — one calm transition. */
.rq-row { transition: background .9s ease; }
.rq-row.is-new { background: #ececef; }
/* Fields: 16px inputs (iOS zoom guard), 44px touch targets. */
.rq-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
.rq-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.rq-field > span { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.rq-field .rq-fine { text-transform: none; letter-spacing: 0; font-weight: 500; }
.rq-full { grid-column: 1 / -1; }
.rq-req { color: #b42318; font-weight: 700; }
.rq-input { width: 100%; border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; min-height: 44px; font-family: inherit; font-size: 16px; color: var(--ink); background: #fff; box-sizing: border-box; }
textarea.rq-input { min-height: 60px; resize: vertical; }
.rq-input:focus { outline: none; border-color: var(--line-strong, #bdbdbd); }
.rq-pickbtn { width: 100%; min-height: 44px; text-align: left; border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; background: #fff; font-family: inherit; font-size: 16px; color: var(--ink); cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rq-pickbtn:hover { background: #f7f7f9; }
.rq-foot { display: flex; gap: 10px; margin-top: 12px; }
.rq-foot .ff-btn-pri, .rq-foot .ff-btn-out { min-height: 44px; }
.rq-fine { font-size: 12px; color: var(--ink-faint); margin-top: 7px; line-height: 1.45; }
.rq-err { margin-top: 8px; background: #fef2f2; border: 1px solid #f3c0bb; color: #b42318; border-radius: 6px; padding: 8px 12px; font-size: 13px; line-height: 1.5; }
/* Cap line — value + small muted uppercase caption anatomy, no joined labels. */
.rq-capline { background: #f7f7f9; border: 1px solid var(--line); border-radius: 6px; padding: 8px 12px; font-size: 13px; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; margin-bottom: 12px; }
/* Banners: unconfigured-recipients (red, persistent) + offline notice. */
.rq-banner { background: #fef2f2; border: 1px solid #dc2626; color: #b42318; border-radius: 10px; padding: 12px 16px; font-size: 13px; font-weight: 700; line-height: 1.5; margin-bottom: 12px; }
.rq-offline { background: #f7f7f9; border: 1px solid var(--line-strong, #bdbdbd); color: var(--ink); border-radius: 10px; padding: 12px 16px; font-size: 13px; font-weight: 500; margin-bottom: 12px; }
/* Read-only subcontract confirm panel + console fact rows. */
.rq-confirm, .rq-cfacts { background: #f7f7f9; border: 1px solid var(--line); border-radius: 6px; padding: 12px 12px; margin: 10px 0; }
.rq-cline { display: flex; justify-content: space-between; gap: 14px; padding: 4px 0; font-size: 13px; }
.rq-cline span:first-child { color: var(--ink-soft); flex: 0 0 auto; }
.rq-cline span:last-child { color: var(--ink); font-weight: 500; text-align: right; overflow-wrap: anywhere; }
/* My Requests rows — extends .ff-lrow. */
.rq-row .rq-note { margin-top: 4px; font-size: 13px; color: #b42318; background: #fff6f5; border: 1px solid #f3c0bb; border-radius: 6px; padding: 8px 12px; overflow-wrap: anywhere; }
.rq-row .rq-row-main { flex: 1 1 auto; min-width: 0; }
.rq-row .rq-cancel { padding: 8px 12px; font-size: 12px; min-height: 34px; }
/* Console rows: header button + expandable body. */
.rq-count { font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--ink-soft); margin-left: 6px; }
.rq-crow { background: #fff; border: 1px solid var(--line); border-radius: 8px; margin-bottom: 9px; overflow: hidden; }
.rq-crow-hd { display: flex; align-items: center; justify-content: space-between; gap: 14px; width: 100%; padding: 12px 16px; min-height: 44px; background: none; border: none; font-family: inherit; text-align: left; cursor: pointer; }
.rq-crow-hd:hover { background: #f7f7f9; }
.rq-crow-main { min-width: 0; }
.rq-crow-main .nm { display: block; font-weight: 500; font-size: 14px; color: var(--ink); }
.rq-crow-main .meta { display: block; font-size: 12px; color: var(--ink-soft); margin-top: 3px; }
.rq-crow-hd .right { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }
.rq-chev { width: 8px; height: 8px; border-right: 1.6px solid var(--ink-faint); border-bottom: 1.6px solid var(--ink-faint); transform: rotate(45deg); transition: transform .15s; }
.rq-crow.is-open .rq-chev { transform: rotate(-135deg); }
.rq-crow-body { padding: 4px 16px 16px; border-top: 1px solid var(--line); }
/* Decision panel: warnings + per-payee stat grid (value + muted caption). */
.rq-warn { background: #fff6f5; border: 1px solid #f3c0bb; color: #b42318; border-radius: 6px; padding: 8px 12px; font-size: 13px; line-height: 1.5; margin: 8px 0; }
.rq-warn-block { background: #b42318; border-color: #b42318; color: #fff; font-weight: 700; }
.rq-payee { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; margin: 8px 0; }
.rq-payee-nm { font-weight: 500; font-size: 14px; color: var(--ink); margin-bottom: 8px; }
.rq-payee-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.rq-stat .n { font-size: 14px; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
.rq-stat .c { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint); margin-top: 2px; }
.rq-decide { margin-top: 10px; }
.rq-btn-danger { color: #b42318; border-color: #f3c0bb; }
.rq-btn-danger:hover { background: #fff6f5; }
/* Failed-submit blocking state accent. */
.rq-failed-title { color: #b42318; }
/* Searchable picker overlay (rides .ff-dispo-ov/.ff-dispo-card). */
.rq-pk-card { max-width: 520px; display: flex; flex-direction: column; max-height: min(72vh, 640px); }
.rq-pk-search { margin: 12px 0 10px; flex: 0 0 auto; }
.rq-pk-list { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; border: 1px solid var(--line); border-radius: 8px; margin-bottom: 12px; min-height: 120px; }
.rq-pk-item { display: block; width: 100%; text-align: left; background: none; border: none; border-bottom: 1px solid var(--line); padding: 10px 12px; min-height: 44px; font-family: inherit; cursor: pointer; }
.rq-pk-item:last-child { border-bottom: none; }
.rq-pk-item:hover { background: #f7f7f9; }
.rq-pk-item .nm { display: block; font-size: 14px; font-weight: 500; color: var(--ink); }
.rq-pk-item .sub { display: block; font-size: 12px; color: var(--ink-soft); margin-top: 2px; }
.rq-pk-item .meta { display: block; font-size: 11px; color: var(--ink-faint); margin-top: 2px; font-variant-numeric: tabular-nums; }
.rq-pk-more { padding: 12px; font-size: 12px; color: var(--ink-soft); text-align: center; }
/* Mobile: forms collapse to one column; hero stacks; console/list rows stack. */
@media (max-width: 820px) {
  .rq-hero { flex-direction: column; align-items: flex-start; gap: 16px; padding: 18px 20px; }
  .rq-hero-side { padding: 0; gap: 22px; }
  .rq-grid { grid-template-columns: 1fr; }
  .rq-payee-grid { grid-template-columns: repeat(2, 1fr); }
  .rq-crow-hd { flex-direction: column; align-items: stretch; }
  .rq-crow-hd .right { justify-content: space-between; }
  .rq-foot { flex-direction: column-reverse; }
  .rq-foot .ff-btn-pri, .rq-foot .ff-btn-out { width: 100%; justify-content: center; }
}

/* ═══════════════════════════════════════════════════════════════
   CLOSER AVAILABILITY (ff382) — status card, editor sheet, timeline
   off-wash, advisory + override surfaces. B&W utilitarian: hatched
   monochrome for "off" (a fact, not an error), one focal point per
   surface, 11px/700/.06em micro-labels, 4px rhythm, 44px targets.
   ═══════════════════════════════════════════════════════════════ */

/* Layer order: the availability confirm sheet rides .ff-dispo-ov (z 80) but a
   FLUSH-time verdict (20s timer) can land while an .rqo form overlay (z 90) is
   open - same canon as #rqPickerOv/#rqFailedOv, it must sit ABOVE. */
#lhAvConfirm { z-index: 97; }

/* ── Status card (top of My Calendar) ── */
.lh-av-card { background: #fff; border: 1px solid var(--line); border-radius: 12px; padding: 16px; margin: 0 0 16px; }
.lh-av-mlabel { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.lh-av-row1 { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.lh-av-sum { font-size: 14px; color: var(--ink); line-height: 1.5; margin-top: 8px; }
.lh-av-sum.is-warn { color: #b42318; }
.lh-av-meta { font-size: 12px; color: var(--ink-soft); line-height: 1.5; margin-top: 4px; }
.lh-av-statrow { display: flex; gap: 12px; margin-top: 12px; }
.lh-av-statcell { flex: 1; border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; }
.lh-av-statcell .v { font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink); line-height: 1.2; }
.lh-av-statcell .l { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); margin-top: 2px; }
.lh-av-statcell .c { font-size: 11px; color: var(--ink-soft); margin-top: 2px; }
.lh-av-actions { margin-top: 12px; }
.lh-av-actions .ff-btn-out { min-height: 44px; }
/* Nudge (designed empty state — an invitation, same anatomy as ffEmpty_) */
.lh-av-nudge-t { font-size: 15px; font-weight: 600; color: var(--ink); margin-top: 8px; }
.lh-av-nudge-s { font-size: 13px; color: var(--ink-soft); line-height: 1.5; margin: 4px 0 12px; max-width: 520px; }
.lh-av-nudge .ff-btn-pri { min-height: 44px; }

/* ── On/Off switch (44px hit area; the knob is the whole affordance) ── */
.lh-av-switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; min-height: 44px; padding: 0 2px; }
.lh-av-switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.lh-av-switch .lh-av-knob { width: 40px; height: 24px; border-radius: 12px; background: #d3d5d9; position: relative; transition: background .15s ease; flex: 0 0 auto; }
.lh-av-switch .lh-av-knob::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: left .15s ease; }
.lh-av-switch input:checked + .lh-av-knob { background: #16181d; }
.lh-av-switch input:checked + .lh-av-knob::after { left: 19px; }
.lh-av-switch input:focus-visible + .lh-av-knob { outline: 2px solid #16181d; outline-offset: 2px; }
.lh-av-onlabel { font-size: 13px; font-weight: 600; color: var(--ink); min-width: 24px; }

/* ── Editor sheet (rides the .rqo-* shell: content-fit bottom sheet on mobile) ── */
.lh-avd-row { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.lh-avd-row:last-of-type { border-bottom: 0; }
.lh-avd-day { flex: 0 0 44px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink); padding-top: 14px; }
.lh-avd-wins { flex: 1; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.lh-avd-off { font-size: 13px; color: var(--ink-soft); padding: 12px 0 0; }
.lh-avd-win { display: flex; align-items: center; gap: 8px; }
.lh-avd-win .lh-avd-sel { font-size: 16px; min-height: 44px; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; background: #fff; color: var(--ink); flex: 1; min-width: 0; }
.lh-avd-dash { color: var(--ink-soft); flex: 0 0 auto; }
.lh-avd-del { flex: 0 0 44px; min-height: 44px; border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--ink-soft); font-size: 18px; line-height: 1; cursor: pointer; }
.lh-avd-del:hover { color: #b42318; border-color: #b42318; }
.lh-avd-btnrow { display: flex; gap: 8px; flex-wrap: wrap; }
.lh-avd-add, .lh-avd-copy { min-height: 44px; border: 1px dashed var(--line); border-radius: 8px; background: #fff; color: var(--ink); font-size: 13px; font-weight: 600; padding: 0 14px; cursor: pointer; }
.lh-avd-add:hover, .lh-avd-copy:hover { border-color: #16181d; }
.lh-av-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 16px; }
.lh-av-fields .lh-avf { display: flex; flex-direction: column; gap: 6px; }
.lh-av-fields .lh-avf > span { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.lh-av-fields input.lh-input { font-size: 16px; min-height: 44px; }
@media (max-width: 640px) { .lh-av-fields { grid-template-columns: 1fr; } }
.lh-av-summary { font-size: 13px; color: var(--ink); line-height: 1.5; background: #f5f6f7; border-radius: 8px; padding: 10px 12px; margin-top: 14px; }
.lh-av-summary.is-warn { color: #b42318; background: #fdf3f2; }
.lh-av-err { font-size: 13px; color: #b42318; margin: 10px 0 0; }
.lh-av-draftnote { font-size: 12px; color: var(--ink-soft); margin: 0 0 10px; }

/* ff389: region chips (owner's IL grid) - the closer's classified region on
   their availability card + the scheduler column headers for setters. */
.lh-av-region, .lh-tl-region { display: inline-block; margin-left: 6px; padding: 1px 7px; border: 1px solid var(--line); border-radius: 4px; font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); background: #fff; vertical-align: 1px; white-space: nowrap; }
.lh-tl-region { font-size: 9px; padding: 1px 5px; margin-left: 5px; }
/* ff395: "No base set" — a closer with hours but no base address (no region,
   inactive drive gate). Muted amber so admins spot who needs to add one. */
.lh-av-region.is-nobase { color: #8a5a00; border-color: #e6cf9a; background: #faf3e3; }

/* ff396: recoverable "full record didn't load" notice on a lead detail (Edit
   locked). Keeps the seed visible; offers a Retry — never a silent dead-end. */
.lh-detail-loaderr { margin-top: 10px; padding: 9px 12px; border: 1px solid #e6cf9a; background: #faf3e3; border-radius: 8px; color: #8a5a00; font-size: 12.5px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.lh-detail-retry { border: 1px solid currentColor; background: transparent; color: inherit; border-radius: 6px; padding: 3px 12px; font-size: 12px; font-weight: 700; cursor: pointer; }

/* ── ff390: the Availability board (Leads Hub ▸ Availability) ──────────────
   One row per closer: state dot + name + region + live state, then the week's
   hours as quiet day chips. Same enterprise anatomy as the rest of the hub —
   pill chips, hairline borders, no color except the state dot. */
.lh-avb { display: flex; flex-direction: column; gap: 10px; }
/* ff391: filter bar — a segmented quick filter + even multi-select dropdowns +
   name search. Rebuilt from the ff390 wrapping-selects layout the owner flagged
   as uneven. Each row is full-width and even; nothing stretches oddly. */
.lh-avb-filters { display: flex; flex-direction: column; gap: 8px; margin-bottom: 2px; }
/* Row 1 — segmented quick filter (All / Available now / Availability set) */
.lh-avb-quick { display: flex; gap: 0; border: 1px solid var(--line, #e4e5e9); border-radius: 9px; overflow: hidden; background: #fff; }
.lh-avb-qbtn { flex: 1 1 0; min-width: 0; height: 38px; padding: 0 6px; border: 0; border-left: 1px solid var(--line, #e4e5e9); background: transparent; color: var(--ink-soft, #565a62); font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lh-avb-qbtn:first-child { border-left: 0; }
.lh-avb-qbtn.is-active { background: var(--ink, #141414); color: #fff; }
/* Row 2 — two EVEN multi-select buttons, styled to MATCH the segmented quick
   filter above (same shape/height/type; black fill when a filter is applied,
   exactly like the active quick segment). */
.lh-avb-selrow { display: flex; gap: 8px; }
.lh-avb-msbtn { flex: 1 1 0; min-width: 0; height: 38px; padding: 0 14px; display: inline-flex; align-items: center; justify-content: space-between; gap: 6px; border: 1px solid var(--line, #e4e5e9); border-radius: 9px; background: #fff; color: var(--ink-soft, #565a62); font-size: 12.5px; font-weight: 600; cursor: pointer; }
.lh-avb-msbtn:hover { color: var(--ink, #141414); }
.lh-avb-msbtn.is-active { background: var(--ink, #141414); border-color: var(--ink, #141414); color: #fff; }
.lh-avb-mscount { color: inherit; opacity: .8; font-weight: 700; font-variant-numeric: tabular-nums; }
.lh-avb-mschev { flex: 0 0 auto; color: currentColor; opacity: .7; transition: transform .15s var(--ease-soft, ease); }
.lh-avb-msbtn.is-open .lh-avb-mschev { transform: rotate(180deg); }
/* Inline checklist panel (no overlay). display lives on :not([hidden]) so the
   `hidden` attribute genuinely hides it — a base `display:flex` here overrides
   the UA [hidden] rule and leaves an empty bar (ff392 bug, caught 2026-07-06). */
.lh-avb-mspanel:not([hidden]) { display: flex; flex-direction: column; gap: 1px; }
.lh-avb-mspanel { border: 1px solid var(--line, #e4e5e9); border-radius: 8px; background: #fff; padding: 6px; max-height: 260px; overflow-y: auto; }
.lh-avb-msall { text-align: left; height: 34px; padding: 0 10px; border: 0; border-radius: 6px; background: transparent; color: var(--ink-soft, #565a62); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; cursor: pointer; }
.lh-avb-msall:hover { background: rgba(0,0,0,.03); }
.lh-avb-msopt { display: flex; align-items: center; gap: 10px; height: 40px; padding: 0 10px; border-radius: 6px; cursor: pointer; font-size: 13.5px; color: var(--ink, #141414); }
.lh-avb-msopt:hover { background: rgba(0,0,0,.03); }
.lh-avb-msopt input { width: 17px; height: 17px; flex: 0 0 auto; accent-color: var(--ink, #141414); }
/* Row 3 — search + clear */
.lh-avb-searchrow { display: flex; gap: 8px; align-items: center; }
.lh-avb-fsearch { flex: 1 1 auto; min-width: 0; height: 38px; }
.lh-avb-fclear { flex: 0 0 auto; height: 38px; padding: 0 14px; border: 1px solid var(--line, #e4e5e9); border-radius: 8px; background: #fff; color: var(--ink-soft, #565a62); font-size: 12.5px; font-weight: 600; cursor: pointer; }
.lh-avb-fclear:hover { background: rgba(0,0,0,.03); color: var(--ink, #141414); }
.lh-avb-list { display: flex; flex-direction: column; gap: 10px; }
.lh-avb-sum { font-size: 13px; color: var(--ink-soft, #565a62); padding: 2px 2px 0; }
.lh-avb-sum b { color: var(--ink, #141414); font-weight: 700; }
.lh-avb-gateoff { color: var(--ink-soft, #565a62); }
.lh-avb-empty { padding: 28px 12px; text-align: center; color: var(--ink-soft, #565a62); font-size: 13.5px; border: 1px dashed var(--line, #e4e5e9); border-radius: 10px; }
.lh-avb-row { border: 1px solid var(--line, #e3e5e9); border-radius: 10px; background: var(--card-bg, #fff); padding: 11px 14px 12px; }
.lh-avb-row.is-off, .lh-avb-row.is-away { opacity: .72; }
.lh-avb-head { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; min-height: 22px; }
.lh-avb-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; background: #b9bcc2; border: 1px solid rgba(0,0,0,.12); }
.lh-avb-row.is-now .lh-avb-dot { background: #1e8a4a; border-color: #1e8a4a; }
.lh-avb-row.is-away .lh-avb-dot { background: #b98a1e; border-color: #b98a1e; }
.lh-avb-row.is-notset .lh-avb-dot { background: #fff; }
.lh-avb-name { font-size: 14px; font-weight: 700; color: var(--ink, #141414); }
.lh-avb-div { font-size: 11.5px; color: var(--ink-soft, #565a62); }
.lh-avb-state { margin-left: auto; font-size: 11.5px; font-weight: 600; color: var(--ink-soft, #565a62); white-space: nowrap; }
.lh-avb-row.is-now .lh-avb-state { color: #1e8a4a; }
/* ff398: rows read as TWO quiet text lines (week sentence + meta) instead of a
   wall of day pills — the pill classes below stay for the free/busy expansion. */
.lh-avb-line { margin-top: 7px; font-size: 13.5px; color: var(--ink, #141414); font-variant-numeric: tabular-nums; line-height: 1.45; }
.lh-avb-line.is-muted { color: var(--ink-soft, #565a62); font-size: 12.5px; }
.lh-avb-sub { margin-top: 3px; font-size: 12px; color: var(--ink-soft, #565a62); font-variant-numeric: tabular-nums; }
.lh-avb-days { display: flex; flex-wrap: wrap; gap: 5px 6px; margin-top: 9px; }
.lh-avb-day { display: inline-flex; align-items: baseline; gap: 5px; padding: 2px 8px; border: 1px solid var(--line, #e4e5e9); border-radius: 999px; font-size: 11px; color: var(--ink, #141414); background: rgba(0,0,0,.02); white-space: nowrap; font-variant-numeric: tabular-nums; }
.lh-avb-day b { font-weight: 700; font-size: 10px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft, #565a62); }
.lh-avb-day.is-off { color: var(--ink-soft, #9a9da3); background: transparent; }
.lh-avb-day.is-note { color: var(--ink-soft, #565a62); background: transparent; border-style: dashed; }
.lh-avb-meta { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px; font-size: 11px; color: var(--ink-soft, #565a62); background: rgba(0,0,0,.055); border: 1px solid var(--line, #e4e5e9); white-space: nowrap; }

/* ff405 CLASS-SWEEP (the ff392 empty-bar disease, third sighting): every
   hidden-toggled element whose base rule sets display MUST carry its [hidden]
   counter-rule — the codebase convention (see styles.css ~739). This belt
   covers the intake mode groups + the two older latent cases found in the
   sweep (fu scope tabs never hid for plain reps; field rows). */
#lhModeAppt[hidden], #lhModeFu[hidden], .lh-fu-scope-tabs[hidden], .lh-field-row[hidden],
.lh-stand[hidden], .lh-cals-quick[hidden], .lh-avb-filters[hidden] { display: none !important; }

/* ff404: "Where does this stand?" — the intake's one question. Same segment
   anatomy as the board's quick filter (one control language portal-wide). */
.lh-stand { display: flex; gap: 0; border: 1px solid var(--line, #e4e5e9); border-radius: 9px; overflow: hidden; background: #fff; }
.lh-stand-btn { flex: 1 1 0; min-width: 0; height: 40px; padding: 0 6px; border: 0; border-left: 1px solid var(--line, #e4e5e9); background: transparent; color: var(--ink-soft, #565a62); font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lh-stand-btn:first-child { border-left: 0; }
.lh-stand-btn.is-active { background: var(--ink, #141414); color: #fff; }
#lhModeAppt, #lhModeFu { display: flex; flex-direction: column; gap: 14px; }

/* ff403: FREE/BUSY — scheduler busy washes (appointments the viewer can't
   open: another setter's lead) + the board's amber in-appt state. Non-
   interactive by design: the wash informs; the booking gate enforces. */
.lh-tl-busy { position: absolute; left: 4px; right: 4px; pointer-events: none; z-index: 2; border-radius: 6px; padding: 4px 7px; overflow: hidden; background: repeating-linear-gradient(-45deg, rgba(0,0,0,.05), rgba(0,0,0,.05) 5px, rgba(0,0,0,.09) 5px, rgba(0,0,0,.09) 10px); border: 1px dashed var(--line, #d6d8dd); color: var(--ink-soft, #565a62); display: flex; flex-direction: column; gap: 1px; font-size: 10.5px; }
.lh-tl-busy .lh-tl-appt-time { font-weight: 700; }
.lh-tl-busy .lh-tl-appt-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lh-avb-row.is-busy .lh-avb-dot { background: #b98a1e; border-color: #b98a1e; }
.lh-avb-row.is-busy .lh-avb-state { color: #8a5a00; }

/* ff402: Calendars-sheet quick-select — availability-based one-tap sets. */
.lh-cals-quick { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 8px 0 4px; }
.lh-cals-quicklbl { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft, #565a62); }
.lh-cals-qbtn { height: 30px; padding: 0 12px; border: 1px solid var(--line, #e4e5e9); border-radius: 999px; background: #fff; color: var(--ink, #141414); font-size: 12px; font-weight: 600; cursor: pointer; }
.lh-cals-qbtn:hover { border-color: var(--ink, #141414); }

/* ff401: composer announcements view — major dividers (Inbox / Sent by me /
   All announcements) sit above the TODAY/EARLIER date dividers in weight. */
.broadcasts-section-divider.bc-div-major { color: var(--ink, #141414); font-weight: 800; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; margin-top: 14px; }

/* ff390: DSP DISPATCH queue badge — a booked lead waiting on a closer (vendor
   or rep-routed). Black pill = it demands action; same weight system as chips. */
.lh-dq-badge { display: inline-flex; align-items: center; margin-left: 8px; padding: 1px 8px; border-radius: 999px; background: var(--ink, #141414); color: #fff; font-size: 10px; font-weight: 700; letter-spacing: .05em; white-space: nowrap; vertical-align: middle; }

/* ff389: optional date bounds (Available from / through) */
.lh-av-datecap { font-size: 12px; color: var(--ink-soft); margin-top: 4px; }
.lh-av-dates { margin-top: 16px; }
.lh-av-datesrow { display: flex; gap: 12px; align-items: flex-end; margin-top: 8px; }
.lh-av-datesrow .lh-avf { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.lh-av-datesrow .lh-avf > span { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.lh-av-datesrow input.lh-input { font-size: 16px; min-height: 44px; width: 100%; }
.lh-avdates-clear { flex: 0 0 auto; min-height: 44px; border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--ink-soft); font-size: 13px; font-weight: 600; padding: 0 14px; cursor: pointer; }
.lh-avdates-clear:hover { color: var(--ink); border-color: #16181d; }
.lh-av-dateshint { font-size: 12px; color: var(--ink-soft); line-height: 1.5; margin-top: 6px; }
@media (max-width: 640px) { .lh-av-datesrow { flex-wrap: wrap; } .lh-av-datesrow .lh-avf { flex: 1 1 44%; } }

/* ── Day-timeline off wash (setters/reps: a designed fact, not blank) ── */
.lh-tl-avoff { position: relative; display: flex; align-items: center; justify-content: center; overflow: hidden;
  background: repeating-linear-gradient(45deg, #f2f3f4 0, #f2f3f4 6px, #e9eaec 6px, #e9eaec 7px);
  border-bottom: 1px solid var(--line); }
.lh-tl-avoff .t { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #9a9ea6; background: rgba(255,255,255,.72); border-radius: 6px; padding: 2px 8px; white-space: nowrap; }
/* Admin: off slots stay tappable — greyed + dashed, the override affordance */
.lh-tl-slot.is-avoff { background: repeating-linear-gradient(45deg, #f5f6f7 0, #f5f6f7 6px, #ededf0 6px, #ededf0 7px) !important; border: 1px dashed #d3d5d9 !important; opacity: .8; }
.lh-tl-slot.is-avoff:hover { border-color: #16181d !important; opacity: 1; }
/* Booked history always renders ABOVE the wash */
.lh-tl-appt { z-index: 2; }
.lh-tl-now { z-index: 3; }
/* Column-head chip + Calendars-list badge */
.lh-tl-offchip, .lh-cals-offbadge { font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #9a9ea6; border: 1px solid var(--line); border-radius: 6px; padding: 1px 6px; margin-left: 6px; flex: 0 0 auto; }

/* ── Add-a-Lead advisory + override chip ── */
.lh-av-advice { font-size: 13px; color: #b42318; line-height: 1.5; margin: 8px 0 0; }
.lh-av-overridechip { font-size: 12px; font-weight: 600; color: #16181d; background: #f5f6f7; border: 1px solid var(--line); border-left: 3px solid #16181d; border-radius: 8px; padding: 8px 12px; margin: 0 0 12px; }

/* ── Internal Charge mode segment (rq form; owner 2026-07-08) ── */
.rq-icmode { display: flex; gap: 6px; }
.rq-icmode-btn { flex: 1; min-height: 40px; padding: 8px 10px; border: 1px solid var(--line); background: #fff; color: var(--ink); font-family: inherit; font-size: 13px; font-weight: 600; border-radius: 8px; cursor: pointer; }
.rq-icmode-btn.is-active { background: #000; color: #fff; border-color: #000; }
.rq-pickbtn.is-picked { font-weight: 700; }
