/* ==========================================================================
   Flow v2 — Warm theme (Job Costing Hub)
   Tokens + component classes transcribed from
   docs/specs/os-performance/job-costing-hub/STYLE_GUIDE.md (default Warm
   theme only). Tokens are namespaced --fv2-* to avoid collisions with
   global tokens; every selector is scoped under the .fv2 wrapper so this
   sheet is inert everywhere the wrapper class is absent.
   Consumed by the Job Costing Hub only. flow-oes.css is unrelated and
   must not be edited.
   ========================================================================== */

:root {
  /* ==========================================================================
     Token aliasing to the global design system (_context/STYLE_GUIDE.md /
     ClearCode/_tokens.scss). The --fv2-* names are kept so none of the ~1,700
     downstream rules or any Hub component markup changes — only the VALUES
     move onto the global tokens, so the Hub adopts the shared palette, ink
     ramp, accent, semantics, fonts, radius and shadows in one place.

     Same pattern the Quality Hub used to adopt this design system (STYLE_GUIDE
     "Resolved decision 6": --qh-* aliased to the global set via var(), no
     component markup changed). Global tokens are defined on :root, so these
     var() refs resolve inside .fv2 with no .ds-root nesting requirement.

     IDENTITY tokens (colour / font-family / radius / shadow) alias to global.
     GEOMETRY tokens below (font-size scale, spacing, line-height, weight,
     motion, z-index, layout dims, control heights) stay as the Hub's own
     literals: the global scale is coarser and the Hub's dense grid/flyout is
     tuned to these steps — remapping them is layout risk for no identity gain.
     ========================================================================== */

  /* ---- Surfaces → global structural surfaces ---- */
  --fv2-surface-canvas:   var(--bg);              /* app background */
  --fv2-surface-raised:   var(--surface);         /* cards, panels, inputs */
  --fv2-surface-sunken:   var(--surface-2);       /* wells, table headers, chips */
  --fv2-surface-hover:    var(--surface-hover);   /* hover fill on subtle elements */
  --fv2-surface-selected: var(--accent-tint);     /* selected rows / items */

  /* ---- Text → global ink ramp (strong→ink … faint→ink-4) ---- */
  --fv2-text-strong:   var(--ink);       /* headings, primary text */
  --fv2-text-base:     var(--ink-2);     /* body */
  --fv2-text-muted:    var(--ink-3);     /* secondary / labels */
  --fv2-text-faint:    var(--ink-4);     /* placeholders, captions */
  --fv2-text-on-accent:var(--on-accent); /* text on accent fills */

  /* ---- Borders → global line tokens ---- */
  --fv2-border-subtle: var(--line);         /* default dividers / card edges */
  --fv2-border-base:   var(--line-strong);  /* inputs, controls */
  --fv2-border-strong: var(--line-strong);  /* hover / emphasis */

  /* ---- Accent (brand) → global accent family ---- */
  --fv2-accent:        var(--accent);
  --fv2-accent-hover:  var(--accent-2);
  --fv2-accent-press:  var(--accent-2);     /* no separate global press step */
  --fv2-accent-soft:   var(--accent-soft);  /* tinted backgrounds (badges, active nav) */
  --fv2-accent-softer: var(--accent-tint);
  --fv2-accent-deep:   var(--accent-ink);   /* text on soft accent */
  --fv2-accent-ring:   var(--accent-soft);  /* focus ring, matches global --focus-ring */

  /* ---- Status → global semantics; neutral → global slate family ---- */
  --fv2-success:  var(--success);  --fv2-success-soft: var(--success-soft);  --fv2-success-deep: var(--success-deep);
  --fv2-warning:  var(--warning);  --fv2-warning-soft: var(--warning-soft);  --fv2-warning-deep: var(--warning-deep);
  --fv2-danger:   var(--danger);   --fv2-danger-soft:  var(--danger-soft);   --fv2-danger-deep:  var(--danger-deep);
  --fv2-info:     var(--info);     --fv2-info-soft:    var(--info-soft);     --fv2-info-deep:    var(--info-deep);
  --fv2-neutral-soft: var(--slate-soft);  --fv2-neutral-deep: var(--slate-ink);

  /* ---- Scrim → global dark-anchored scrim (only color that must not invert) ---- */
  --fv2-scrim: var(--scrim);

  /* ---- Typography: family → global; size/lh/weight scales kept (Hub geometry) ---- */
  --fv2-font-sans: var(--font-sans);
  --fv2-font-mono: var(--font-mono);

  --fv2-fs-xs: 11px;  --fv2-fs-sm: 12px;  --fv2-fs-base: 14px;  --fv2-fs-md: 15px;
  --fv2-fs-lg: 17px;  --fv2-fs-xl: 20px;  --fv2-fs-2xl: 24px;   --fv2-fs-3xl: 30px;
  --fv2-fs-4xl: 36px; --fv2-fs-5xl: 44px;

  --fv2-lh-tight: 1.15;  --fv2-lh-snug: 1.35;  --fv2-lh-base: 1.5;  --fv2-lh-loose: 1.7;

  --fv2-fw-regular: 400;  --fv2-fw-medium: 500;  --fv2-fw-semibold: 600;  --fv2-fw-bold: 700;

  /* ---- Spacing (4px scale — Hub geometry) ---- */
  --fv2-sp-0: 0;     --fv2-sp-1: 4px;   --fv2-sp-2: 8px;   --fv2-sp-3: 12px;  --fv2-sp-4: 16px;
  --fv2-sp-5: 20px;  --fv2-sp-6: 24px;  --fv2-sp-7: 32px;  --fv2-sp-8: 40px;  --fv2-sp-9: 48px;
  --fv2-sp-10: 64px; --fv2-sp-11: 80px;

  /* ---- Radius → global radius steps (nearest by role); pill kept literal ---- */
  --fv2-r-xs: var(--radius-sm);  --fv2-r-sm: var(--radius);   --fv2-r-md: var(--radius-lg);  --fv2-r-lg: var(--radius-xl);
  --fv2-r-xl: var(--radius-xl);  --fv2-r-2xl: var(--radius-xl); --fv2-r-pill: 999px;

  /* ---- Shadows → global elevation (theme-aware); ring → global focus ring ---- */
  --fv2-shadow-xs: var(--shadow-1);
  --fv2-shadow-sm: var(--shadow-1);
  --fv2-shadow-md: var(--shadow-2);
  --fv2-shadow-lg: var(--shadow-2);
  --fv2-shadow-xl: var(--shadow-3);
  --fv2-shadow-ring: var(--focus-ring);  /* focus state */

  /* ---- Motion ---- */
  --fv2-dur-fast: 120ms;  --fv2-dur-base: 200ms;  --fv2-dur-slow: 320ms;
  --fv2-ease:     cubic-bezier(0.2, 0.7, 0.2, 1);
  --fv2-ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* ---- Z-index ---- */
  --fv2-z-base: 1;  --fv2-z-sticky: 40;  --fv2-z-overlay: 80;
  --fv2-z-modal: 100;  --fv2-z-popover: 120;  --fv2-z-toast: 140;

  /* ---- Layout dimensions ---- */
  --fv2-topbar-h: 60px;
  --fv2-rail-w: 244px;          --fv2-rail-w-collapsed: 64px;
  --fv2-row-h: 44px;            --fv2-row-h-compact: 36px;
  --fv2-control-h: 36px;        --fv2-control-h-sm: 28px;  --fv2-control-h-lg: 44px;
}

/* Base — the guide's body rules, scoped to the wrapper. The guide's global
   `* { margin:0; padding:0; box-sizing:border-box }` reset is scoped to
   .fv2 descendants so it cannot leak outside the Hub. */
.fv2 * { box-sizing: border-box; }

.fv2 {
  font-family: var(--fv2-font-sans);
  font-size: var(--fv2-fs-base);
  line-height: var(--fv2-lh-base);
  color: var(--fv2-text-base);
  background: var(--fv2-surface-canvas);
}

/* Page-shell mechanics carried over from the Flow OES wrapper: MainLayout
   wraps every page in `.content px-4` (1.1rem top / 1.5rem horizontal
   padding); the negative margins extend the canvas edge to edge. Dialog
   hosts (e.g. SaveAsDialog) neutralise these with inline margin/min-height
   overrides, same as they did for .flow-oes-page. */
.fv2 {
  display: flex;
  flex-direction: column;
  flex: 1;
  margin: -1.1rem -1.5rem 0;
  min-height: calc(100% + 1.1rem);
  overflow: auto;
  -webkit-font-smoothing: antialiased;

  /* Height of the global FlowMES top toolbar (.top-row, 3.5rem, z-index
     998) — the drawer + scrim anchor below it. */
  --fv2-app-header-h: 3.5rem;
}

/* Page-shell height containment — fixes the double vertical scrollbar.
   `.content` (>=768px) is `height:100%; overflow:auto`, so it owns a page
   scrollbar; the base `.fv2` above only sets `min-height` (a floor), so the
   grid grows the shell past the viewport and BOTH `.content` and the grid
   (`.fo-grid`, `overflow:auto; max-height:100%`) end up scrolling. Worse,
   CCFlowGrid uses <Virtualize>, which needs exactly ONE stable bounded
   scroll ancestor — with two candidate scrollers it oscillates and the
   layout flickers between one and two scrollbars.

   Fix: give the shell a *definite* capped height, then make the inner
   CONTENT COLUMN (KPI strip + callout + grid) the single scroll region.
   Scrolling it carries the KPIs/callout out of view and lets the grid use
   the full height, while the grid's own header stays pinned (sticky). This
   is the intended "scroll the page, not the grid" model — the grid itself
   flows at natural height and never scrolls (see `.fv2 .fo-grid` below).

   Scoped to `.content > .fv2` so it hits ONLY the full-page Hub shell — the
   SaveAsDialog also uses `.fv2` but lives in a dialog portal (not under
   `.content`) and neutralises the shell mechanics inline.

   `min-height: 0` is required on every nested flex column between the shell
   and the scroll column: flex items default to `min-height: auto` and
   refuse to shrink below their content, so without it `.workspace` (and the
   inner column) balloon to the grid's full height and the capped shell
   height — the scroll budget — is wasted. */
.content > .fv2 {
  height: calc(100% + 1.1rem);
  overflow: hidden;
}
.content > .fv2 > .workspace { min-height: 0; }
.content > .fv2 > .workspace > div {
  min-height: 0;
  overflow: auto;   /* the single scroll region (both axes: rows + wide grids) */
}

/* ==========================================================================
   2. Typography utilities
   ========================================================================== */

.fv2 .eyebrow {
  font-family: var(--fv2-font-mono);
  font-size: 11px;
  font-weight: var(--fv2-fw-medium);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
}

.fv2 .tnum { font-variant-numeric: tabular-nums; }
.fv2 .mono { font-family: var(--fv2-font-mono); }

/* ==========================================================================
   3. Layout — page header band
   ========================================================================== */

.fv2 .page-h {
  padding: var(--fv2-sp-7) var(--fv2-sp-7) var(--fv2-sp-5);
  background: var(--fv2-surface-raised);
  border-bottom: 1px solid var(--fv2-border-subtle);
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--fv2-sp-5); flex-wrap: wrap;
}
.fv2 .page-h__title {
  font-size: var(--fv2-fs-3xl); font-weight: var(--fv2-fw-semibold);
  color: var(--fv2-text-strong); letter-spacing: -0.02em; line-height: var(--fv2-lh-tight);
}
.fv2 .page-h__kicker {
  font-family: var(--fv2-font-mono);
  font-size: 11px;
  font-weight: var(--fv2-fw-medium);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
}
.fv2 .page-h__sub { margin-top: var(--fv2-sp-2); color: var(--fv2-text-muted); font-size: var(--fv2-fs-md); max-width: 580px; }

/* ==========================================================================
   4. Buttons — pill-shaped, uppercase mono
   ========================================================================== */

.fv2 .btn {
  height: 36px;
  padding: 0 18px;
  border-radius: var(--fv2-r-pill);
  border: 1px solid transparent;
  font-family: var(--fv2-font-mono);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  display: inline-flex; align-items: center; gap: var(--fv2-sp-2);
  cursor: pointer;
  transition: background var(--fv2-dur-fast) var(--fv2-ease), border-color var(--fv2-dur-fast) var(--fv2-ease);
}

.fv2 .btn--primary   { background: var(--fv2-accent); border-color: var(--fv2-accent); color: var(--fv2-text-on-accent); }
.fv2 .btn--primary:hover  { background: var(--fv2-accent-hover); }
.fv2 .btn--primary:active { background: var(--fv2-accent-press); }

.fv2 .btn--secondary { background: var(--fv2-surface-raised); border-color: var(--fv2-border-base); color: var(--fv2-text-strong); }
.fv2 .btn--secondary:hover { border-color: var(--fv2-border-strong); }

.fv2 .btn--ghost     { background: transparent; color: var(--fv2-text-muted); }
.fv2 .btn--ghost:hover { background: var(--fv2-surface-hover); }

.fv2 .btn--danger    { background: var(--fv2-danger); border-color: var(--fv2-danger); color: var(--fv2-text-on-accent); }
.fv2 .btn--danger:hover { background: var(--fv2-danger-deep); }

/* sizes & variants */
.fv2 .btn--lg   { height: var(--fv2-control-h-lg); padding: 0 var(--fv2-sp-5); font-size: var(--fv2-fs-base); }
.fv2 .btn--sm   { height: var(--fv2-control-h-sm); padding: 0 var(--fv2-sp-3); font-size: var(--fv2-fs-xs); }
.fv2 .btn--icon { width: var(--fv2-control-h); padding: 0; }

.fv2 .is-disabled { opacity: 0.5; cursor: not-allowed; pointer-events: none; }

/* ==========================================================================
   5. Form Controls
   ========================================================================== */

.fv2 .field { display: flex; flex-direction: column; gap: var(--fv2-sp-2); }
.fv2 .field__label { font-size: var(--fv2-fs-xs); font-weight: var(--fv2-fw-medium); color: var(--fv2-text-muted); letter-spacing: 0.02em; }
.fv2 .field__hint  { font-size: var(--fv2-fs-xs); color: var(--fv2-text-faint); }
.fv2 .field__error { font-size: var(--fv2-fs-xs); color: var(--fv2-danger); }

.fv2 .input {
  width: 100%;
  height: var(--fv2-control-h);
  padding: 0 var(--fv2-sp-3);
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-md);
  font-size: var(--fv2-fs-sm);
  color: var(--fv2-text-base);
  outline: none;
  transition: border-color var(--fv2-dur-fast) var(--fv2-ease), box-shadow var(--fv2-dur-fast) var(--fv2-ease);
}
.fv2 .input:hover { border-color: var(--fv2-border-strong); }
.fv2 .input:focus { border-color: var(--fv2-accent); box-shadow: var(--fv2-shadow-ring); }

/* icon inside a field */
.fv2 .input-group { display: flex; align-items: center; position: relative; }
.fv2 .input-group .input { padding-left: 36px; }
.fv2 .input-group__icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--fv2-text-faint); pointer-events: none; }

.fv2 .select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6359' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 14px;
  padding-right: 32px;
}

/* Checkbox */
.fv2 .checkbox {
  width: 16px; height: 16px;
  border: 1.5px solid var(--fv2-border-strong);
  border-radius: var(--fv2-r-xs);
  background: var(--fv2-surface-raised);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; transition: all var(--fv2-dur-fast) var(--fv2-ease);
}
.fv2 .checkbox:hover { border-color: var(--fv2-accent); }
.fv2 .checkbox.is-on, .fv2 .checkbox.is-indeterminate { background: var(--fv2-accent); border-color: var(--fv2-accent); color: var(--fv2-text-on-accent); }

/* Radio */
.fv2 .radio {
  width: 16px; height: 16px; border-radius: var(--fv2-r-pill);
  border: 1.5px solid var(--fv2-border-strong);
  background: var(--fv2-surface-raised);
  display: inline-flex; align-items: center; justify-content: center;
  transition: all var(--fv2-dur-fast) var(--fv2-ease);
}
.fv2 .radio.is-on { border-color: var(--fv2-accent); }
.fv2 .radio.is-on::after { content: ""; width: 8px; height: 8px; border-radius: var(--fv2-r-pill); background: var(--fv2-accent); }

/* Toggle switch */
.fv2 .toggle {
  width: 34px; height: 20px;
  background: var(--fv2-surface-sunken);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-pill);
  position: relative; cursor: pointer;
  transition: background var(--fv2-dur-fast) var(--fv2-ease);
}
.fv2 .toggle::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 14px; height: 14px; background: var(--fv2-text-on-accent);
  border-radius: var(--fv2-r-pill); box-shadow: var(--fv2-shadow-xs);
  transition: transform var(--fv2-dur-base) var(--fv2-ease);
}
.fv2 .toggle.is-on { background: var(--fv2-accent); border-color: var(--fv2-accent); }
.fv2 .toggle.is-on::after { transform: translateX(14px); }

/* ==========================================================================
   6. Cards
   ========================================================================== */

.fv2 .card {
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-subtle);
  border-radius: var(--fv2-r-lg);
  overflow: hidden;
  transition: border-color var(--fv2-dur-fast) var(--fv2-ease), box-shadow var(--fv2-dur-fast) var(--fv2-ease);
}
.fv2 .card:hover { border-color: var(--fv2-border-base); }
.fv2 .card--interactive { cursor: pointer; }
.fv2 .card--interactive:hover { box-shadow: var(--fv2-shadow-md); }

/* ==========================================================================
   7. Badges, Chips & Status
   ========================================================================== */

.fv2 .badge {
  display: inline-flex; align-items: center; gap: 6px;
  height: 22px; padding: 0 8px;
  border-radius: var(--fv2-r-pill);
  font-size: var(--fv2-fs-xs); font-weight: var(--fv2-fw-medium); line-height: 1;
  background: var(--fv2-neutral-soft); color: var(--fv2-text-strong);
  white-space: nowrap;
}
.fv2 .badge--success { background: var(--fv2-success-soft); color: var(--fv2-success-deep); }
.fv2 .badge--warning { background: var(--fv2-warning-soft); color: var(--fv2-warning-deep); }
.fv2 .badge--danger  { background: var(--fv2-danger-soft);  color: var(--fv2-danger-deep); }
.fv2 .badge--info    { background: var(--fv2-info-soft);    color: var(--fv2-info-deep); }
.fv2 .badge--accent  { background: var(--fv2-accent-soft);  color: var(--fv2-accent-deep); }
.fv2 .badge--neutral { background: var(--fv2-neutral-soft); color: var(--fv2-neutral-deep); }
.fv2 .badge--outline { background: transparent; border: 1px solid currentColor; }
.fv2 .badge--lg      { height: 26px; padding: 0 10px; font-size: var(--fv2-fs-sm); }
.fv2 .badge__dot     { width: 6px; height: 6px; border-radius: var(--fv2-r-pill); background: currentColor; }

.fv2 .chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 10px;
  border-radius: var(--fv2-r-pill);
  background: var(--fv2-surface-sunken);
  border: 1px solid transparent;
  font-size: var(--fv2-fs-xs); font-weight: var(--fv2-fw-medium); color: var(--fv2-text-base);
  cursor: pointer; transition: all var(--fv2-dur-fast) var(--fv2-ease);
}
.fv2 .chip:hover { border-color: var(--fv2-border-base); }
.fv2 .chip.is-active { background: var(--fv2-accent-soft); color: var(--fv2-accent-deep); border-color: var(--fv2-accent); }

.fv2 .status { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fv2-fs-sm); font-weight: var(--fv2-fw-medium); color: var(--fv2-text-strong); }
.fv2 .status__dot { width: 8px; height: 8px; border-radius: var(--fv2-r-pill); }
/* color the dot per state: var(--fv2-success) / var(--fv2-accent) / var(--fv2-info) / var(--fv2-warning) */
/* live/processing dot: animation: fv2-pulse 2s var(--fv2-ease) infinite; */

/* ==========================================================================
   8. Tabs
   ========================================================================== */

.fv2 .tabs {
  display: flex; gap: 2px;
  background: var(--fv2-surface-raised);
  border-bottom: 1px solid var(--fv2-border-subtle);
  padding: 0 var(--fv2-sp-7);
  overflow-x: auto;
}
.fv2 .tabs::-webkit-scrollbar { height: 0; }
.fv2 .tab {
  font-family: var(--fv2-font-mono);
  font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--fv2-text-muted);
  padding: var(--fv2-sp-3) var(--fv2-sp-2);
  border-bottom: 2px solid transparent;
  cursor: pointer;
}
.fv2 .tab:hover { color: var(--fv2-text-strong); }
.fv2 .tab.is-active { color: var(--fv2-accent); border-bottom-color: var(--fv2-accent); }

/* ==========================================================================
   9. Tables
   ========================================================================== */

.fv2 .table-wrap {
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-subtle);
  border-radius: var(--fv2-r-lg);
  overflow: hidden;
}
.fv2 .table-toolbar {
  display: flex; align-items: center; gap: var(--fv2-sp-2);
  padding: var(--fv2-sp-3) var(--fv2-sp-4);
  border-bottom: 1px solid var(--fv2-border-subtle);
}
.fv2 .table { width: 100%; border-collapse: collapse; }
.fv2 .table thead th {
  background: var(--fv2-surface-sunken);
  border-bottom: 1px solid var(--fv2-border-subtle);
  padding: var(--fv2-sp-3);
  text-align: left;
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs); font-weight: var(--fv2-fw-medium);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--fv2-text-muted); white-space: nowrap; user-select: none;
}
.fv2 .table tbody td { padding: var(--fv2-sp-3); border-bottom: 1px solid var(--fv2-border-subtle); font-size: var(--fv2-fs-sm); }
.fv2 .table tbody tr:hover { background: var(--fv2-surface-hover); }
.fv2 .table tbody tr.is-selected { background: var(--fv2-surface-selected); }

/* ==========================================================================
   10. Overlays — Modal, Toast, Tooltip
   ========================================================================== */

.fv2 .modal {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: min(560px, 92vw);
  background: var(--fv2-surface-raised);
  border-radius: var(--fv2-r-xl);
  box-shadow: var(--fv2-shadow-xl);
  z-index: var(--fv2-z-modal);
  overflow: hidden;
  animation: fv2-pop-in var(--fv2-dur-base) var(--fv2-ease-out);
}
.fv2 .modal__head {
  padding: var(--fv2-sp-5) var(--fv2-sp-6);
  border-bottom: 1px solid var(--fv2-border-subtle);
  display: flex; align-items: center; justify-content: space-between; gap: var(--fv2-sp-3);
}
.fv2 .modal__title { font-size: var(--fv2-fs-lg); font-weight: var(--fv2-fw-semibold); color: var(--fv2-text-strong); }

.fv2 .overlay { position: fixed; inset: 0; background: var(--fv2-scrim); z-index: var(--fv2-z-overlay); }

.fv2 .toast {
  position: fixed; bottom: 24px; right: 24px;
  background: var(--fv2-text-strong); color: var(--fv2-surface-raised);
  padding: var(--fv2-sp-3) var(--fv2-sp-4);
  border-radius: var(--fv2-r-md);
  box-shadow: var(--fv2-shadow-lg);
  z-index: var(--fv2-z-toast);
  font-size: var(--fv2-fs-sm);
  display: flex; align-items: center; gap: var(--fv2-sp-3);
  animation: fv2-slide-up var(--fv2-dur-base) var(--fv2-ease-out);
}

/* ==========================================================================
   11. Small Utilities
   ========================================================================== */

.fv2 .kbd {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 4px;
  background: var(--fv2-surface-sunken);
  border: 1px solid var(--fv2-border-subtle);
  border-radius: var(--fv2-r-xs);
  font-family: var(--fv2-font-mono); font-size: 10px;
  color: var(--fv2-text-muted);
}
.fv2 .avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  border-radius: var(--fv2-r-pill);
  background: var(--fv2-neutral-soft); color: var(--fv2-text-base);
  font-family: var(--fv2-font-mono); font-size: var(--fv2-fs-xs); font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.02em; text-transform: uppercase;
}
.fv2 .avatar--sm { width: 22px; height: 22px; font-size: 10px; }
.fv2 .avatar--lg { width: 36px; height: 36px; font-size: var(--fv2-fs-sm); }

/* ==========================================================================
   12. Animations — keyframe names are global, so they carry the fv2- prefix
   to keep this sheet collision-free. Bodies are verbatim from the guide.
   ========================================================================== */

@keyframes fv2-pop-in {
  from { opacity: 0; transform: translate(-50%, -48%) scale(0.96); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes fv2-slide-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes fv2-fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes fv2-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.6; transform: scale(0.8); }
}
@keyframes fv2-chatDot {
  0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
  30%           { opacity: 1; transform: translateY(-3px); }
}

/* ==========================================================================
   Job Costing Hub — page shell + header (restyle ITEM 2)
   Composed from the guide's §3 page-h band, §2 eyebrow, §4 buttons, and
   §7 chips. Selectors carrying the old fo-* names are INTERIM: they keep
   the drawer chrome working until ITEM 4 renames the fly-out classes.
   ========================================================================== */

.fv2 .page-h__top {
  display: flex;
  width: 100%;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--fv2-sp-5);
  flex-wrap: wrap;
}
.fv2 .page-h__title { margin: 0; }
.fv2 .page-h__kicker { margin-bottom: 6px; }
.fv2 .eyebrow .accent,
.fv2 .page-h__kicker .accent { color: var(--fv2-accent); }
.fv2 .eyebrow .dot,
.fv2 .page-h__kicker .dot { color: var(--fv2-border-strong); padding: 0 6px; }

/* Applied-view row under the title: view name + grain chip */
.fv2 .page-h__view {
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-2);
  margin-top: var(--fv2-sp-1);
}
.fv2 .page-h__view-name {
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-sm);
  font-weight: var(--fv2-fw-medium);
  color: var(--fv2-text-muted);
}
/* Grain label as a chip — §7 .chip.is-active supplies the accent-soft
   fill; this modifier only de-interactivizes it and applies the mono
   "system text" register (grain is locked once saved → active state). */
.fv2 .chip--grain {
  cursor: default;
  height: 22px;
  font-family: var(--fv2-font-mono);
  font-size: 10px;
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.fv2 .page-h__actions {
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-3);
}

.fv2 .btn svg {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.5;
}

/* Segmented mode toggle (Data / Analysis; also the fly-out grain toggle —
   the .fo-mode-toggle alias is INTERIM until ITEM 4 renames it). Active
   segment follows the guide's is-active treatment (accent-soft fill,
   accent-deep text). */
.fv2 .mode-toggle {
  display: inline-flex;
  background: var(--fv2-surface-sunken);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-pill);
  padding: 2px;
  height: 32px;
}
.fv2 .mode-toggle button {
  background: transparent;
  border: 0;
  padding: 0 14px;
  font-family: var(--fv2-font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fv2-text-muted);
  cursor: pointer;
  border-radius: var(--fv2-r-pill);
  transition: all var(--fv2-dur-fast) var(--fv2-ease);
  height: 26px;
}
.fv2 .mode-toggle button.is-active {
  background: var(--fv2-accent-soft);
  color: var(--fv2-accent-deep);
}
.fv2 .mode-toggle button:not(.is-active):hover {
  color: var(--fv2-text-strong);
}
.fv2 .mode-toggle button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Workspace + empty state */
.fv2 .workspace {
  flex: 1;
  padding: var(--fv2-sp-7);
  display: flex;
  align-items: center;
  justify-content: center;
}
.fv2 .empty { text-align: center; max-width: 420px; }
.fv2 .empty__icon {
  width: 56px;
  height: 56px;
  border-radius: var(--fv2-r-lg);
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-subtle);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--fv2-text-faint);
  margin-bottom: var(--fv2-sp-4);
}
.fv2 .empty__icon svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.5; }
.fv2 .empty__title {
  font-size: var(--fv2-fs-lg);
  font-weight: var(--fv2-fw-semibold);
  color: var(--fv2-text-strong);
  letter-spacing: -0.01em;
  margin: 0 0 6px;
}
.fv2 .empty__sub {
  font-size: var(--fv2-fs-base);
  color: var(--fv2-text-muted);
  margin: 0 0 18px;
}

/* Drawer (fly-out) chrome — positioning + panel surfaces (reconciled to
   .flyout* names in ITEM 4). Sits under the global toolbar (z 998). */
.fv2 .flyout__scrim {
  position: fixed;
  top: var(--fv2-app-header-h);
  right: 0;
  bottom: 0;
  left: 0;
  background: var(--fv2-scrim);
  z-index: var(--fv2-z-overlay);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--fv2-dur-base) var(--fv2-ease-out);
}
.fv2 .flyout__scrim.is-open { opacity: 1; pointer-events: auto; }

.fv2 .flyout {
  position: fixed;
  top: var(--fv2-app-header-h);
  right: 0;
  height: calc(100vh - var(--fv2-app-header-h));
  width: 600px;
  max-width: 100vw;
  background: var(--fv2-surface-raised);
  border-left: 1px solid var(--fv2-border-subtle);
  box-shadow: var(--fv2-shadow-xl);
  z-index: calc(var(--fv2-z-overlay) + 1);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform var(--fv2-dur-slow) var(--fv2-ease-out);
}
.fv2 .flyout.is-open { transform: translateX(0); }

.fv2 .flyout__head {
  padding: var(--fv2-sp-5) var(--fv2-sp-6) var(--fv2-sp-4);
  border-bottom: 1px solid var(--fv2-border-subtle);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--fv2-sp-4);
  flex-shrink: 0;
}
.fv2 .flyout__head-titles { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.fv2 .flyout-title {
  font-size: var(--fv2-fs-lg);
  font-weight: var(--fv2-fw-semibold);
  color: var(--fv2-text-strong);
  letter-spacing: -0.01em;
  margin: 0;
}
.fv2 .flyout__body {
  flex: 1;
  /* min-height:0 lets this flex child shrink below content height so it
     scrolls internally instead of pushing the footer off the drawer. */
  min-height: 0;
  overflow-y: auto;
  padding: var(--fv2-sp-4) var(--fv2-sp-6) var(--fv2-sp-6);
}
.fv2 .flyout__foot {
  border-top: 1px solid var(--fv2-border-subtle);
  padding: var(--fv2-sp-3) var(--fv2-sp-6);
  background: var(--fv2-surface-sunken);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  flex-shrink: 0;
}
.fv2 .flyout__close {
  width: 32px;
  height: 32px;
  border-radius: var(--fv2-r-pill);
  background: transparent;
  border: 1px solid var(--fv2-border-base);
  color: var(--fv2-text-faint);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
  transition: background var(--fv2-dur-fast) var(--fv2-ease);
  flex-shrink: 0;
}
.fv2 .flyout__close:hover {
  background: var(--fv2-surface-hover);
  color: var(--fv2-text-strong);
}

/* ==========================================================================
   Job Costing Hub — fly-out interior (restyle ITEM 4)
   Warm-theme port of the OES fly-out interior. Layout mechanics (flex,
   sizes, positioning) preserved; surfaces/type/radii re-tokened per guide
   §4 (buttons), §5 (form controls), §7 (chips/badges), §8 (tabs).
   Type-mark palette maps OES per-type colors onto guide status pairs:
   money→success, percent→accent, number/enum→info, bool→warning,
   date/text→neutral.
   ========================================================================== */

.fv2 .btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* Saved-filters strip */
.fv2 .section-label {
  font-family: var(--fv2-font-mono);
  font-size: 10px;
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
  margin-bottom: var(--fv2-sp-2);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.fv2 .section-label .count {
  letter-spacing: 0;
  text-transform: none;
  font-weight: var(--fv2-fw-medium);
  color: var(--fv2-text-faint);
}
.fv2 .views {
  padding: var(--fv2-sp-4) var(--fv2-sp-6);
  border-bottom: 1px solid var(--fv2-border-subtle);
  background: var(--fv2-surface-sunken);
}
.fv2 .views__list { display: flex; flex-wrap: wrap; gap: 6px; }
.fv2 .view-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 28px;
  padding: 0 12px 0 10px;
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-pill);
  font-size: var(--fv2-fs-xs);
  font-weight: var(--fv2-fw-medium);
  color: var(--fv2-text-muted);
  cursor: pointer;
  transition: all var(--fv2-dur-fast) var(--fv2-ease);
  position: relative;
}
.fv2 .view-chip:hover {
  background: var(--fv2-surface-hover);
  color: var(--fv2-text-strong);
  border-color: var(--fv2-border-strong);
}
.fv2 .view-chip.is-active {
  background: var(--fv2-accent-soft);
  color: var(--fv2-accent-deep);
  border-color: var(--fv2-accent);
}
.fv2 .view-chip.is-active:hover { background: var(--fv2-accent-soft); }
.fv2 .view-chip .bar {
  width: 3px;
  height: 12px;
  background: var(--fv2-accent);
  border-radius: 1px;
}
.fv2 .view-chip .dirty {
  width: 5px;
  height: 5px;
  background: var(--fv2-accent);
  border-radius: var(--fv2-r-pill);
}
.fv2 .view-chip--add {
  background: transparent;
  border-style: dashed;
  color: var(--fv2-text-faint);
}
.fv2 .view-chip--add:hover { color: var(--fv2-accent); border-color: var(--fv2-accent); }
.fv2 .view-chip--skeleton {
  background: var(--fv2-surface-hover);
  border-color: var(--fv2-border-subtle);
  color: transparent;
  pointer-events: none;
  min-width: 80px;
}
.fv2 .view-error {
  font-size: var(--fv2-fs-xs);
  color: var(--fv2-danger);
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-2);
}
.fv2 .view-error button {
  background: transparent;
  border: 0;
  color: var(--fv2-accent);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 0;
}

/* View meta row (name + Modified pill + Reset / Save as / Save) */
.fv2 .view-meta {
  margin-top: var(--fv2-sp-3);
  padding-top: var(--fv2-sp-3);
  border-top: 1px dashed var(--fv2-border-base);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.fv2 .view-meta__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--fv2-sp-2);
}
.fv2 .view-meta__name {
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-2);
  font-size: 13px;
  min-width: 0;
}
.fv2 .view-meta__name b {
  font-weight: var(--fv2-fw-semibold);
  color: var(--fv2-text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fv2 .view-meta__name .modified {
  font-family: var(--fv2-font-mono);
  font-size: 9px;
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fv2-accent-deep);
  background: var(--fv2-accent-soft);
  padding: 1px 6px;
  border-radius: var(--fv2-r-pill);
  flex-shrink: 0;
}
.fv2 .view-meta__actions { display: flex; gap: var(--fv2-sp-1); flex-shrink: 0; }

/* Grain row (above the tabs) */
.fv2 .grain-row {
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-3);
  padding: var(--fv2-sp-3) 0;
  border-bottom: 1px solid var(--fv2-border-subtle);
}
.fv2 .grain-row__label {
  font-family: var(--fv2-font-mono);
  font-size: 10px;
  font-weight: var(--fv2-fw-medium);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
}
.fv2 .grain-row__locked {
  display: inline-flex;
  align-items: center;
  gap: var(--fv2-sp-1);
  color: var(--fv2-text-faint);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
}

/* Tabs (Filter / Columns) — §8 with count badges */
.fv2 .flyout .tabs { padding: 0 var(--fv2-sp-6); }
.fv2 .tab {
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-2);
  background: transparent;
  border-top: 0;
  border-left: 0;
  border-right: 0;
  margin-right: var(--fv2-sp-5);
}
.fv2 .tab .count {
  font-family: var(--fv2-font-sans);
  font-size: 10px;
  font-weight: var(--fv2-fw-medium);
  letter-spacing: 0;
  background: var(--fv2-surface-sunken);
  color: var(--fv2-text-faint);
  padding: 1px 6px;
  border-radius: var(--fv2-r-pill);
}
.fv2 .tab.is-active .count {
  background: var(--fv2-accent-soft);
  color: var(--fv2-accent-deep);
}

/* Empty-state hint boxes inside the fly-out body */
.fv2 .flyout-hint {
  padding: var(--fv2-sp-7) var(--fv2-sp-4);
  text-align: center;
  color: var(--fv2-text-faint);
  font-size: var(--fv2-fs-sm);
  border: 1px dashed var(--fv2-border-base);
  border-radius: var(--fv2-r-md);
}
.fv2 .link-btn {
  background: transparent;
  border: 0;
  color: var(--fv2-accent);
  font-weight: var(--fv2-fw-semibold);
  cursor: pointer;
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-sm);
  padding: 0;
}
.fv2 .link-btn:hover { color: var(--fv2-accent-hover); }

/* Group card (one AND-group) — §6 card */
.fv2 .group {
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-subtle);
  border-radius: var(--fv2-r-lg);
}
.fv2 .group__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px var(--fv2-sp-3) var(--fv2-sp-2);
  border-bottom: 1px solid var(--fv2-border-subtle);
  font-family: var(--fv2-font-mono);
  font-size: 10px;
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
}
.fv2 .group__head .label { display: flex; align-items: center; gap: 6px; }
.fv2 .group__head .all-pill {
  background: var(--fv2-surface-sunken);
  color: var(--fv2-text-strong);
  padding: 1px 6px;
  border-radius: var(--fv2-r-pill);
  letter-spacing: 0.1em;
  font-weight: var(--fv2-fw-bold);
  border: 1px solid var(--fv2-border-subtle);
}
.fv2 .dim { color: var(--fv2-text-faint); }
.fv2 .group__remove {
  background: transparent;
  border: 0;
  padding: 4px 6px;
  color: var(--fv2-text-faint);
  cursor: pointer;
  border-radius: var(--fv2-r-sm);
  font-size: 13px;
  line-height: 1;
  font-family: var(--fv2-font-mono);
}
.fv2 .group__remove:hover { color: var(--fv2-danger-deep); background: var(--fv2-danger-soft); }
.fv2 .criteria-list { padding: var(--fv2-sp-1) var(--fv2-sp-3); }

/* Criterion row */
.fv2 .crit {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: var(--fv2-sp-2) 0;
  border-bottom: 1px solid var(--fv2-border-subtle);
  flex-wrap: wrap;
}
.fv2 .crit:last-child { border-bottom: 0; }
.fv2 .crit__remove {
  width: 26px;
  height: 28px;
  background: transparent;
  border: 0;
  border-radius: var(--fv2-r-sm);
  color: var(--fv2-text-faint);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  margin-left: auto;
  flex-shrink: 0;
}
.fv2 .crit__remove:hover { color: var(--fv2-danger-deep); background: var(--fv2-danger-soft); }

/* Field chip */
.fv2 .field-chip-wrap { position: relative; display: inline-block; }
.fv2 .field-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--fv2-sp-2);
  height: var(--fv2-control-h-sm);
  padding: 0 10px;
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-md);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-sm);
  font-weight: var(--fv2-fw-semibold);
  color: var(--fv2-text-strong);
  cursor: pointer;
  position: relative;
  white-space: nowrap;
  max-width: 220px;
  transition: all var(--fv2-dur-fast) var(--fv2-ease);
}
.fv2 .field-chip:hover { border-color: var(--fv2-border-strong); }
.fv2 .field-chip.is-empty {
  color: var(--fv2-text-faint);
  border-style: dashed;
  font-weight: var(--fv2-fw-medium);
}
.fv2 .field-chip .caret { color: var(--fv2-text-faint); font-size: 9px; flex-shrink: 0; }

/* Type marks — shared by field chip, picker options, and column rows */
.fv2 .field-chip .type-mark,
.fv2 .picker__option .mark,
.fv2 .col-row__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  font-size: 9px;
  font-weight: var(--fv2-fw-bold);
  background: var(--fv2-surface-sunken);
  color: var(--fv2-text-faint);
  border-radius: var(--fv2-r-xs);
  flex-shrink: 0;
  letter-spacing: 0;
}
.fv2 .field-chip .type-mark.is-money,   .fv2 .picker__option .mark.is-money,   .fv2 .col-row__mark.is-money   { background: var(--fv2-success-soft); color: var(--fv2-success-deep); }
.fv2 .field-chip .type-mark.is-percent, .fv2 .picker__option .mark.is-percent, .fv2 .col-row__mark.is-percent { background: var(--fv2-accent-soft);  color: var(--fv2-accent-deep); }
.fv2 .field-chip .type-mark.is-number,  .fv2 .picker__option .mark.is-number,  .fv2 .col-row__mark.is-number  { background: var(--fv2-info-soft);    color: var(--fv2-info-deep); }
.fv2 .field-chip .type-mark.is-bool,    .fv2 .picker__option .mark.is-bool,    .fv2 .col-row__mark.is-bool    { background: var(--fv2-warning-soft); color: var(--fv2-warning-deep); }
.fv2 .field-chip .type-mark.is-date,    .fv2 .picker__option .mark.is-date,    .fv2 .col-row__mark.is-date    { background: var(--fv2-neutral-soft); color: var(--fv2-neutral-deep); }
.fv2 .field-chip .type-mark.is-text,    .fv2 .picker__option .mark.is-text,    .fv2 .col-row__mark.is-text    { background: var(--fv2-neutral-soft); color: var(--fv2-text-muted); }
.fv2 .field-chip .type-mark.is-enum,    .fv2 .picker__option .mark.is-enum,    .fv2 .col-row__mark.is-enum    { background: var(--fv2-info-soft);    color: var(--fv2-info-deep); }

/* Operator select — §5 select treatment, compact */
.fv2 .op-select {
  appearance: none;
  height: var(--fv2-control-h-sm);
  padding: 0 24px 0 10px;
  background: var(--fv2-surface-sunken);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-md);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-sm);
  font-weight: var(--fv2-fw-medium);
  color: var(--fv2-text-base);
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6359' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 12px;
}

/* Value editors — §5 input treatment, compact */
.fv2 .val { display: flex; align-items: center; gap: var(--fv2-sp-1); flex: 1; min-width: 0; }
.fv2 .val-input {
  height: var(--fv2-control-h-sm);
  padding: 0 10px;
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-md);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-sm);
  font-weight: var(--fv2-fw-medium);
  color: var(--fv2-text-base);
  min-width: 0;
  width: 100%;
  outline: none;
  transition: border-color var(--fv2-dur-fast) var(--fv2-ease), box-shadow var(--fv2-dur-fast) var(--fv2-ease);
}
.fv2 .val-input:hover { border-color: var(--fv2-border-strong); }
.fv2 .val-input:focus { border-color: var(--fv2-accent); box-shadow: var(--fv2-shadow-ring); }
.fv2 .val-and {
  font-family: var(--fv2-font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
  font-weight: var(--fv2-fw-semibold);
  padding: 0 4px;
  flex-shrink: 0;
}
.fv2 .val-bool {
  display: flex;
  align-items: center;
  background: var(--fv2-surface-sunken);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-pill);
  padding: 2px;
  height: var(--fv2-control-h-sm);
}
.fv2 .val-bool button {
  flex: 1;
  background: transparent;
  border: 0;
  padding: 0 14px;
  height: 22px;
  border-radius: var(--fv2-r-pill);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  font-weight: var(--fv2-fw-semibold);
  color: var(--fv2-text-faint);
  cursor: pointer;
}
.fv2 .val-bool button.is-active { background: var(--fv2-accent-soft); color: var(--fv2-accent-deep); }
.fv2 .val-multi {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--fv2-sp-1);
  min-height: var(--fv2-control-h-sm);
  padding: 3px 6px;
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-md);
  width: 100%;
  cursor: text;
}
.fv2 .val-multi .tag {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 6px;
  background: var(--fv2-surface-sunken);
  border: 1px solid var(--fv2-border-subtle);
  border-radius: var(--fv2-r-xs);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  font-weight: var(--fv2-fw-medium);
  color: var(--fv2-text-base);
}
.fv2 .val-multi .placeholder {
  color: var(--fv2-text-faint);
  font-size: var(--fv2-fs-xs);
  font-style: italic;
  padding: 0 4px;
}

/* Bracket toggle + grid */
.fv2 .crit__bracket-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 var(--fv2-sp-2);
  background: transparent;
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-pill);
  font-family: var(--fv2-font-mono);
  font-size: 10px;
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
  cursor: pointer;
  transition: all var(--fv2-dur-fast) var(--fv2-ease);
}
.fv2 .crit__bracket-toggle:hover { color: var(--fv2-text-strong); border-color: var(--fv2-border-strong); }
.fv2 .crit__bracket-toggle.is-on {
  background: var(--fv2-accent-softer);
  color: var(--fv2-accent-deep);
  border-color: var(--fv2-accent);
}
.fv2 .crit__bracket-toggle .checkbox {
  width: 12px;
  height: 12px;
  border: 1px solid currentColor;
  border-radius: var(--fv2-r-xs);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  line-height: 1;
}
.fv2 .crit__bracket-toggle.is-on .checkbox {
  background: var(--fv2-accent);
  color: var(--fv2-text-on-accent);
  border-color: var(--fv2-accent);
}
.fv2 .bracket-wrap {
  width: 100%;
  margin-top: var(--fv2-sp-2);
  background: var(--fv2-surface-sunken);
  border: 1px dashed var(--fv2-border-base);
  border-radius: var(--fv2-r-lg);
  padding: 10px var(--fv2-sp-3);
}
.fv2 .bracket-config {
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-2);
  margin-bottom: var(--fv2-sp-2);
  font-size: var(--fv2-fs-xs);
  color: var(--fv2-text-muted);
}
.fv2 .bracket-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-sm);
}
.fv2 .bracket-table th,
.fv2 .bracket-table td {
  padding: 6px var(--fv2-sp-2);
  text-align: left;
  border-bottom: 1px solid var(--fv2-border-subtle);
}
.fv2 .bracket-table th {
  font-size: 9px;
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
}
.fv2 .bracket-table input {
  width: 100%;
  height: 24px;
  padding: 0 6px;
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-sm);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  color: var(--fv2-text-base);
  outline: none;
}
.fv2 .bracket-table input:focus { border-color: var(--fv2-accent); box-shadow: var(--fv2-shadow-ring); }
.fv2 .bracket-table .row-remove {
  background: transparent;
  border: 0;
  color: var(--fv2-text-faint);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 2px 6px;
  border-radius: var(--fv2-r-sm);
}
.fv2 .bracket-table .row-remove:hover { color: var(--fv2-danger-deep); background: var(--fv2-danger-soft); }
.fv2 .bracket-add {
  margin-top: 6px;
  background: transparent;
  border: 1px dashed var(--fv2-border-base);
  padding: 4px 10px;
  border-radius: var(--fv2-r-pill);
  font-family: var(--fv2-font-mono);
  font-size: 10.5px;
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fv2-text-muted);
  cursor: pointer;
}
.fv2 .bracket-add:hover { color: var(--fv2-accent); border-color: var(--fv2-accent); }
.fv2 .bracket-hint {
  margin: var(--fv2-sp-1) 0 var(--fv2-sp-2);
  font-style: italic;
  font-size: var(--fv2-fs-xs);
  line-height: 16px;
  color: var(--fv2-text-muted);
}
.fv2 .bracket-warn {
  margin-top: 6px;
  background: var(--fv2-warning-soft);
  border: 1px solid var(--fv2-warning);
  color: var(--fv2-warning-deep);
  border-radius: var(--fv2-r-md);
  padding: 6px var(--fv2-sp-2);
  font-size: var(--fv2-fs-xs);
  line-height: 16px;
}

/* Field picker popover */
.fv2 .picker {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: var(--fv2-z-popover);
  width: 320px;
  max-height: 360px;
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-subtle);
  border-radius: var(--fv2-r-lg);
  box-shadow: var(--fv2-shadow-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.fv2 .picker__search {
  padding: var(--fv2-sp-2) 10px;
  border-bottom: 1px solid var(--fv2-border-subtle);
  background: var(--fv2-surface-sunken);
  display: flex;
  align-items: center;
  gap: 6px;
}
.fv2 .picker__search svg {
  width: 12px;
  height: 12px;
  stroke: var(--fv2-text-faint);
  fill: none;
  stroke-width: 1.5;
  flex-shrink: 0;
}
.fv2 .picker__search input {
  flex: 1;
  border: 0;
  background: transparent;
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  color: var(--fv2-text-base);
  outline: none;
}
.fv2 .picker__list { flex: 1; overflow-y: auto; padding: var(--fv2-sp-1) 0; }
.fv2 .picker__group-label {
  padding: var(--fv2-sp-2) var(--fv2-sp-3) var(--fv2-sp-1);
  font-family: var(--fv2-font-mono);
  font-size: 9px;
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
}
.fv2 .picker__option {
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-2);
  padding: 6px var(--fv2-sp-3);
  font-size: var(--fv2-fs-sm);
  cursor: pointer;
  color: var(--fv2-text-base);
  transition: background var(--fv2-dur-fast) var(--fv2-ease);
}
.fv2 .picker__option:hover { background: var(--fv2-surface-hover); }
.fv2 .picker__option.is-disabled { color: var(--fv2-text-faint); cursor: not-allowed; }
.fv2 .picker__option.is-disabled:hover { background: transparent; }
.fv2 .picker__option .new-pill {
  margin-left: auto;
  font-family: var(--fv2-font-mono);
  font-size: 8.5px;
  font-weight: var(--fv2-fw-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fv2-accent-deep);
  background: var(--fv2-accent-soft);
  padding: 1px 5px;
  border-radius: var(--fv2-r-pill);
}
.fv2 .picker__empty {
  padding: var(--fv2-sp-4);
  text-align: center;
  font-size: var(--fv2-fs-xs);
  color: var(--fv2-text-faint);
}

/* Add buttons + OR divider */
.fv2 .add-condition {
  margin: var(--fv2-sp-2) var(--fv2-sp-3) var(--fv2-sp-3);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px dashed var(--fv2-border-base);
  padding: 6px var(--fv2-sp-3);
  border-radius: var(--fv2-r-pill);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fv2-text-muted);
  cursor: pointer;
}
.fv2 .add-condition:hover {
  color: var(--fv2-accent-deep);
  border-color: var(--fv2-accent);
  background: var(--fv2-accent-softer);
}
.fv2 .add-or-group {
  width: 100%;
  margin-top: var(--fv2-sp-4);
  background: transparent;
  border: 1px dashed var(--fv2-border-base);
  padding: 10px;
  border-radius: var(--fv2-r-lg);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fv2-text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--fv2-sp-2);
}
.fv2 .add-or-group:hover {
  color: var(--fv2-warning-deep);
  border-color: var(--fv2-warning);
  background: var(--fv2-warning-soft);
}
.fv2 .or-divider {
  position: relative;
  margin: var(--fv2-sp-4) 0;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 24px;
}
.fv2 .or-divider::before {
  content: "";
  position: absolute;
  left: var(--fv2-sp-3);
  right: var(--fv2-sp-3);
  top: 50%;
  height: 1px;
  background: var(--fv2-border-subtle);
}
.fv2 .or-divider .pill {
  background: var(--fv2-warning-soft);
  color: var(--fv2-warning-deep);
  font-family: var(--fv2-font-mono);
  font-weight: var(--fv2-fw-bold);
  font-size: 10px;
  letter-spacing: 0.08em;
  padding: 2px 10px;
  border-radius: var(--fv2-r-pill);
  position: relative;
  border: 1px solid var(--fv2-warning);
}

/* Match count (drawer footer) */
.fv2 .match { flex: 1; min-width: 0; }
.fv2 .match__numbers {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-variant-numeric: tabular-nums;
}
.fv2 .match__primary {
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xl);
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: -0.01em;
  color: var(--fv2-text-strong);
}
.fv2 .match__secondary { font-size: 13px; color: var(--fv2-text-faint); }
.fv2 .match__label {
  font-family: var(--fv2-font-mono);
  font-size: 10px;
  font-weight: var(--fv2-fw-medium);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
  margin-top: var(--fv2-sp-1);
}
.fv2 .match__pulse {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: var(--fv2-r-pill);
  background: var(--fv2-success);
  margin-right: 6px;
  vertical-align: middle;
}

/* Columns tab */
.fv2 .columns-tab__hint {
  font-size: var(--fv2-fs-sm);
  color: var(--fv2-text-faint);
  margin-bottom: var(--fv2-sp-3);
  line-height: 18px;
}
.fv2 .col-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: var(--fv2-sp-2) var(--fv2-sp-3);
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-subtle);
  border-radius: var(--fv2-r-md);
  margin-bottom: 6px;
}
.fv2 .col-row.is-dragging { opacity: 0.4; }
.fv2 .col-row.is-drop-target {
  border-color: var(--fv2-accent);
  box-shadow: var(--fv2-shadow-ring);
}
.fv2 .col-row__grip {
  color: var(--fv2-text-faint);
  cursor: grab;
  display: flex;
  align-items: center;
}
.fv2 .col-row__grip:active { cursor: grabbing; }
.fv2 .col-row__grip svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 1.5; }
.fv2 .col-row__name { flex: 1; font-size: 13px; font-weight: var(--fv2-fw-medium); }
.fv2 .col-row__name--unknown { color: var(--fv2-text-faint); }
.fv2 .col-row__unknown-tag { font-style: normal; color: var(--fv2-danger); }
.fv2 .col-row__priority {
  font-family: var(--fv2-font-mono);
  font-size: 10px;
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fv2-text-faint);
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-1);
}
.fv2 .col-row__priority b { color: var(--fv2-text-strong); font-size: var(--fv2-fs-xs); }
.fv2 .col-row__sort {
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-1);
  background: var(--fv2-surface-sunken);
  border: 1px solid var(--fv2-border-base);
  border-radius: var(--fv2-r-pill);
  padding: 2px;
  height: 24px;
}
.fv2 .col-row__sort button {
  width: 22px;
  height: 20px;
  background: transparent;
  border: 0;
  font-family: var(--fv2-font-mono);
  font-size: 10px;
  font-weight: var(--fv2-fw-semibold);
  color: var(--fv2-text-faint);
  cursor: pointer;
  border-radius: var(--fv2-r-pill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.fv2 .col-row__sort button.is-active { background: var(--fv2-accent-soft); color: var(--fv2-accent-deep); }
.fv2 .col-row__remove {
  width: 22px;
  height: 22px;
  background: transparent;
  border: 0;
  color: var(--fv2-text-faint);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  border-radius: var(--fv2-r-sm);
}
.fv2 .col-row__remove:hover { color: var(--fv2-danger-deep); background: var(--fv2-danger-soft); }
.fv2 .add-column {
  width: 100%;
  margin-top: var(--fv2-sp-2);
  background: transparent;
  border: 1px dashed var(--fv2-border-base);
  padding: var(--fv2-sp-2) var(--fv2-sp-3);
  border-radius: var(--fv2-r-pill);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  font-weight: var(--fv2-fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fv2-text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  position: relative;
}
.fv2 .add-column:hover {
  color: var(--fv2-accent-deep);
  border-color: var(--fv2-accent);
  background: var(--fv2-accent-softer);
}
.fv2 .add-column-wrap { position: relative; }

/* ==========================================================================
   Job Costing Hub — grid (restyle ITEM 3)
   Guide §9 (Tables) mapped onto the shared CCFlowGrid .fo-grid class
   structure as wrapper-scoped OVERRIDES. The .fo-grid base rules in
   flow-oes.css stay untouched (CCFlowGridTestPage still consumes them);
   these selectors only win inside the Hub's .fv2 wrapper.
   NOTE row heights stay 36px / 28px-dense (not §9's 44px --row-h):
   Virtualize ItemSize is hardcoded in CCFlowGrid and a CSS height that
   disagrees with it desyncs the scroller. Surfaced in the ITEM 3 report.
   ========================================================================== */

.fv2 .fo-grid {
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-subtle);
  border-radius: var(--fv2-r-lg);
  /* The grid is NOT its own scroll container — the inner content column
     above owns the single scrollbar (see the page-shell block). The grid
     flows at its natural, full virtualized height so that column scrolls
     through every row while the grid's sticky header stays pinned.

     `overflow: visible` hands scrolling to the column (both axes must be
     visible together — CSS promotes a lone `overflow-x/y:auto` back to a
     scroll container, which would re-create the second scrollbar and the
     <Virtualize> oscillation). `max-height: none` defeats the base rule's
     `max-height:100%`; `flex: 0 0 auto` keeps the grid at full height
     instead of being shrunk by the flex column. */
  flex: 0 0 auto;
  min-height: 0;
  max-height: none;
  overflow: visible;
}

.fv2 .fo-grid__head {
  background: var(--fv2-surface-sunken);
  border-bottom: 1px solid var(--fv2-border-subtle);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  font-weight: var(--fv2-fw-medium);
  line-height: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fv2-text-muted);
  white-space: nowrap;
  user-select: none;
  padding: 10px var(--fv2-sp-3);
}
.fv2 .fo-grid__head--sortable:hover { color: var(--fv2-text-strong); }
.fv2 .fo-grid__head--sorted { color: var(--fv2-text-strong); }
.fv2 .fo-sort-active { color: var(--fv2-accent); }

/* Backlog F — formula-surfacing popover. The trigger icon and tooltip
   content only; positioning/arrow/shadow chrome comes from the shared
   CCTooltip primitive (CCToolTip.scss) and is intentionally untouched. */
.fv2 .fo-grid__head-info-anchor {
  display: inline-block;
  margin-left: 4px;
  vertical-align: middle;
}
.fv2 .fo-grid__head-info {
  font-size: 11px;
  color: var(--fv2-text-faint);
  cursor: help;
}
.fv2 .fo-grid__head-info:hover { color: var(--fv2-accent); }
.fv2 .fo-grid__head-tooltip {
  max-width: 280px;
  font-family: var(--fv2-font-sans);
  text-transform: none;
  letter-spacing: normal;
}
.fv2 .fo-grid__head-tooltip-summary {
  font-size: var(--fv2-fs-sm);
  font-weight: var(--fv2-fw-regular);
  line-height: 18px;
  color: var(--fv2-text-strong);
}
.fv2 .fo-grid__head-tooltip-formula {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--fv2-border-subtle);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  line-height: 16px;
  color: var(--fv2-text-muted);
}

.fv2 .fo-grid__cell {
  padding: var(--fv2-sp-2) var(--fv2-sp-3);
  font-family: var(--fv2-font-sans);
  font-size: var(--fv2-fs-sm);
  font-weight: var(--fv2-fw-regular);
  line-height: 20px;
  color: var(--fv2-text-base);
  border-bottom: 1px solid var(--fv2-border-subtle);
  height: 36px;
}
.fv2 .fo-grid__cell--numeric {
  font-family: var(--fv2-font-mono);
  font-weight: var(--fv2-fw-medium);
  font-variant-numeric: tabular-nums;
}

.fv2 .fo-grid__row:hover { background: var(--fv2-surface-hover); }
.fv2 .fo-grid__row--selected { background: var(--fv2-surface-selected); }
.fv2 .fo-grid__row--selected .fo-grid__cell:first-child {
  box-shadow: inset 3px 0 0 var(--fv2-accent);
}

/* Dense mode — re-stated at .fv2 specificity so the 36px default above
   doesn't out-cascade the base dense rules. Heights match ItemSize 28. */
.fv2 .fo-grid--dense .fo-grid__cell { height: 28px; padding: var(--fv2-sp-1) var(--fv2-sp-3); }
.fv2 .fo-grid--dense .fo-grid__head { padding: 6px var(--fv2-sp-3); }

.fv2 .fo-grid__empty {
  color: var(--fv2-text-faint);
  font-family: var(--fv2-font-sans);
  font-size: var(--fv2-fs-sm);
}

.fv2 .fo-grid__footer {
  border-top: 1px solid var(--fv2-border-subtle);
  background: var(--fv2-surface-sunken);
  color: var(--fv2-text-faint);
  font-family: var(--fv2-font-mono);
  font-size: var(--fv2-fs-xs);
  font-weight: var(--fv2-fw-regular);
  line-height: 16px;
}
/* Capped chip — badge--accent treatment (accent-soft fill, accent-deep
   text, accent-ring border) replacing the OES orange tint. */
.fv2 .fo-grid__footer-cap {
  border-color: var(--fv2-accent-ring);
  background: var(--fv2-accent-soft);
  color: var(--fv2-accent-deep);
}

/* ==========================================================================
   Job Costing Hub — action callout (wire-up 1c ITEM 4)
   Warm-theme port of the mockup's ACTION CALLOUT block
   (job-costing-hub-main-surface.html). Sits between the KPI strip and the
   grid. Render-plus-stub: the buttons exist but route to a placeholder
   pending the Path A/B workflow decision.
   ========================================================================== */

.fv2 .callout {
  margin-bottom: var(--fv2-sp-4);
  background: var(--fv2-surface-raised);
  border: 1px solid var(--fv2-border-subtle);
  border-left: 3px solid var(--fv2-accent);
  border-radius: var(--fv2-r-lg);
  padding: var(--fv2-sp-4) 18px;
  display: flex;
  align-items: center;
  gap: var(--fv2-sp-5);
  /* The mockup is fixed-width; at 1024px the actions wrap under the body
     instead of crushing it. */
  flex-wrap: wrap;
}
.fv2 .callout__icon {
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: var(--fv2-r-md);
  background: var(--fv2-accent-softer);
  border: 1px solid var(--fv2-accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--fv2-accent-press);
}
.fv2 .callout__icon svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.7; }
.fv2 .callout__body { flex: 1; min-width: 240px; }
.fv2 .callout__head { font-size: 13px; font-weight: var(--fv2-fw-semibold); color: var(--fv2-text-strong); }
.fv2 .callout__sub { font-size: var(--fv2-fs-sm); color: var(--fv2-text-muted); margin-top: 2px; }
.fv2 .callout__support { font-size: var(--fv2-fs-sm); color: var(--fv2-text-faint); margin-top: 4px; }
.fv2 .callout__actions { display: flex; gap: var(--fv2-sp-2); flex: none; }
