/* =====================================================================
 * Personal mode — visibility rules
 * ---------------------------------------------------------------------
 * All rules scoped to body.personal-mode so they're cleanly inert in
 * Dispatcher mode. No JS-level hiding — toggling the body class is the
 * single switch.
 *
 * What's hidden in Personal mode:
 *   - The left "ACTIVISTS" sidebar (.left-toolbar / .activists-panel)
 *   - All map markers EXCEPT the user's own and shift flags
 *     (volunteer-marker, home-dot-marker, animated-horse-marker for
 *     anyone other than the caller)
 *   - Any UI element opted-in via .dispatcher-only utility class
 *     (e.g. tasks panel, ideas panel, hidden-activists button)
 *
 * What stays visible:
 *   - The map (with shift flags + the user's own pin only)
 *   - Right "Today's Shifts" panel (with reduced info — handled in
 *     Phase 2 once we know which fields to strip per shift card)
 *   - The new "👤 Me" chip + 🪞/🛠️ toggle in the top-right tray
 *
 * The Me chip lives in the top-right-tools tray today and gets a
 * compact pill style so it visually reads as "user/account" rather
 * than another generic toggle.
 * ===================================================================== */

/* Hide the left activist sidebar entirely in Personal mode. The center
   map expands to fill the freed horizontal space — Leaflet honors the
   container resize on next render so we don't need to fire any JS.
   The actual element in this app's markup is .volunteer-panel
   (verified against index.html). The other selectors are kept as
   defensive aliases in case the markup gets renamed. */
body.personal-mode .volunteer-panel,
body.personal-mode #volunteer-panel,
body.personal-mode .left-toolbar,
body.personal-mode .activists-panel,
body.personal-mode .left-panel,
body.personal-mode #left-panel,
body.personal-mode #activists-panel,
body.personal-mode .activist-sidebar,
body.personal-mode #volunteer-list-panel {
  display: none !important;
}

/* Generic dispatcher-only escape hatch. Add this class to any element
   in markup to suppress it for Personal users without writing another
   selector — e.g. the inbox button, the Asana settings, etc. Phase 2
   may sprinkle this onto more buttons in the top-right tray. */
body.personal-mode .dispatcher-only {
  display: none !important;
}

/* Hide the existing dispatcher-only buttons in the top-right tray
   without needing to mark each one — same intent as .dispatcher-only
   but applied to known IDs so we don't have to edit index.html for
   Phase 1. The mode-toggle (#btn-personal-mode-toggle) and the Me
   chip (#top-me-chip) stay visible because they belong to Personal
   mode. Dark mode and sound buttons stay too — those are personal
   preferences, not dispatcher-specific tools. */
body.personal-mode #btn-hidden,
body.personal-mode #btn-ideas,
body.personal-mode #btn-tasks,
body.personal-mode #btn-twilio,
body.personal-mode #btn-voicemails,
body.personal-mode #btn-inbox,
body.personal-mode #btn-auto-menu,
body.personal-mode #btn-stats-menu,
body.personal-mode #btn-leaderboard-menu,
body.personal-mode #btn-workflow-menu,
body.personal-mode #btn-coalition {
  display: none !important;
}

/* Hide the per-shift ⭐ "prioritize this shift" star in personal
   mode. Per user request 2026-05-11: "Remove the star icon on
   shifts that lets users prioritize a shift if it's in personal
   mode." The star is a dispatcher-only triage tool (toggleStar
   in dispatch.js writes to the dispatcher's local storage so
   they can pin shifts to the top of their sort); activists in
   personal mode have a separate ⭐ Featured flag set by the
   organizer and don't need a per-shift priority toggle. */
body.personal-mode .shift-star {
  display: none !important;
}

/* Twilio SMS Settings is a Staff-only configuration tool.
   Organizers (level 4) dispatch shifts but don't need to fiddle with
   the underlying Twilio account credentials. Hide it for anyone
   except level-5 Staff. Per user request 2026-05-10: "organizers
   don't need to see the twilio button". Also hides the mobile
   drawer proxy in mobile.js (which carries data-source-id). */
/* Per user request 2026-05-12: "Make sure that organizers can also
   view and use the call features in the right toolbar. An organizer
   was saying they couldn't find it." The 📱 Twilio settings panel
   carries the forward-number field every dispatcher needs to place a
   call (and the Twilio account creds used for SMS / voicemail). It
   was staff-only — organizers (ladder level 4) couldn't see the
   button at all. Opened up to organizers too so they can configure
   their own forward number and run phone banks alongside staff. */
body:not(.role-staff):not(.role-organizer) #btn-twilio,
body:not(.role-staff):not(.role-organizer) .mobile-drawer-btn[data-source-id="btn-twilio"] {
  display: none !important;
}

/* Personal mode: title reads just "Stampede" (no "Dispatch" suffix).
   The suffix span is wrapped in .app-title-suffix in index.html for
   exactly this reason — Dispatcher mode keeps the full "Stampede
   Dispatch" branding, Personal mode is the activist-facing view. */
body.personal-mode .app-title-suffix {
  display: none !important;
}

/* Right-side "Today's Shifts" panel — kept VISIBLE in Personal mode
   (with self-only chip filter). Hide just the dispatcher-specific
   filter pills and bulk-action rows; the shift list itself stays.
   The 2026-05-10 simplification replaced the Mine/Hosting/Capacity
   multi-selects with plain <select>s — #shift-mine-filter-select
   ("Mine") stays visible since it's the obvious self-filter for an
   activist; hosting/capacity/sort/need-ward all hide. */
body.personal-mode .filter-row:has(#shift-host-filter-select),
body.personal-mode .filter-row:has(#shift-capacity-filter-select),
body.personal-mode .filter-row:has(#shift-sort-mode-select),
body.personal-mode .filter-row:has(#shift-need-ward),
body.personal-mode .bulk-actions-row {
  display: none !important;
}

/* The recommendation list lives on the LEFT side in Personal mode,
   where the activist sidebar (#volunteer-panel) used to be. Hidden in
   Dispatcher mode entirely. */
.personal-shift-recommendations { display: none; }
body.personal-mode .personal-shift-recommendations {
  /* Flex column placement (May 2026 layout reorg): the panel spans
     col 1, rows 1-2 of the body grid (.volunteer-panel is display:none
     in Personal mode so col 1 is free). Internal stacking is now flex
     column so the panel-static block at the top sizes to its own
     content — the top toolbar height is no longer locked to side-panel
     static heights and stays compact for more map space.
     overflow: visible — matches the dispatcher panels so the
     panel-collapse-btn at right:-18px (sticking into the map column)
     isn't clipped. The .panel-scroll inside owns its own scroll
     container. */
  display: flex;
  flex-direction: column;
  grid-column: 1;
  grid-row: 2;
  border-right: 1px solid #ccc;
  background: #fafafa;
  position: relative;
  overflow: visible;
  min-width: 0;
  min-height: 0;
}
body.personal-mode .personal-shift-recommendations .panel-static {
  /* Header + tabs stack vertically; auto-height block at the top. */
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  background: #fafafa;
  border-bottom: 1px solid var(--border);
  padding: 0;
}
body.personal-mode .personal-shift-recommendations .panel-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  /* Padding so the list cards don't touch the panel's right edge or
     the bottom toolbar. Without this the cards run flush to the
     panel border which looks cramped. */
  padding: 6px 8px 12px;
}
body.personal-mode .personal-shift-recommendations .reco-list {
  /* Cards stretch to fill the panel-scroll width (the parent now has
     padding so they have breathing room from the panel edges). */
  width: 100%;
}
body.personal-mode .personal-shift-recommendations .reco-card {
  width: 100%;
  box-sizing: border-box;
}
/* Collapsed state: panel shrinks to a thin sliver showing only the
   re-open button. Mirrors the right shift-panel's collapse UX. */
body.personal-mode .personal-shift-recommendations.collapsed {
  flex: 0 0 18px;
  width: 18px;
  overflow: hidden;
}
body.personal-mode .personal-shift-recommendations.collapsed .panel-header,
body.personal-mode .personal-shift-recommendations.collapsed .reco-tabs,
body.personal-mode .personal-shift-recommendations.collapsed .reco-list {
  display: none !important;
}
/* Thin button at the right edge of the panel — visible always so the
   user can re-open after hiding. Sits in the gutter when collapsed. */
.personal-shift-recommendations .panel-collapse-left.reco-collapse-btn {
  /* Mirrors the dispatcher panels' .panel-collapse-btn styling so all
     three collapse handles look identical: a thin white tab sticking
     out the panel's outer edge with a subtle drop shadow. The reco
     panel sits on the LEFT of the viewport so this handle extends
     RIGHTWARD into the map column (right: -18px) — same direction as
     the dispatcher Activists panel. */
  position: absolute;
  top: 0;
  right: -18px;
  z-index: 10;
  width: 18px;
  height: 100%;
  background: #fff;
  border: 1px solid #ddd;
  border-left: none;
  border-radius: 0;
  cursor: pointer;
  font-size: 10px;
  color: #666;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 2px 0 4px rgba(0,0,0,0.08);
  transition: background 0.15s;
}
.personal-shift-recommendations .panel-collapse-left.reco-collapse-btn:hover {
  background: #f0f0f0;
}
body.personal-mode .personal-shift-recommendations.collapsed .panel-collapse-left.reco-collapse-btn {
  border-left: none;
}
[data-theme="dark"] body.personal-mode .personal-shift-recommendations {
  background: var(--card-bg);
  border-right-color: var(--border);
}

/* Reco panel header now reuses the dispatcher panel-header structure
   (.panel-header / .panel-header-title / .header-tray) so the three
   side panels look identical. The .panel-header base rule in
   style.css already gives us flex layout, accent border, padding,
   uppercase title, and the white background. We just need to
   apply the LEFT-edge accent (style.css applies left-edge by
   default; the Shifts panel overrides to the right) and ensure the
   tray's nav-toggle buttons inherit the standard tile look. */
body.personal-mode .personal-shift-recommendations .panel-header {
  /* Default .panel-header already has border-left: 4px solid var(--primary).
     Reco panel sits on the LEFT of the viewport so left-accent is the
     correct outer-edge orientation — same as the Activists panel. No
     override needed here, but keep the rule slot so future tweaks
     have a clear home. */
}

/* Day / Week tabs — pill-shaped switch above the recommendation list.
   Active tab gets the primary green; inactive gets neutral gray. */
.personal-shift-recommendations .reco-tabs {
  display: flex;
  gap: 0;
  margin: 0 0 8px 0;
  padding: 0 4px;
}
.personal-shift-recommendations .reco-tab {
  flex: 1;
  background: #f5f5f5;
  border: 1px solid #999;
  font-size: 12px;
  font-weight: 600;
  padding: 6px 10px;
  cursor: pointer;
  border-radius: 0;
  color: #555;
}
.personal-shift-recommendations .reco-tab + .reco-tab { border-left: 0; }
.personal-shift-recommendations .reco-tab:hover { background: #e8e8e8; }
.personal-shift-recommendations .reco-tab.active {
  background: var(--primary, #5ae200);
  color: #fff;
  border-color: var(--primary-dark, #3c8f00);
}
[data-theme="dark"] .personal-shift-recommendations .reco-tab {
  background: var(--input-bg);
  color: var(--text);
  border-color: var(--border);
}
[data-theme="dark"] .personal-shift-recommendations .reco-tab.active {
  background: var(--primary, #5ae200);
  color: #000;
}

.reco-list { display: flex; flex-direction: column; gap: 8px; }
.reco-card {
  border: 1px solid #ccc;
  background: #fff;
  /* Type-coded LEFT-edge stripe — same Stampede swatches the
     dispatcher Shifts panel uses (driven by the --shift-stripe-color
     custom property set inline by personal-mode.js). Featured-card
     gold accent moved to a 2px inset shadow so the type stripe stays
     intact even for ⭐ Featured shifts. */
  border-left: 4px solid var(--shift-stripe-color, transparent);
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
}
.reco-card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}
.reco-card-name {
  font-weight: 700;
  flex: 1;
  line-height: 1.3;
}
.reco-card-score {
  font-weight: 700;
  font-size: 11px;
  color: #fff;
  background: var(--primary, #5ae200);
  padding: 2px 6px;
  border-radius: 0;
  flex-shrink: 0;
}
.reco-card-when { color: #555; font-size: 11.5px; }
.reco-addr { color: #777; font-size: 11px; }
.reco-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  font-size: 11px;
  color: #555;
}

/* "Why this shift?" reason badges row. Renders below the address
   and above the meta line. Each reason is a small pill with an icon
   (and optional count for things like "👯 2 friends going"). The
   tooltip on each badge spells out which reason fired. Scan the
   row to see at a glance: friends going (👯), hearted before (❤️),
   hosted before (👑), attended before (✅), near home (🏠), Stampede
   featured (⭐), needs more people (🆘). */
.reco-card-reasons {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 2px;
}
.reco-reason {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  background: #f8f8f8;
  border: 1px solid #d0d0d0;
  border-radius: 10px;
  padding: 1px 7px;
  font-size: 12px;
  line-height: 1.3;
  cursor: help;
  user-select: none;
}
.reco-reason-count {
  font-size: 10px;
  font-weight: 700;
  color: #555;
}
/* "🎩❓ No host yet" reason badge — distinct red/dashed treatment so
   it visually flags missing host coverage instead of blending in
   with the green-themed positive reasons (friends going / hearted /
   hosted before / etc.). Per user request 2026-05-10: "In the
   recommendations toolbar it should have an icon that represents
   that the shift is unhosted." */
.reco-reason.reco-reason-unhosted {
  background: #ffebee;
  border: 1px dashed #c62828;
  color: #c62828;
  font-weight: 600;
}
[data-theme="dark"] .reco-reason {
  background: var(--card-bg);
  border-color: var(--border);
  color: var(--text);
}
[data-theme="dark"] .reco-reason.reco-reason-unhosted {
  background: #4a1a1a;
  border-color: #ef5350;
  color: #ffcdd2;
}
[data-theme="dark"] .reco-reason-count {
  color: var(--text-light);
}
.reco-meta-item { white-space: nowrap; }
.reco-meta-item.reco-friends-label {
  background: #f3e5f5;
  color: #4a148c;
  border: 1px solid #ba68c8;
  padding: 1px 4px;
}
.reco-meta-item.reco-featured-label {
  background: #fff8e1;
  color: #6d4c00;
  border: 1px solid #ffb300;
  padding: 1px 4px;
  font-weight: 600;
}
/* Featured-shift cards get a subtle gold left border so the dispatcher's
   ⭐ priority pick stands out without overpowering the recommendation
   list. Pairs with the inline ⭐ Featured badge in the meta row. */
.reco-card.reco-card-featured {
  /* Don't touch border-left — that slot is owned by the Stampede-
     type stripe. Mark featured shifts with a soft gold inset glow
     instead. The ⭐ Featured badge in the reasons row also surfaces
     the flag for screen readers and explicit hover-tip readers. */
  box-shadow: inset 0 0 0 2px #ffb300;
}
.reco-rsvp-btn {
  display: inline-block;
  background: var(--primary, #5ae200);
  color: #fff !important;
  font-weight: 700;
  font-size: 11px;
  padding: 4px 8px;
  text-decoration: none !important;
  text-align: center;
  border: 1px solid var(--primary-dark, #3c8f00);
  margin-top: 4px;
  align-self: flex-start;
}
.reco-rsvp-btn:hover { background: #4ec500; }
.reco-empty {
  color: #888;
  font-size: 12px;
  font-style: italic;
  padding: 16px 8px;
  text-align: center;
}

/* Recommendation preferences modal — same backdrop/container pattern
   as the self-info modal for consistency. */
.reco-prefs-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  z-index: 4000;
  overflow-y: auto;
  padding: 40px 16px;
}
.reco-prefs-modal {
  background: #fff;
  border: 1px solid #999;
  box-shadow: 0 4px 22px rgba(0, 0, 0, 0.3);
  width: min(520px, 96vw);
  max-height: calc(100vh - 80px);
  display: flex;
  flex-direction: column;
}
.reco-prefs-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid #ddd;
}
.reco-prefs-modal-header h2 { font-size: 15px; font-weight: 700; margin: 0; }
.reco-prefs-close {
  background: none;
  border: none;
  font-size: 22px;
  cursor: pointer;
  color: #666;
}
.reco-prefs-modal-body { overflow-y: auto; padding: 14px 16px; }
.reco-prefs-help {
  font-size: 11.5px;
  color: #666;
  margin: 0 0 12px;
  line-height: 1.4;
}
.reco-pref-row { margin-bottom: 12px; }
.reco-pref-label-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 2px;
}
.reco-pref-label { flex: 1; font-weight: 600; font-size: 12px; }
.reco-pref-input {
  width: 70px;
  padding: 4px 6px;
  border: 1px solid #bbb;
  font-size: 13px;
  text-align: right;
  border-radius: 0;
}
.reco-pref-help { font-size: 11px; color: #777; line-height: 1.35; }
.reco-prefs-modal-actions {
  display: flex;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid #ddd;
  align-items: center;
}
.reco-prefs-modal-actions button {
  padding: 6px 14px;
  font-weight: 600;
  font-size: 12px;
  border: 1px solid #999;
  background: #f5f5f5;
  cursor: pointer;
  border-radius: 0;
}
.reco-prefs-modal-actions .reco-prefs-save {
  background: var(--primary, #5ae200);
  color: #fff;
  border-color: var(--primary-dark, #3c8f00);
}
.reco-prefs-modal-actions .reco-prefs-save:hover { background: #4ec500; }
.reco-prefs-modal-actions .reco-prefs-reset {
  background: #fff8e1;
  border-color: #c9a227;
  color: #5a4500;
  font-size: 11px;
}

[data-theme="dark"] .personal-shift-recommendations .panel-header-title { color: var(--text); }
[data-theme="dark"] .reco-card { background: var(--card-bg); border-color: var(--border); color: var(--text); }
[data-theme="dark"] .reco-card-when { color: var(--text-light); }
[data-theme="dark"] .reco-addr { color: var(--text-light); }
[data-theme="dark"] .reco-card-meta { color: var(--text-light); }
[data-theme="dark"] .reco-prefs-modal,
[data-theme="dark"] .reco-prefs-modal-header,
[data-theme="dark"] .reco-prefs-modal-actions { border-color: var(--border); }
[data-theme="dark"] .reco-prefs-modal { background: var(--card-bg); color: var(--text); }
[data-theme="dark"] .reco-prefs-input { background: var(--input-bg); color: var(--text); border-color: var(--border); }
[data-theme="dark"] .reco-prefs-modal-actions button { background: var(--input-bg); color: var(--text); border-color: var(--border); }

/* Phase 1: hide ALL activist-related map markers (horse pins, home
   dots, animated travel horses, dispatcher connection lines). This
   gives Personal mode the privacy guarantee — no info about other
   activists' homes is visible — even before the Phase 3 server-side
   filtering lands.
   Phase 2 will re-add the caller's own pin (just for self-orientation
   on the map). For now the user sees: basemap + shift flags + their
   own Me chip in the top toolbar. */
body.personal-mode .volunteer-marker,
body.personal-mode .home-dot-marker,
body.personal-mode .animated-horse-marker {
  display: none !important;
}

/* The dispatcher's drag-to-assign connection lines also leak info
   about other activists' homes (each line's origin is someone's
   address). Hidden in Personal mode along with the markers. */
body.personal-mode .leaflet-overlay-pane svg path.connection-line,
body.personal-mode .drag-line-glow {
  display: none !important;
}

/* ====================================================================
   Self-info modal (Phase 2) — opened by clicking the "👤 Me" chip.
   Layered over the page; backdrop dims the rest of the UI.
   Read-only Stampede rows render with subdued styling and a
   "from Stampede" badge so the activist can tell they're informational
   only. Editable rows get a normal text input with a yellow divergence
   warning when the input value differs from Stampede.
   ==================================================================== */
.self-info-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  z-index: 4000;
  overflow-y: auto;
  padding: 40px 16px;
}
.self-info-modal {
  background: #fff;
  border: 1px solid #999;
  box-shadow: 0 4px 22px rgba(0, 0, 0, 0.3);
  width: min(560px, 96vw);
  max-height: calc(100vh - 80px);
  display: flex;
  flex-direction: column;
  font-size: 13px;
  color: #222;
}

/* ───────────────────────────────────────────────────────────────
 * Bottom-of-map variant for the Activist Details modal.
 * ───────────────────────────────────────────────────────────────
 * Per user request 2026-05-25: "I would like the activist details
 * to also pop up like [the organizer recommendations one]."
 *
 * Mounted into .map-container (not document.body) so the panel
 * sits flush across the bottom of the map column. The map + the
 * shifts panel stay fully clickable behind it (pointer-events:
 * none on the backdrop, auto on the modal). The body uses a
 * responsive grid so the activist's sections flow into 2-3
 * columns instead of stacking vertically — fits comfortably in
 * the ~40vh budget so most of the map stays visible.
 *
 * Purple accent border distinguishes it from the SMS-family
 * bottom panels (blue) and RHC's Organizer Recs (green).
 * ─────────────────────────────────────────────────────────────── */
.self-info-modal-backdrop.self-info-modal-backdrop--bottom {
  position: absolute;
  inset: auto 8px 8px 8px;
  background: transparent;
  z-index: 650;
  padding: 0;
  overflow: visible;
  pointer-events: none;             /* map stays clickable behind */
  align-items: stretch;
}
.self-info-modal-backdrop--bottom .self-info-modal {
  width: 100%;
  max-width: none;
  max-height: 40vh;                 /* slightly taller than SMS modals — more content */
  min-height: 200px;
  pointer-events: auto;             /* the modal itself accepts clicks */
  border: 2px solid #6a1b9a;        /* purple accent */
  border-top: 4px solid #6a1b9a;
  border-radius: 8px;
  box-shadow: 0 -4px 24px rgba(0,0,0,0.3);
}
.self-info-modal-backdrop--bottom .self-info-modal-header {
  padding: 8px 14px;
}
.self-info-modal-backdrop--bottom .self-info-modal-header h2 {
  font-size: 14px;
}
.self-info-modal-backdrop--bottom .self-info-modal-body {
  /* Sections flow into as many 230px+ columns as fit horizontally.
     Result: 2-3 columns on a typical map width, 1 on a narrow column
     (auto-fit collapses to single column when there's no room). */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  column-gap: 14px;
  row-gap: 8px;
  align-content: start;
  padding: 10px 14px;
}
.self-info-modal-backdrop--bottom .self-info-section {
  margin: 0;                        /* override the 18px stacked margin */
}
.self-info-modal-backdrop--bottom .self-info-autosave-note {
  grid-column: 1 / -1;              /* the autosave note spans full width above sections */
  margin: 0 0 4px;
  font-size: 11px;
  color: #666;
}
.self-info-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid #ddd;
}
.self-info-modal-header h2 {
  font-size: 15px;
  font-weight: 700;
  margin: 0;
}
.self-info-close {
  background: none;
  border: none;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  color: #666;
  padding: 0 4px;
}
.self-info-close:hover { color: #000; }

.self-info-modal-body {
  overflow-y: auto;
  padding: 14px 16px;
}
.self-info-section { margin-bottom: 18px; }
.self-info-section:last-child { margin-bottom: 0; }
.self-info-section-title {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: #555;
  margin: 0 0 6px;
}
.self-info-section-help {
  font-size: 11.5px;
  color: #666;
  margin: 0 0 8px;
  line-height: 1.4;
}

/* Autosave reassurance shown at the very top of the modal body. Lets
   the activist know they don't need to hunt for a Save button — every
   field flushes to Firestore automatically (overrides debounced 600ms,
   prefs/notes/friends/emoji on change/blur). */
.self-info-autosave-note {
  font-size: 11px;
  color: #666;
  background: #f5f5f5;
  border-left: 3px solid var(--primary, #5ae200);
  padding: 6px 10px;
  margin: 0 0 14px;
  font-style: italic;
}
[data-theme="dark"] .self-info-autosave-note {
  background: var(--input-bg);
  color: var(--text-light);
}

/* Each editable row stacks label / input / warning vertically. */
.self-info-row { margin-bottom: 10px; }
.self-info-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  color: #555;
  margin-bottom: 3px;
}
.self-info-input {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid #bbb;
  font-size: 13px;
  font-family: inherit;
  border-radius: 0;
}
.self-info-input:focus {
  outline: 2px solid var(--primary, #5ae200);
  outline-offset: 0;
  border-color: var(--primary-dark, #3c8f00);
}
.self-info-divergence {
  margin-top: 4px;
  background: #fff8e1;
  border-left: 3px solid #c9a227;
  padding: 5px 8px;
  font-size: 11px;
  color: #5a4500;
  line-height: 1.4;
}
.self-info-divergence code {
  background: #fff3cd;
  padding: 0 3px;
  font-size: 11px;
}

/* Read-only rows (Account section): single-line, no input, with a small
   "from Stampede" tag aligned to the right. */
.self-info-row-readonly {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  border-bottom: 1px solid #f0f0f0;
  margin-bottom: 0;
}
.self-info-row-readonly:last-child { border-bottom: none; }
.self-info-row-readonly .self-info-label {
  flex: 0 0 70px;
  margin: 0;
}
.self-info-readonly-value {
  flex: 1;
  font-weight: 500;
  color: #222;
}
.self-info-readonly-source {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  color: #888;
  letter-spacing: 0.3px;
  background: #f5f5f5;
  padding: 2px 6px;
  border-radius: 0;
}

.self-info-notes {
  width: 100%;
  padding: 8px;
  border: 1px solid #bbb;
  font-size: 13px;
  font-family: inherit;
  resize: vertical;
  min-height: 70px;
  border-radius: 0;
}

.self-info-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid #ddd;
}
.self-info-modal-actions button {
  padding: 6px 14px;
  font-weight: 600;
  font-size: 12px;
  border: 1px solid #999;
  background: #f5f5f5;
  cursor: pointer;
  border-radius: 0;
}
.self-info-modal-actions button:hover { background: #e8e8e8; }
.self-info-modal-actions .self-info-save {
  background: var(--primary, #5ae200);
  color: #fff;
  border-color: var(--primary-dark, #3c8f00);
}
.self-info-modal-actions .self-info-save:hover { background: #4ec500; }
.self-info-modal-actions .self-info-save:disabled {
  background: #aaa;
  border-color: #888;
  cursor: not-allowed;
}
.self-info-save-error {
  flex: 1;
  text-align: right;
  color: #b71c1c;
  font-size: 11px;
  align-self: center;
  padding-right: 8px;
}

[data-theme="dark"] .self-info-modal {
  background: var(--card-bg);
  border-color: var(--border);
  color: var(--text);
}
[data-theme="dark"] .self-info-modal-header,
[data-theme="dark"] .self-info-modal-actions {
  border-color: var(--border);
}
[data-theme="dark"] .self-info-section-title,
[data-theme="dark"] .self-info-section-help,
[data-theme="dark"] .self-info-label,
[data-theme="dark"] .self-info-readonly-source {
  color: var(--text-light);
}
[data-theme="dark"] .self-info-row-readonly { border-bottom-color: var(--border); }
[data-theme="dark"] .self-info-readonly-value { color: var(--text); }
[data-theme="dark"] .self-info-readonly-source { background: var(--input-bg); }
[data-theme="dark"] .self-info-input,
[data-theme="dark"] .self-info-notes {
  background: var(--input-bg);
  color: var(--text);
  border-color: var(--border);
}
[data-theme="dark"] .self-info-modal-actions button {
  background: var(--input-bg);
  color: var(--text);
  border-color: var(--border);
}
[data-theme="dark"] .self-info-divergence {
  background: rgba(212, 179, 66, 0.12);
  border-left-color: #d4b342;
  color: #f5e7a8;
}
[data-theme="dark"] .self-info-divergence code {
  background: rgba(212, 179, 66, 0.22);
  color: #fff5cc;
}

/* Under-construction banner — pinned to the very top of the viewport
   above the existing header. Visible only in Personal mode. Color is
   the construction-site yellow/amber stripe pattern so it reads
   immediately as "active development, things may move." */
.personal-mode-construction-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 5500;
  background: repeating-linear-gradient(
    135deg,
    #ffeaa7,
    #ffeaa7 12px,
    #fdcb6e 12px,
    #fdcb6e 24px
  );
  color: #2d3436;
  border-bottom: 2px solid #c9a227;
  padding: 8px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12.5px;
  line-height: 1.4;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
}
.personal-mode-construction-banner .banner-icon {
  font-size: 18px;
  flex-shrink: 0;
}
.personal-mode-construction-banner .banner-text {
  flex: 1;
}
.personal-mode-construction-banner .banner-text strong {
  font-weight: 700;
}
.personal-mode-construction-banner .banner-dismiss {
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid rgba(0, 0, 0, 0.2);
  color: #2d3436;
  font-size: 18px;
  line-height: 1;
  padding: 0 8px;
  height: 24px;
  cursor: pointer;
  border-radius: 0;
  flex-shrink: 0;
}
.personal-mode-construction-banner .banner-dismiss:hover {
  background: rgba(255, 255, 255, 0.85);
}
[data-theme="dark"] .personal-mode-construction-banner {
  color: #2d3436;
}

/* Push the page content down so the banner doesn't overlap the header.
   Only applied in Personal mode — Dispatcher mode keeps the existing
   layout untouched. */
body.personal-mode {
  padding-top: 42px;
}

/* Note: the dispatcher tools tray (#top-right-tools) used to need a
   personal-mode `top: 50px` push because the construction banner
   covered its old top-right corner position. As of the May 2026
   layout reorg the tray is now position-fixed bottom-center stacked
   below the map toolbar — no banner overlap to fix anymore. Rule
   intentionally omitted. */

/* Top-LEFT tray holding the "Me" chip. Mirrors the position of the
   existing top-right-tools tray on the opposite side. Visible only
   in Personal mode (Dispatcher mode hides it via .top-left-me-tray
   default display:none below). */
/* The Me-chip tray was previously fixed top-left, but post the May
   2026 layout reorg the recommendations panel occupies that exact
   spot. Personal-mode.js now appends the tray INSIDE the
   recommendations panel's .panel-static section after the tabs, so
   it sits in the user's identity area rather than overlapping
   anything. Default tray styling becomes static (in-flow) below. */
.top-left-me-tray {
  display: none;
  padding: 4px 8px;
  background: #f0f0f0;
  border-top: 1px solid var(--border, #d5d5d5);
}
body.personal-mode .top-left-me-tray {
  display: block;
}

/* "🛠️ Switch to Dispatcher mode" button — lives in the existing
   top-right icon tray alongside 🔔 Notifications and ⚙️ Settings.
   Per user request 2026-05-25: "It should be with the other icons
   (notifications + settings)." Blue accent so it visually reads as
   a primary mode-switch action distinct from the neutral utility
   icons in the same tray. Visibility gated by both:
   1. body.personal-mode (CSS hides in dispatcher mode)
   2. canUseDispatcherMode() in updateToggleButton (display:none for
      ladder 0-3 accounts that can't access dispatcher). */
.top-right-mode-toggle {
  background: #1a73e8;
  color: #fff;
  border: 1px solid #1a5fb8 !important;
}
.top-right-mode-toggle:hover {
  background: #1565c0;
}
body:not(.personal-mode) .top-right-mode-toggle {
  display: none;
}
/* The reco panel is the full sidebar width on desktop (--sidebar-width:
   280px). The Me chip should expand to fill it horizontally so the
   activist sees the same "card-shaped" identity layout that
   dispatcher activist chips use in the sidebar — not a narrow pill
   sitting awkwardly in the corner. */
body.personal-mode #personal-shift-recommendations .top-left-me-tray {
  padding: 6px 10px 8px;
}

/* The Me chip itself — styled to mirror a collapsed dispatcher sidebar
   card: emoji on the left, name (and small badges) on the right,
   green-tinted background to signify "this is me" identity. Compact
   to fit in the header without dominating. */
.personal-me-chip {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 3px;
  /* Solid brand-green background (2026-05-10 user request — "the
     'Me' chip in personal mode should be a solid color"). The
     previous pastel #e8f5d0 read as washed-out against the white
     reco panel; a saturated #5AE200 gives the activist's own
     identity card the same visual weight as the Stampede primary
     accent, with dark text for legibility. */
  background: var(--primary, #5AE200);
  border: 1px solid var(--primary-dark, #3c8f00);
  border-radius: 0;
  padding: 6px 10px;
  font-family: inherit;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
  font-size: 12px;
  text-align: left;
  color: #1a3a00;
  min-height: 32px;
  /* Expand to fill the reco panel width — the chip is the activist's
     own identity card, so it should match the visual weight of the
     recommendation cards stacked below it. */
  width: 100%;
  box-sizing: border-box;
}
.personal-me-chip:hover {
  background: var(--primary-dark, #3c8f00);
  color: #fff;
}
.personal-me-chip .me-chip-top {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
/* Row 1 alert badges (trained, ladder, notebook, BOE, tags, friends)
   sit inline with the name on the right side. Wraps gracefully if
   the chip is narrow. May 2026: was previously a separate
   .me-chip-row-alerts div making the chip 4 rows; merged into row 1
   so the chip is exactly 3 rows: identity / weekly / all-time. */
.personal-me-chip .me-chip-name-alerts {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 3px;
  margin-left: auto;
}
.personal-me-chip .me-chip-emoji {
  font-size: 18px;
  line-height: 1;
}
.personal-me-chip .me-chip-name {
  font-weight: 700;
  font-size: 13px;
  line-height: 1.1;
  color: #1a1a1a;
}
/* Three optional badge rows mirroring the dispatcher's collapsed
   sidebar card: alerts, this-week activity (📅), all-time (🕰️). Each
   row only renders when it has badges so the chip stays compact for
   newer activists with no history. */
.personal-me-chip .me-chip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 3px;
  padding-left: 0;
}
.personal-me-chip .me-chip-row-label {
  font-size: 10px;
  opacity: 0.6;
  margin-right: 2px;
  user-select: none;
}
.personal-me-chip .me-chip-badge {
  font-size: 10px;
  padding: 1px 5px;
  font-weight: 600;
  border-radius: 0;
  border: 1px solid;
  line-height: 1.4;
  white-space: nowrap;
}
.personal-me-chip .me-chip-badge-trained {
  background: #c8e6c9;
  color: #1b5e20;
  border-color: #4caf50;
}
.personal-me-chip .me-chip-badge-ladder {
  background: #fff;
  color: #2d7a00;
  border-color: var(--primary-dark, #3c8f00);
}
.personal-me-chip .me-chip-badge-notebook,
.personal-me-chip .me-chip-badge-boe,
.personal-me-chip .me-chip-badge-friends {
  background: #fff;
  color: #333;
  border-color: #aaa;
}
/* Weekly badges — match the dispatcher chip palette so a 👑5 in the Me
   chip looks the same as a 👑5 in a shift chip. */
.personal-me-chip .me-week-host {
  background: #fff8e1;
  border-color: #ffb300;
  color: #6d4c00;
}
.personal-me-chip .me-week-attend {
  background: #c8e6c9;
  border-color: #4caf50;
  color: #1b5e20;
}
.personal-me-chip .me-week-tent,
.personal-me-chip .me-week-tentative {
  background: #fff8e1;
  border-color: #c9a227;
  color: #5a4500;
}
.personal-me-chip .me-week-asked {
  background: #fff9c4;
  border-color: #FFEB00;
  color: #6d4c00;
}
.personal-me-chip .me-week-msg {
  background: #e3f2fd;
  border-color: #42a5f5;
  color: #0d47a1;
}
.personal-me-chip .me-week-ghost {
  background: #eceff1;
  border-color: #90a4ae;
  color: #37474f;
}
.personal-me-chip .me-week-decline {
  background: #ffe0b2;
  border-color: #FF8E00;
  color: #6d3c00;
}
.personal-me-chip .me-week-noshow {
  background: #e3f2fd;
  border-color: #42a5f5;
  color: #0d47a1;
}
/* Lifetime badges — slightly muted vs weekly. */
.personal-me-chip .me-life-host {
  background: #fff8e1;
  border-color: #ffb300;
  color: #6d4c00;
  opacity: 0.9;
}
.personal-me-chip .me-life-attend {
  background: #c8e6c9;
  border-color: #4caf50;
  color: #1b5e20;
  opacity: 0.9;
}
.personal-me-chip .me-life-noshow {
  background: #e3f2fd;
  border-color: #42a5f5;
  color: #0d47a1;
  opacity: 0.9;
}
.personal-me-chip .me-chip-tagwrap {
  display: inline-flex;
  gap: 3px;
}
[data-theme="dark"] .personal-me-chip {
  background: rgba(90, 226, 0, 0.18);
  border-color: var(--primary, #5ae200);
  color: #c0f59f;
}
[data-theme="dark"] .personal-me-chip .me-chip-name { color: #fff; }

/* Cleanup — these dispatcher-only toolbar items aren't useful in
   Personal mode. Hidden via id selectors so we don't have to mark
   each in markup. The same applies to dispatcher-style tentative
   sections inside shift cards (the right panel) that reveal who
   else is on a shift; Personal mode shows just the user's own RSVP
   status, not who their teammates are. */
body.personal-mode #btn-box-select,
body.personal-mode #btn-coalition,
body.personal-mode #auto-menu-wrap,
body.personal-mode #workflow-menu-wrap,
body.personal-mode #stats-menu-wrap,
body.personal-mode #find-host-toolbar-pill,
body.personal-mode #btn-toggle-coalition {
  /* Kept visible:
     - #btn-toggle-districts (ward map) — explicitly requested back
     - .lines-menu-wrap (📏 connection lines) — useful in Personal mode
       for the user to see their own connection lines to shifts they're
       going to
     - #btn-toggle-faded-shifts (📅 faded shifts) — also useful in
       Personal mode for context on cross-day shifts
     - .map-search-box (🔍 Search any location) — activists also need
       to look up addresses (their home, the metro stop nearest a
       shift, etc.); kept available in Personal mode (used to be
       hidden here, restored 2026-05-09 per user request).
     The associated district-picker selects are hidden by default via
     inline style, only shown by toggleDistricts() — no rule needed. */
  display: none !important;
}

/* Right shift panel (#shift-list) is RESTORED in Personal mode. The
   activist sees the same per-shift cards a dispatcher would — minus
   tentative host candidates and minus other activists' chips. Only
   the user's OWN chip on each shift is visible, so they can see "I'm
   tentative for this," "I'm confirmed for that," etc.
   The non-self-chip hide is done at JS time via a dynamic <style>
   injection keyed to the user's UID (see personal-mode.js's
   _applySelfOnlyChipFilter). */

/* Hide the pencil ✏️ "custom message" button on shift cards in
   personal mode. Activists don't compose dispatch templates — that's
   a dispatcher tool. Per user request 2026-05-12: "in personal mode,
   remove the pencil icon that lets users write a customized message.
   It's not necessary for this mode." */
body.personal-mode .custom-msg-btn {
  display: none !important;
}

/* Make it obvious where to click to expand a shift card in personal
   mode — cursor + subtle hover lift. The "▾ Tap to expand" hint at
   the bottom of .shift-card-info lives in style.css so it inherits
   the existing personal-mode + demo-new-layout positioning. */
body.personal-mode .shift-card {
  cursor: pointer;
  transition: box-shadow 0.15s ease-out, transform 0.15s ease-out;
}
body.personal-mode .shift-card:hover {
  box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  transform: translateY(-1px);
}

/* Hide the all-time activity row + weekly activity row on chips in
   personal mode. Per user request 2026-05-12: "please remove the
   activist data that shows their all-time attended and host history.
   That takes up too much space on the activist chip for Personal mode" */
body.personal-mode .chip-alltime-row,
body.personal-mode .chip-weekly-row {
  display: none !important;
}

/* Hide ward-signature heat maps in personal mode for activists below
   ladder level 4 (organizer / staff). Per user request 2026-05-12:
   "for personal mode, can you make it so that the heat maps are not
   displayed for anyone who is under ladder status level 4?" The
   role-staff (level 5) and role-organizer (level 4) body classes
   are set by app.js based on the signed-in user's ladderStatus.
   Anyone else — pending / prospect / recruit / member — gets the
   heat map hidden because it's only meaningful for organizers
   evaluating ward signature collection performance. */
body.personal-mode:not(.role-staff):not(.role-organizer) .shift-ward-history {
  display: none !important;
}

/* Hide the "why is this shift recommended for you" badge row inside
   shift cards in personal mode, and use the freed vertical space to
   bump the shift name + hours + address font sizes so they're easier
   to read on the small bottom-toolbar cards. Per user request
   2026-05-12: "for personal mode, when it shows the recommendations
   for shifts with badges for why they are being recommended for those
   shifts, can you actually completely take those away and use the
   extra space to increase the font size of each shift so that the
   viewer can read it more easily?" */
body.personal-mode .shift-card .shift-card-reasons-wrap,
body.personal-mode .shift-card .reco-card-reasons {
  display: none !important;
}
body.personal-mode .shift-card .shift-title {
  font-size: 15px !important;
  line-height: 1.25 !important;
}
body.personal-mode .shift-card .shift-hours {
  font-size: 14px !important;
}
body.personal-mode .shift-card .shift-address,
body.personal-mode .shift-card .shift-address a {
  font-size: 13px !important;
}

/* "No shifts on this date" message — when the shift panel is the
   bottom horizontal toolbar (demo-new-layout) the default 40px
   vertical padding on .no-shifts pushes the panel content past the
   bottom of the screen. Per user request 2026-05-12: "bottom toolbar
   for personal mode. The no-shifts on this date extend past the
   bottom of the screen. Can you make it run horizontally?" Switch
   the empty-state div to a single-line horizontal banner that
   spans the full width of the bottom toolbar so it sits in-row with
   the shift cards' would-be position instead of stacking vertically.
   Also bump the scoped variant for personal-mode (right-side panel)
   so the empty state stays compact and doesn't dominate the strip. */
body.personal-mode #shift-list .no-shifts,
body.personal-mode.demo-new-layout #shift-list .no-shifts {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  flex: 1 1 100%;
  width: 100%;
  min-width: 100%;
  height: 100%;
  padding: 8px 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
  font-style: italic;
  color: #999;
  box-sizing: border-box;
}

/* Tentative-host candidate section never appears in Personal mode —
   that exposes who the dispatcher is shopping the host slot to. */
body.personal-mode .tentative-hosts-section,
body.personal-mode .host-placeholder,
body.personal-mode .vol-label .bulk-sms-btn,
body.personal-mode .bulk-sms-btn,
body.personal-mode .tentative-toggle {
  display: none !important;
}

/* Drop zones still trigger drag-drop when present, even invisibly,
   which would let an activist accidentally re-trigger drag flows.
   Keep the zone container so the host chip can render inside it,
   but disable pointer events on the drag zones so no drops register. */
body.personal-mode .shift-drop-zone,
body.personal-mode .host-drop-zone {
  pointer-events: none;
}
body.personal-mode .shift-drop-zone .assigned-chip,
body.personal-mode .host-drop-zone .assigned-chip {
  pointer-events: auto; /* still let the user click their own chip */
}

/* Replace the dispatcher's "Activists [Message All] [Clear Tentative]"
   row label with a clean "Your status" label so the section heading
   makes sense when only the user's own chip is shown. */
body.personal-mode .vol-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: #888;
  font-weight: 700;
}

/* Box-select rectangle (the green dashed marquee) and its popup never
   appear in Personal mode — the box-select tool is hidden so they
   shouldn't be triggerable, but defensive hide just in case. */
body.personal-mode #box-select-rect,
body.personal-mode #box-select-popup {
  display: none !important;
}

/* Per-shift Stampede deep link in the right toolbar swaps its text
   between modes. Dispatcher mode shows "View on Stampede →" (the
   default rule in style.css). Personal mode swaps to "RSVP on Stampede
   →" because that's the relevant call to action for an activist. */
body.personal-mode .shift-stampede-label-dispatcher { display: none; }
body.personal-mode .shift-stampede-label-personal { display: inline; }

/* ===================================================================
 * Dispatcher Quick Actions section inside the universal activist modal
 * (only rendered when !isSelf — i.e., dispatcher viewing another
 * activist). Mirrors the buttons that previously lived in the sidebar
 * chip's expand-on-click section.
 * ================================================================== */
.self-info-dispatcher-actions {
  background: #f7faff;
  border: 1px solid #d6e3f7;
  padding: 10px 12px;
  border-radius: 4px;
}
.self-info-action-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 6px;
}
.self-info-action-btn {
  border: 1px solid #c2c8d0;
  background: #fff;
  color: #222;
  font-size: 12px;
  padding: 5px 10px;
  border-radius: 3px;
  cursor: pointer;
  font-family: inherit;
  line-height: 1.2;
}
.self-info-action-btn:hover {
  background: #eef4ff;
  border-color: #6a93d4;
}
.self-info-action-btn.self-info-action-warn {
  background: #fff3e0;
  border-color: #ffb74d;
  color: #6d4500;
}
.self-info-action-btn.self-info-action-warn:hover {
  background: #ffe0b2;
}
.self-info-action-btn.self-info-action-danger {
  background: #ffebee;
  border-color: #ef9a9a;
  color: #8b1f1f;
}
.self-info-action-btn.self-info-action-danger:hover {
  background: #ffcdd2;
}
.self-info-boe-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  margin-top: 4px;
  cursor: pointer;
  user-select: none;
}
.self-info-boe-toggle input { margin: 0; cursor: pointer; }
.self-info-phone-display {
  font-size: 11.5px;
  color: #555;
  margin-top: 6px;
  font-family: 'SFMono-Regular', Consolas, monospace;
}
.self-info-phone-display.self-info-no-phone {
  font-style: italic;
  color: #888;
  font-family: inherit;
}

/* Stampede notes shown read-only above the editable note when a
   dispatcher views another activist. Lets dispatchers see the notes
   that came from the activist's Stampede profile without conflating
   them with their own dispatcher note. */
.self-info-stampede-notes {
  font-size: 11.5px;
  color: #444;
  background: #f5f5f5;
  border-left: 3px solid #999;
  padding: 6px 10px;
  margin-bottom: 8px;
  line-height: 1.45;
}
.self-info-stampede-notes em {
  color: #666;
  font-weight: 600;
  font-style: normal;
  margin-right: 4px;
}

[data-theme="dark"] .self-info-dispatcher-actions {
  background: var(--input-bg);
  border-color: var(--border-color);
}
[data-theme="dark"] .self-info-action-btn {
  background: var(--input-bg);
  color: var(--text-color);
  border-color: var(--border-color);
}
[data-theme="dark"] .self-info-action-btn:hover { background: var(--hover-bg); }
[data-theme="dark"] .self-info-stampede-notes {
  background: var(--input-bg);
  color: var(--text-color);
}
