/* ============================================================================
 * ZoneLens Design Tokens — single source of truth
 *
 * WHY THIS FILE EXISTS
 * Before this, workspace.css defined 52 variables and then bypassed them with
 * 61 hardcoded hex values, 18 distinct border-radius values, and 7 transition
 * durations. Tokens that get bypassed aren't a design system. Everything
 * visual should resolve to a name defined here.
 *
 * DESIGN POSTURE
 * ZoneLens is a professional land-use decision workstation, not a consumer
 * dashboard. The discipline below follows the Ready Room philosophy
 * (C:\projects\flight\dev_docs\Ready_Room_UI_Design_Philosophy.md):
 *
 *   - Information density over whitespace
 *   - Structured surfaces and dividers, not floating cards
 *   - Every color carries meaning; no decorative color
 *   - Depth via border + surface contrast, not shadow
 *   - Mono + tabular figures for identifiers and measurements
 *   - Restrained, purposeful motion
 *
 * The CHARACTER is ZoneLens's own — surveying and municipal record-keeping
 * (parcels, lot lines, setbacks, envelopes), not naval aviation. The indigo
 * accent is the existing ZoneLens brand and is deliberately preserved.
 *
 * USAGE RULES
 *   1. Never write a raw hex value in a component stylesheet. Add a token.
 *   2. Only --zl-radius-tight / --zl-radius-standard. Nothing else.
 *   3. Only the three motion durations. Nothing else.
 *   4. Use --zl-font-data for any identifier or measurement (BBL, FAR, sqft,
 *      dates, coordinates) so columns of numbers align.
 *   5. Decision state = --zl-go / --zl-review / --zl-nogo / --zl-unknown.
 *      These mirror the product's GO / REVIEW / NO-GO vocabulary. Do not use
 *      them decoratively.
 * ========================================================================= */

:root {
  /* ── Typography ─────────────────────────────────────────────────────────
   * Two families only. Data gets mono + tabular figures so numeric columns
   * line up — essential for BBLs, FAR values, and lot areas. */
  --zl-font-ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --zl-font-data: 'IBM Plex Mono', ui-monospace, SFMono-Regular, 'SF Mono',
                  Consolas, 'Liberation Mono', monospace;

  /* Type scale — workstation, not landing page. Nothing above 20px in-app. */
  --zl-text-micro: 10px;   /* column headers, meta labels */
  --zl-text-label: 11px;   /* section headers (uppercase, tracked) */
  --zl-text-small: 12px;   /* secondary/supporting text */
  --zl-text-body: 13px;    /* tables and dense content — the workhorse */
  --zl-text-ui: 14px;      /* controls, nav, standard reading */
  --zl-text-title: 16px;   /* panel/view titles */
  --zl-text-display: 20px; /* primary work-object name; ceiling in-app */

  --zl-tracking-label: 0.06em; /* uppercase section headers */

  /* ── Geometry ───────────────────────────────────────────────────────────
   * Two radii. Tight for dense inline chrome, standard for panels/controls.
   * Circles (status dots, progress fills) use 9999px directly — legitimate
   * geometry rather than decorative rounding. */
  --zl-radius-tight: 2px;
  --zl-radius-standard: 4px;

  /* ── Motion ─────────────────────────────────────────────────────────────
   * Three durations. Motion clarifies state change; it never decorates. */
  --zl-motion-fast: 100ms;      /* hover, focus, color shifts */
  --zl-motion-standard: 160ms;  /* panel/row expansion, tab switches */
  --zl-motion-slow: 220ms;      /* drawers, overlays */
  --zl-ease: cubic-bezier(0.2, 0, 0, 1);

  /* ── Elevation ──────────────────────────────────────────────────────────
   * Only genuinely floating layers get a shadow: modals, dropdowns, toasts.
   * Inline content earns depth from borders and surface contrast instead.
   * There is deliberately no "card shadow" token. */
  --zl-elevation-overlay: 0 8px 32px rgba(0, 0, 0, 0.40);
  --zl-elevation-popover: 0 4px 16px rgba(0, 0, 0, 0.30);
  --zl-focus-ring: 0 0 0 2px var(--zl-accent-ring);

  /* ── Decision states — the product's actual vocabulary ──────────────────
   * -fg = text/icon on a normal surface (contrast-checked)
   * -bg = tint for chips, row highlights, table cells
   * -line = border for the same
   *
   * NOTE :root IS THE DARK THEME (light is the override below), so the
   * foregrounds here are the LIGHT variants — a dark-green -fg on the
   * #0F1117 base would land near 2.5:1 and fail WCAG AA. */
  --zl-go: #10B981;
  --zl-go-fg: #34D399;
  --zl-go-bg: rgba(16, 185, 129, 0.16);
  --zl-go-line: rgba(16, 185, 129, 0.42);

  --zl-review: #F59E0B;
  --zl-review-fg: #FBBF24;
  --zl-review-bg: rgba(245, 158, 11, 0.16);
  --zl-review-line: rgba(245, 158, 11, 0.42);

  --zl-nogo: #EF4444;
  --zl-nogo-fg: #F87171;
  --zl-nogo-bg: rgba(239, 68, 68, 0.16);
  --zl-nogo-line: rgba(239, 68, 68, 0.42);

  --zl-unknown: #8B8FA3;
  --zl-unknown-fg: #A2A7B8;
  --zl-unknown-bg: rgba(139, 143, 163, 0.16);
  --zl-unknown-line: rgba(139, 143, 163, 0.36);

  /* Informational (neutral emphasis — not a decision state) */
  --zl-info: #3B82F6;
  --zl-info-bg: rgba(59, 130, 246, 0.14);

  /* ── Brand accent ───────────────────────────────────────────────────────
   * ZoneLens indigo. Reserved for SELECTION and FOCUS — the active view, the
   * selected row, the primary action. Never a decorative fill.
   *
   * CONTRAST CONSTRAINT: on the dark theme this measures 4.37:1 against the
   * base surface. That clears the 3:1 bar for UI components and large text
   * (WCAG 1.4.11 / 1.4.3) but NOT the 4.5:1 bar for body copy. Use it for
   * fills, borders, rails and focus rings — not for small text on dark.
   * Use --text-primary for reading copy. */
  --zl-accent: #6C63FF;
  --zl-accent-hover: #7B73FF;
  --zl-accent-pressed: #5B52EE;
  --zl-accent-ring: rgba(108, 99, 255, 0.45);
  --zl-accent-wash: rgba(108, 99, 255, 0.12);
}

/* ── Light theme ──────────────────────────────────────────────────────────
 * The primary working surface. Warm neutrals rather than cold blue-grays —
 * closer to drafting stock than to a chat app. */
html[data-theme="light"] {
  --zl-accent: #5A52E0;
  --zl-accent-hover: #4F46D8;
  --zl-accent-pressed: #4338CA;
  --zl-accent-ring: rgba(90, 82, 224, 0.40);
  --zl-accent-wash: rgba(90, 82, 224, 0.10);

  /* Light surfaces need DARK semantic foregrounds for contrast (the inverse
     of :root above). Each is >= 4.5:1 on --bg-surface #FFFFFF. */
  --zl-go: #0F9668;
  --zl-go-fg: #0B6B4A;
  --zl-go-bg: rgba(16, 185, 129, 0.12);
  --zl-go-line: rgba(16, 185, 129, 0.40);

  --zl-review: #D97B06;
  --zl-review-fg: #8F5104;
  --zl-review-bg: rgba(245, 158, 11, 0.14);
  --zl-review-line: rgba(245, 158, 11, 0.42);

  --zl-nogo: #DC3B3B;
  --zl-nogo-fg: #A81D24;
  --zl-nogo-bg: rgba(239, 68, 68, 0.12);
  --zl-nogo-line: rgba(239, 68, 68, 0.40);

  --zl-unknown: #7A7F8F;
  --zl-unknown-fg: #5D6270;
  --zl-unknown-bg: rgba(122, 127, 143, 0.12);
  --zl-unknown-line: rgba(122, 127, 143, 0.34);

  --zl-elevation-overlay: 0 8px 32px rgba(15, 17, 23, 0.15);
  --zl-elevation-popover: 0 4px 16px rgba(15, 17, 23, 0.12);
}

/* ============================================================================
 * BRIDGE — legacy token aliases
 *
 * workspace.css and its components reference the pre-existing token names.
 * Rather than a risky 3,849-line rewrite, the legacy names now RESOLVE to the
 * tokens above, so the discipline propagates automatically and both systems
 * stay in sync. Migrate call sites to --zl-* opportunistically; delete a line
 * here once its legacy name has no remaining references.
 * ========================================================================= */

:root,
html[data-theme="light"] {
  --accent: var(--zl-accent);
  --accent-hover: var(--zl-accent-hover);
  --accent-pressed: var(--zl-accent-pressed);
  --border-focus: var(--zl-accent);

  /* Glow removed: the philosophy forbids glowing borders. Kept as a name so
     existing references degrade to a legitimate focus ring instead of a halo. */
  --accent-glow: var(--zl-focus-ring);

  --success: var(--zl-go);
  --warning: var(--zl-review);
  --danger: var(--zl-nogo);
  --info: var(--zl-info);

  /* v4 (DEC-024) retired the five paid app tiers. Only Free and API remain;
     archived names resolve to neutral so any stale reference is harmless. */
  --tier-explorer: var(--zl-unknown);
  --tier-api: var(--zl-accent);
  --tier-professional: var(--zl-unknown);
  --tier-team: var(--zl-unknown);
  --tier-developer: var(--zl-unknown);
  --tier-enterprise: var(--zl-unknown);
}

/* ============================================================================
 * PRIMITIVES — the structural vocabulary that replaces floating cards
 * ========================================================================= */

/* Section header: a labelled band opening a region of content. */
.zl-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 32px;
  padding: 0 12px;
  border-bottom: 1px solid var(--border-default);
  color: var(--text-secondary);
  font-size: var(--zl-text-label);
  font-weight: 700;
  letter-spacing: var(--zl-tracking-label);
  text-transform: uppercase;
}

/* Status board: label/value rows. Use instead of a row of stat cards. */
.zl-status-board {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0;
  font-size: var(--zl-text-body);
}

.zl-status-board dt,
.zl-status-board dd {
  padding: 6px 12px;
  margin: 0;
  border-bottom: 1px solid var(--border-subtle);
}

.zl-status-board dt {
  color: var(--text-secondary);
  font-size: var(--zl-text-small);
  text-transform: uppercase;
  letter-spacing: var(--zl-tracking-label);
  white-space: nowrap;
}

.zl-status-board dd {
  font-family: var(--zl-font-data);
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

/* Identifiers and measurements — BBLs, FAR, areas, dates, coordinates.
   Tabular figures keep numeric columns aligned. */
.zl-data,
.zl-parcel-id,
.zl-bbl,
.zl-measure {
  font-family: var(--zl-font-data);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* Decision chip — compact, square, semantic. Not a pill. */
.zl-state {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 6px;
  border-radius: var(--zl-radius-tight);
  border: 1px solid transparent;
  font-size: var(--zl-text-micro);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.zl-state--go      { color: var(--zl-go-fg);      background: var(--zl-go-bg);      border-color: var(--zl-go-line); }
.zl-state--review  { color: var(--zl-review-fg);  background: var(--zl-review-bg);  border-color: var(--zl-review-line); }
.zl-state--nogo    { color: var(--zl-nogo-fg);    background: var(--zl-nogo-bg);    border-color: var(--zl-nogo-line); }
.zl-state--unknown { color: var(--zl-unknown-fg); background: var(--zl-unknown-bg); border-color: var(--zl-unknown-line); }

/* Dense data table — the default way to present a collection. */
.zl-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--zl-text-body);
}

.zl-table th,
.zl-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border-subtle);
  text-align: left;
}

.zl-table th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-default);
  color: var(--text-secondary);
  font-size: var(--zl-text-micro);
  font-weight: 700;
  letter-spacing: var(--zl-tracking-label);
  text-transform: uppercase;
  white-space: nowrap;
}

.zl-table td.zl-num,
.zl-table th.zl-num {
  text-align: right;
  font-family: var(--zl-font-data);
  font-variant-numeric: tabular-nums;
}

.zl-table tbody tr {
  transition: background-color var(--zl-motion-fast) var(--zl-ease);
}

.zl-table tbody tr:hover {
  background: var(--bg-card-hover);
}

/* Selection reads as a marked row, not a lifted card. */
.zl-table tbody tr[aria-selected="true"] {
  background: var(--zl-accent-wash);
  box-shadow: inset 3px 0 0 var(--zl-accent);
}

@media (prefers-reduced-motion: reduce) {
  .zl-table tbody tr { transition: none; }
}

/* ============================================================================
 * MASTER → DETAIL LAYOUT
 *
 * The philosophy's central interaction model (§12): a list beside a detail
 * pane that STAYS VISIBLE while the user moves between records. Replaces
 * "click a card, swap the whole view", which loses context on every glance.
 * ========================================================================= */

.zl-master-detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 0;
  align-items: start;
  border: 1px solid var(--border-default);
  border-radius: var(--zl-radius-standard);
  overflow: hidden;
  background: var(--bg-surface);
}

.zl-master { min-width: 0; }

.zl-table-wrap {
  overflow-x: auto;   /* wide tables scroll inside the panel, never the page */
  max-width: 100%;
}

.zl-detail {
  border-left: 1px solid var(--border-default);
  background: var(--bg-base);
  min-height: 100%;
  position: sticky;
  top: 0;
}

.zl-detail-empty {
  padding: 24px 16px;
  color: var(--text-muted);
  font-size: var(--zl-text-small);
}

.zl-detail-header {
  padding: 12px;
  border-bottom: 1px solid var(--border-default);
}

.zl-detail-title {
  font-size: var(--zl-text-title);
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.3;
  word-break: break-word;
}

.zl-detail-sub {
  margin-top: 2px;
  font-size: var(--zl-text-small);
  color: var(--text-secondary);
}

.zl-detail-note {
  padding: 8px 12px;
  font-size: var(--zl-text-small);
  color: var(--zl-review-fg);
  background: var(--zl-review-bg);
  border-bottom: 1px solid var(--border-subtle);
}

.zl-detail-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
}

.zl-detail-actions .ws-btn { width: 100%; text-align: center; }

/* ── Status-board table ─────────────────────────────────────────────────── */

.zl-projects-table tbody tr { cursor: pointer; }

.zl-project-name {
  font-weight: 600;
  color: var(--text-primary);
}

.zl-row--archived .zl-project-name { color: var(--text-muted); font-weight: 400; }

/* Counts carry decision meaning; zero stays muted so real signal stands out. */
.zl-num--go      { color: var(--zl-go-fg);     font-weight: 600; }
.zl-num--review  { color: var(--zl-review-fg); font-weight: 600; }
.zl-num--nogo    { color: var(--zl-nogo-fg);   font-weight: 600; }
.zl-num--zero    { color: var(--text-muted); }
.zl-muted        { color: var(--text-muted); }

.zl-screened { font-size: var(--zl-text-small); color: var(--text-secondary); }

.zl-row-actions { text-align: right; white-space: nowrap; }

.zl-open-link {
  color: var(--zl-accent);
  font-size: var(--zl-text-small);
  font-weight: 600;
  text-decoration: none;
  opacity: 0;
  transition: opacity var(--zl-motion-fast) var(--zl-ease);
}

/* Reveal the row action on hover/selection/focus — visible when relevant,
   quiet otherwise. Always visible to keyboard users. */
.zl-projects-table tbody tr:hover .zl-open-link,
.zl-projects-table tbody tr[aria-selected="true"] .zl-open-link,
.zl-open-link:focus { opacity: 1; }

/* Sortable headers */
.zl-sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}

.zl-sort:hover { color: var(--text-primary); }
.zl-sort--active { color: var(--zl-accent); }
.zl-sort-arrow { font-size: 9px; }

.zl-table th.zl-num .zl-sort { justify-content: flex-end; width: 100%; }

/* Column totals — a status board should foot up. */
.zl-totals td {
  border-top: 1px solid var(--border-default);
  border-bottom: none;
  padding: 7px 10px;
  font-size: var(--zl-text-small);
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--bg-elevated);
}

.zl-totals td.zl-num {
  font-family: var(--zl-font-data);
  font-variant-numeric: tabular-nums;
}

/* Focus visibility for keyboard row navigation */
.zl-project-row:focus-visible {
  outline: 2px solid var(--zl-accent);
  outline-offset: -2px;
}

/* ── Responsive: below 1100px the detail pane docks under the list ──────── */
@media (max-width: 1100px) {
  .zl-master-detail { grid-template-columns: minmax(0, 1fr); }
  .zl-detail {
    border-left: none;
    border-top: 1px solid var(--border-default);
    position: static;
  }
  .zl-detail-actions { flex-direction: row; flex-wrap: wrap; }
  .zl-detail-actions .ws-btn { width: auto; flex: 1 1 auto; }
}

/* ============================================================================
 * IDENTIFIERS & MEASUREMENTS IN EXISTING VIEWS
 *
 * BBLs, parcel IDs and numeric columns were rendering in the proportional UI
 * font, so digits varied in width and columns of numbers did not align — a
 * real legibility cost for a product whose primary objects are 10-digit
 * identifiers. Mono + tabular figures fixes the alignment without touching
 * the markup that produces these cells.
 * ========================================================================= */

.ws-parcel-td--id,
.ws-parcel-td--num,
td.ws-parcel-td[data-num],
.ws-parcel-id,
.ws-bbl {
  font-family: var(--zl-font-data);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  letter-spacing: -0.01em;   /* mono runs wide; pull back slightly */
}

/* The BBL column is the row's identity — give it primary weight. */
.ws-parcel-td--id {
  color: var(--text-primary);
  font-weight: 500;
}

/* ============================================================================
 * FUNCTIONAL STAGE RAIL
 *
 * Ready Room §10.5: the process rail should be an instrument, not decoration.
 * A rail that only shows position tells you where you are; a rail that names
 * the blocking condition tells you what to do next. The current stage now
 * carries its blocker beneath the label.
 * ========================================================================= */

.ws-gate-blocker {
  display: block;
  margin-top: 2px;
  max-width: 150px;
  font-size: var(--zl-text-micro);
  line-height: 1.35;
  color: var(--zl-review-fg);
  text-align: center;
}

/* The blocker belongs to the active stage only — keep it quiet elsewhere. */
.ws-gate-node--complete .ws-gate-blocker,
.ws-gate-node--pending .ws-gate-blocker { display: none; }

.ws-gate-node[data-gate-tab] { cursor: pointer; }

.ws-gate-node:focus-visible {
  outline: 2px solid var(--zl-accent);
  outline-offset: 2px;
  border-radius: var(--zl-radius-tight);
}

/* ============================================================================
 * FORM HINTS (ZL-WQA-007)
 * Explain a smart default rather than letting it look arbitrary — the Add
 * Parcels zoning family is pre-set from the project's intended use.
 * ========================================================================= */

.ws-form-hint {
  margin: 4px 0 0;
  font-size: var(--zl-text-small);
  line-height: 1.4;
  color: var(--text-secondary);
}

.ws-form-optional {
  font-weight: 400;
  color: var(--text-muted);
}
