/* =========================================================================
   AGRIFLOOD — UNIVERSAL UI FOUNDATION (Phase 3B)
   =========================================================================
   Purpose
   -------
   This file is the single, reusable design-system layer that every later
   Phase 3 feature (filters, compare, forecast UI, dashboard/graph redesign,
   quick tour, help center, export/report redesign) will build on top of.

   Rules followed
   --------------
   - ADDITIVE ONLY. Nothing in main.css is overridden or removed. Every
     selector here is either a new "uf-" (Universal Foundation) prefixed
     class, or a very low-risk, scoped enhancement (focus rings, scrollbars,
     reduced-motion, print) that cannot break existing pages.
   - No architecture, database, AutoML, forecasting, validation, deployment
     or routing logic is touched. This is presentation only.
   - No analytics, filters, compare, forecast, dashboard/graph redesign,
     quick tour, help center, or export/report redesign is implemented
     here. Where a component below is described as "search-ready",
     "sort-ready", "pagination-ready" or "export-ready", that means the
     visual/markup slot exists for a later phase to wire up — no filtering
     or data logic ships in this phase.
   - Reuses the existing design tokens defined in main.css's :root wherever
     they exist (colors, radius, shadow) instead of inventing a second
     palette. New tokens below only fill gaps (spacing scale, type scale,
     motion, z-index, focus ring).
   - Mobile → Tablet → Laptop → Desktop breakpoints match the app's existing
     convention (430 / 640 / 780 / 900 / 1100) so new components feel
     native next to old ones.

   Load order: main.css, then this file (see includes/header.php).
   ========================================================================= */

:root {
  /* ---- Spacing scale (used by every uf- component below) ---- */
  --uf-space-1: 4px;
  --uf-space-2: 8px;
  --uf-space-3: 12px;
  --uf-space-4: 16px;
  --uf-space-5: 20px;
  --uf-space-6: 24px;
  --uf-space-8: 32px;

  /* ---- Type scale (Universal Typography) ---- */
  --uf-text-xs: 12px;
  --uf-text-sm: 13.5px;
  --uf-text-base: 15px;
  --uf-text-md: 16.5px;
  --uf-text-lg: 19px;
  --uf-text-xl: 23px;
  --uf-text-2xl: 28px;
  --uf-line-tight: 1.25;
  --uf-line-normal: 1.6;
  --uf-line-relaxed: 1.75;

  /* ---- Radius / elevation (fall back to existing tokens when present) ---- */
  --uf-radius-sm: 8px;
  --uf-radius-md: var(--radius, 10px);
  --uf-radius-lg: 14px;
  --uf-radius-pill: 999px;
  --uf-shadow-sm: var(--shadow, 0 1px 3px rgba(0,0,0,.08));
  --uf-shadow-md: var(--shadow-md, 0 4px 6px -1px rgba(0,0,0,.08));
  --uf-shadow-lg: 0 16px 40px rgba(15,23,42,.14);

  /* ---- Motion ---- */
  --uf-motion-fast: .15s ease;
  --uf-motion-base: .2s ease;

  /* ---- Focus ring (accessibility) ---- */
  --uf-focus-ring: 0 0 0 3px rgba(22,163,74,.28);

  /* ---- Universal color system ------------------------------------------
     These map onto the app's existing palette (see main.css :root) so
     badges, notifications, and status dots always agree with each other,
     no matter which page or component renders them. Every pair below
     meets WCAG AA contrast for normal text on its own background. */
  --uf-success: var(--green-mid, #16a34a);
  --uf-success-bg: var(--green-light, #dcfce7);
  --uf-success-text: #15803d;
  --uf-warning: #d97706;
  --uf-warning-bg: var(--amber-light, #fef3c7);
  --uf-warning-text: #92400e;
  --uf-review: #7c3aed;
  --uf-review-bg: #f5f3ff;
  --uf-review-text: #5b21b6;
  --uf-blocking: #dc2626;
  --uf-blocking-bg: var(--red-light, #fee2e2);
  --uf-blocking-text: #991b1b;
  --uf-info: var(--blue, #1d4ed8);
  --uf-info-bg: var(--blue-light, #dbeafe);
  --uf-info-text: #1e40af;
  --uf-neutral-bg: var(--gray-100, #f1f5f9);
  --uf-neutral-text: var(--gray-600, #475569);

  --uf-z-toast: 4000;
}

/* Consistent box model everywhere new components are used. */
.uf-scope, .uf-scope * { box-sizing: border-box; }

/* Respect users who've asked for reduced motion — applies app-wide, safe. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}

/* Accessible, visible focus outline app-wide. Purely additive — elements
   that already define their own :focus style keep that style; this only
   fills in the (accessibility) gap for elements that had none. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--uf-success);
  outline-offset: 2px;
}

/* Nicer, thinner scrollbars inside scroll containers (tables, sidebars). */
.uf-scrollable { scrollbar-width: thin; scrollbar-color: var(--gray-400,#94a3b8) transparent; }
.uf-scrollable::-webkit-scrollbar { height: 8px; width: 8px; }
.uf-scrollable::-webkit-scrollbar-thumb { background: var(--gray-400,#94a3b8); border-radius: 8px; }
.uf-scrollable::-webkit-scrollbar-track { background: transparent; }


/* =========================================================================
   1. UNIVERSAL TYPOGRAPHY
   ========================================================================= */
.uf-h1, .uf-h2, .uf-h3, .uf-h4 { margin: 0; color: var(--text, #0f172a); letter-spacing: -.3px; font-weight: 600; }
.uf-h1 { font-size: var(--uf-text-2xl); line-height: var(--uf-line-tight); letter-spacing: -.6px; }
.uf-h2 { font-size: var(--uf-text-xl);  line-height: var(--uf-line-tight); letter-spacing: -.4px; }
.uf-h3 { font-size: var(--uf-text-lg);  line-height: 1.3; }
.uf-h4 { font-size: var(--uf-text-md);  line-height: 1.35; font-weight: 600; }

.uf-lead      { font-size: var(--uf-text-md); line-height: var(--uf-line-relaxed); color: var(--gray-600, #475569); margin: var(--uf-space-2) 0 0; }
.uf-body      { font-size: var(--uf-text-base); line-height: var(--uf-line-normal); color: var(--text, #0f172a); }
.uf-caption   { font-size: var(--uf-text-xs); line-height: var(--uf-line-normal); color: var(--muted, #64748b); }
.uf-eyebrow   { display: block; font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--uf-success-text); margin-bottom: var(--uf-space-1); }
.uf-text-muted { color: var(--muted, #64748b); }

/* Readability polish for plain prose that a page hasn't specially styled
   (e.g. a paragraph of explanatory copy dropped straight into .content).
   Scoped to :not([class]) so any component with its own class is
   completely unaffected — zero regression risk. */
.content p:not([class]),
.content li:not([class]) {
  font-size: var(--uf-text-base);
  line-height: var(--uf-line-relaxed);
  color: var(--gray-600, #475569);
}
.content p:not([class]) + p:not([class]) { margin-top: var(--uf-space-3); }


/* =========================================================================
   2. UNIVERSAL CARDS  (.uf-card)
   Slots: icon, title, description, status, actions.
   States: default, hover, loading (skeleton), empty.
   Opt-in — existing .card is untouched and keeps working everywhere.
   ========================================================================= */
.uf-card {
  display: flex;
  flex-direction: column;
  gap: var(--uf-space-3);
  background: var(--card-bg, #fff);
  border: 1px solid var(--border, #e2e8f0);
  border-radius: var(--uf-radius-md);
  box-shadow: var(--uf-shadow-sm);
  padding: var(--uf-space-5);
  min-width: 0;
  transition: box-shadow var(--uf-motion-base), border-color var(--uf-motion-base), transform var(--uf-motion-base);
}
.uf-card--interactive:hover,
.uf-card.uf-card--hover:hover {
  box-shadow: var(--uf-shadow-md);
  border-color: var(--gray-400, #cbd5e1);
  transform: translateY(-2px);
}
.uf-card-top { display: flex; align-items: flex-start; gap: var(--uf-space-3); justify-content: space-between; }
.uf-card-icon {
  display: grid; place-items: center; flex-shrink: 0;
  width: 40px; height: 40px; border-radius: var(--uf-radius-sm);
  background: var(--uf-success-bg); color: var(--uf-success-text);
}
.uf-card-heading { min-width: 0; }
.uf-card-title { font-size: var(--uf-text-md); font-weight: 600; color: var(--text, #0f172a); margin: 0; }
.uf-card-desc  { font-size: var(--uf-text-sm); color: var(--muted, #64748b); margin: var(--uf-space-1) 0 0; line-height: var(--uf-line-normal); }
.uf-card-status { flex-shrink: 0; }
.uf-card-actions { display: flex; flex-wrap: wrap; gap: var(--uf-space-2); margin-top: auto; padding-top: var(--uf-space-2); }
.uf-card-body { min-width: 0; }

/* Loading state: swap real content for skeleton blocks via [data-uf-state="loading"] */
.uf-card[data-uf-state="loading"] .uf-card-body,
.uf-card[data-uf-state="loading"] .uf-card-actions { visibility: hidden; height: 0; overflow: hidden; margin: 0; padding: 0; }
.uf-card[data-uf-state="loading"] .uf-card-title,
.uf-card[data-uf-state="loading"] .uf-card-desc { color: transparent !important; border-radius: 6px; background: linear-gradient(90deg,#eef1f5 25%,#e4e8ee 37%,#eef1f5 63%); background-size: 400% 100%; animation: uf-shimmer 1.4s ease infinite; }

/* Empty state inside a card */
.uf-card[data-uf-state="empty"] .uf-card-body { display: none; }

/* Responsive card grid — auto-fills, never overflows, wraps on mobile */
.uf-card-grid { display: grid; gap: var(--uf-space-5); grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
@media (max-width: 640px) { .uf-card-grid { grid-template-columns: 1fr; } }


/* =========================================================================
   3. UNIVERSAL BUTTONS  (.uf-btn)
   Variants: primary, secondary, outline, danger, success, download,
             print, compare, filter, reset.
   Note: "compare" and "filter" are styled variants only — no compare or
   filter *behavior* is wired up in this phase, per scope.
   ========================================================================= */
.uf-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--uf-space-2);
  min-height: 40px; padding: 0 var(--uf-space-4);
  border-radius: var(--uf-radius-sm); border: 1px solid transparent;
  font: 600 var(--uf-text-sm) 'DM Sans', sans-serif; letter-spacing: -.1px;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background var(--uf-motion-fast), border-color var(--uf-motion-fast), color var(--uf-motion-fast), transform var(--uf-motion-fast);
  user-select: none;
}
.uf-btn:active { transform: translateY(1px); }
.uf-btn:disabled, .uf-btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; pointer-events: none; }
.uf-btn svg { width: 16px; height: 16px; flex-shrink: 0; }

.uf-btn--primary   { background: var(--green-mid, #16a34a); border-color: var(--green-mid, #16a34a); color: #fff; }
.uf-btn--primary:hover { background: var(--green, #166534); border-color: var(--green, #166534); }

.uf-btn--secondary { background: var(--gray-100, #f1f5f9); border-color: var(--gray-100, #f1f5f9); color: var(--text, #0f172a); }
.uf-btn--secondary:hover { background: var(--gray-200, #e2e8f0); }

.uf-btn--outline   { background: #fff; border-color: var(--border, #e2e8f0); color: var(--text, #0f172a); }
.uf-btn--outline:hover { border-color: var(--gray-400, #94a3b8); background: var(--gray-50, #f8fafc); }

.uf-btn--danger    { background: #fff; border-color: #fecaca; color: var(--uf-blocking-text); }
.uf-btn--danger:hover { background: var(--uf-blocking-bg); }

.uf-btn--success   { background: var(--uf-success-bg); border-color: #bbf7d0; color: var(--uf-success-text); }
.uf-btn--success:hover { background: #bbf7d0; }

.uf-btn--download,
.uf-btn--print     { background: #fff; border-color: var(--border, #e2e8f0); color: var(--uf-info-text); }
.uf-btn--download:hover,
.uf-btn--print:hover { background: var(--uf-info-bg); border-color: #bfdbfe; }

.uf-btn--compare    { background: var(--uf-review-bg); border-color: #ddd6fe; color: var(--uf-review-text); }
.uf-btn--compare:hover { background: #ede9fe; }

.uf-btn--filter,
.uf-btn--reset      { background: #fff; border-color: var(--border, #e2e8f0); color: var(--muted, #64748b); }
.uf-btn--filter:hover, .uf-btn--reset:hover { background: var(--gray-50, #f8fafc); color: var(--text,#0f172a); }

.uf-btn--sm { min-height: 32px; padding: 0 var(--uf-space-3); font-size: var(--uf-text-xs); }
.uf-btn--block { width: 100%; }
.uf-btn-group { display: flex; flex-wrap: wrap; gap: var(--uf-space-2); }
@media (max-width: 430px) { .uf-btn-group { flex-direction: column; } .uf-btn-group .uf-btn { width: 100%; } }


/* =========================================================================
   4. UNIVERSAL TABLES  (.uf-table-wrap)
   Responsive scroll container + sticky header, ready for later phases to
   attach pagination, search and sort logic. No such logic ships now.
   ========================================================================= */
.uf-table-wrap { position: relative; border: 1px solid var(--border, #e2e8f0); border-radius: var(--uf-radius-md); background: var(--card-bg,#fff); overflow: hidden; }
.uf-table-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--uf-space-3);
  padding: var(--uf-space-3) var(--uf-space-4); border-bottom: 1px solid var(--border, #e2e8f0);
}
.uf-table-toolbar-title { font-size: var(--uf-text-sm); font-weight: 600; color: var(--text,#0f172a); }
/* Search / sort / export controls render as inert, disabled placeholders
   until a later phase turns them on — keeps this phase filter-free while
   still shipping the reusable slot. */
.uf-table-search { min-height: 36px; padding: 0 var(--uf-space-3); border: 1px solid var(--border,#e2e8f0); border-radius: var(--uf-radius-pill); font-size: var(--uf-text-xs); color: var(--muted,#64748b); background: var(--gray-50,#f8fafc); }
.uf-table-scroll { overflow-x: auto; max-width: 100%; }
.uf-table { width: 100%; min-width: 480px; border-collapse: collapse; font-size: var(--uf-text-sm); }
.uf-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--gray-50, #f8fafc); text-align: left;
  padding: var(--uf-space-3) var(--uf-space-4); font-size: var(--uf-text-xs); font-weight: 700;
  color: var(--muted, #64748b); text-transform: uppercase; letter-spacing: .04em;
  border-bottom: 2px solid var(--border, #e2e8f0); white-space: nowrap;
}
.uf-table th[data-uf-sortable] { cursor: not-allowed; } /* cursor communicates "not active yet" until a later phase enables it */
.uf-table tbody td { padding: var(--uf-space-3) var(--uf-space-4); border-bottom: 1px solid var(--gray-100,#f1f5f9); color: var(--text,#0f172a); vertical-align: middle; }
.uf-table tbody tr:hover td { background: var(--gray-50, #f8fafc); }
.uf-table tbody tr:last-child td { border-bottom: 0; }
.uf-table-footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--uf-space-2); padding: var(--uf-space-3) var(--uf-space-4); border-top: 1px solid var(--border,#e2e8f0); font-size: var(--uf-text-xs); color: var(--muted,#64748b); }
/* Pagination-ready slot (no active paging logic in this phase) */
.uf-pagination { display: inline-flex; gap: var(--uf-space-1); }
.uf-pagination button { min-width: 30px; height: 30px; border: 1px solid var(--border,#e2e8f0); background: #fff; border-radius: var(--uf-radius-sm); color: var(--muted,#64748b); }

/* Edge shadows that appear only when a table can scroll further —
   communicates "more content" instead of silently cutting text off. */
.uf-table-scroll.uf-can-scroll-left  { box-shadow: inset 8px 0 8px -8px rgba(15,23,42,.18); }
.uf-table-scroll.uf-can-scroll-right { box-shadow: inset -8px 0 8px -8px rgba(15,23,42,.18); }
.uf-table-scroll.uf-can-scroll-left.uf-can-scroll-right { box-shadow: inset 8px 0 8px -8px rgba(15,23,42,.18), inset -8px 0 8px -8px rgba(15,23,42,.18); }

@media (max-width: 640px) {
  .uf-table-toolbar { flex-direction: column; align-items: stretch; }
  .uf-table-search { width: 100%; }
}


/* =========================================================================
   5. UNIVERSAL EMPTY STATES  (.uf-empty)
   Variants via data-uf-empty="no-data | no-records | filtered | no-forecast
   | no-analytics | no-comparison"
   ========================================================================= */
.uf-empty {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--uf-space-2); padding: var(--uf-space-8) var(--uf-space-4);
  color: var(--muted, #64748b);
}
.uf-empty-icon {
  width: 52px; height: 52px; display: grid; place-items: center;
  border-radius: 50%; background: var(--gray-100, #f1f5f9); color: var(--gray-400, #94a3b8); margin-bottom: var(--uf-space-1);
}
.uf-empty-title { font-size: var(--uf-text-md); font-weight: 600; color: var(--text, #0f172a); margin: 0; }
.uf-empty-desc  { font-size: var(--uf-text-sm); max-width: 420px; line-height: var(--uf-line-relaxed); margin: 0; }
.uf-empty-actions { margin-top: var(--uf-space-2); display: flex; gap: var(--uf-space-2); flex-wrap: wrap; justify-content: center; }

/* Friendly per-variant tinting so a farmer can tell "nothing recorded yet"
   apart from "your filters removed everything" at a glance. */
[data-uf-empty="filtered"]      .uf-empty-icon { background: var(--uf-info-bg); color: var(--uf-info-text); }
[data-uf-empty="no-forecast"]   .uf-empty-icon { background: var(--uf-warning-bg); color: var(--uf-warning-text); }
[data-uf-empty="no-comparison"] .uf-empty-icon { background: var(--uf-review-bg); color: var(--uf-review-text); }


/* =========================================================================
   6. UNIVERSAL LOADING STATES  (skeletons)
   ========================================================================= */
@keyframes uf-shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
.uf-skel {
  background: linear-gradient(90deg,#eef1f5 25%,#e4e8ee 37%,#eef1f5 63%);
  background-size: 400% 100%; animation: uf-shimmer 1.4s ease infinite;
  border-radius: 6px; display: block;
}
.uf-skel-text  { height: 12px; margin: var(--uf-space-2) 0; }
.uf-skel-text--sm { width: 40%; }
.uf-skel-text--md { width: 70%; }
.uf-skel-text--lg { width: 90%; }
.uf-skel-title { height: 18px; width: 55%; margin-bottom: var(--uf-space-3); }
.uf-skel-avatar,
.uf-skel-icon  { width: 40px; height: 40px; border-radius: var(--uf-radius-sm); }
.uf-skel-card  { padding: var(--uf-space-5); border: 1px solid var(--border,#e2e8f0); border-radius: var(--uf-radius-md); background: var(--card-bg,#fff); }
.uf-skel-graph { width: 100%; height: 220px; border-radius: var(--uf-radius-md); }
.uf-skel-row   { height: 14px; margin: var(--uf-space-2) 0; }
.uf-skel-table .uf-skel-row:nth-child(3n+1) { width: 96%; }
.uf-skel-table .uf-skel-row:nth-child(3n+2) { width: 88%; }
.uf-skel-table .uf-skel-row:nth-child(3n+3) { width: 92%; }


/* =========================================================================
   7. UNIVERSAL NOTIFICATIONS  (.uf-notice, toast)
   Types: success, warning, review, blocking, info.
   Wording is friendly by default (see universal-foundation.js UF.notify()).
   ========================================================================= */
.uf-notice {
  display: flex; align-items: flex-start; gap: var(--uf-space-3);
  padding: var(--uf-space-3) var(--uf-space-4); border-radius: var(--uf-radius-sm);
  border: 1px solid transparent; font-size: var(--uf-text-sm); line-height: var(--uf-line-normal);
}
.uf-notice-icon { flex-shrink: 0; width: 20px; height: 20px; margin-top: 1px; }
.uf-notice-body { min-width: 0; }
.uf-notice-title { font-weight: 700; margin: 0 0 2px; }
.uf-notice-text  { margin: 0; }
.uf-notice-close { margin-left: auto; flex-shrink: 0; background: none; border: 0; cursor: pointer; opacity: .6; padding: 2px; }
.uf-notice-close:hover { opacity: 1; }

.uf-notice--success  { background: var(--uf-success-bg);  border-color: #bbf7d0; color: var(--uf-success-text); }
.uf-notice--warning   { background: var(--uf-warning-bg);  border-color: #fde68a; color: var(--uf-warning-text); }
.uf-notice--review    { background: var(--uf-review-bg);   border-color: #ddd6fe; color: var(--uf-review-text); }
.uf-notice--blocking   { background: var(--uf-blocking-bg); border-color: #fecaca; color: var(--uf-blocking-text); }
.uf-notice--info       { background: var(--uf-info-bg);     border-color: #bfdbfe; color: var(--uf-info-text); }

/* Toast stack rendered by UF.notify() in universal-foundation.js */
.uf-toast-stack {
  position: fixed; right: var(--uf-space-5); bottom: var(--uf-space-5); z-index: var(--uf-z-toast);
  display: flex; flex-direction: column; gap: var(--uf-space-2); width: min(360px, calc(100vw - 32px));
}
.uf-toast { box-shadow: var(--uf-shadow-lg); animation: uf-toast-in .18s ease; }
@keyframes uf-toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 430px) {
  .uf-toast-stack { left: var(--uf-space-3); right: var(--uf-space-3); width: auto; bottom: var(--uf-space-3); }
}


/* =========================================================================
   8. UNIVERSAL RESPONSIVE FRAMEWORK
   Breakpoints (match existing app convention):
     Mobile  ≤ 640px   Tablet ≤ 900px   Laptop ≤ 1200px   Desktop > 1200px
   ========================================================================= */
.uf-container { width: 100%; max-width: 1320px; margin: 0 auto; padding: 0 var(--uf-space-5); }
.uf-hide-mobile  { display: initial; }
.uf-hide-desktop { display: none; }
.uf-only-mobile  { display: none; }

@media (max-width: 900px) {
  .uf-only-mobile  { display: initial; }
  .uf-hide-mobile  { display: none; }
  .uf-hide-desktop { display: initial; }
}

/* Guardrails so a table, code block, or long value never forces the page
   to scroll sideways — matches the "no horizontal scrolling unless
   required" rule. Applied only to a small, safe set of generic elements. */
.content img, .content svg, .content video { max-width: 100%; height: auto; }
.uf-scope, .uf-card, .uf-notice, .uf-empty { overflow-wrap: anywhere; }


/* =========================================================================
   9. UNIVERSAL COLOR SYSTEM
   All badge / status colors funnel through these tokens so a "warning" or
   "review" state always looks the same everywhere it appears. See the
   token block at the top of this file for the values.
   ========================================================================= */
.uf-badge {
  display: inline-flex; align-items: center; gap: var(--uf-space-1);
  padding: 3px var(--uf-space-2); border-radius: var(--uf-radius-pill);
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
}
.uf-badge--success  { background: var(--uf-success-bg);  color: var(--uf-success-text); }
.uf-badge--warning   { background: var(--uf-warning-bg);  color: var(--uf-warning-text); }
.uf-badge--review    { background: var(--uf-review-bg);   color: var(--uf-review-text); }
.uf-badge--blocking   { background: var(--uf-blocking-bg); color: var(--uf-blocking-text); }
.uf-badge--info       { background: var(--uf-info-bg);     color: var(--uf-info-text); }
.uf-badge--neutral    { background: var(--uf-neutral-bg);  color: var(--uf-neutral-text); }
.uf-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.uf-dot--success { background: var(--uf-success); } .uf-dot--warning { background: var(--uf-warning); }
.uf-dot--review { background: var(--uf-review); }   .uf-dot--blocking { background: var(--uf-blocking); }
.uf-dot--info { background: var(--uf-info); }


/* =========================================================================
   10. UNIVERSAL ICONS
   Consistent sizing so no page ever mixes a 14px icon next to a 28px one.
   ========================================================================= */
.uf-icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.uf-icon svg { width: 100%; height: 100%; }
.uf-icon--xs { width: 14px; height: 14px; }
.uf-icon--sm { width: 16px; height: 16px; }
.uf-icon--md { width: 20px; height: 20px; }
.uf-icon--lg { width: 28px; height: 28px; }
.uf-icon--circle { border-radius: 50%; background: var(--uf-neutral-bg); padding: var(--uf-space-2); }


/* =========================================================================
   11. UNIVERSAL PAGE HEADERS  (.uf-page-header)
   Optional component for module-level headers inside a page's own content
   area. The existing global topbar in includes/header.php is untouched;
   this is for a secondary in-page header when a module needs one.
   ========================================================================= */
.uf-page-header {
  display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between;
  gap: var(--uf-space-4); margin-bottom: var(--uf-space-5);
}
.uf-page-header-copy { min-width: 0; }
.uf-breadcrumbs { display: flex; flex-wrap: wrap; align-items: center; gap: var(--uf-space-1); font-size: var(--uf-text-xs); color: var(--muted,#64748b); margin-bottom: var(--uf-space-2); }
.uf-breadcrumbs a { color: var(--muted,#64748b); text-decoration: none; }
.uf-breadcrumbs a:hover { color: var(--text,#0f172a); text-decoration: underline; }
.uf-breadcrumbs .uf-crumb-sep { opacity: .5; }
.uf-page-header-actions { display: flex; flex-wrap: wrap; gap: var(--uf-space-2); flex-shrink: 0; }
@media (max-width: 640px) {
  .uf-page-header { flex-direction: column; align-items: stretch; }
  .uf-page-header-actions { width: 100%; }
  .uf-page-header-actions .uf-btn { flex: 1; }
}


/* =========================================================================
   12. UNIVERSAL LAYOUT
   Consistent margins / padding / containers so every module feels like
   part of one system instead of a patchwork of one-off spacing values.
   ========================================================================= */
.uf-stack   { display: flex; flex-direction: column; }
.uf-stack > * + * { margin-top: var(--uf-space-5); }
.uf-stack--sm > * + * { margin-top: var(--uf-space-3); }
.uf-stack--lg > * + * { margin-top: var(--uf-space-8); }
.uf-section { margin-bottom: var(--uf-space-6); }
.uf-row     { display: flex; flex-wrap: wrap; gap: var(--uf-space-4); }
.uf-row > * { min-width: 0; }
.uf-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--uf-space-2); }

/* Print polish shared by any "print" button/action added by uf-btn--print */
@media print {
  .sidebar, .topbar, .uf-btn, .uf-toast-stack, .menu-toggle { display: none !important; }
  .content { padding: 0 !important; overflow: visible !important; }
  .layout, .main { display: block !important; height: auto !important; overflow: visible !important; }
}
