/* _astoler-shared.css — A. S. Toler suite shared design foundation.
 *
 * Loaded by every panel via:
 *   <link rel="stylesheet" href="/assets/_astoler-shared.css" />
 *
 * Defines canonical design tokens (`--bg`, `--panel`, `--accent`, status colors,
 * spacing/radii) and a small set of base components prefixed `f-*` so they
 * don't collide with panel-local CSS.
 *
 * Panels can still override any token via a later `:root {
  color-scheme: light dark;

  /* Claude-inspired warm cream/terracotta palette */
  --bg:        #FAF9F5;
  --panel:     #FFFFFF;
  --panel2:    #F5F4ED;
  --panel3:    #FBFAF4;
  --border:    #E6E2D6;
  --text:      #3D3929;
  --muted:     #6B6552;
  --muted2:    #8C8676;
  --accent:    #D97757;        /* Claude terracotta */
  --accent-2:  #C0673D;
  --accent-glow: rgba(217, 119, 87, 0.20);
  --shadow:    rgba(61, 57, 41, 0.12);

  /* Status palette — warm-tinted */
  --good:      #5C8C42;
  --warn:      #C99A2E;
  --bad:       #C84840;

  --good-bg:      #EAF3DC;
  --good-border:  #B8D194;
  --good-text:    #2F5121;
  --danger-bg:    #FBE7E5;
  --danger-border:#E8B0AB;
  --danger-text:  #7A2521;
  --warn-bg:      #FBF1D8;
  --warn-border:  #D9BE74;

  --accent-bg:     rgba(217, 119, 87, 0.10);
  --accent-border: rgba(217, 119, 87, 0.35);
}` block. Main
 * Panel keeps its cosmic blue palette this way; Field Panel keeps its green
 * accent. The shared layer just establishes a sane default — drift only when
 * intentional.
 *
 * Companion: /assets/_astoler-shared.js (escapeHtml, showToast, fetchJson...)
 */

/* ------------------------------------------------------------ design tokens */
:root {
  color-scheme: dark light;

  /* Base surfaces — Bid/Bay/PM share these verbatim, the de-facto canonical set */
  --bg:        #0f0f0f;
  --panel:     #171717;
  --panel2:    #1f1f1f;
  --panel3:    #121212;
  --border:    #2a2a2a;
  --text:      #eaeaea;
  --muted:     #a7a7a7;
  --muted2:    #7d7d7d;
  --accent:    #d4d4d4;   /* neutral default; panels override (Main blue, Field green) */
  --shadow:    rgba(0,0,0,0.45);

  /* Status palette */
  --good:      #22c55e;
  --warn:      #fcd34d;
  --bad:       #ef4444;

  /* Status surfaces (used for row highlights, banners) */
  --good-bg:      #132015;
  --good-border:  #1f4d2a;
  --good-text:    #bdf7c9;
  --danger-bg:    #2a1414;
  --danger-border:#5a1d1d;
  --danger-text:  #ffb4b4;
  --warn-bg:      rgba(252, 211, 77, 0.15);
  --warn-border:  rgba(252, 211, 77, 0.45);

  /* Accent-derived surfaces (Ops/Field pattern) */
  --accent-bg:     rgba(212, 212, 212, 0.18);
  --accent-border: rgba(212, 212, 212, 0.45);

  /* Form + table surfaces (PM Panel pattern, generalized) */
  --input-bg:  #101010;
  --table-bg:  #101010;
  --th-bg:     #131313;

  /* Spacing scale (4px grid) — use as `var(--space-3)` for 12px etc. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;

  /* Radii */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;

  /* Typography */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;

  /* z-index scale (matches existing /assets/ widgets to avoid collisions) */
  --z-base:        1;
  --z-nav:         50;
  --z-last-pill:   80;       /* astoler-last-updated.js — bottom-left pill */
  --z-suggestions: 1100;     /* astoler-suggestions.js — bottom-right widget */
  --z-theme:       1100;     /* astoler-theme.js — top-right circle */
  --z-modal:       2000;
  --z-toast:       10000;    /* shared toast — sits above everything */
}

html[data-theme="light"] {
  color-scheme: light;
  --bg:        #f4f4f5;
  --panel:     #ffffff;
  --panel2:    #f6f6f7;
  --panel3:    #ffffff;
  --border:    #e4e4e7;
  --text:      #101012;
  --muted:     #52525b;
  --muted2:    #71717a;
  --accent:    #111827;
  --shadow:    rgba(0,0,0,0.08);

  --good-bg:      #ecfdf5;
  --good-border:  #a7f3d0;
  --good-text:    #065f46;
  --danger-bg:    #fff1f2;
  --danger-border:#fecdd3;
  --danger-text:  #9f1239;
  --warn-bg:      #fffbeb;
  --warn-border:  #fcd34d;

  --accent-bg:     rgba(17, 24, 39, 0.08);
  --accent-border: rgba(17, 24, 39, 0.18);

  --input-bg:  #ffffff;
  --table-bg:  #ffffff;
  --th-bg:     #fafafa;
}

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

/* Buttons (`.f-btn`) — Field Panel's `.btn-*` system, generalized.
   Panels keep their existing `.btn` classes too; `.f-btn` is opt-in. */
.f-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 10px 14px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--panel2);
  color: var(--text);
  font: 700 13px/1.2 var(--font-sans);
  letter-spacing: .2px;
  cursor: pointer;
  user-select: none;
  transition: background 120ms ease, border-color 120ms ease, transform 80ms ease, opacity 150ms ease;
}
.f-btn:hover    { background: var(--panel); border-color: var(--muted2); }
.f-btn:active   { transform: translateY(1px); }
.f-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.f-btn[disabled], .f-btn.is-disabled { opacity: .45; cursor: not-allowed; }

.f-btn-primary {
  background: var(--accent);
  border-color: transparent;
  color: #0f0f0f;
  font-weight: 800;
}
.f-btn-primary:hover { filter: brightness(1.08); background: var(--accent); }

.f-btn-danger {
  background: var(--bad);
  border-color: transparent;
  color: #ffffff;
  font-weight: 800;
}
.f-btn-danger:hover { filter: brightness(1.08); }

.f-btn-ghost {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
}
.f-btn-ghost:hover { background: var(--panel2); color: var(--text); }

/* Form inputs (`.f-input`, plus base `input/select/textarea` are intentionally
   NOT styled here — too disruptive to existing panels. Opt-in only.) */
.f-input,
.f-select,
.f-textarea {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--input-bg);
  color: var(--text);
  font: 600 14px/1.4 var(--font-sans);
  outline: none;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.f-input:focus,
.f-select:focus,
.f-textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}
.f-textarea { min-height: 88px; resize: vertical; }
.f-input::placeholder,
.f-textarea::placeholder { color: var(--muted2); }

html[data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator,
html[data-theme="dark"] .f-input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(1) brightness(1.15);
  opacity: .85;
}

/* Tables (`.f-table`) */
.f-table {
  width: 100%;
  border-collapse: collapse;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--table-bg);
  border: 1px solid var(--border);
  font-size: 13px;
}
.f-table th {
  text-align: left;
  padding: 10px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .4px;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--th-bg);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 1;
}
.f-table td {
  padding: 10px;
  font-size: 13px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.f-table tbody tr:hover td { background: rgba(255,255,255,0.02); }
html[data-theme="light"] .f-table tbody tr:hover td { background: rgba(0,0,0,0.025); }
.f-table .num   { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.f-table .strong{ font-weight: 800; }
.f-table .row-overdue td { background: var(--danger-bg); }

/* Modals (`.f-modal-wrap` + `.f-modal-card`) — matches Ops Panel's `.est-modal-*`
   which is the cleanest existing implementation. Backdrop opacity .72 is the
   most common across panels (Ops .72, Bay .70, Field .72). */
.f-modal-wrap {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.72);
  z-index: var(--z-modal);
  display: none;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  padding: 40px 16px;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.f-modal-wrap.is-open { display: flex; }
.f-modal-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  width: 100%;
  max-width: 720px;
  display: flex;
  flex-direction: column;
  box-shadow: 0 30px 80px rgba(0,0,0,0.55);
  animation: f-modal-in 180ms cubic-bezier(.2,.8,.2,1);
}
@keyframes f-modal-in {
  from { transform: translateY(16px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
.f-modal-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  background: var(--panel);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  z-index: 1;
}
.f-modal-head h3,
.f-modal-head .f-modal-title {
  margin: 0;
  font: 800 15px/1.3 var(--font-sans);
  color: var(--text);
}
.f-modal-close {
  appearance: none;
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  padding: 4px 8px;
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.f-modal-close:hover { color: var(--text); background: var(--panel2); }
.f-modal-body { padding: 16px 18px; }
.f-modal-foot {
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
  padding: 12px 18px;
  border-top: 1px solid var(--border);
}
body.f-modal-open { overflow: hidden; }

/* Toast (`#f-toast-host`) — _astoler-shared.js creates this on first showToast()
   call. Position matches takeoff/canvas's already-shipped implementation. */
#f-toast-host {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column-reverse;
  gap: 8px;
  max-width: 360px;
  pointer-events: none;
}
.f-toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: var(--radius-md);
  font: 600 12px/1.4 var(--font-sans);
  border: 1px solid;
  box-shadow: 0 6px 24px rgba(0,0,0,0.35);
  animation: f-toast-slide 220ms ease-out;
}
.f-toast.is-leaving { transition: opacity 300ms; opacity: 0; }
.f-toast .f-toast-icon  { font-size: 14px; flex-shrink: 0; }
.f-toast .f-toast-msg   { flex: 1; }
.f-toast .f-toast-close { font-size: 13px; cursor: pointer; opacity: .6; flex-shrink: 0; }
.f-toast .f-toast-close:hover { opacity: 1; }
.f-toast.is-warn    { background: rgba(251,191,36,.12);  border-color: rgba(251,191,36,.5);  color: #fde68a; }
.f-toast.is-error   { background: rgba(248,113,113,.15); border-color: rgba(248,113,113,.6); color: #fecaca; }
.f-toast.is-success { background: rgba(34,197,94,.12);   border-color: rgba(34,197,94,.5);   color: #bbf7d0; }
.f-toast.is-info    { background: rgba(125,211,252,.12); border-color: rgba(125,211,252,.5); color: #bae6fd; }
@keyframes f-toast-slide {
  from { transform: translateX(20px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}

/* Light-theme toast contrast */
html[data-theme="light"] .f-toast.is-warn    { background: #fffbeb; color: #92400e; }
html[data-theme="light"] .f-toast.is-error   { background: #fef2f2; color: #991b1b; }
html[data-theme="light"] .f-toast.is-success { background: #f0fdf4; color: #166534; }
html[data-theme="light"] .f-toast.is-info    { background: #f0f9ff; color: #075985; }

/* Utility: visually-hidden for a11y labels */
.f-sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}

/* =====================================================================
 * CANONICAL PAGE CHROME — 2026-05-20 consistency pass
 * ---------------------------------------------------------------------
 * One header, KPI row, chip row, and theme-toggle position so the four
 * daily panels (Admin, Bid Panel, PM Panel, Bay Bid List) feel like
 * one product instead of four. Per the approved plan, NO panel-specific
 * overrides — every panel renders the same chrome.
 *
 * Adoption (in order, one per commit):
 *   1. Admin  — site/admin/index.html (also keeps the build stamp)
 *   2. Bid    — site/bid-panel/index.html + astoler-pm panel mirror N/A
 *   3. Bay    — site/bay-bid-list/index.html + astoler-bay-bid-list/src
 *   4. PM     — site/pm-panel/index.html + astoler-pm panel/src
 *
 * Field / Ops / Takeoff are explicitly out of scope for this pass.
 * ===================================================================== */

:root {
  --max-content-width: 1120px;
}

/* ---- .f-page-header -----------------------------------------------
 * Layout:  [logo] [title block]                          [nav]
 *                 [subtitle]
 * Logo + title block flex together on the left; nav sits at the end.
 * On narrow screens, nav drops to a new line (flex-wrap).
 * Subtitle defaults to "A. S. Toler Corp." — the company sub-
 * brand line PM Panel originated. Panels override the text but keep
 * the position. The eyebrow class (.f-page-eyebrow) is kept dormant
 * in CSS for any future variant that wants it. */
.f-page-header {
  max-width: var(--max-content-width);
  margin: 0 auto var(--space-5);
  padding: var(--space-5) var(--space-4) var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
}
.f-page-brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: 1 1 auto;
  min-width: 0;
}
.f-page-logo {
  height: 44px;
  width: auto;
  display: block;
  flex: 0 0 auto;
}
.f-page-titles {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
  min-width: 0;
}
.f-page-title {
  margin: 0;
  font-size: 24px;
  font-weight: 900;
  letter-spacing: -0.005em;
  color: var(--text);
  line-height: 1.15;
}
.f-page-sub {
  margin: 4px 0 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--muted);
  line-height: 1.4;
}
/* Eyebrow kept available but no longer the default. Panels can still
 * render <div class="f-page-eyebrow"> inside .f-page-titles above the
 * title if they want a section-kicker line. */
.f-page-eyebrow {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 2px;
}
.f-page-eyebrow .f-page-section {
  color: var(--text);
}
.f-page-nav {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  justify-content: flex-end;
  flex: 0 0 auto;
}
/* Nav buttons inside the page header are pill-shaped + uppercase. Alex
 * approved this look 2026-05-20 — applies automatically to any
 * .f-btn-ghost or <a class="f-btn-ghost"> inside .f-page-nav so future
 * panel migrations pick it up without re-styling each button. Scoped
 * to .f-page-nav so generic .f-btn-ghost elsewhere keeps its
 * rectangular shape. */
.f-page-nav .f-btn-ghost {
  border-radius: 999px;
  padding: 8px 18px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-weight: 800;
  font-size: 12px;
  color: var(--text);
  text-decoration: none;
}
.f-page-nav .f-btn-ghost:hover {
  background: var(--panel2);
  border-color: var(--muted2);
  color: var(--text);
}
.f-page-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.3px;
  border: 1px solid var(--border);
  background: var(--panel2);
  color: var(--muted);
}
.f-page-status::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--muted2);
}
.f-page-status.f-status-good {
  background: var(--good-bg);
  border-color: var(--good-border);
  color: var(--good-text);
}
.f-page-status.f-status-good::before {
  background: var(--good);
  box-shadow: 0 0 6px rgba(34, 197, 94, 0.55);
}
.f-page-status.f-status-warn {
  background: var(--warn-bg);
  border-color: var(--warn-border);
  color: var(--warn);
}
.f-page-status.f-status-warn::before { background: var(--warn); }
.f-page-status.f-status-bad {
  background: var(--danger-bg);
  border-color: var(--danger-border);
  color: var(--danger-text);
}
.f-page-status.f-status-bad::before { background: var(--bad); }

@media (max-width: 720px) {
  /* Flex layout already wraps nav to a new line; just tighten things
   * up. Nav stays right-justified even when wrapped so it sits in
   * the same visual spot. */
  .f-page-header { gap: var(--space-3); padding: var(--space-4); }
  .f-page-title { font-size: 20px; }
  .f-page-logo { height: 36px; }
}

/* ---- .f-kpi-row + .f-kpi ------------------------------------------ */
.f-kpi-row {
  max-width: var(--max-content-width);
  margin: 0 auto var(--space-5);
  padding: 0 var(--space-4);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3);
}
.f-kpi {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 92px;
}
.f-kpi-label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--muted);
}
.f-kpi-value {
  font-size: 30px;
  font-weight: 900;
  color: var(--text);
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.f-kpi-sub {
  font-size: 11px;
  color: var(--muted2);
  line-height: 1.4;
}
.f-kpi.is-good   .f-kpi-value { color: var(--good); }
.f-kpi.is-warn   .f-kpi-value { color: var(--warn); }
.f-kpi.is-bad    .f-kpi-value { color: var(--bad); }

/* ---- .f-chip-row + .f-chip ---------------------------------------- */
.f-chip-row {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 4px;
  background: var(--panel2);
  border: 1px solid var(--border);
  border-radius: 999px;
  flex-wrap: wrap;
}
.f-chip {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--muted);
  padding: 6px 14px;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2px;
  border-radius: 999px;
  cursor: pointer;
  transition: color 120ms, background 120ms;
}
.f-chip:hover { color: var(--text); }
.f-chip.is-active {
  background: var(--panel);
  color: var(--text);
  box-shadow: 0 1px 2px var(--shadow);
}

/* ---- .f-theme-toggle (consistent dot position) -------------------- */
/* astoler-theme.js owns behavior; this class only pins the position +
 * baseline appearance so every panel's toggle lives in the same spot. */
.f-theme-toggle {
  position: fixed;
  top: 14px;
  right: 14px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--panel2);
  cursor: pointer;
  z-index: var(--z-theme);
  transition: background 120ms, transform 120ms;
}
.f-theme-toggle:hover { transform: scale(1.08); }
html[data-theme="light"] .f-theme-toggle { background: var(--text); }

/* ---- .f-build-stamp (Admin only) ---------------------------------- */
/* Per the consistency pass, only /admin/ shows a build stamp. The
 * other panels strip theirs. Format: sequential integer. */
.f-build-stamp {
  position: fixed;
  left: 14px;
  bottom: 12px;
  font-size: 11px;
  color: var(--muted2);
  letter-spacing: 0.3px;
  z-index: var(--z-last-pill);
  pointer-events: none;
  user-select: none;
}
