/* ==========================================================================
   Vector — design tokens. The shared visual contract.

   Read before writing any UI. Every surface imports THIS file and uses these
   tokens; a hard-coded hex or a magic pixel value in a component is a defect.

   Design posture: an instrument, not a dashboard. The people using this are
   Quantity Surveyors adjudicating money under bid pressure. So:
     · data density is a feature — numbers are the product, give them room but
       never waste a row
     · the interface must be silent until it has something to say; colour is a
       signal, not decoration
     · motion is confirmation, never spectacle: 120–180ms, transform/opacity
       only, and it always respects prefers-reduced-motion
     · dark-first, because this is used next to drawing sets on a second screen
   ========================================================================== */

:root {
  color-scheme: dark light;

  /* ---- surface ladder (dark is the default authored direction) ---------- */
  --s-base:        #0a0d0b;   /* app background */
  --s-sunken:      #070908;   /* wells, the drawing canvas */
  --s-raised:      #101511;   /* panels, table container */
  --s-overlay:     #151b16;   /* popovers, sticky headers */
  --s-hover:       #1a211b;
  --s-active:      #212a22;

  /* ---- hairlines: the main structural device at this density ------------ */
  --line:          #1e261f;
  --line-strong:   #2f3b30;
  --line-focus:    #b4dc6a;

  /* ---- type ------------------------------------------------------------- */
  --ink:           #e9efe5;   /* primary */
  --ink-muted:     #9aa797;   /* labels, secondary */
  --ink-faint:     #5f6c5f;   /* disabled, placeholder */
  --ink-inverse:   #0a0d0b;

  /* ---- one accent. More than one accent is a design failure. ------------ */
  --accent:        #b4dc6a;
  --accent-hover:  #c6e884;
  --accent-sunken: #1e2a14;
  --accent-ink:    #0d1606;

  /* ---- semantic: these carry MEANING from the domain ------------------- */
  --verified:      #35c08a;   /* QS_Verified */
  --verified-bg:   #10241c;
  --predicted:     #d9a33a;   /* AI_Predicted — unreviewed, not "bad" */
  --predicted-bg:  #2a2010;
  --fire:          #e5604d;   /* FRL-rated element */
  --fire-bg:       #2b1512;
  --wet:           #3fb5c9;   /* wet-area element */
  --wet-bg:        #0f242a;
  --danger:        #ff6b5b;
  --unresolved:    #b06ce0;   /* [UNRESOLVED] / null wall type */
  --unresolved-bg: #221430;

  /* ---- severity (exception queue) --------------------------------------- */
  --sev-high:      var(--danger);
  --sev-medium:    var(--predicted);
  --sev-low:       var(--ink-muted);

  /* ---- typography ------------------------------------------------------- */
  --font-ui: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI",
             Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;

  --t-micro:  0.6875rem;  /* 11px — column headers, badges */
  --t-small:  0.8125rem;  /* 13px — table body, secondary */
  --t-body:   0.9375rem;  /* 15px — prose */
  --t-lead:   1.125rem;   /* 18px */
  --t-title:  1.375rem;   /* 22px */
  --t-hero:   clamp(2rem, 5vw, 3.25rem);

  --lh-tight: 1.25;
  --lh-body:  1.55;

  /* Numbers must align in columns. Non-negotiable in the spreadsheet. */
  --num: var(--font-mono);

  /* ---- space: 4px base, named by intent not size ------------------------ */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;
  --gutter: var(--sp-4);

  /* ---- radius ----------------------------------------------------------- */
  --r-sm: 4px;
  --r-md: 6px;
  --r-lg: 10px;
  --r-pill: 999px;

  /* ---- elevation: borders first, shadow only for true overlays ---------- */
  --shadow-pop: 0 8px 24px -8px rgb(0 0 0 / 0.55), 0 2px 6px rgb(0 0 0 / 0.35);
  --shadow-panel: 0 1px 0 rgb(255 255 255 / 0.03) inset;

  /* ---- motion: fast, and only ever transform/opacity ------------------- */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-in: cubic-bezier(0.55, 0.06, 0.68, 0.19);
  --dur-instant: 90ms;
  --dur-fast: 140ms;
  --dur-med: 220ms;

  /* ---- layout ----------------------------------------------------------- */
  --row-h: 30px;           /* spreadsheet row — dense on purpose */
  --control-h: 32px;       /* every input/select/button (spec 022 FR-004) */
  --header-h: 52px;
  --rail-w: 44px;
  --panel-min: 320px;
  --prose-max: 68ch;
}

/* Light theme. Authored second, but must be equally correct — a QS may work
   next to a window. Same token names, so no component knows the difference.

   The base is a deliberate grey, not near-white. An earlier version used
   #fbfbfc against a #ffffff raised surface: one step apart, so panels had no
   tonal lift and every bit of hierarchy fell to borders. Dark mode separates
   its surfaces properly, and light has to earn that separation on its own
   terms rather than inheriting the assumption that white-on-near-white reads
   as elevated. Keep raised pure white and let the field around it be grey. */
/* Wise-inspired light palette (spec 016): bright green accent (#9fe870) with
   forest-green ink on it, forest ink, off-white surfaces. The five domain
   semantic colours below stay their own hues so a bright-lime interaction
   accent never collides with the meaning-bearing verified/predicted/fire/
   wet/unresolved signals (FR-004). --accent-ink and --line-focus MUST be
   overridden here: white ink on bright lime is unreadable, and a blue focus
   ring is off-palette. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --s-base: #f4f6f1;
    --s-sunken: #e9ede4;
    --s-raised: #ffffff;
    --s-overlay: #ffffff;
    --s-hover: #eef2e8;
    --s-active: #e1e8d8;
    --line: #e2e7dc;
    --line-strong: #c6cfbc;
    --line-focus: #3d6b1d;
    --ink: #14210d;
    --ink-muted: #55624f;
    --ink-faint: #8a9684;
    --ink-inverse: #ffffff;
    --accent: #a9d460;
    --accent-hover: #9bc94f;
    --accent-sunken: #eef6df;
    --accent-ink: #14210d;
    --verified: #0e8a5f;
    --verified-bg: #e2f4ec;
    --predicted: #96660b;
    --predicted-bg: #fdf1dc;
    --fire: #c0392b;
    --fire-bg: #fdeae7;
    --wet: #17798c;
    --wet-bg: #e2f4f7;
    --danger: #c0392b;
    --unresolved: #7b3bb0;
    --unresolved-bg: #f4e9fc;
    --shadow-pop: 0 8px 24px -10px rgb(16 40 8 / 0.16), 0 2px 6px rgb(16 40 8 / 0.07);
    --shadow-panel: none;
  }
}

:root[data-theme="light"] {
  --s-base: #f4f6f1; --s-sunken: #e9ede4; --s-raised: #ffffff;
  --s-overlay: #ffffff; --s-hover: #eef2e8; --s-active: #e1e8d8;
  --line: #e2e7dc; --line-strong: #c6cfbc; --line-focus: #3d6b1d;
  --ink: #14210d; --ink-muted: #55624f; --ink-faint: #8a9684; --ink-inverse: #ffffff;
  --accent: #a9d460; --accent-hover: #9bc94f; --accent-sunken: #eef6df; --accent-ink: #14210d;
  --verified: #0e8a5f; --verified-bg: #e2f4ec;
  --predicted: #96660b; --predicted-bg: #fdf1dc;
  --fire: #c0392b; --fire-bg: #fdeae7;
  --wet: #17798c; --wet-bg: #e2f4f7;
  --danger: #c0392b; --unresolved: #7b3bb0; --unresolved-bg: #f4e9fc;
  --shadow-pop: 0 8px 24px -10px rgb(16 40 8 / 0.16);
  --shadow-panel: none;
}

/* ==========================================================================
   Primitives. Shared so three surfaces cannot drift apart.
   ========================================================================== */

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

html, body {
  margin: 0;
  max-width: 100%;
  overflow-x: hidden;
}

body {
  background: var(--s-base);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Focus must always be visible. A keyboard-first tool with invisible focus is
   broken, not minimal. */
:focus-visible {
  outline: 2px solid var(--line-focus);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
:focus:not(:focus-visible) { outline: none; }

/* Numbers align. Everywhere. */
.num, td.num, .tabular {
  font-family: var(--num);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  text-align: right;
  letter-spacing: -0.01em;
}

/* ---- form controls (spec 022 FR-004) ------------------------------------
   A fixed height plus vertical padding clipped select text in half. Controls
   get a minimum height, no vertical padding and a normal line box instead. */
select,
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]) {
  box-sizing: border-box;
  min-height: var(--control-h);
  padding-block: 0;
  line-height: normal;
}

/* ---- buttons ----------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0 var(--sp-3);
  height: var(--control-h);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--s-raised);
  color: var(--ink);
  font: inherit;
  font-size: var(--t-small);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              transform var(--dur-instant) var(--ease);
}
.btn:hover { background: var(--s-hover); border-color: var(--line-focus); }
.btn:active { transform: translateY(1px); background: var(--s-active); }
.btn[aria-pressed="true"] {
  background: var(--accent-sunken);
  border-color: var(--accent);
  color: var(--ink);
}
.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn--quiet { background: transparent; border-color: transparent; color: var(--ink-muted); }
.btn--quiet:hover { background: var(--s-hover); color: var(--ink); border-color: transparent; }

/* ---- badges: the confidence flag is the most-read element in the app --- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 1px var(--sp-2);
  border-radius: var(--r-pill);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  border: 1px solid transparent;
}
.badge--verified  { background: var(--verified-bg);  color: var(--verified);  border-color: color-mix(in oklab, var(--verified) 35%, transparent); }
.badge--predicted { background: var(--predicted-bg); color: var(--predicted); border-color: color-mix(in oklab, var(--predicted) 35%, transparent); }
.badge--fire      { background: var(--fire-bg);      color: var(--fire);      border-color: color-mix(in oklab, var(--fire) 35%, transparent); }
.badge--wet       { background: var(--wet-bg);       color: var(--wet);       border-color: color-mix(in oklab, var(--wet) 35%, transparent); }
.badge--unresolved{ background: var(--unresolved-bg);color: var(--unresolved);border-color: color-mix(in oklab, var(--unresolved) 35%, transparent); }

/* ---- panel ------------------------------------------------------------- */
.panel {
  background: var(--s-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-panel);
}

/* ---- skeleton / pending ------------------------------------------------ */
@keyframes vec-pulse { 0%,100% { opacity: 0.45; } 50% { opacity: 0.8; } }
.skeleton {
  background: var(--s-hover);
  border-radius: var(--r-sm);
  animation: vec-pulse 1.4s var(--ease) infinite;
}

/* ---- entrance: used for row reveal and panel open --------------------- */
@keyframes vec-rise {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
.rise { animation: vec-rise var(--dur-med) var(--ease) both; }

/* Accessibility: motion is confirmation, so it is always optional. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---- visually hidden but announced ------------------------------------ */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}


/* ==========================================================================
   Brand (2026-10-12): the avocado mark, an avocado-flesh accent, a faint engineering grid and a soft glow.
   Branding only — no sizes, spacing or layout change here.
   ========================================================================== */
:root {
  --brand-skin: #2f5219;
  --brand-glow: rgb(180 220 106 / 0.22);
  --grid-line: rgb(233 239 229 / 0.035);
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) { --brand-glow: rgb(110 160 40 / 0.18); --grid-line: rgb(20 33 13 / 0.028); }
}
:root[data-theme="light"] { --brand-glow: rgb(110 160 40 / 0.18); --grid-line: rgb(20 33 13 / 0.028); }

body {
  background-image:
    radial-gradient(900px 420px at 85% -10%, var(--brand-glow), transparent 70%),
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: auto, 32px 32px, 32px 32px;
  background-attachment: fixed;
}
.btn--primary { box-shadow: 0 1px 0 rgb(255 255 255 / 0.25) inset, 0 6px 18px -10px var(--accent); }
.btn--primary:hover { box-shadow: 0 1px 0 rgb(255 255 255 / 0.3) inset, 0 8px 22px -8px var(--accent); }
:focus-visible { outline-color: var(--line-focus); }
