/* ═══════════════════════════════════════════════════════════
   CRM Design System · Light Theme
   Navy #0D2447  ·  Teal #00C5A8  ·  Outfit + Instrument Serif
   ═══════════════════════════════════════════════════════════ */

:root {
  /* ── Brand Palette ── */
  --crm-navy:        #0D2447;
  --crm-navy-dark:   #091A36;
  --crm-navy-700:    #162F5A;
  --crm-navy-600:    #1E3D70;
  --crm-navy-400:    #3A5A96;
  --crm-teal:        #00C5A8;
  --crm-teal-600:    #009E88;
  --crm-teal-50:     rgba(0, 197, 168, 0.08);
  --crm-teal-glow:   rgba(0, 197, 168, 0.18);

  /* ── Raw RGB (for rgba() in glass effects — updated by branding.js) ── */
  --crm-navy-rgb:    13, 36, 71;
  --crm-teal-rgb:    0, 197, 168;

  /* ── Glass ── */
  --crm-glass-bg:     rgba(255, 255, 255, 0.06);
  --crm-glass-border: rgba(255, 255, 255, 0.12);
  --crm-glass-blur:   24px;

  /* ── Surfaces ── */
  --crm-bg:          #F2F6FC;
  --crm-white:       #ffffff;
  --crm-surface-2:   #E6EEF8;

  /* ── Text ── */
  --crm-text:        #0D2447;
  --crm-text-2:      #4A5B78;
  --crm-text-3:      #8A9BB5;

  /* ── Borders ── */
  --crm-border:      #DCE5F0;
  --crm-border-2:    #C5D3E8;

  /* ── Shadows ── */
  --crm-shadow-xs:   0 1px 3px rgba(13,36,71,0.05);
  --crm-shadow-sm:   0 2px 8px rgba(13,36,71,0.07), 0 1px 2px rgba(13,36,71,0.04);
  --crm-shadow:      0 4px 16px rgba(13,36,71,0.09), 0 2px 4px rgba(13,36,71,0.05);
  --crm-shadow-lg:   0 8px 32px rgba(13,36,71,0.13), 0 4px 8px rgba(13,36,71,0.06);
  --crm-shadow-lift: 0 20px 48px rgba(13,36,71,0.17), 0 8px 16px rgba(13,36,71,0.08);

  /* ── Shape ── */
  --crm-r-sm:  6px;
  --crm-r:     10px;
  --crm-r-lg:  16px;
  --crm-r-xl:  20px;

  /* ── Motion ── */
  --crm-ease:  cubic-bezier(0.16, 1, 0.3, 1);
  --crm-fast:  0.15s;
  --crm-mid:   0.25s;
  --crm-slow:  0.38s;
}

/* ─────────────────────────────────────────────────────────
   Base
   ───────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  font-family: 'Outfit', system-ui, -apple-system, sans-serif;
  font-size: 15px;
  color: var(--crm-text);
  background: var(--crm-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ─────────────────────────────────────────────────────────
   Typography
   ───────────────────────────────────────────────────────── */

h1, .h1 {
  font-family: 'Instrument Serif', Georgia, serif;
  font-size: 1.85rem;
  font-weight: 400;
  color: var(--crm-navy);
  letter-spacing: -0.015em;
  line-height: 1.15;
}

h2, .h2 {
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--crm-navy);
  letter-spacing: -0.01em;
}

h3, h4, h5, h6 {
  font-weight: 600;
  color: var(--crm-navy);
}

/* ─────────────────────────────────────────────────────────
   Links
   ───────────────────────────────────────────────────────── */

a, .btn-link {
  color: var(--crm-navy-600);
  text-decoration: none;
  transition: color var(--crm-fast) ease;
}

a:hover, .btn-link:hover {
  color: var(--crm-teal-600);
  text-decoration: none;
}

/* ─────────────────────────────────────────────────────────
   Buttons
   ───────────────────────────────────────────────────────── */

.btn {
  font-family: 'Outfit', sans-serif;
  font-weight: 500;
  font-size: 0.875rem;
  letter-spacing: 0.01em;
  border-radius: var(--crm-r-sm);
  transition: transform var(--crm-mid) var(--crm-ease),
              box-shadow var(--crm-mid) var(--crm-ease),
              background-color var(--crm-fast) ease,
              border-color var(--crm-fast) ease,
              color var(--crm-fast) ease;
  position: relative;
  overflow: hidden;
}

/* Shimmer fill layer */
.btn::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 45%, rgba(255,255,255,0.14) 100%);
  opacity: 0;
  transition: opacity var(--crm-mid) ease;
  pointer-events: none;
}

.btn:hover::after { opacity: 1; }

.btn-primary {
  background: var(--crm-navy) !important;
  border-color: var(--crm-navy) !important;
  color: #fff !important;
}
.btn-primary:hover {
  background: var(--crm-navy-600) !important;
  border-color: var(--crm-navy-600) !important;
  box-shadow: var(--crm-shadow-sm) !important;
  transform: translateY(-1px);
}
.btn-primary:active { transform: translateY(0) !important; }

/* Opt-in white plate behind a brand logo on dark surfaces (admin "Logo backdrop" toggle).
   Global so it applies inside scoped components (sign-in, survey, public header, top bars). */
.logo-plate { background: #fff; border-radius: 8px; padding: 4px; }

/* FocusOnNavigate (App.razor) moves focus to each page's <h1> so screen readers announce the new
   page. The heading isn't interactive, so it shouldn't paint a focus box across the page — the same
   rule Blazor's own template ships. */
h1:focus { outline: none; }

/* ── Portal page shell (member + vendor) ──────────────────────────────────────
   Global, and it has to be. MemberLayout and VendorLayout each render this markup
   themselves, so each gets its OWN scoped-CSS attribute — rules living in
   MemberLayout.razor.css match only MemberLayout's copy and silently do nothing for
   the vendor's. These lived there until now, which is why every vendor portal page
   rendered with no background, no max-width and no padding.

   Same trap PortalTopBar.razor.css documents at the top of the file: shared markup
   needs either a shared component or global styles, never another layout's scope. */
.member-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: #f4f6fb;
    color: #1c2334;
}

.member-main {
    flex: 1 1 auto;
    padding: 2.5rem 1.5rem 4rem;
}

.member-container {
    max-width: 1100px;
    margin: 0 auto;
}

/* The directory is the one portal page that is a working surface rather than a reading
   one — a table of every member organization needs the room, and its cards pack more
   columns into it. Widened here rather than for every page so the prose ones keep a
   comfortable measure. The top bar runs to 1380 to match.

   Keyed on .md-page, which PortalDirectory renders unconditionally — keying it on the
   toolbar instead would leave the page 1100 wide until the fetch resolved, then jump. */
.member-container:has(.md-page) {
    max-width: 1380px;
}

@media (max-width: 720px) {
    .member-main {
        padding: 1.5rem 1rem 3rem;
    }
}

/* The member home runs edge to edge: its hero is a full-width brand band under the bar, and it
   lays out its own 1280 wrap below. Keyed on .mh-page, which MemberHome renders in every state. */
.member-main:has(.mh-page) { padding: 0; }
.member-container:has(.mh-page) { max-width: none; }

/* So does an event's page (EventLanding), whose hero is the same band. .evt-page renders while
   loading too, so the page doesn't jump from boxed to full width when the event arrives. */
.member-main:has(.evt-page) { padding: 0; }
.member-container:has(.evt-page) { max-width: none; }
/* The home's .mh-wrap. Sides only: a .reg-shell is often also the .reg-body, whose top and bottom
   padding a shorthand here would wipe. */
.member-main .evt-page .reg-shell { max-width: 1280px; padding-left: 2rem; padding-right: 2rem; }
@media (max-width: 720px) { .member-main .evt-page .reg-shell { padding-left: 1rem; padding-right: 1rem; } }

.btn-outline-primary {
  border-color: var(--crm-navy) !important;
  color: var(--crm-navy) !important;
  background: transparent !important;
}
.btn-outline-primary:hover {
  background: var(--crm-navy) !important;
  color: #fff !important;
  transform: translateY(-1px);
  box-shadow: var(--crm-shadow-sm) !important;
}

.btn-outline-secondary {
  border-color: var(--crm-border-2) !important;
  color: var(--crm-text-2) !important;
  background: var(--crm-white) !important;
}
.btn-outline-secondary:hover {
  border-color: var(--crm-navy) !important;
  color: var(--crm-navy) !important;
  background: var(--crm-surface-2) !important;
  transform: translateY(-1px);
}

/* A segmented toggle (a radio .btn-check followed by its label button). The !important rules above
   outrank Bootstrap's checked styles, so the picked option looked like every other one. */
.btn-check:checked + .btn-outline-primary,
.btn-check:checked + .btn-outline-secondary {
  background: var(--crm-navy) !important;
  border-color: var(--crm-navy) !important;
  color: #fff !important;
}
.btn-check:focus-visible + .btn {
  box-shadow: 0 0 0 3px var(--crm-teal-glow) !important;
}

.btn-sm { padding: 0.3rem 0.75rem; font-size: 0.8rem; }

.btn:focus, .btn:active:focus,
.btn-link.nav-link:focus,
.form-control:focus,
.form-check-input:focus {
  box-shadow: 0 0 0 3px var(--crm-teal-glow) !important;
  outline: none;
}

/* ─────────────────────────────────────────────────────────
   Forms
   ───────────────────────────────────────────────────────── */

.form-control, .form-select {
  font-family: 'Outfit', sans-serif;
  font-size: 0.9rem;
  border: 1px solid var(--crm-border-2);
  border-radius: var(--crm-r-sm);
  color: var(--crm-text);
  background-color: var(--crm-white);
  transition: border-color var(--crm-fast) ease, box-shadow var(--crm-fast) ease;
  padding: 0.5rem 0.875rem;
}

/* A select draws its chevron as a background image at the right edge, and Bootstrap reserves room
   for it with padding-right: 2.25rem. The shorthand above replaces all four sides, so text was
   allowed to run under the chevron on every select in the app — visible wherever a select has no
   slack, which is any select sized to its content. Restore the gutter, RTL included. */
.form-select {
  padding-right: 2.25rem;
  padding-left: 0.875rem;
}
.form-select-sm { padding-right: 2rem; }
[dir="rtl"] .form-select { padding-right: 0.875rem; padding-left: 2.25rem; }
[dir="rtl"] .form-select-sm { padding-left: 2rem; }

.form-control:focus, .form-select:focus {
  border-color: var(--crm-teal);
  box-shadow: 0 0 0 3px var(--crm-teal-glow);
  outline: none;
}

.form-label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--crm-text-2);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 0.35rem;
}

.form-check-input:checked {
  background-color: var(--crm-teal);
  border-color: var(--crm-teal);
}

/* ─────────────────────────────────────────────────────────
   Cards
   ───────────────────────────────────────────────────────── */

.card {
  border: 1px solid var(--crm-border) !important;
  border-radius: var(--crm-r) !important;
  box-shadow: var(--crm-shadow-sm);
  background: var(--crm-white);
  transition: box-shadow var(--crm-mid) var(--crm-ease), border-color var(--crm-mid) var(--crm-ease);
}

/* Cards are containers, so they sit still. Only a card that navigates somewhere (.card-link)
   answers the pointer, and with a deeper shadow and border rather than movement. */
.card.card-link { cursor: pointer; }
.card.card-link:hover {
  box-shadow: var(--crm-shadow);
  border-color: var(--crm-navy) !important;
}

/* Nested cards (e.g. list items) carry no shadow of their own */
.card .card { box-shadow: none; }

.card-header {
  background: var(--crm-bg) !important;
  border-bottom: 1px solid var(--crm-border) !important;
  border-left: 3px solid var(--crm-teal);
  border-radius: var(--crm-r) var(--crm-r) 0 0 !important;
  padding: 0.6rem 1.25rem;
  font-weight: 700;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--crm-text-3);
}

.card-body { padding: 1.25rem; }

/* ── Stat cards ─────────────────────────────────────── */

.text-bg-primary  { background: var(--crm-navy)    !important; color: #fff !important; border-color: transparent !important; }
.text-bg-success  { background: var(--crm-teal)    !important; color: var(--crm-navy) !important; border-color: transparent !important; }
.text-bg-info     { background: var(--crm-navy-600) !important; color: #fff !important; border-color: transparent !important; }
.text-bg-warning  { background: #F59E0B             !important; color: #fff !important; border-color: transparent !important; }

.text-bg-primary, .text-bg-success, .text-bg-info, .text-bg-warning {
  position: relative;
  overflow: hidden;
  border-radius: var(--crm-r) !important;
}

/* Decorative circle accent on stat cards */
.text-bg-primary::after, .text-bg-success::after,
.text-bg-info::after, .text-bg-warning::after {
  content: '';
  position: absolute;
  top: -24px;
  right: -24px;
  width: 88px;
  height: 88px;
  border-radius: 50%;
  background: rgba(255,255,255,0.09);
  pointer-events: none;
}

.text-bg-primary .card-title,
.text-bg-info .card-title { color: rgba(255,255,255,0.75); font-size: 0.8rem; font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase; }
.text-bg-success .card-title { color: rgba(13,36,71,0.65); font-size: 0.8rem; font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase; }
.text-bg-warning .card-title { color: rgba(255,255,255,0.8); font-size: 0.8rem; font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase; }

.text-bg-primary .display-6, .text-bg-info .display-6, .text-bg-warning .display-6 {
  font-family: 'Outfit', sans-serif;
  font-weight: 700;
  font-size: 2.4rem;
  letter-spacing: -0.03em;
  color: #fff;
}
.text-bg-success .display-6 {
  font-family: 'Outfit', sans-serif;
  font-weight: 700;
  font-size: 2.4rem;
  letter-spacing: -0.03em;
  color: var(--crm-navy);
}

/* ─────────────────────────────────────────────────────────
   Tables
   ───────────────────────────────────────────────────────── */

.table {
  --bs-table-hover-bg: var(--crm-teal-50);
  border-color: var(--crm-border);
  font-size: 0.9rem;
}

.table thead th {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--crm-text-3);
  border-bottom: 2px solid var(--crm-border) !important;
  padding: 0.875rem 1rem;
  background: var(--crm-white);
  white-space: nowrap;
}

.table tbody td {
  padding: 0.875rem 1rem;
  vertical-align: middle;
  border-color: var(--crm-border);
  color: var(--crm-text);
}

.table-hover tbody tr {
  transition: background-color var(--crm-fast) ease;
  border-left: 3px solid transparent;
  cursor: pointer;
}

.table-hover tbody tr:hover {
  background-color: var(--crm-teal-50) !important;
  border-left-color: var(--crm-teal);
}

/* ─────────────────────────────────────────────────────────
   Sheet grid runs as an app shell
   ─────────────────────────────────────────────────────────
   A spreadsheet needs its own bounded viewport: otherwise the scroll box is as tall as the
   whole table, so its horizontal scrollbar sits below the last row (off-screen on any real
   sheet) and there is nothing for a sticky header to stick inside. Capping .page and turning
   article.content into a flex column lets the grid claim the leftover height and own both
   scrollbars.

   Gated on :has() so this touches nothing else — not the Forms/Automation tabs of the same
   page, not any other table in the app. The descendant selector (rather than a bare
   :has(.sheet-grid)) also keeps it off the member/vendor portal, which renders the same grid
   without this shell.

   Specificity is load-bearing: crm.Client.styles.css loads AFTER this file, so a tie would
   lose to MainLayout's scoped rules. :has() contributes its most specific argument, giving
   (0,3,0) and (0,4,1) against .page[b-…] (0,2,0) and article.content[b-…] (0,2,1).

   Desktop only. Below 641px the window is the scroll container by design; the grid bounds
   itself there with its own max-height instead. */
@media (min-width: 641px) {
  .page:has(.sheet-workspace .sheet-grid) {
    height: 100vh; /* was only min-height, so the page grew with the table */
  }

  .page article.content:has(.sheet-workspace .sheet-grid) {
    display: flex;
    flex-direction: column;
    min-height: 0; /* the unlock: cancels min-height:auto so the flex children may shrink */
  }
}

/* ─────────────────────────────────────────────────────────
   Badges
   ───────────────────────────────────────────────────────── */

.badge {
  font-family: 'Outfit', sans-serif;
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.025em;
  border-radius: 20px;
  padding: 0.3em 0.7em;
}

.badge.bg-success  { background: var(--crm-teal)   !important; color: var(--crm-navy) !important; }
.badge.bg-secondary { background: var(--crm-surface-2) !important; color: var(--crm-text-2) !important; }
.badge.bg-danger   { background: #FEE2E2 !important; color: #B91C1C !important; }
.badge.bg-warning.text-dark { background: #FEF3C7 !important; color: #92400E !important; }

/* ─────────────────────────────────────────────────────────
   List Groups
   ───────────────────────────────────────────────────────── */

.list-group-flush .list-group-item {
  padding: 0.875rem 1.25rem;
  border-color: var(--crm-border);
  font-size: 0.9rem;
  transition: background-color var(--crm-fast) ease;
}

.list-group-flush .list-group-item:hover {
  background-color: var(--crm-teal-50);
}

/* ─────────────────────────────────────────────────────────
   Alerts
   ───────────────────────────────────────────────────────── */

.alert-danger {
  background: #FEF2F2;
  border: 1px solid #FECACA;
  color: #991B1B;
  border-radius: var(--crm-r-sm);
  font-size: 0.875rem;
}

/* ─────────────────────────────────────────────────────────
   Nav Tabs
   ───────────────────────────────────────────────────────── */

.nav-tabs {
  border-bottom: 2px solid var(--crm-border);
  gap: 0.125rem;
}

.nav-tabs .nav-link {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--crm-text-2);
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  padding: 0.625rem 1rem;
  margin-bottom: -2px;
  transition: color var(--crm-fast) ease, border-color var(--crm-fast) ease;
}

.nav-tabs .nav-link:hover {
  color: var(--crm-navy);
  border-bottom-color: var(--crm-border-2);
  background: transparent;
}

.nav-tabs .nav-link.active {
  color: var(--crm-teal-600);
  border-bottom-color: var(--crm-teal);
  background: transparent;
  font-weight: 600;
}

/* ─────────────────────────────────────────────────────────
   Nav Pills — segmented control

   Bootstrap's default active pill is #0d6efd, which is the
   one blue in the product. Styled as a track with a raised
   selected segment: it reads as "pick one of these" rather
   than as a link row, which is what pills are used for here.
   ───────────────────────────────────────────────────────── */

.nav-pills {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.15rem;
  padding: 0.25rem;
  background: var(--crm-surface-2);
  border-radius: var(--crm-r);
}

.nav-pills .nav-link {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.9rem;
  border: none;
  border-radius: var(--crm-r-sm);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--crm-text-2);
  background: transparent;
  transition: color var(--crm-fast) ease, background var(--crm-fast) ease;
}

.nav-pills .nav-link:hover { color: var(--crm-navy); background: rgba(255, 255, 255, 0.55); }

.nav-pills .nav-link.active {
  background: var(--crm-white);
  color: var(--crm-navy);
  font-weight: 600;
  box-shadow: var(--crm-shadow-xs);
}

/* Teal marks the live segment — the same signal the tab bars use. */
.nav-pills .nav-link.active i { color: var(--crm-teal-600); }

/* ─────────────────────────────────────────────────────────
   Page header with right-aligned action area. Used by edit
   forms to balance an h1 against a page-level affordance
   (e.g. the EffectiveDateInput chip). Wraps on narrow screens.
   ───────────────────────────────────────────────────────── */
.ef-header--with-actions {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.ef-header--with-actions > h1 {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
}

/* ─────────────────────────────────────────────────────────
   Entrance Animations
   ───────────────────────────────────────────────────────── */

@keyframes crm-slide-up {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes crm-slide-in-row {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: translateX(0); }
}

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

@keyframes crm-scale-up {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}

@keyframes crm-float-orb {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(60px, -80px); }
  50%  { transform: translate(-40px, -120px); }
  75%  { transform: translate(-80px, -40px); }
  100% { transform: translate(0, 0); }
}

@keyframes crm-pulse-glow {
  0%, 100% { box-shadow: 0 0 16px rgba(var(--crm-teal-rgb), 0.15), 0 0 4px rgba(var(--crm-teal-rgb), 0.10); }
  50%      { box-shadow: 0 0 28px rgba(var(--crm-teal-rgb), 0.28), 0 0 8px rgba(var(--crm-teal-rgb), 0.18); }
}

@keyframes crm-border-sweep {
  0%   { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}

@keyframes crm-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

/* ── Skeleton shimmer utilities ── */

.crm-skel {
  background: linear-gradient(90deg,
    var(--crm-surface-2) 25%,
    rgba(255, 255, 255, 0.7) 50%,
    var(--crm-surface-2) 75%);
  background-size: 200% 100%;
  animation: crm-shimmer 1.6s ease-in-out infinite;
  border-radius: var(--crm-r-sm);
}

.crm-skel--dark {
  background: linear-gradient(90deg,
    rgba(255, 255, 255, 0.06) 25%,
    rgba(255, 255, 255, 0.13) 50%,
    rgba(255, 255, 255, 0.06) 75%);
  background-size: 200% 100%;
  animation: crm-shimmer 1.6s ease-in-out infinite;
  border-radius: var(--crm-r-sm);
}

@media (prefers-reduced-motion: reduce) {
  .crm-skel, .crm-skel--dark { animation: none; }
}

/* Card stagger via column parents.
   Fill-mode is `backwards` (NOT `both`): `backwards` applies the `from` keyframe
   during the stagger delay so the entrance still looks right, but does NOT retain
   the `to` keyframe afterward. The `to` state is `transform: translateY(0)` — a
   *non-none* transform — and with `both`/`forwards` it persists, which permanently
   turns every card into a CSS stacking context. That trap makes absolutely-positioned
   overlays inside a card (e.g. the EntitySearchSelect search dropdown) render *behind*
   a later sibling card instead of above it, regardless of their z-index. Leaving the
   transform off at rest lets those overlays honor their z-index. Keep `backwards`. */
.row > [class*="col"]:nth-child(1) .card { animation: crm-slide-up var(--crm-slow) var(--crm-ease) backwards 0.00s; }
.row > [class*="col"]:nth-child(2) .card { animation: crm-slide-up var(--crm-slow) var(--crm-ease) backwards 0.06s; }
.row > [class*="col"]:nth-child(3) .card { animation: crm-slide-up var(--crm-slow) var(--crm-ease) backwards 0.12s; }
.row > [class*="col"]:nth-child(4) .card { animation: crm-slide-up var(--crm-slow) var(--crm-ease) backwards 0.18s; }
.row > [class*="col"]:nth-child(5) .card { animation: crm-slide-up var(--crm-slow) var(--crm-ease) backwards 0.24s; }
.row > [class*="col"]:nth-child(6) .card { animation: crm-slide-up var(--crm-slow) var(--crm-ease) backwards 0.30s; }

/* Table row stagger */
tbody tr { animation: crm-slide-in-row 0.26s var(--crm-ease) both; }
tbody tr:nth-child(1)  { animation-delay: 0.03s; }
tbody tr:nth-child(2)  { animation-delay: 0.07s; }
tbody tr:nth-child(3)  { animation-delay: 0.11s; }
tbody tr:nth-child(4)  { animation-delay: 0.15s; }
tbody tr:nth-child(5)  { animation-delay: 0.19s; }
tbody tr:nth-child(6)  { animation-delay: 0.23s; }
tbody tr:nth-child(7)  { animation-delay: 0.27s; }
tbody tr:nth-child(8)  { animation-delay: 0.31s; }
tbody tr:nth-child(9)  { animation-delay: 0.35s; }
tbody tr:nth-child(10) { animation-delay: 0.39s; }
tbody tr:nth-child(n+11) { animation-delay: 0.42s; }

/* ─────────────────────────────────────────────────────────
   Validation
   ───────────────────────────────────────────────────────── */

.valid.modified:not([type=checkbox]) { border-color: var(--crm-teal) !important; }
.invalid { border-color: #EF4444 !important; }
.validation-message { color: #DC2626; font-size: 0.8rem; margin-top: 0.25rem; }

/* ─────────────────────────────────────────────────────────
   Loading Spinner
   ───────────────────────────────────────────────────────── */

.loading-progress {
  position: absolute;
  display: block;
  width: 3rem;
  height: 3rem;
  inset: 0;
  margin: auto;
}

.loading-progress circle {
  fill: none;
  stroke: rgba(255, 255, 255, 0.08);
  stroke-width: 0.35rem;
  transform-origin: 50% 50%;
  transform: rotate(-90deg);
}

.loading-progress circle:last-child {
  stroke: var(--crm-teal);
  stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
  transition: stroke-dasharray 0.05s ease-in-out;
}

.loading-progress-text {
  position: absolute;
  text-align: center;
  font-weight: 500;
  font-family: 'Outfit', sans-serif;
  font-size: 0.7rem;
  color: rgba(255, 255, 255, 0.4);
  inset: calc(50% + 1.75rem) 0 auto 0;
}

.loading-progress-text::after {
  content: var(--blazor-load-percentage-text, "Loading");
}

/* ─────────────────────────────────────────────────────────
   Blazor Error UI
   ───────────────────────────────────────────────────────── */

#blazor-error-ui {
  color-scheme: light only;
  background: #FFFBEB;
  border-top: 2px solid #F59E0B;
  bottom: 0;
  box-shadow: 0 -2px 12px rgba(0,0,0,0.08);
  box-sizing: border-box;
  display: none;
  left: 0;
  padding: 0.75rem 1.5rem;
  position: fixed;
  width: 100%;
  z-index: 1000;
  font-size: 0.875rem;
  color: #92400E;
}

#blazor-error-ui .dismiss {
  cursor: pointer;
  position: absolute;
  right: 0.75rem;
  top: 0.6rem;
}

.blazor-error-boundary {
  background: #FEF2F2;
  border: 1px solid #FECACA;
  border-radius: var(--crm-r);
  padding: 1.25rem;
  color: #991B1B;
  font-size: 0.875rem;
}

.blazor-error-boundary::after { content: "An error has occurred."; }

/* ─────────────────────────────────────────────────────────
   Utilities
   ───────────────────────────────────────────────────────── */

.content { padding-top: 0; }
.text-muted { color: var(--crm-text-3) !important; }
code {
  color: var(--crm-teal-600);
  background: var(--crm-teal-50);
  padding: 0.1em 0.35em;
  border-radius: 3px;
  font-size: 0.85em;
}

/* Floating label fix */
.form-floating > .form-control-plaintext::placeholder,
.form-floating > .form-control::placeholder {
  color: var(--crm-text-3);
  text-align: end;
}
.form-floating > .form-control-plaintext:focus::placeholder,
.form-floating > .form-control:focus::placeholder {
  text-align: start;
}


/* ── Audit trail (global — used by AuditTrail.razor component) ── */

.audit-trail { display: flex; flex-direction: column; gap: 0.5rem; }

.audit-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.55rem 0.75rem;
    background: var(--crm-bg);
    border: 1px solid var(--crm-border);
    border-radius: var(--crm-r-sm);
    font-size: 0.82rem;
    transition: background var(--crm-fast) ease;
}
.audit-row:hover { background: var(--crm-white); }

.audit-time    { color: var(--crm-text-2); }
.audit-actor   { font-weight: 500; color: var(--crm-navy); }
.audit-notes-inline { color: var(--crm-text-3); font-style: italic; }

.audit-action-badge {
    display: inline-block;
    padding: 0.18rem 0.5rem;
    border-radius: 20px;
    font-size: 0.71rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
}
.audit-badge-auth    { background: var(--crm-teal-50); color: var(--crm-teal-600); border: 1px solid var(--crm-teal); }
.audit-badge-create  { background: #ecfdf5; color: #065f46; border: 1px solid #6ee7b7; }
.audit-badge-update  { background: #eff6ff; color: #1e40af; border: 1px solid #93c5fd; }
.audit-badge-delete  { background: #fef2f2; color: #991b1b; border: 1px solid #fca5a5; }
.audit-badge-complete { background: #f0fdf4; color: #166534; border: 1px solid #86efac; }
.audit-badge-neutral { background: var(--crm-bg); color: var(--crm-text-2); border: 1px solid var(--crm-border-2); }

/* ─────────────────────────────────────────────────────────
   Tab bar (shared across Admin Settings, Profile, etc.)
   ───────────────────────────────────────────────────────── */

.admin-tab-bar {
  display: flex;
  gap: 0.25rem;
  border-bottom: 2px solid var(--crm-border);
  padding-bottom: 0;
  /* A long strip wraps rather than running off the side. It can't scroll
     instead: the tabs overlap the bar's border with a -2px margin, so making
     this a scroll container clips the active tab's underline. */
  flex-wrap: wrap;
}

.admin-tab {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem 1.25rem;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  font-family: 'Outfit', sans-serif;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--crm-text-2);
  cursor: pointer;
  transition: color var(--crm-fast) ease, border-color var(--crm-fast) ease;
  border-radius: var(--crm-r-sm) var(--crm-r-sm) 0 0;
}

.admin-tab:hover { color: var(--crm-navy); }

.admin-tab.active {
  color: var(--crm-teal-600);
  border-bottom-color: var(--crm-teal);
  font-weight: 600;
}

/* ── Clickable card link ─────────────────────────────────── */

a.card-link { color: var(--crm-text); }
a.card-link:hover { color: var(--crm-text); }
a.card-link .fw-semibold { transition: color var(--crm-fast) ease; }
a.card-link:hover .fw-semibold { color: var(--crm-navy-600); }

/* ── Activity list — type accent borders ──────────────────── */

.activity-item {
  border-left: 4px solid transparent;
  transition: border-color var(--crm-fast) ease;
}
.activity-call    { border-left-color: var(--crm-navy-400); }
.activity-email   { border-left-color: #6366F1; }
.activity-meeting { border-left-color: var(--crm-teal); }
.activity-note    { border-left-color: var(--crm-border-2); }

/* ── Empty state ─────────────────────────────────────────── */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 2.5rem 1rem;
  color: var(--crm-text-3);
}
.empty-state svg { opacity: 0.45; }
.empty-state p { margin: 0; font-size: 0.875rem; }

/* ── Filter chips ─────────────────────────────────────────────
   These styles back the role / classification chip buttons rendered
   inline in list pages (AccountList, ContactList). The same selectors
   exist in ClassificationFilter.razor.css scoped to that component;
   list pages render their own chips outside the component so they
   need a global rule. */
.cf-wrapper { width: 100%; }

.cf-chipbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
}

.cf-label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--bs-secondary-color, #6c757d);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin-right: 0.25rem;
}

.cf-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0.65rem;
  font-size: 0.8125rem;
  line-height: 1.25;
  border-radius: 999px;
  border: 1px solid transparent;
  background: transparent;
  transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease;
  cursor: pointer;
  user-select: none;
}
.cf-chip:focus-visible {
  outline: 2px solid var(--bs-primary, #0d6efd);
  outline-offset: 2px;
}
.cf-chip i { font-size: 0.875rem; line-height: 1; }

.cf-chip-neutral {
  border-color: var(--bs-border-color, #dee2e6);
  color: var(--bs-body-color, #212529);
}
.cf-chip-neutral:hover {
  background: var(--bs-tertiary-bg, #f8f9fa);
  border-color: var(--bs-secondary, #6c757d);
}
.cf-chip-neutral i { color: var(--bs-tertiary-color, #adb5bd); }

.cf-chip-include {
  background: var(--bs-primary, #0d6efd);
  border-color: var(--bs-primary, #0d6efd);
  color: #fff;
}
.cf-chip-include:hover { filter: brightness(1.08); }

.cf-chip-exclude {
  background: var(--bs-danger-bg-subtle, #f8d7da);
  border-color: var(--bs-danger-border-subtle, #f1aeb5);
  color: var(--bs-danger-text-emphasis, #58151c);
  text-decoration: line-through;
}
.cf-chip-exclude:hover {
  background: var(--bs-danger, #dc3545);
  border-color: var(--bs-danger, #dc3545);
  color: #fff;
}

.cf-clear {
  padding: 0 0.25rem;
  color: var(--bs-secondary-color, #6c757d);
  text-decoration: none;
}
.cf-clear:hover {
  color: var(--bs-body-color, #212529);
  text-decoration: underline;
}

.cf-chip-name { white-space: nowrap; }

/* A chip row's chips, wrapped so the list filter bar can hang the label in a gutter
   (ListFilterBar.razor.css). Everywhere else the wrapper doesn't take part in layout. */
.cf-chips { display: contents; }

/* Mobile-only actions toggle (the ⋮ button). Hidden by default; the
   mobile media block below flips it on. Compound `.btn.…` specificity
   is required because the global `.btn` rule below sets
   `display: inline-flex` and would otherwise win on single-class equals.
   The list-filters toggle that used to live here has moved into the
   shared <ListFilters> component. */
.btn.list-actions-toggle { display: none; }

/* Neutral count chip used by list pages to surface the DB-side total
   matching the current filter ("1,234 records"). tabular-nums keeps the
   number visually steady as the filter narrows (1,234 → 87) instead of
   wobbling on every keystroke. Same rule rendered by <TotalCountChip>
   in both the ListFilters header and inline on filter-less list pages. */
.total-count-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.1rem 0.55rem;
  background: rgba(13, 36, 71, 0.06);
  color: var(--bs-secondary-color, #6c757d);
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  user-select: none;
}

/* List-page header search input. Sits inline between the H1 and the
   action cluster on desktop — constrained width so it reads as a search
   bar, not a stretched form field. Mobile rules override flex / margin
   so it expands to share the H1 row with the actions toggle. */
.list-page-search {
  flex: 0 1 480px;
  max-width: 480px;
  margin: 0;
}

/* Desktop polish for list-page headers. Bootstrap's `.justify-content-
   between` distributes three items (H1, search, actions) evenly which
   marooned the search in the middle with empty gutters either side.
   Cluster H1 + search on the left with a tight gap and let the actions
   cluster anchor itself to the right via auto margin. */
@media (min-width: 641px) {
  article.content > .d-flex.justify-content-between.align-items-center {
    justify-content: flex-start;
    gap: 0.75rem;
  }
  article.content > .d-flex.justify-content-between.align-items-center > .d-flex.list-actions {
    margin-left: auto;
  }
  /* Filter inputs sit one rung below the header search in the visual
     hierarchy on desktop — small density signals "refiners" rather than
     "primary find affordances". Targets the shared <ListFilters>
     component body. */
  .lf-body .form-control,
  .lf-body .form-select {
    font-size: 0.875rem;
    padding-top: 0.4rem;
    padding-bottom: 0.4rem;
  }
}

/* Consistent button alignment — Bootstrap's default `.btn` is
   `display: inline-block` which baseline-aligns icons against text and
   produces the "some buttons sit a bit low" look across the app. Force
   inline-flex with center alignment so every .btn (icon-only, icon+text,
   text-only) sits the same way regardless of inner content. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Helper to hide a button's text on mobile while keeping the icon visible.
   Use as `<i class="bi ..."></i><span class="btn-label-mobile-hidden ms-1">Customize</span>`. */
@media (max-width: 640.98px) {
  .btn-label-mobile-hidden { display: none; }
  /* Hide an entire element on mobile-sized viewports. Useful for desktop-
     only affordances that don't translate to phone use (e.g. dashboard
     Customize, drag handles). */
  .d-mobile-none { display: none !important; }
}

/* ── Mobile optimizations ─────────────────────────────────── */

@media (max-width: 640.98px) {
  /* Scrollable admin / profile tab bars */
  .admin-tab-bar {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    flex-wrap: nowrap;
  }
  .admin-tab-bar::-webkit-scrollbar { display: none; }
  .admin-tab { flex-shrink: 0; font-size: 0.82rem; padding: 0.5rem 0.85rem; }
  .admin-tab:last-child { margin-right: 1.5rem; }

  /* Mobile table density */
  .table-responsive .table th,
  .table-responsive .table td {
    white-space: nowrap;
    font-size: 0.82rem;
    padding: 0.5rem 0.65rem;
  }

  /* Opt-in card layout for list pages: add `table-mobile-cards` to the
     <table> and `data-label="..."` to each <td>. Header row is hidden;
     each row stacks as a card with column labels prefixed inline. */
  .table-responsive .table.table-mobile-cards {
    white-space: normal;
  }
  .table-responsive .table.table-mobile-cards thead { display: none; }
  .table-responsive .table.table-mobile-cards,
  .table-responsive .table.table-mobile-cards tbody,
  .table-responsive .table.table-mobile-cards tr,
  .table-responsive .table.table-mobile-cards td {
    display: block;
    width: 100%;
  }
  .table-responsive .table.table-mobile-cards tr {
    background: var(--crm-white, #fff);
    border: 1px solid var(--crm-border, #e5e7eb);
    border-radius: 12px;
    padding: 0.85rem 1rem;
    margin-bottom: 0.65rem;
    box-shadow: 0 1px 3px rgba(13, 36, 71, 0.04);
    white-space: normal;
  }
  .table-responsive .table.table-mobile-cards td {
    border: 0;
    padding: 0.2rem 0;
    font-size: 0.9rem;
    white-space: normal;
  }
  .table-responsive .table.table-mobile-cards td:empty { display: none; }
  .table-responsive .table.table-mobile-cards td[data-label]::before {
    content: attr(data-label) ": ";
    font-weight: 600;
    color: var(--crm-text-3, #6b7280);
    margin-right: 0.4rem;
  }
  /* The first cell typically holds the row's primary label (account name,
     contact name, etc) — render it as the card title with no prefix. */
  .table-responsive .table.table-mobile-cards td.table-mobile-cards-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--crm-text-1, #0D2447);
    margin-bottom: 0.25rem;
    /* Title leaves room for the absolutely-positioned action cell so the
       edit button doesn't collide with long names. */
    padding-right: 4.5rem !important;
  }
  .table-responsive .table.table-mobile-cards td.table-mobile-cards-title[data-label]::before {
    content: '';
    margin: 0;
  }
  /* Action cells (edit links) are hidden on mobile cards — users tap the
     card to open the detail page where the edit affordance lives. Saves
     a row of vertical space and removes the empty right-side gutter. */
  .table-responsive .table.table-mobile-cards td.table-mobile-cards-action {
    display: none;
  }
  /* Reset the title's reserved right padding now that no action sits there. */
  .table-responsive .table.table-mobile-cards td.table-mobile-cards-title {
    padding-right: 0 !important;
  }

  /* Chips cell — no label prefix; the chips are self-explanatory. */
  .table-responsive .table.table-mobile-cards td.tmc-chips {
    padding: 0.2rem 0 0.35rem;
  }
  .table-responsive .table.table-mobile-cards td.tmc-chips[data-label]::before {
    content: '';
    margin: 0;
  }

  /* Compact "meta" cell — no label prefix, smaller muted text, flows
     inline with separators between siblings (Email · Phone, City, ST). */
  .table-responsive .table.table-mobile-cards td.tmc-meta {
    display: inline;
    font-size: 0.85rem;
    color: var(--crm-text-3, #6b7280);
    padding: 0;
    margin: 0;
  }
  .table-responsive .table.table-mobile-cards td.tmc-meta[data-label]::before {
    content: '';
    margin: 0;
  }
  .table-responsive .table.table-mobile-cards td.tmc-meta + td.tmc-meta::before {
    content: ' · ';
    color: var(--crm-text-4, #9ca3af);
  }
  /* Force a line break before the first meta cell so it doesn't run into
     the title or chip row above. */
  .table-responsive .table.table-mobile-cards td.tmc-meta-start {
    display: block;
    margin-top: 0.15rem;
  }
  .table-responsive .table.table-mobile-cards td.tmc-meta-start::before {
    content: '' !important;
  }
  .table-responsive .table.table-mobile-cards td.tmc-meta-start + td.tmc-meta::before {
    content: ' · ';
  }

  /* Subtitle cell — second-line context like "CFO at Crown Banana".
     No label prefix; sits just under the title. */
  .table-responsive .table.table-mobile-cards td.tmc-subtitle {
    font-size: 0.875rem;
    color: var(--crm-text-2, #4b5563);
    padding: 0;
    margin-bottom: 0.2rem;
  }
  .table-responsive .table.table-mobile-cards td.tmc-subtitle[data-label]::before {
    content: '';
    margin: 0;
  }
  /* Empty subtitle/meta cells should collapse without leaving stray separators. */
  .table-responsive .table.table-mobile-cards td.tmc-subtitle:empty,
  .table-responsive .table.table-mobile-cards td.tmc-meta:empty {
    display: none;
  }

  /* Page header bar: H1 + action buttons cluster. Default desktop pattern
     uses justify-content: between which crashes on narrow viewports.
     On mobile the H1 shares its row with a single Actions toggle (⋮);
     the action buttons collapse to a second row revealed on tap.
     The bar pins to the viewport top so filters / actions / +New stay
     reachable without scrolling. */
  article.content > .d-flex.justify-content-between.align-items-center {
    flex-wrap: wrap;
    gap: 0.5rem;
    row-gap: 0.5rem;
    position: sticky;
    top: 0;
    z-index: 12;
    background: var(--crm-bg, #f6f8fb);
    /* Negative margin + matching padding extends the strip to the article
       edges so content scrolling under it doesn't peek through the gap. */
    margin: -1.25rem -1rem 0.75rem;
    padding: 0.75rem 1rem 0.5rem;
    border-bottom: 1px solid var(--crm-border, #e5e7eb);
  }
  /* Row 1 layout: [H1] [search] [⋮]. H1 sizes to content; search grows
     to fill the middle; ⋮ pins to the right. */
  article.content > .d-flex.justify-content-between.align-items-center > h1 {
    flex: 0 0 auto;
    margin-bottom: 0;
    font-size: 1.1rem;
    min-width: 0;
    order: 0;
  }
  article.content > .d-flex.justify-content-between.align-items-center > .list-page-search {
    flex: 1 1 0;
    margin: 0;
    max-width: none;
    min-width: 0;
    order: 1;
  }
  article.content > .d-flex.justify-content-between.align-items-center > .list-page-search input {
    font-size: 0.85rem;
    padding: 0.4rem 0.65rem;
    height: auto;
  }
  /* The action cluster is a `.d-flex.gap-2` div; pages opt-in to the
     mobile collapse behavior by adding `.list-actions`. Without the
     class (e.g. dashboard with only Customize), it just wraps below. */
  article.content > .d-flex.justify-content-between.align-items-center > .d-flex.list-actions {
    display: none !important;
    width: 100%;
    order: 3;
  }
  article.content > .d-flex.justify-content-between.align-items-center > .d-flex.list-actions.list-actions--open {
    display: flex !important;
    flex-wrap: wrap;
  }
  article.content > .d-flex.justify-content-between.align-items-center .list-actions .btn {
    flex: 1 1 auto;
    font-size: 0.85rem;
  }

  /* The Actions toggle (the ⋮ button) sits next to the search input.
     Hidden on desktop; shown when paired with `.list-actions`.
     Compound selector to beat `.btn.list-actions-toggle { display: none }`
     on the desktop default. */
  .btn.list-actions-toggle {
    display: inline-flex;
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    padding: 0;
    order: 2;
  }

  /* Smaller page headings */
  article.content h1 { font-size: 1.45rem; }

  /* Tap-target floor: every interactive control gets at least 44px so
     thumbs land cleanly. Use `.btn-link-tight` to opt out (e.g. inline
     pencil/x icons inside dense rows where 44px would look broken). */
  .btn,
  .form-check-input,
  label.btn-radio-chip,
  .filter-chip,
  a.nav-link {
    min-height: 44px;
  }
  .btn:not(.btn-link-tight),
  label.btn-radio-chip,
  .filter-chip {
    min-width: 44px;
  }
  .btn-link-tight {
    min-height: 0;
    min-width: 0;
  }
  .form-check-input { width: 1.4rem; height: 1.4rem; }
  .filter-chip,
  label.btn-radio-chip {
    padding: 0.55rem 0.85rem;
    font-size: 0.85rem;
  }
}

/* ── Member portal styles ───────────────────────────────────────────────────
   Used by MemberLayout pages. Kept in global app.css (not scoped per page) so
   the shared component patterns (.member-card, .member-pill) render the same
   on MemberHome, MemberProfile, and MemberAccountDetail. */

.page-header {
    margin-bottom: 1.5rem;
}

.page-header h1 {
    font-size: 2rem;
    font-weight: 700;
    color: var(--crm-navy, #14213d);
    margin: 0 0 0.25rem 0;
}

.back-link {
    display: inline-block;
    margin-bottom: 0.5rem;
    font-size: 0.85rem;
    color: var(--crm-navy-400, #6b7589);
    text-decoration: none;
}

.back-link:hover {
    color: var(--crm-navy, #14213d);
}

.member-greeting { margin-bottom: 2rem; }

.member-greeting-eyebrow,
.member-card-eyebrow {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--crm-navy-400, #6b7589);
    font-weight: 600;
    margin-bottom: 0.5rem;
}

.member-greeting-name {
    font-size: 2.25rem;
    font-weight: 700;
    color: var(--crm-navy, #14213d);
    margin: 0 0 0.25rem 0;
}

.member-section-heading {
    margin-top: 2.5rem;
    margin-bottom: 1rem;
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--crm-navy, #14213d);
    letter-spacing: 0.02em;
}

.member-card {
    background: #fff;
    border: 1px solid #e6e9f1;
    border-radius: 12px;
    padding: 1.5rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
    height: 100%;
}

.member-card-title {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--crm-navy, #14213d);
    margin: 0 0 0.75rem 0;
}

.member-account-tile {
    display: block;
    background: #fff;
    border: 1px solid #e6e9f1;
    border-radius: 12px;
    padding: 1.25rem;
    text-decoration: none;
    color: inherit;
    transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}

.member-account-tile:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06);
    border-color: var(--crm-teal, #2a9d8f);
    color: inherit;
    text-decoration: none;
}

.member-account-name {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--crm-navy, #14213d);
    margin-bottom: 0.5rem;
}

.member-account-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.member-pill {
    display: inline-block;
    padding: 0.18rem 0.6rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 500;
    background: rgba(var(--crm-navy-rgb, 20, 33, 61), 0.08);
    color: var(--crm-navy, #14213d);
}

.member-pill-admin {
    background: var(--crm-teal-50, rgba(42, 157, 143, 0.12));
    color: var(--crm-teal-600, #1f7a6f);
}

/* Sortable list tables: drop thead padding so the SortableHeader button fills the cell. */
.bd-list-table thead th {
    padding: 0;
}

/* ── Archived row styling ────────────────────────────────────────────────────
   Applied on list pages when the "Show archived" toggle surfaces records that
   are archived. Dims the row so live records read more strongly, and pairs
   with the inline "Archived" badge in the name cell. Hover restores opacity
   so the user can still see what they're about to click into.
*/

/* Browser quirk: CSS `opacity` doesn't render on <tr> in most browsers
   because table rows don't form a stacking context. Target the cells
   directly so the dim applies to every td/th in the row. The row/card
   variants used inside detail-page related sections are normal block/inline
   elements so the property applies fine. */
.archived-row > td,
.archived-row > th,
.cd-row-archived,
.acp-other-card-archived,
.acp-wg-member-archived,
.vd-attendee-archived {
    opacity: 0.55;
    transition: opacity 0.15s ease;
}

.archived-row:hover > td,
.archived-row:hover > th,
.cd-row-archived:hover,
.acp-other-card-archived:hover,
.acp-wg-member-archived:hover,
.vd-attendee-archived:hover {
    opacity: 0.85;
}

.archived-list-badge {
    display: inline-block;
    background: #e9ecef;
    color: #6c757d;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.1rem 0.4rem;
    border-radius: 0.25rem;
    margin-left: 0.4rem;
    vertical-align: middle;
}

/* ── Survey file-upload drag-and-drop zone (SurveyQuestionInput) ─────────── */
.sq-dropzone {
    border: 2px dashed #cbd5e1;
    border-radius: 10px;
    padding: 0.85rem;
    background: #f8fafc;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.sq-dropzone.dz-over {
    border-color: #2563eb;
    background: #eff6ff;
}

.sq-dropzone-hint {
    color: #64748b;
    font-size: 0.9rem;
    margin-bottom: 0.45rem;
}

/* ─────────────────────────────────────────────────────────
   Service Desk admin config tables (teams / categories / SLA /
   mailboxes) — cohesive with the queue surface.
   ───────────────────────────────────────────────────────── */
.svc-panel {
    background: var(--crm-white);
    border: 1px solid var(--crm-border);
    border-radius: var(--crm-r-lg);
    box-shadow: var(--crm-shadow-sm);
    overflow: hidden;
}

.svc-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    margin: 0;
}

.svc-table thead th {
    font-family: 'Outfit', sans-serif;
    font-size: 0.64rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--crm-text-3);
    text-align: left;
    padding: 0.6rem 0.8rem;
    background: var(--crm-bg);
    border-bottom: 1px solid var(--crm-border);
    white-space: nowrap;
}

.svc-table tbody td {
    padding: 0.65rem 0.8rem;
    border-bottom: 1px solid var(--crm-border);
    vertical-align: middle;
    color: var(--crm-text);
}

.svc-table tbody tr:last-child td { border-bottom: none; }
.svc-table tbody tr.svc-editing { background: var(--crm-teal-50, rgba(0,197,168,0.06)); }

.svc-name { font-weight: 600; color: var(--crm-navy); }
.svc-sub { color: var(--crm-text-3); font-size: 0.75rem; }
.svc-empty { text-align: center; color: var(--crm-text-3); padding: 1.5rem; }
.svc-active { color: #16A34A; }
.svc-inactive { color: var(--crm-text-3); }

.svc-chip {
    display: inline-block;
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
    background: var(--crm-surface-2, #E6EEF8);
    color: var(--crm-text-2);
}

/* ── Guided-tour spotlight (wwwroot/js/help-tour.js) ─────────────────────────
   Created by script outside any component, so it cannot be scoped CSS. One ring;
   its huge box-shadow dims the page. pointer-events: none — a tour guides, it never
   blocks. Above the command palette (1200); the step bubble (TourHost) sits at 1310. */
.help-tour-ring {
    position: fixed;
    z-index: 1300;
    pointer-events: none;
    border-radius: var(--crm-r);
    box-shadow:
        0 0 0 3px var(--crm-teal),
        0 0 0 7px rgba(var(--crm-teal-rgb), 0.25),
        0 0 0 9999px rgba(var(--crm-navy-rgb), 0.42);
    transition:
        left var(--crm-mid) var(--crm-ease),
        top var(--crm-mid) var(--crm-ease),
        width var(--crm-mid) var(--crm-ease),
        height var(--crm-mid) var(--crm-ease);
}

.help-tour-ring--none {
    box-shadow: 0 0 0 9999px rgba(var(--crm-navy-rgb), 0.42);
}

@media (prefers-reduced-motion: reduce) {
    .help-tour-ring { transition: none; }
}

/* Assistant reply links (Shared/AiMarkdownView). Global because AiMarkdownView builds
   these with RenderTreeBuilder, which never carries a scoped-CSS attribute. */
.ai-md-help-link {
    color: var(--crm-teal-600);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.ai-md-tour-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin: 2px 0;
    padding: 2px 10px;
    border: 1px solid var(--crm-teal);
    border-radius: 999px;
    background: var(--crm-teal-50);
    color: var(--crm-navy);
    font-size: 0.85em;
    font-weight: 600;
    line-height: 1.5;
    cursor: pointer;
}

.ai-md-tour-btn:hover,
.ai-md-tour-btn:focus-visible {
    background: var(--crm-teal-glow);
}

/* Profile → "Sign-in & security" link card (member and vendor portals). */
.security-link-card {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    color: inherit;
    text-decoration: none;
}

.security-link-card:hover,
.security-link-card:focus-visible {
    color: inherit;
    border-color: var(--crm-border-2);
}

.security-link-card > .bi-shield-lock {
    font-size: 1.35rem;
    color: var(--crm-teal, var(--bs-primary));
}


/* Forgot / reset password on the staff sign-in backdrop. */
.auth-panel {
    width: 100%;
    max-width: 440px;
    margin: 1.5rem auto 3rem;
    padding: 0 1rem;
}

.auth-panel-card .card-header h4 {
    font-size: 1.1rem;
    font-weight: 600;
}

/* Forgot / reset password on the portal: one card, centred on the portal's light backdrop. */
.portal-auth-simple {
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 1rem;
    background: var(--crm-bg);
}

.portal-auth-simple-card {
    width: 100%;
    max-width: 440px;
}

.portal-auth-simple-brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-weight: 600;
    color: var(--crm-text-2);
    margin-bottom: 1rem;
}

.portal-auth-simple-logo {
    height: 32px;
    width: auto;
}
