/* customer_dashboard_overrides.css — TitrateLab brand on top of Tabler.

   Design language: quietly-dense premium SaaS for serious operators.
   Reference: Linear, Vercel Dashboard, Stripe.

   Strategy
   --------
   1. ONE token layer at :root — palette, type scale, spacing, radii, shadows,
      motion. Everything below references those tokens; nothing hardcodes
      colors/spacing.
   2. Override Tabler's own --tblr-* vars at :root so all Tabler components
      pick up the brand without needing per-component selectors.
   3. Component layer below the tokens — buttons, cards, tiles, sidebar — each
      one a small set of selectors that build on the tokens.
   4. Motion is premium-quiet: 160ms cubic-bezier(0.4, 0, 0.2, 1). No springs,
      no bounce. Hover lifts use translateY + opacity, not scale.

   Loaded AFTER Tabler so :root specificity wins. */

/* ────────────────────────────────────────────────────────────────────────
   1. TOKEN LAYER
   ──────────────────────────────────────────────────────────────────────── */
:root,
[data-bs-theme="dark"] {
  /* — Brand palette — */
  --tl-navy-900: #0a1530;          /* darkest — sidebar / topbar */
  --tl-navy-800: #0F1E3D;          /* page bg */
  --tl-navy-700: #16264a;          /* card bg (a touch lighter than before for separation) */
  --tl-navy-600: #1f3260;          /* elevated card / hover surface */
  --tl-gold-500: #DAA520;          /* primary brand */
  --tl-gold-400: #e6b94a;          /* hover lift */
  --tl-gold-600: #b8881a;          /* pressed / link-hover */

  /* — Ink (text) — */
  --tl-ink-100: #FAFAF7;           /* primary text */
  --tl-ink-300: #c8cdd9;           /* secondary text — bumped up from #aab1c2 for 4.5:1 contrast */
  --tl-ink-500: #8a93a8;           /* tertiary / placeholder */

  /* — Borders / dividers — */
  --tl-border:        rgba(255, 255, 255, 0.06);
  --tl-border-strong: rgba(255, 255, 255, 0.12);
  --tl-border-gold:   rgba(218, 165, 32, 0.35);

  /* — Semantic — */
  --tl-success: #4ADE80;
  --tl-danger:  #f87171;
  --tl-info:    #adbde8;

  /* — Spacing scale (4px base, fibonacci-ish) — */
  --tl-space-1: 4px;
  --tl-space-2: 8px;
  --tl-space-3: 12px;
  --tl-space-4: 16px;
  --tl-space-5: 20px;
  --tl-space-6: 24px;
  --tl-space-8: 32px;
  --tl-space-10: 40px;

  /* — Radius — */
  --tl-radius-sm: 6px;
  --tl-radius-md: 10px;
  --tl-radius-lg: 14px;

  /* — Shadow elevation — */
  --tl-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.18);
  --tl-shadow-md: 0 4px 14px rgba(0, 0, 0, 0.28);
  --tl-shadow-lg: 0 12px 30px rgba(0, 0, 0, 0.36);
  --tl-shadow-gold: 0 6px 20px rgba(218, 165, 32, 0.18);

  /* — Type scale — */
  --tl-font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --tl-font-mono: ui-monospace, SFMono-Regular, "JetBrains Mono", Menlo, Consolas, monospace;
  --tl-fs-display: 32px;
  --tl-fs-h1: 24px;
  --tl-fs-h2: 18px;
  --tl-fs-h3: 15px;
  --tl-fs-body: 14px;
  --tl-fs-small: 13px;
  --tl-fs-micro: 11px;
  --tl-lh-tight: 1.2;
  --tl-lh-body: 1.55;

  /* — Motion — */
  --tl-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --tl-dur-fast: 120ms;
  --tl-dur:      160ms;
  --tl-dur-slow: 220ms;

  /* — Tabler bridge: rewire Tabler's own design tokens to ours — */
  --tblr-primary:           var(--tl-gold-500);
  --tblr-primary-rgb:       218, 165, 32;
  --tblr-primary-fg:        var(--tl-navy-800);
  --tblr-link-color:        var(--tl-gold-500);
  --tblr-link-hover-color:  var(--tl-gold-400);

  --tblr-yellow:            var(--tl-gold-500);
  --tblr-yellow-rgb:        218, 165, 32;
  --tblr-yellow-darken:     var(--tl-gold-600);
  --tblr-yellow-fg:         var(--tl-navy-800);

  --tblr-bg-surface:           var(--tl-navy-800);
  --tblr-bg-surface-secondary: var(--tl-navy-700);
  --tblr-bg-surface-tertiary:  var(--tl-navy-600);
  --tblr-body-bg:              var(--tl-navy-800);
  --tblr-body-color:           var(--tl-ink-100);
  --tblr-card-bg:              var(--tl-navy-700);
  --tblr-card-border-color:    var(--tl-border);
  --tblr-border-color:         var(--tl-border);
  --tblr-secondary:            var(--tl-ink-300);
  --tblr-secondary-rgb:        200, 205, 217;
}

/* ────────────────────────────────────────────────────────────────────────
   2. BASE — body, links, headings
   ──────────────────────────────────────────────────────────────────────── */
body {
  font-family: var(--tl-font-sans);
  font-size: var(--tl-fs-body);
  line-height: var(--tl-lh-body);
  background: var(--tl-navy-800);
  color: var(--tl-ink-100);
  font-feature-settings: "cv02", "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
}

.text-secondary { color: var(--tl-ink-300) !important; }
.small, small { font-size: var(--tl-fs-small); }

/* Tabular numerics everywhere they belong — KPI values, money, dates, IDs */
.font-monospace, .font-mono, code, kbd, samp { font-family: var(--tl-font-mono); }

/* Page titles + card titles */
h1, .h1, .page-title { font-size: var(--tl-fs-h1); font-weight: 700; line-height: var(--tl-lh-tight); letter-spacing: -0.01em; color: var(--tl-ink-100); }
h2, .h2 { font-size: 20px; font-weight: 600; line-height: var(--tl-lh-tight); }
h3, .h3, .card-title { font-size: var(--tl-fs-h2); font-weight: 600; line-height: var(--tl-lh-tight); color: var(--tl-ink-100); }
h4, .h4 { font-size: var(--tl-fs-h3); font-weight: 600; }
.page-pretitle {
  font-size: var(--tl-fs-micro);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tl-ink-300);
}

/* ────────────────────────────────────────────────────────────────────────
   3. SIDEBAR
   ──────────────────────────────────────────────────────────────────────── */
.navbar-vertical {
  background: var(--tl-navy-900);
  border-right: 1px solid var(--tl-border);
}
.navbar-vertical .navbar-brand img { filter: brightness(1.15); }
.navbar-brand-image { height: 32px; width: auto; }

.navbar-vertical .nav-link {
  color: var(--tl-ink-300);
  border-radius: var(--tl-radius-sm);
  margin: 2px 8px;
  padding: 8px 12px;
  transition: color var(--tl-dur) var(--tl-ease),
              background-color var(--tl-dur) var(--tl-ease);
}
.navbar-vertical .nav-link:hover,
.navbar-vertical .nav-link:focus {
  color: var(--tl-ink-100);
  background: rgba(255, 255, 255, 0.04);
}
.navbar-vertical .nav-item.active > .nav-link,
.navbar-vertical .nav-link.active {
  color: var(--tl-gold-500);
  background: rgba(218, 165, 32, 0.10);
  /* Removed left-border that shifted padding. Use box-shadow inset instead — no layout reflow. */
  box-shadow: inset 3px 0 0 var(--tl-gold-500);
  padding-left: 12px;
}
.navbar-vertical .nav-link-icon {
  margin-right: 10px;
  opacity: 0.85;
}
.navbar-vertical .nav-link-title {
  font-size: var(--tl-fs-body);
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Prevent Pro lock+badge from clipping past sidebar's right edge */
  flex-wrap: wrap;
}

/* Pro lock badge in sidebar — inline, never wider than its column.
   Sidebar nav-link-title flex-wraps so badge drops to a new line on tight widths. */
.navbar-vertical .nav-link-title .badge,
.tl-nav-pro-badge {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 2px 5px;
  vertical-align: middle;
  line-height: 1.2;
  margin-left: 4px;
}
.tl-pro-lock { opacity: 0.85; vertical-align: middle; }

/* Sidebar footer plan chip — stack the label + badge instead of inlining,
   so wide labels ("Founding-20 reserved") don't push the badge offscreen */
.navbar-vertical .mt-auto > div.text-secondary {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  font-size: var(--tl-fs-small);
}
.navbar-vertical .mt-auto > div.text-secondary .badge {
  margin-left: 0 !important;
}

/* Inherit-color override for nested anchors (legacy fix from prior CSS) */
.navbar-vertical .nav-link a,
.navbar .nav-link a { color: inherit; }

/* ────────────────────────────────────────────────────────────────────────
   4. TOPBAR
   ──────────────────────────────────────────────────────────────────────── */
.page > header.navbar {
  background: var(--tl-navy-900);
  border-bottom: 1px solid var(--tl-border);
  min-height: 56px;
}
.page > header.navbar .avatar {
  font-weight: 600;
  font-size: var(--tl-fs-small);
  letter-spacing: 0.02em;
}

/* ────────────────────────────────────────────────────────────────────────
   5. PAGE HEADER (page-pretitle + page-title + actions row)
   ──────────────────────────────────────────────────────────────────────── */
.page-header {
  padding: var(--tl-space-6) 0 var(--tl-space-4);
  border-bottom: 0;
}
.page-header .page-pretitle { margin-bottom: 4px; }
.page-header .page-title { margin: 0; }

/* Mobile: action buttons go on their own row, full-width — no overlay on title.
   Long emails as page titles also need word-break to avoid overflow. */
@media (max-width: 575.98px) {
  .page-header .row.align-items-center { row-gap: var(--tl-space-3); }
  .page-header .col-auto.ms-auto { width: 100%; margin-left: 0 !important; }
  .page-header .col-auto.ms-auto > .d-flex,
  .page-header .col-auto.ms-auto { display: flex; flex-wrap: wrap; gap: var(--tl-space-2); }
  .page-header .col-auto.ms-auto .btn { flex: 1 1 auto; min-width: 140px; }
  .page-header .page-title { font-size: 20px; word-break: break-word; }
}

/* ────────────────────────────────────────────────────────────────────────
   6. CARDS — base + KPI + paywall variants
   ──────────────────────────────────────────────────────────────────────── */
.card {
  background: var(--tl-navy-700);
  border: 1px solid var(--tl-border);
  border-radius: var(--tl-radius-md);
  box-shadow: var(--tl-shadow-sm);
  transition: border-color var(--tl-dur) var(--tl-ease),
              box-shadow var(--tl-dur) var(--tl-ease);
}
.card-header {
  border-bottom: 1px solid var(--tl-border);
  padding: var(--tl-space-4) var(--tl-space-5);
  background: transparent;
  /* Stack card-title + card-subtitle vertically — fixes the orders-mobile
     "Order history" heading wrapping into the body copy at narrow widths */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.card-header .card-title { margin: 0; }
.card-header .card-subtitle {
  margin: 0;
  font-size: var(--tl-fs-small);
  color: var(--tl-ink-300);
  font-weight: 400;
  line-height: 1.45;
}
.card-body { padding: var(--tl-space-5); }
.card-title { color: var(--tl-ink-100); }

/* Paywall card variant — gold accent border instead of Tabler's harsh orange */
.card.border-warning {
  border-color: var(--tl-border-gold);
  box-shadow: var(--tl-shadow-gold);
}
.tl-paywall-icon {
  font-size: 28px;
  line-height: 1;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.4));
}

/* ── KPI cards — the 4-up row on /dashboard ── */
.tl-kpi-card {
  background: var(--tl-navy-700);
  border: 1px solid var(--tl-border);
  border-radius: var(--tl-radius-md);
  padding: var(--tl-space-5);
  position: relative;
  height: 100%;
  /* Tabler's .row-deck makes parent cols `display: flex` (for equal heights),
     which means without an explicit width: 100% on the card, each card sizes
     to its content's natural width — and tiles with shorter copy (Pulse
     "Latest investigation ready." vs Watchlist's wrapped multi-line body)
     end up narrower than their col. Forces every card to fill its col,
     keeping gutters uniform across the row. */
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 156px;
  overflow: hidden;
  box-shadow: var(--tl-shadow-sm);
  transition:
    transform var(--tl-dur) var(--tl-ease),
    border-color var(--tl-dur) var(--tl-ease),
    box-shadow var(--tl-dur) var(--tl-ease);
}
.tl-kpi-card:hover {
  border-color: var(--tl-border-strong);
  box-shadow: var(--tl-shadow-md);
  transform: translateY(-1px);
}
.tl-kpi-card::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: linear-gradient(180deg, var(--tl-gold-500) 0%, rgba(218, 165, 32, 0.2) 100%);
}
.tl-kpi-card .tl-kpi-label {
  font-size: var(--tl-fs-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tl-ink-300);
  margin-bottom: var(--tl-space-2);
  display: flex;
  align-items: center;
  gap: 6px;
}
.tl-kpi-card .tl-kpi-label .badge {
  font-size: 9px;
  letter-spacing: 0.06em;
  padding: 2px 5px;
  text-transform: uppercase;
}
.tl-kpi-card .tl-kpi-value {
  font-size: var(--tl-fs-display);
  font-weight: 700;
  color: var(--tl-ink-100);
  line-height: var(--tl-lh-tight);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.tl-kpi-card .tl-kpi-headline {
  font-size: var(--tl-fs-small);
  color: var(--tl-ink-300);
  margin-top: var(--tl-space-2);
  line-height: 1.45;
}
.tl-kpi-card .tl-kpi-link {
  font-size: var(--tl-fs-small);
  font-weight: 600;
  color: var(--tl-gold-500);
  margin-top: var(--tl-space-3);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  text-decoration: none;
  align-self: flex-start;
  transition: color var(--tl-dur) var(--tl-ease), gap var(--tl-dur) var(--tl-ease);
}
.tl-kpi-card .tl-kpi-link:hover {
  color: var(--tl-gold-400);
  gap: 9px;
}

/* Editorial KPI variant — for tiles whose "value" is a state or a sentence,
   not a number. The headline takes over the visual-anchor role that the
   giant numeric value plays in metric tiles (Orders/Research), so the four
   tiles feel like equal-weight rectangles in the row. The status pill is
   demoted to a small annotation above the headline. Used by Today's Pulse
   + Watchlist (Free) — both editorial-by-nature, not metric-driven. */
.tl-kpi-card.tl-kpi-editorial .tl-kpi-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--tl-fs-micro);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(74, 222, 128, 0.12);
  color: var(--tl-success);
  margin-bottom: var(--tl-space-3);
  align-self: flex-start;
}
.tl-kpi-card.tl-kpi-editorial .tl-kpi-status[data-state="muted"] {
  background: rgba(255, 255, 255, 0.06);
  color: var(--tl-ink-300);
}
.tl-kpi-card.tl-kpi-editorial .tl-kpi-status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.16);
}
.tl-kpi-card.tl-kpi-editorial .tl-kpi-status[data-state="muted"]::before {
  box-shadow: none;
  opacity: 0.6;
}
.tl-kpi-card.tl-kpi-editorial .tl-kpi-headline {
  font-size: var(--tl-fs-h2);    /* 18px — matches the visual weight of the */
  color: var(--tl-ink-100);      /*       numeric value's anchoring presence */
  font-weight: 600;
  line-height: 1.3;
  margin-top: 0;
  letter-spacing: -0.01em;
}
/* Push the CTA link to the bottom of every KPI tile regardless of how
   short the body content is — keeps row-deck-equalized tiles visually
   balanced rather than leaving dead space at the bottom of editorial cards. */
.tl-kpi-card .tl-kpi-link {
  margin-top: auto;
}

/* Page-header back-link breadcrumb — used on dashboard sub-pages
   (Submit COA, etc.) to give a quick "back to /dashboard" affordance
   above the page title, in addition to the standard sidebar nav. */
.tl-back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--tl-ink-300);
  text-decoration: none;
  font-size: var(--tl-fs-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: color var(--tl-dur) var(--tl-ease), gap var(--tl-dur) var(--tl-ease);
}
.tl-back-link:hover {
  color: var(--tl-gold-500);
  gap: 9px;
}

/* Quick-actions grid layout — used when Quick actions occupies the wide
   column (col-lg-8 on /dashboard). Each action becomes a 2-row chip with
   icon, label, and a sub-caption. Stacks single-column on mobile. */
.tl-quick-actions-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--tl-space-3);
}
@media (min-width: 992px) {
  .tl-quick-actions-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
/* Action chips are intentionally lightweight — no per-chip border or
   background by default. Visual structure comes from the parent card and
   the grid gutter; chips earn a frame only on hover (affordance) and on
   the two semantic accent states (is-primary, is-upgrade). This avoids
   the "boxes inside boxes" feel of fully-framed chips. */
.tl-quick-actions-grid .tl-action {
  display: flex;
  align-items: flex-start;
  gap: var(--tl-space-3);
  padding: var(--tl-space-3) var(--tl-space-4);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--tl-radius-md);
  text-decoration: none;
  color: var(--tl-ink-100);
  transition:
    border-color var(--tl-dur) var(--tl-ease),
    background var(--tl-dur) var(--tl-ease),
    transform var(--tl-dur) var(--tl-ease);
}
.tl-quick-actions-grid .tl-action:hover {
  border-color: var(--tl-border-strong);
  background: rgba(255, 255, 255, 0.025);
  transform: translateY(-1px);
}
.tl-quick-actions-grid .tl-action.is-primary {
  border-color: var(--tl-border-gold);
  background: linear-gradient(180deg, rgba(218, 165, 32, 0.10), rgba(218, 165, 32, 0.04));
}
.tl-quick-actions-grid .tl-action.is-primary:hover {
  border-color: var(--tl-gold-500);
  background: linear-gradient(180deg, rgba(218, 165, 32, 0.16), rgba(218, 165, 32, 0.06));
}
.tl-quick-actions-grid .tl-action.is-upgrade {
  border-color: var(--tl-border-gold);
  background: rgba(218, 165, 32, 0.04);
}
.tl-quick-actions-grid .tl-action .tl-action-icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--tl-radius-sm);
  background: rgba(255, 255, 255, 0.04);
  color: var(--tl-gold-500);
}
.tl-quick-actions-grid .tl-action .tl-action-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.tl-quick-actions-grid .tl-action .tl-action-label {
  font-size: var(--tl-fs-body);
  font-weight: 600;
  color: var(--tl-ink-100);
  line-height: 1.25;
}
.tl-quick-actions-grid .tl-action .tl-action-caption {
  font-size: var(--tl-fs-small);
  color: var(--tl-ink-300);
  line-height: 1.35;
}
.tl-quick-actions-grid .tl-action.is-disabled {
  opacity: 0.6;
  pointer-events: none;
}

/* ────────────────────────────────────────────────────────────────────────
   7. BUTTONS — unified height/padding/states across all 6 pages
   ──────────────────────────────────────────────────────────────────────── */
.btn {
  font-weight: 500;
  border-radius: var(--tl-radius-sm);
  padding: 8px 14px;
  font-size: var(--tl-fs-body);
  line-height: 1.4;
  letter-spacing: 0.005em;
  border-width: 1px;
  transition:
    background-color var(--tl-dur) var(--tl-ease),
    border-color var(--tl-dur) var(--tl-ease),
    color var(--tl-dur) var(--tl-ease),
    transform var(--tl-dur-fast) var(--tl-ease),
    box-shadow var(--tl-dur) var(--tl-ease);
}
.btn:focus-visible {
  outline: 2px solid var(--tl-gold-500);
  outline-offset: 2px;
  box-shadow: none;
}
.btn:active { transform: translateY(1px); }

.btn-sm {
  padding: 5px 10px;
  font-size: var(--tl-fs-small);
  border-radius: var(--tl-radius-sm);
}
.btn-lg {
  padding: 11px 18px;
  font-size: 15px;
}

/* Primary brand button (gold) — solid, navy ink */
.btn-yellow,
.btn-yellow:link,
.btn-yellow:visited {
  background: var(--tl-gold-500);
  border-color: var(--tl-gold-500);
  color: var(--tl-navy-800);
  font-weight: 600;
}
.btn-yellow:hover,
.btn-yellow:focus {
  background: var(--tl-gold-400);
  border-color: var(--tl-gold-400);
  color: var(--tl-navy-800);
  box-shadow: var(--tl-shadow-gold);
}
.btn-yellow:active {
  background: var(--tl-gold-600);
  border-color: var(--tl-gold-600);
}
.btn-yellow:disabled,
.btn-yellow.disabled {
  background: rgba(218, 165, 32, 0.45);
  border-color: rgba(218, 165, 32, 0.45);
  color: rgba(15, 30, 61, 0.7);
}

/* Outline button — secondary action */
.btn-outline-secondary {
  color: var(--tl-ink-100);
  border-color: var(--tl-border-strong);
  background: transparent;
}
.btn-outline-secondary:hover,
.btn-outline-secondary:focus {
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--tl-gold-500);
  color: var(--tl-gold-500);
}

/* Ghost / link-style button */
.btn-link {
  color: var(--tl-gold-500);
  text-decoration: none;
  padding: 6px 8px;
}
.btn-link:hover { color: var(--tl-gold-400); text-decoration: underline; }

/* Destructive */
.btn-outline-danger {
  color: var(--tl-danger);
  border-color: rgba(248, 113, 113, 0.4);
}
.btn-outline-danger:hover {
  background: rgba(248, 113, 113, 0.08);
  border-color: var(--tl-danger);
  color: var(--tl-danger);
}

/* Outline-warning (used by free-tier upgrade button) — gold-tinted */
.btn-outline-warning {
  color: var(--tl-gold-500);
  border-color: var(--tl-gold-500);
  background: transparent;
}
.btn-outline-warning:hover,
.btn-outline-warning:focus {
  background: var(--tl-gold-500);
  border-color: var(--tl-gold-500);
  color: var(--tl-navy-800);
}

/* ────────────────────────────────────────────────────────────────────────
   8. QUICK-ACTIONS card — left-aligned button stack with icon gutter
   ──────────────────────────────────────────────────────────────────────── */
.tl-quick-actions { padding: var(--tl-space-4) var(--tl-space-5); }
.tl-quick-actions .btn {
  width: 100%;
  text-align: left;
  display: flex;
  align-items: center;
  gap: var(--tl-space-3);
  margin-bottom: var(--tl-space-2);
  padding: 10px 14px;
  font-weight: 500;
  border-radius: var(--tl-radius-sm);
}
.tl-quick-actions .btn:last-child { margin-bottom: 0; }
.tl-quick-actions .btn svg { flex-shrink: 0; opacity: 0.9; }
.tl-quick-actions .btn-yellow {
  margin-bottom: var(--tl-space-3);
  box-shadow: var(--tl-shadow-sm);
}
.tl-quick-actions .btn-outline-secondary {
  background: transparent;
  border-color: var(--tl-border);
  color: var(--tl-ink-100);
}
.tl-quick-actions .btn-outline-secondary:hover {
  background: rgba(218, 165, 32, 0.08);
  border-color: var(--tl-gold-500);
  color: var(--tl-gold-500);
}

/* ────────────────────────────────────────────────────────────────────────
   9. FORM CONTROLS
   ──────────────────────────────────────────────────────────────────────── */
.form-control,
.form-select {
  background-color: var(--tl-navy-800);
  border: 1px solid var(--tl-border-strong);
  color: var(--tl-ink-100);
  border-radius: var(--tl-radius-sm);
  padding: 8px 12px;
  font-size: var(--tl-fs-body);
  transition: border-color var(--tl-dur) var(--tl-ease), box-shadow var(--tl-dur) var(--tl-ease);
}
.form-control:focus,
.form-select:focus {
  border-color: var(--tl-gold-500);
  box-shadow: 0 0 0 3px rgba(218, 165, 32, 0.18);
  background-color: var(--tl-navy-800);
  color: var(--tl-ink-100);
}
.form-label {
  font-size: var(--tl-fs-small);
  font-weight: 500;
  color: var(--tl-ink-300);
  margin-bottom: 6px;
}

/* ────────────────────────────────────────────────────────────────────────
   10. ALERTS / BANNERS (founding-20 strip, free-tier strip)
   ──────────────────────────────────────────────────────────────────────── */
.alert {
  border-radius: var(--tl-radius-md);
  border: 1px solid var(--tl-border);
  padding: var(--tl-space-3) var(--tl-space-4);
  font-size: var(--tl-fs-small);
}
.alert-warning {
  background: linear-gradient(180deg, rgba(218, 165, 32, 0.10), rgba(218, 165, 32, 0.04));
  border-color: var(--tl-border-gold);
  color: var(--tl-ink-100);
}
.alert-secondary {
  background: rgba(255, 255, 255, 0.025);
  border-color: var(--tl-border);
  color: var(--tl-ink-100);
}
.alert strong { color: var(--tl-ink-100); }

/* ────────────────────────────────────────────────────────────────────────
   11. TABLES
   ──────────────────────────────────────────────────────────────────────── */
.table-vcenter > :not(caption) > * > * { vertical-align: middle; }
.table.card-table {
  color: var(--tl-ink-100);
  margin: 0;
}
.table.card-table thead th {
  color: var(--tl-ink-300);
  font-size: var(--tl-fs-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: var(--tl-space-3) var(--tl-space-4);
  border-bottom: 1px solid var(--tl-border);
  background: rgba(255, 255, 255, 0.015);
}
.table.card-table tbody td {
  padding: var(--tl-space-3) var(--tl-space-4);
  border-color: var(--tl-border);
  font-size: var(--tl-fs-body);
}
.table.card-table tbody tr {
  transition: background-color var(--tl-dur) var(--tl-ease);
}
.table.table-hover tbody tr:hover,
.table.card-table tbody tr:hover { background: rgba(255, 255, 255, 0.025); }

/* ────────────────────────────────────────────────────────────────────────
   12. BADGES (status, plan-tier, watchlist kind)
   ──────────────────────────────────────────────────────────────────────── */
.badge {
  font-size: var(--tl-fs-micro);
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 4px 8px;
  border-radius: 4px;
}
.bg-yellow-lt {
  background: rgba(218, 165, 32, 0.14) !important;
  color: var(--tl-gold-500) !important;
}
.bg-blue-lt {
  background: rgba(173, 189, 232, 0.14) !important;
  color: var(--tl-info) !important;
}
.bg-green-lt {
  background: rgba(74, 222, 128, 0.14) !important;
  color: var(--tl-success) !important;
}

.avatar.bg-yellow { background: var(--tl-gold-500); }
.avatar.text-navy { color: var(--tl-navy-800); }

/* ────────────────────────────────────────────────────────────────────────
   13. EMPTY STATES + ACTIVITY FEED
   ──────────────────────────────────────────────────────────────────────── */
.empty {
  padding: var(--tl-space-8) var(--tl-space-6);
}
.empty .empty-icon {
  color: var(--tl-gold-500);
  opacity: 0.55;
}
.empty .empty-title {
  font-size: var(--tl-fs-h2);
  font-weight: 600;
  margin-top: var(--tl-space-3);
  color: var(--tl-ink-100);
}
.empty .empty-subtitle {
  font-size: var(--tl-fs-small);
  color: var(--tl-ink-300);
  max-width: 48ch;
  margin-left: auto;
  margin-right: auto;
}

.tl-activity-feed .list-group-item {
  background: transparent;
  border-color: var(--tl-border);
  padding: var(--tl-space-3) 0;
  display: flex;
  gap: var(--tl-space-3);
  align-items: flex-start;
}
.tl-activity-feed .list-group-item:first-child { border-top: 0; }
.tl-activity-feed .activity-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--tl-gold-500);
  margin-top: 6px;
  flex-shrink: 0;
  box-shadow: 0 0 0 3px rgba(218, 165, 32, 0.15);
}
.tl-activity-feed .activity-time {
  font-size: var(--tl-fs-micro);
  color: var(--tl-ink-300);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-family: var(--tl-font-mono);
}
.tl-activity-feed .activity-body {
  font-size: var(--tl-fs-body);
  color: var(--tl-ink-100);
  line-height: 1.45;
}
.tl-activity-feed .activity-meta {
  font-size: var(--tl-fs-small);
  color: var(--tl-ink-300);
  margin-top: 2px;
}

/* ────────────────────────────────────────────────────────────────────────
   14. RESEARCH list-group (article rows)
   ──────────────────────────────────────────────────────────────────────── */
.list-group-item-action {
  padding: var(--tl-space-4) var(--tl-space-5);
  border-color: var(--tl-border) !important;
  transition: background-color var(--tl-dur) var(--tl-ease);
}
.list-group-item-action:hover {
  background: rgba(255, 255, 255, 0.025);
  color: var(--tl-ink-100);
}
.list-group-item-action h4 {
  font-size: var(--tl-fs-h3);
  font-weight: 600;
  color: var(--tl-ink-100);
  margin: 0 0 4px;
}
.list-group-item-action small {
  color: var(--tl-ink-300);
  font-family: var(--tl-font-mono);
  font-size: var(--tl-fs-micro);
}
.list-group-item-action p { font-size: var(--tl-fs-small); color: var(--tl-ink-300); margin: 0; }

/* ────────────────────────────────────────────────────────────────────────
   15. PROGRESS (routed-orders bar)
   ──────────────────────────────────────────────────────────────────────── */
.progress {
  background: rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  height: 6px;
}
.progress-bar.bg-yellow {
  background: linear-gradient(90deg, var(--tl-gold-600), var(--tl-gold-500), var(--tl-gold-400));
  border-radius: 999px;
  transition: width var(--tl-dur-slow) var(--tl-ease);
}

/* ────────────────────────────────────────────────────────────────────────
   16. MODAL — add-watchlist-modal
   ──────────────────────────────────────────────────────────────────────── */
.modal-content {
  background: var(--tl-navy-700);
  border: 1px solid var(--tl-border-strong);
  border-radius: var(--tl-radius-lg);
  box-shadow: var(--tl-shadow-lg);
}
.modal-header {
  border-bottom: 1px solid var(--tl-border);
  padding: var(--tl-space-4) var(--tl-space-5);
}
.modal-body { padding: var(--tl-space-5); }
.modal-footer {
  border-top: 1px solid var(--tl-border);
  padding: var(--tl-space-3) var(--tl-space-5);
  gap: var(--tl-space-2);
}

/* ────────────────────────────────────────────────────────────────────────
   17. FOOTER
   ──────────────────────────────────────────────────────────────────────── */
.footer.footer-transparent {
  border-top: 1px solid var(--tl-border);
  padding: var(--tl-space-5) 0;
  font-size: var(--tl-fs-small);
  color: var(--tl-ink-300);
}
.footer .link-secondary {
  color: var(--tl-ink-300);
  transition: color var(--tl-dur) var(--tl-ease);
}
.footer .link-secondary:hover { color: var(--tl-gold-500); }

/* ────────────────────────────────────────────────────────────────────────
   18. UTILITY OVERRIDES
   ──────────────────────────────────────────────────────────────────────── */
/* Spinner border in gold */
.spinner-border.spinner-border-sm { color: var(--tl-gold-500); }

/* Limit reading-width on prose containers — copy stays scannable */
.card-header .card-subtitle,
.empty-subtitle { max-width: 72ch; }

/* Reduced-motion respect */
@media (prefers-reduced-motion: reduce) {
  .tl-kpi-card,
  .card,
  .btn,
  .navbar-vertical .nav-link,
  .table.card-table tbody tr,
  .list-group-item-action,
  .tl-kpi-card .tl-kpi-link,
  .footer .link-secondary { transition: none !important; }
  .tl-kpi-card:hover { transform: none; }
}

/* ────────────────────────────────────────────────────────────────────────
   19. RESEARCH FEEDS (added 2026-05-10)
   Pro-tier dashboard surface at /dashboard/research/feeds + the cross-link
   promo card on /dashboard/research. All rules are additive (no edits to
   existing selectors above). Cache-buster on _base.html will be bumped by
   the operator after merging with parallel-agent CSS additions.
   ──────────────────────────────────────────────────────────────────────── */

/* Feed cards — same hover lift as .tl-kpi-card, sized for full-width
   article rows rather than 4-up KPI tiles. */
.tl-feed-card {
  background: var(--tl-navy-700);
  border: 1px solid var(--tl-border);
  border-radius: var(--tl-radius-md);
  transition:
    transform var(--tl-dur) var(--tl-ease),
    border-color var(--tl-dur) var(--tl-ease),
    box-shadow var(--tl-dur) var(--tl-ease);
}
.tl-feed-card:hover {
  border-color: var(--tl-border-strong);
  box-shadow: var(--tl-shadow-md);
  transform: translateY(-1px);
}
.tl-feed-card .tl-feed-title {
  font-size: 1.05rem;
  line-height: 1.35;
  margin-bottom: var(--tl-space-2);
}
.tl-feed-card .tl-feed-title a {
  color: var(--tl-ink-100, #fff);
  text-decoration: none;
}
.tl-feed-card .tl-feed-title a:hover {
  color: var(--tl-gold-500);
  text-decoration: underline;
}
.tl-feed-card .tl-feed-snippet {
  /* 2026-05-13: bumped from 92ch → 100ch with the structured-section
     redesign — cards now carry rich multi-section content so the
     legacy single-paragraph fallback can use the full article width.
     Still inside the typographic comfort band's upper bound. */
  max-width: 100ch;
  font-size: 0.92rem;
  line-height: 1.5;
}

/* ── Structured-digest sections (2026-05-13 card-redesign) ─────────────
   Mirrors the Discord webhook embed's structure: ─── separator between
   sections, small-caps gold header per section, italic limitations
   block at the bottom, plus #tag chips. Drops the legacy <details>
   accordion entirely — the rich content was being buried behind a
   click while Discord operators got the full embed. */
.tl-feed-card .tl-feed-section {
  margin-top: var(--tl-space-3);
}
.tl-feed-card .tl-feed-section-header {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--tl-gold-500);
  font-weight: 600;
  margin-bottom: var(--tl-space-2);
}
.tl-feed-card .tl-feed-section-body {
  font-size: 0.92rem;
  line-height: 1.5;
  max-width: 100ch;
  color: var(--tl-ink-200, #cbd5e1);
}
/* markdown-rendered prose: zero out trailing <p> margin so sections
   stack tight. Mirrors the .tl-feed-snippet pattern above. */
.tl-feed-card .tl-feed-section-body > p:last-child,
.tl-feed-card .tl-feed-section-body > ul:last-child,
.tl-feed-card .tl-feed-section-body > ol:last-child {
  margin-bottom: 0;
}
.tl-feed-card .tl-feed-section-body ul,
.tl-feed-card .tl-feed-section-body ol {
  margin-bottom: 0.4rem;
  padding-left: 1.25rem;
}
.tl-feed-card .tl-feed-section-body a {
  color: var(--tl-gold-500, #d4af37);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.tl-feed-card .tl-feed-section-body code {
  font-size: 0.85rem;
  background: rgba(255, 255, 255, 0.04);
  padding: 0 0.25rem;
  border-radius: 3px;
}
/* Horizontal-rule separator between sections — visually matches the
   Discord embed's ``─ ─ ─ ─ ─ ─`` divider. Keeps the page navigable
   even when a card carries 5 sections. */
.tl-feed-card .tl-feed-section-divider {
  border: 0;
  border-top: 1px solid var(--tl-border);
  margin: var(--tl-space-3) 0;
  opacity: 0.7;
}
/* Key Findings: bullet list with gold ▸ marker matching the Discord
   embed's bullets. ``list-style: none`` lets us own the marker. */
.tl-feed-card .tl-feed-key-findings {
  list-style: none;
  padding-left: 0;
  margin-bottom: 0;
}
.tl-feed-card .tl-feed-key-findings li {
  padding-left: 1.25em;
  text-indent: -1.25em;
  margin-bottom: 0.35em;
  line-height: 1.45;
  font-size: 0.92rem;
}
.tl-feed-card .tl-feed-key-findings li::before {
  content: "▸";
  color: var(--tl-gold-500);
  margin-right: 0.5em;
  display: inline-block;
  width: 0.75em;
}
/* Limitations: italic block-quote-ish style. Distinct visual weight so
   the caveat doesn't compete with the affirmative sections. */
.tl-feed-card .tl-feed-limitations {
  font-style: italic;
  font-size: 0.85rem;
  color: var(--tl-ink-400, #94a3b8);
  margin-top: var(--tl-space-3);
  border-left: 3px solid var(--tl-warning, #cda434);
  padding-left: 0.75em;
}
.tl-feed-card .tl-feed-limitations > p {
  display: inline;
  margin: 0;
}
/* Tags row — small mono chips at the card footer, before the
   "Source: pubmed:... — Ingested ..." footer. */
.tl-feed-card .tl-feed-tags {
  display: flex;
  gap: 0.4em;
  flex-wrap: wrap;
  margin-top: var(--tl-space-3);
  margin-bottom: var(--tl-space-2);
}
.tl-feed-card .tl-feed-tag {
  font-family: var(--tl-font-mono, ui-monospace, "SF Mono", Menlo, monospace);
  font-size: 0.72rem;
  padding: 0.15em 0.5em;
  background: var(--tl-navy-800);
  border: 1px solid var(--tl-border);
  border-radius: var(--tl-radius-sm, 4px);
  color: var(--tl-ink-300, #94a3b8);
  white-space: nowrap;
}
/* 2026-05-13: markdown-rendered summary container — markdown-it wraps
   the prose in <p>, which inherits browser default margin and stacks
   awkwardly inside the .tl-feed-snippet div. Zero out the trailing
   margin so the badge + first paragraph stay tight. Bullet lists +
   inline links inherit Tabler/Bootstrap defaults. */
.tl-feed-card .tl-feed-snippet > p:last-child {
  margin-bottom: 0;
}
.tl-feed-card .tl-feed-snippet > p:first-child {
  display: inline;
}
.tl-feed-card .tl-feed-snippet ul,
.tl-feed-card .tl-feed-snippet ol {
  margin-bottom: 0.4rem;
  padding-left: 1.25rem;
}
.tl-feed-card .tl-feed-snippet a {
  color: var(--tl-gold-500, #d4af37);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.tl-feed-card .tl-feed-snippet a:hover {
  text-decoration: underline;
  filter: brightness(1.15);
}
.tl-feed-card .tl-feed-snippet code {
  font-size: 0.85rem;
  background: rgba(255, 255, 255, 0.04);
  padding: 0 0.25rem;
  border-radius: 3px;
}
/* NOTE: the legacy ``.tl-feed-details`` and ``.tl-feed-why-it-matters``
   rules were removed 2026-05-13 with the card redesign — the <details>
   accordion is gone, the rich digest renders inline via structured
   .tl-feed-section blocks. */
.tl-feed-card code {
  font-size: 0.78rem;
  opacity: 0.7;
  background: transparent;
  padding: 0;
}

/* Source-kind badges — color-coded so the timeline is scannable. */
.tl-feed-source-badge {
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: none;
  border: 1px solid transparent;
}
.tl-feed-source-badge[data-source="pubmed"] {
  background: rgba(43, 108, 176, 0.18);
  color: #79bcff;
  border-color: rgba(43, 108, 176, 0.45);
}
.tl-feed-source-badge[data-source="clinicaltrials"] {
  background: rgba(56, 178, 172, 0.16);
  color: #5be1d4;
  border-color: rgba(56, 178, 172, 0.45);
}
.tl-feed-source-badge[data-source="europepmc"] {
  background: rgba(159, 122, 234, 0.16);
  color: #c8a9ff;
  border-color: rgba(159, 122, 234, 0.45);
}
.tl-feed-source-badge[data-source="pubchem"] {
  background: rgba(72, 187, 120, 0.16);
  color: #7fe9a4;
  border-color: rgba(72, 187, 120, 0.45);
}

/* Filter chip row — All / PubMed / ClinicalTrials / EuropePMC / PubChem */
.tl-feed-filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--tl-space-2, 8px);
  align-items: center;
}
.tl-feed-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--tl-border);
  border-radius: 999px;
  background: var(--tl-navy-700);
  color: var(--tl-ink-200, #cbd5e1);
  font-size: 0.86rem;
  text-decoration: none;
  transition:
    border-color var(--tl-dur) var(--tl-ease),
    color var(--tl-dur) var(--tl-ease),
    background var(--tl-dur) var(--tl-ease);
}
.tl-feed-chip:hover {
  border-color: var(--tl-border-strong);
  color: var(--tl-ink-100, #fff);
  text-decoration: none;
}
.tl-feed-chip.is-active {
  border-color: var(--tl-border-gold);
  color: var(--tl-gold-500);
  background: rgba(218, 165, 32, 0.06);
}
.tl-feed-chip-count {
  font-size: 0.75rem;
  opacity: 0.7;
  font-variant-numeric: tabular-nums;
}

/* COE 2026-05-10 AI-5: secondary peptide chips. Smaller, lighter
 * weight to defer visually to the primary peptide chip while still
 * exposing the full extracted compound list at a glance. */
.tl-feed-extra-peptide-chip {
  font-size: 0.7rem;
  opacity: 0.78;
  padding-inline: 0.4rem;
}

/* Semantic-search input + relevance-score chip (search-on-feeds MVP) */
.tl-feed-search {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
  align-items: stretch;
}
.tl-feed-search input[type="search"] {
  flex: 1 1 auto;
}
.tl-feed-relevance-chip {
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  background: rgba(56, 142, 60, 0.18);
  color: #a8d8ad;
  border: 1px solid rgba(56, 142, 60, 0.35);
  border-radius: 999px;
  padding: 0.05rem 0.45rem;
  margin-left: 0.4rem;
  white-space: nowrap;
}

/* Cross-link promo card on /dashboard/research */
.tl-feed-promo-card {
  border: 1px solid var(--tl-border);
  background: linear-gradient(
    135deg,
    var(--tl-navy-700) 0%,
    rgba(218, 165, 32, 0.04) 100%
  );
  transition:
    border-color var(--tl-dur) var(--tl-ease),
    box-shadow var(--tl-dur) var(--tl-ease);
}
.tl-feed-promo-card:hover {
  border-color: var(--tl-border-gold);
  box-shadow: var(--tl-shadow-md);
}

@media (prefers-reduced-motion: reduce) {
  .tl-feed-card,
  .tl-feed-chip,
  .tl-feed-promo-card { transition: none !important; }
  .tl-feed-card:hover { transform: none; }
}

/* ── Bottom-left sidebar user menu (replaces top-right account dropdown) ─── */
.tl-sidebar-usermenu {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  padding-top: 8px;
}

.tl-usermenu-trigger {
  border-radius: 6px;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.tl-usermenu-trigger:hover,
.tl-usermenu-trigger:focus {
  background: rgba(255, 255, 255, 0.04);
  outline: none;
}

.tl-usermenu-trigger.active {
  background: rgba(218, 165, 32, 0.10);
}

.tl-sidebar-usermenu .dropdown-menu {
  min-width: 220px;
  margin-bottom: 4px;
}

/* Bug 5 (2026-05-11): force the sidebar account dropdown to open UPWARD
   even when Bootstrap's Popper.js positioner decides the menu fits below.
   The avatar sits at the bottom of a fixed-height sidebar so a downward
   menu clips on shorter viewports (Sign out lands at y=1092 on a 1100px
   tall window per the 2026-05-11 QA report).

   Root cause: Tabler's CSS leaves `.dropdown-menu` at `position: static`
   by default, so `inset: auto auto 100% 0` has no effect. Force
   absolute positioning + `bottom: 100%` so the menu always reflects above
   its trigger inside the .dropup wrapper. */
.tl-sidebar-usermenu .dropup {
  position: relative !important;
}
.tl-sidebar-usermenu .dropup .dropdown-menu,
.tl-sidebar-usermenu .dropdown-menu,
.tl-sidebar-usermenu .dropdown-menu.show {
  position: absolute !important;
  bottom: 100% !important;
  top: auto !important;
  left: 0 !important;
  right: auto !important;
  margin-top: 0 !important;
  margin-bottom: 4px !important;
  transform: none !important;
  inset: auto auto 100% 0 !important;
}

/* Watchlist polish 2026-05-11: newsworthy vendor cards get a left-edge
   gold accent so they're scannable at a glance. The accent is intentionally
   subtle (4px) rather than a full re-color — Tabler's `bg-orange-lt`
   "newsworthy" pill in the header already carries the loud signal. */
.tl-watch-card-newsworthy {
  border-left: 4px solid var(--tl-gold-500) !important;
}
/* SVG sparkline sits inline with the card text; force a baseline-align so
   the polyline doesn't drift relative to surrounding badges. */
.tl-watch-spark {
  display: inline-block;
  vertical-align: middle;
}

/* ── Tabler modal + toast polish (2026-05-11) ───────────────────────────
   Backs the shared tl-ui.js helpers (tlConfirm / tlToast / tlAlert) so the
   modals + toasts inherit the brand-token aesthetic instead of Tabler's
   default gray. Replaces oldschool-Windows window.alert / window.confirm
   across customer JS. */

/* Modal: tighter fade, brand colors */
.modal-backdrop.fade { transition: opacity var(--tl-dur) var(--tl-ease); }
.modal-backdrop.show { background: var(--tl-navy-900); opacity: 0.6; }
.modal-content {
  background: var(--tl-navy-700);
  border: 1px solid var(--tl-border-strong);
  border-radius: var(--tl-radius-md);
  box-shadow: var(--tl-shadow-lg);
}
.modal-header {
  border-bottom-color: var(--tl-border);
  padding: 16px 20px;
}
.modal-body {
  padding: 16px 20px;
  color: var(--tl-ink-300);
  line-height: var(--tl-lh-body);
}
.modal-footer {
  border-top-color: var(--tl-border);
  padding: 12px 20px;
}
.modal-title {
  font-size: 17px;
  font-weight: 600;
  color: var(--tl-ink-100);
}

/* Toast container: bottom-right, stack */
.toast-container { z-index: 1080; }
.toast {
  background: var(--tl-navy-700);
  border: 1px solid var(--tl-border-strong);
  border-radius: var(--tl-radius-md);
  box-shadow: var(--tl-shadow-md);
  color: var(--tl-ink-100);
  min-width: 280px;
  margin-bottom: 8px;
}
.toast .toast-header {
  background: transparent;
  color: var(--tl-ink-100);
  border-bottom: 1px solid var(--tl-border-strong);
}
.toast .toast-body {
  color: var(--tl-ink-300);
  line-height: var(--tl-lh-body);
}
.toast.tl-toast-success { border-left: 4px solid var(--tl-success); }
.toast.tl-toast-danger  { border-left: 4px solid var(--tl-danger); }
.toast.tl-toast-warning { border-left: 4px solid var(--tl-gold-500); }
.toast.tl-toast-info    { border-left: 4px solid var(--tl-info); }
