/* ── Typography ──────────────────────────────────────────────────
   Figtree  → body, UI labels, table content
   Bricolage Grotesque → large metric numbers (add .font-display)
   ---------------------------------------------------------------- */
body {
  font-family: 'Figtree', system-ui, -apple-system, sans-serif;
}
.font-display {
  font-family: 'Bricolage Grotesque', system-ui, sans-serif;
  font-variation-settings: 'opsz' 32;
}

/* ── Skip-to-content link ────────────────────────────────────────
   Invisible until focused by keyboard — satisfies WCAG 2.4.1.
   ---------------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
  z-index: 9999;
  text-decoration: none;
}
.skip-link:focus {
  position: fixed;
  top: 12px;
  left: 12px;
  width: auto;
  height: auto;
  padding: 8px 18px;
  background: var(--brand-blue);
  color: #fff;
  border-radius: 8px;
  font-size: 0.875rem;
  font-weight: 600;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.25);
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* ── Dashboard visual upgrades ─────────────────────────────────── */

/* Title icon badge */
.title-icon-badge {
  background: linear-gradient(135deg, var(--brand-blue) 0%, var(--brand-blue-hover) 100%);
  width: 32px;
  height: 32px;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: 0 2px 8px color-mix(in srgb, var(--brand-blue) 35%, transparent);
}

/* Platform card color-coded top accents — use brand tokens, not raw hex.
   Mapping per .impeccable.md: Blue = PayPal, Orange = Wells Fargo,
   Green = Live Oak. PayPal and Live Oak were previously swapped; the
   .source-pill--* rules below always had it right. */
.platform-card-paypal   { border-top: 3px solid var(--brand-blue) !important; }
.platform-card-wf       { border-top: 3px solid var(--brand-orange) !important; }
.platform-card-live-oak { border-top: 3px solid var(--brand-green) !important; }

/* Card section header tints */
.card-header-tint {
  background: linear-gradient(90deg, #f4f8fc 0%, #fff 60%);
}
html.dark .card-header-tint { background: transparent; }

/* Section left-rule accent */
.section-rule {
  display: inline-block;
  width: 3px;
  height: 14px;
  border-radius: 2px;
  background: var(--brand-blue);
  flex-shrink: 0;
}

/* ── Nav tabs ─────────────────────────────────────────────────── */
.nav-tab {
    display: inline-flex;
    align-items: center;
    padding: 0.625rem 0.875rem;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--t-muted);
    border-bottom: 2px solid transparent;
    white-space: nowrap;
    transition: color 0.15s, border-color 0.15s;
    text-decoration: none;
}
.nav-tab:hover { color: var(--t-body); }
.nav-tab--active {
    color: var(--brand-blue);
    border-bottom-color: var(--brand-blue);
}
html.dark .nav-tab { color: #94a3b8; }
html.dark .nav-tab:hover { color: #f1f5f9; background-color: rgba(255,255,255,0.05); }
html.dark .nav-tab--active { color: var(--brand-blue); border-bottom-color: var(--brand-blue); }

/* ── Source pills ─────────────────────────────────────────────── */
.source-pill {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.625rem;
    border-radius: 9999px;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}
.source-pill--paypal,
.source-pill--paypal_paypal {
    background: var(--brand-blue-surface);
    color: var(--brand-blue-text);
}
.source-pill--wells_fargo,
.source-pill--plaid_wells_fargo {
    background: var(--brand-orange-surface);
    color: var(--brand-orange-text);
}
.source-pill--live_oak,
.source-pill--plaid_live_oak {
    background: var(--brand-green-surface);
    color: var(--brand-green-text);
}
.source-pill--manual {
    background: var(--s-raised);
    color: var(--t-muted);
}

/* ── Brand utility classes (supplement theme.css) ─────────────── */
.bg-brand-blue-light   { background-color: var(--brand-blue-surface); }
.bg-brand-orange-light { background-color: var(--brand-orange-surface); }
.bg-brand-green-light  { background-color: var(--brand-green-surface); }
.brand-blue     { color: var(--brand-blue); }
.brand-green    { color: var(--brand-green); }
.brand-orange   { color: var(--brand-orange); }
/* Border color utilities for platform filter tabs */
.border-brand-green  { border-color: var(--brand-green) !important; }
.border-brand-blue   { border-color: var(--brand-blue) !important; }
.border-brand-orange { border-color: var(--brand-orange) !important; }

/* ── Focus rings ─────────────────────────────────────────────── */
/* The ring must be perceivable: rgba(29,112,166,0.15) composites to #ddeaf2,
   which is 1.23:1 against a white card. WCAG 1.4.11 requires 3:1. A solid
   --brand-blue ring is 5.36:1. The inner card-coloured ring separates it from
   the control's own border. */
.focus\:border-brand-blue:focus { border-color: var(--brand-blue) !important; }
.focus\:ring-2:focus {
  box-shadow: 0 0 0 2px var(--s-card), 0 0 0 4px var(--brand-blue) !important;
}

/* ── Transition helpers ──────────────────────────────────────── */
.transition-colors { transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease; }

/* ── bg-brand-blue-hover ─────────────────────────────────────── */
.bg-brand-blue-hover { background-color: var(--brand-blue-hover); }
.hover\:bg-brand-blue-hover:hover { background-color: var(--brand-blue-hover); }

/* ── Dark mode display utilities ─────────────────────────────────
   The vendored Tailwind build omits dark:display variants entirely.
   These rules replicate dark:hidden / dark:block / dark:inline-block /
   dark:inline-flex / dark:flex so logo swap patterns work correctly.
   ---------------------------------------------------------------- */
html.dark .dark\:hidden        { display: none !important; }
html.dark .dark\:block         { display: block !important; }
html.dark .dark\:inline-block  { display: inline-block !important; }
html.dark .dark\:inline-flex   { display: inline-flex !important; }
html.dark .dark\:flex          { display: flex !important; }

/* ── Platform card — now links, so hover lift is meaningful ─── */
.platform-card-paypal,
.platform-card-wf,
.platform-card-live-oak {
  transition: transform 0.18s ease, box-shadow 0.18s ease;
  cursor: pointer;
  text-decoration: none;
  display: block;
}
.platform-card-paypal:hover,
.platform-card-wf:hover,
.platform-card-live-oak:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08) !important;
}
html.dark .platform-card-paypal:hover,
html.dark .platform-card-wf:hover,
html.dark .platform-card-live-oak:hover {
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.40) !important;
}

/* ── Goal progress bar ───────────────────────────────────────
   Static brand-blue fill; shimmer only when motion is allowed.
   ------------------------------------------------------------ */
.goal-progress-bar {
  background: var(--brand-blue);
}
@keyframes progressShimmer {
  0%   { background-position: -300% center; }
  100% { background-position: 300% center; }
}
@media (prefers-reduced-motion: no-preference) {
  .goal-progress-bar {
    background: linear-gradient(
      90deg,
      color-mix(in srgb, var(--brand-blue) 85%, white) 0%,
      color-mix(in srgb, var(--brand-blue) 85%, white) 38%,
      white                                             50%,
      color-mix(in srgb, var(--brand-blue) 85%, white) 62%,
      color-mix(in srgb, var(--brand-blue) 85%, white) 100%
    );
    background-size: 300% auto;
    animation: progressShimmer 3.5s linear infinite;
  }
}

/* ── Receipt table empty state ──────────────────────────────── */
.receipts-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 44px 20px;
  color: var(--t-muted);
  font-size: 0.875rem;
}
.receipts-empty-state svg {
  opacity: 0.30;
  color: var(--t-muted);
}
.receipts-empty-state .empty-hint {
  font-size: 0.75rem;
  color: var(--t-faint);
}

/* ── Pace card: run-rate projection box — dark mode overrides ────
   The vendored Tailwind build omits dark:bg-*/dark:border-* for
   orange-900/green-900 surfaces. These rules fill the gap.
   ---------------------------------------------------------------- */
html.dark .run-rate-box--positive {
  background-color: rgba(20, 83, 45, 0.25) !important;  /* green-900/25 */
  border-color:     rgba(22, 101, 52, 0.5) !important;  /* green-800/50 */
}
html.dark .run-rate-box--negative {
  background-color: rgba(124, 45, 18, 0.25) !important; /* orange-900/25 */
  border-color:     rgba(154, 52, 18, 0.5) !important;  /* orange-800/50 */
}

/* ══════════════════════════════════════════════════════════════════
   Accessibility & typography corrections
   Added after a WCAG 2.2 AA audit. See notes on each block.
   ══════════════════════════════════════════════════════════════════ */

/* ── Tabular figures ─────────────────────────────────────────────
   Figtree and Bricolage are proportional by default, so "1" is
   narrower than "8" and currency columns jitter row to row. This is
   a numbers-first dashboard; digits must line up. */
table td, table th,
.font-display, .tnum {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ── Light-mode text contrast ────────────────────────────────────
   --t-faint (#9ca3af) is 2.54:1 on white and documented as
   decorative-only, but .text-gray-400 was used for ~40 pieces of
   real content (stat labels, "% of total", the Sign out link, fee
   amounts). Dark mode already remapped these; light mode did not,
   so the DEFAULT theme was the failing one. */
html:not(.dark) .text-gray-400 { color: var(--t-muted) !important; }  /* 4.83:1 */
html:not(.dark) .text-gray-300 { color: var(--t-muted) !important; }  /* was 1.47:1 */
html:not(.dark) .text-slate-400 { color: var(--t-muted) !important; }
html:not(.dark) .text-slate-500 { color: var(--t-muted) !important; }

/* Required-field asterisks were #f87171 (2.77:1) — often the only
   indication a field is required. */
html:not(.dark) .text-red-400 { color: var(--status-error-text) !important; }

/* ── Button fills ────────────────────────────────────────────────
   White label text needs 4.5:1. amber-500 gave 2.15:1 and green-600
   gave 3.30:1 — both fail, and one of them is "Send to Queue". */
.bg-amber-500 { background-color: #b45309 !important; }  /* white 5.02:1 */
.hover\:bg-amber-600:hover { background-color: #92400e !important; }
.bg-green-600 { background-color: #15803d !important; }  /* white 5.02:1 */
.hover\:bg-green-700:hover { background-color: #166534 !important; }

/* ── Focus not obscured (WCAG 2.4.11) ────────────────────────────
   The header is sticky at 56px; without this the browser scrolls a
   focused table row underneath it. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
  scroll-margin-top: 5rem;
}

/* ── Reduced motion ──────────────────────────────────────────────
   The D3 charts and modals already honour this; the spinners and
   hover transforms did not. */
@media (prefers-reduced-motion: reduce) {
  .animate-spin { animation: none !important; }
  .platform-card-paypal:hover,
  .platform-card-wf:hover,
  .platform-card-live-oak:hover { transform: none !important; }
  html { scroll-behavior: auto !important; }
}

/* ══════════════════════════════════════════════════════════════════
   Missing Tailwind utilities
   The vendored static/vendor/tailwind.min.css is a partial build: ~130
   classes used across the templates emit no CSS at all, so those styles
   silently do nothing. Rebuilding Tailwind is the real fix; until then
   these fill the gaps that have a visible consequence.
   ══════════════════════════════════════════════════════════════════ */

/* Layout */
.max-w-7xl   { max-width: 80rem; }
.max-w-\[60\%\] { max-width: 60%; }
.max-h-\[90vh\] { max-height: 90vh; }
.min-w-\[220px\] { min-width: 220px; }
.w-\[76px\]  { width: 76px; }
.w-40 { width: 10rem; } .w-48 { width: 12rem; }
.w-80 { width: 20rem; } .w-96 { width: 24rem; } .w-px { width: 1px; }
.h-px { height: 1px; } .h-0\.5 { height: .125rem; } .h-1 { height: .25rem; }
.z-30 { z-index: 30; } .z-40 { z-index: 40; }
.top-10 { top: 2.5rem; } .bottom-0 { bottom: 0; } .bottom-6 { bottom: 1.5rem; }
.left-1\/2 { left: 50%; }
.-translate-x-1\/2 { transform: translateX(-50%); }
.self-center { align-self: center; }
.border-0 { border-width: 0; }
.tracking-tight { letter-spacing: -0.015em; }
.backdrop-blur-sm { backdrop-filter: blur(4px); }

/* Spacing the build omitted */
.gap-5 { gap: 1.25rem; }
.mx-4 { margin-left: 1rem; margin-right: 1rem; }
.mx-0\.5 { margin-left: .125rem; margin-right: .125rem; }
.mr-1 { margin-right: .25rem; } .ml-1\.5 { margin-left: .375rem; }
.mt-5 { margin-top: 1.25rem; } .mt-8 { margin-top: 2rem; } .mb-10 { margin-bottom: 2.5rem; }
.-mt-2 { margin-top: -.5rem; } .-mt-0\.5 { margin-top: -.125rem; } .-mr-0\.5 { margin-right: -.125rem; }
.p-0\.5 { padding: .125rem; } .p-12 { padding: 3rem; }
.pl-1 { padding-left: .25rem; } .pl-6 { padding-left: 1.5rem; } .pr-2 { padding-right: .5rem; }
.pb-3 { padding-bottom: .75rem; } .pb-12 { padding-bottom: 3rem; } .pb-16 { padding-bottom: 4rem; }
.pt-7 { padding-top: 1.75rem; } .pt-8 { padding-top: 2rem; }
.py-3\.5 { padding-top: .875rem; padding-bottom: .875rem; }
.py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; }
.py-7 { padding-top: 1.75rem; padding-bottom: 1.75rem; }

/* Responsive variants the build dropped — tablet is a stated use case */
@media (min-width: 640px) {
  .sm\:flex { display: flex; }
  .sm\:inline { display: inline; }
  .sm\:table-cell { display: table-cell; }
  .sm\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .sm\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
  .sm\:px-5 { padding-left: 1.25rem; padding-right: 1.25rem; }
  .sm\:px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
}
@media (min-width: 768px)  { .md\:table-cell { display: table-cell; } }
@media (min-width: 1024px) {
  .lg\:table-cell { display: table-cell; }
  .lg\:col-span-2 { grid-column: span 2 / span 2; }
  .lg\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
  .lg\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
}

/* Colours — modal backdrops were fully transparent without these */
.bg-black\/40 { background-color: rgba(0,0,0,.4); }
.bg-white\/15 { background-color: rgba(255,255,255,.15); }
.bg-white\/20 { background-color: rgba(255,255,255,.2); }
.bg-white\/25 { background-color: rgba(255,255,255,.25); }
.hover\:bg-white\/25:hover { background-color: rgba(255,255,255,.25); }
.bg-gray-50\/60 { background-color: rgba(249,250,251,.6); }
.hover\:bg-gray-50\/70:hover { background-color: rgba(249,250,251,.7); }
.bg-green-50\/20 { background-color: rgba(240,253,244,.2); }
.bg-green-50\/30 { background-color: rgba(240,253,244,.3); }
.bg-amber-50\/30 { background-color: rgba(255,251,235,.3); }
.bg-slate-100 { background-color: #f1f5f9; }
.bg-amber-900 { background-color: #78350f; }
.text-amber-100 { color: #fef3c7; }
.hover\:bg-amber-800:hover { background-color: #92400e; }
.bg-blue-400 { background-color: #60a5fa; }
.bg-green-400 { background-color: #4ade80; }
.bg-orange-400 { background-color: #fb923c; }
.bg-amber-500 { background-color: #b45309; }          /* darkened for AA */
.text-blue-800 { color: #1e40af; }
.text-green-500 { color: #16a34a; }
.text-amber-700\/70 { color: rgba(180,83,9,.7); }
.border-gray-50 { border-color: #f9fafb; }
.divide-gray-50 > * + * { border-color: #f3f4f6; }
.divide-amber-50 > * + * { border-color: #fef3c7; }
.placeholder-gray-400::placeholder { color: #6b7280; }  /* was 2.54:1 */
.from-blue-100 { --tw-gradient-from: #dbeafe; }
.to-blue-200 { --tw-gradient-to: #bfdbfe; }
.hover\:bg-blue-50:hover { background-color: #eff6ff; }
.hover\:bg-blue-50\/50:hover { background-color: rgba(239,246,255,.5); }
.hover\:bg-blue-700:hover { background-color: #1d4ed8; }
.hover\:bg-green-50:hover { background-color: #f0fdf4; }
.hover\:bg-green-100:hover { background-color: #dcfce7; }
.hover\:bg-gray-100:hover { background-color: #f3f4f6; }
.hover\:bg-amber-600:hover { background-color: #92400e; }
.hover\:text-amber-600:hover { color: #b45309; }
.hover\:text-amber-700:hover { color: #92400e; }
.hover\:text-red-600:hover  { color: #dc2626; }
.hover\:text-red-700:hover  { color: #b91c1c; }
.hover\:text-brand-blue:hover { color: var(--brand-blue); }
.hover\:underline:hover { text-decoration: underline; }
.group:hover .group-hover\:bg-blue-100 { background-color: #dbeafe; }
.group:hover .group-hover\:text-blue-500 { color: #3b82f6; }

/* Focus states */
.focus-within\:ring-2:focus-within {
  box-shadow: 0 0 0 2px var(--s-card), 0 0 0 4px var(--brand-blue);
}
.focus\:ring-brand-blue:focus,
.focus-within\:ring-brand-blue:focus-within { --tw-ring-color: var(--brand-blue); }
.disabled\:cursor-not-allowed:disabled { cursor: not-allowed; }
.disabled\:opacity-50:disabled { opacity: .5; }

/* Lists — list-decimal/list-inside are absent from the build */
.list-decimal { list-style-type: decimal; }
.list-inside  { list-style-position: inside; }

/* Smallest step of the type scale, replacing text-[10px]/[11px] literals */
.text-2xs { font-size: .6875rem; line-height: 1rem; }
