/* ============================================================
   Scorecard grid — the core Excel-like RAG grid.
   Rebuilt to artboard 02 (Paper "Cadry.ai" / A2-0): centered 1280
   column on fog, joined KPI strip, chronological period columns
   ending at the (tinted) current period, trailing trend column,
   floating status bar.
   ============================================================ */

/* ---- page scaffold ---- */
/* 1280px content column (mock: 1280 @ 1440) + the page's own gutters. */
.page.grid-page{
  max-width:1336px; margin:0 auto; padding:36px 28px 48px;
  display:flex; flex-direction:column;
}
/* 20px rhythm between sections (mock gap 20). The AI banner collapses to
   zero height but stays display:flex, so a flex `gap` would double up around
   it — margins with a collapsed-banner exception keep the rhythm exact. */
.grid-page > * + *{ margin-top:20px; }
.grid-page > .rt-ai-banner:not(.rt-on){ margin-top:0; }
/* An empty KPI wrapper (no metrics yet) must not hold a 20px slot open. */
.grid-page > .team-kpis-wrap:not(:has(*)){ margin-top:0; }

.grid-page .page-head{ padding:0; border-bottom:0; }
.grid-page .page-sub{ margin-top:6px; }
.grid-page .page-meta{ gap:12px; padding-bottom:4px; }
.grid-page .page-meta .pill{
  height:24px; padding:0 10px; gap:6px; border-radius:12px;
  text-transform:uppercase;
}
.grid-page .page-meta .btn{
  height:34px; padding:0 14px; border-radius:7px;
  font-size:13px; color:var(--ink); box-shadow:none;
}
.grid-page .page-meta .btn.primary{ padding:0 16px; color:#FFFFFF; }

/* ---- KPI strip: one joined container, internal dividers ---- */
/* Overrides the shared .team-kpis/.tk-tile (design.css) for this page only —
   class names stay so realtime flash + broadcasts keep targeting them. */
.grid-page .team-kpis{
  display:flex; flex-wrap:wrap; gap:0;
  background:var(--surface); border:1px solid var(--rule-2);
  border-radius:var(--radius-lg); overflow:hidden;
}
.grid-page .tk-tile{
  flex:1 1 0; min-width:240px; min-height:0;
  padding:18px 22px; gap:8px;
  background:var(--surface); border-right:1px solid var(--rule);
}
.grid-page .tk-tile:last-child{ border-right:0; }
.grid-page .tk-tile .tk-label{ letter-spacing:0.12em; }
.grid-page .tk-tile .tk-rag.empty{ background:transparent; border:1px dashed var(--ink-4); }
.grid-page .tk-tile .tk-val{ font-size:28px; line-height:34px; display:block; }
.grid-page .tk-tile .tk-sub{ color:var(--ink-4); }

/* ---- toolbar ---- */
.toolbar{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:0; border:0; background:transparent;
}
.toolbar .sp{ flex:1; }

/* read-only cadence indicator (not a switcher — cadence changes in settings) */
.cadence-badge{
  display:inline-flex; align-items:center; gap:7px; height:32px; padding:0 12px;
  background:var(--surface); border:1px solid var(--rule-2); border-radius:7px;
  font-family:var(--mono); font-size:11px; font-weight:500; letter-spacing:0.1em;
  color:var(--ink-3);
}

.grid-page .toolbar .seg{ padding:3px; border-radius:8px; }
.grid-page .toolbar .seg .si{ height:26px; padding:0 14px; border-radius:6px; }

.filter-chip{
  display:inline-flex; align-items:center; gap:7px;
  height:32px; padding:0 12px; font-size:12.5px; font-weight:500; color:var(--ink);
  background:var(--surface); border:1px solid var(--rule-3); border-radius:7px; cursor:pointer;
}
.filter-chip:hover{ background:var(--surface-2); }
.filter-chip .fc-val{ color:var(--ink); font-weight:500; }
.filter-chip.open{ background:var(--surface-2); border-color:var(--rule-3); }
.fc-wrap{ position:relative; }

/* caps-mono status legend: ● ON TRACK ● AT RISK ● OFF TRACK ○ EMPTY */
.legend{
  display:flex; align-items:center; gap:14px;
  font-size:10.5px; color:var(--ink-3); font-family:var(--mono);
  text-transform:uppercase;
}
.legend .lg{ display:flex; align-items:center; gap:5px; }
.legend .sw{ display:inline-block; width:8px; height:8px; border-radius:50%; flex-shrink:0; }
.legend .sw.ok{ background:var(--ok); }
.legend .sw.warn{ background:var(--warn); }
.legend .sw.bad{ background:var(--bad); }
.legend .sw.empty{ background:transparent; border:1px dashed var(--ink-4); }

/* ---- popovers ---- */
.pop{
  position:absolute; top:calc(100% + 6px); left:0; z-index:50; min-width:200px;
  background:var(--surface); border:1px solid var(--rule-2);
  border-radius:7px; box-shadow:var(--shadow-pop); padding:4px; display:none;
}
.pop.on{ display:block; }
.pop-opt{ display:flex; align-items:center; gap:8px; padding:6px 8px; border-radius:4px; font-size:12.5px; color:var(--ink-2); cursor:pointer; user-select:none; text-decoration:none; }
.pop-opt:hover{ background:var(--surface-2); color:var(--ink); }
.pop-opt.on{ color:var(--ink); font-weight:500; }
.pop-check{ width:12px; display:inline-block; text-align:center; color:var(--accent); font-size:11px; font-weight:600; }
.pop-av{ width:18px; height:18px; border-radius:50%; font-size:8.5px; font-weight:600; color:white; display:grid; place-items:center; flex-shrink:0; }
.pop-count{ margin-left:auto; font-family:var(--mono); font-size:10.5px; color:var(--ink-4); }
.pop-sep{ height:1px; background:var(--rule); margin:4px 2px; }

/* ---- grid shell ---- */
/* Card: 1px border, radius 12, NO shadow (shadows are for popovers only). */
.grid-wrap{
  margin:0; background:var(--surface);
  border:1px solid var(--rule-2); border-radius:var(--radius-lg); overflow:hidden;
}
.grid-scroll{ overflow:auto; max-height:calc(100vh - 300px); }

/* display:table is load-bearing: the class is literally "grid", which collides
   with Tailwind's `.grid{display:grid}` utility. Without this, the table renders
   as a CSS grid — thead/tbody stop sharing a column model and the month headers
   drift out of alignment with their values. Keep it explicit. */
table.grid{ display:table; border-collapse:separate; border-spacing:0; width:max-content; min-width:100%; font-size:13px; }
table.grid th, table.grid td{
  height:var(--row-h); padding:0 12px; text-align:right; white-space:nowrap;
  border-bottom:1px solid var(--rule);
  vertical-align:middle; background:var(--surface);
}
table.grid thead th{
  position:sticky; top:0; z-index:5; height:36px;
  font-family:var(--mono); font-size:10.5px; font-weight:500; color:var(--ink-4);
  letter-spacing:0.08em; text-transform:uppercase; background:var(--bg);
  border-bottom:1px solid var(--rule-2);
}
table.grid thead th .yr{ display:inline-block; margin-left:4px; font-size:9.5px; color:var(--ink-4); font-weight:400; }
/* Current period — the LAST period column (columns run oldest→newest). The
   header carries an accent-soft fill + accent label; the column cells get a
   faint accent-tinted wash. Hue comes from the workspace accent tokens, never
   a hardcoded blue, so warm workspaces tint warm. */
table.grid thead th.cur{ color:var(--accent); font-weight:600; background:var(--accent-soft); }
table.grid td.cur{ background:color-mix(in oklch, var(--accent-soft) 45%, var(--surface)); }
table.grid td.cell.cur .v{ font-weight:500; }

table.grid th.metric-h, table.grid td.metric-c{
  text-align:left; position:sticky; left:0; z-index:4; background:var(--surface);
  border-right:1px solid var(--rule-2); min-width:300px; padding:0 16px;
}
table.grid thead th.metric-h{ z-index:6; background:var(--bg); color:var(--ink-3); letter-spacing:0.12em; }

/* ---- group separator row ---- */
tr.group td{
  height:32px; background:var(--bg);
  border-bottom:1px solid var(--rule);
  padding:0 16px; font-family:var(--mono); font-size:10.5px; font-weight:600;
  color:var(--ink-3); letter-spacing:0.14em; text-transform:uppercase; text-align:left;
}
tr.group td.metric-c{ position:sticky; left:0; z-index:3; background:var(--bg); }
tr.group td .gcell{ display:flex; align-items:center; gap:8px; }
tr.group td .gcount{ color:var(--ink-4); font-weight:400; font-size:10.5px; letter-spacing:0; }
/* the synthetic "Ungrouped" section header reads quieter than real groups */
tr.group td .gcell-ungrouped{ color:var(--ink-4); font-weight:500; }
tr.group td.span-rest{ background:var(--bg); }

/* ---- metric name cell: owner chip, then name over caps-mono sub (unit · target) ---- */
.mcell{ display:flex; align-items:center; gap:10px; height:100%; }
.mcell .mtext{ min-width:0; display:flex; flex-direction:column; justify-content:center; gap:1px; }
.mcell .owner-chip{ cursor:default; }
/* Team-owned: dashed hollow chip — shared, not a person. */
.mcell .owner-chip.team{
  background:var(--surface); border:1.5px dashed var(--ink-4); color:var(--ink-3);
}
.mcell .name{ min-width:0; display:flex; align-items:center; gap:6px; }
.mcell .name .label{ font-size:13px; line-height:16px; color:var(--ink); font-weight:500; cursor:pointer; overflow:hidden; text-overflow:ellipsis; }
.mcell .name .label:hover{ color:var(--accent); }
.mcell .name .flag{ color:var(--warn); font-size:11px; }
.mcell .msub{
  font-family:var(--mono); font-size:10px; line-height:12px; font-weight:400;
  color:var(--ink-3); letter-spacing:0.08em; text-transform:uppercase;
  overflow:hidden; text-overflow:ellipsis;
}

/* ---- RAG cell (default = stripe: 3px full-height left spine) ---- */
td.cell{ cursor:cell; position:relative; padding:0 12px; font-family:var(--mono); font-size:12.5px; color:var(--ink); font-weight:400; }
td.cell .v{ display:inline-block; }
td.cell::before{ content:''; position:absolute; left:0; top:0; bottom:0; width:3px; background:transparent; }
td.cell.t-ok::before{ background:var(--ok); }
td.cell.t-warn::before{ background:var(--warn); }
td.cell.t-bad::before{ background:var(--bad); }
td.cell.t-empty{ color:var(--ink-4); }
td.cell.t-empty::before{ background:repeating-linear-gradient(180deg, var(--ink-5) 0 3px, transparent 3px 6px); }

/* alt RAG styles via body[data-rag] */
body[data-rag="dot"] td.cell::before{ display:none; }
body[data-rag="dot"] td.cell .v::after{ content:''; display:inline-block; width:6px; height:6px; border-radius:50%; background:var(--rag-color, transparent); margin-left:6px; vertical-align:middle; }
body[data-rag="dot"] td.cell.t-ok{ --rag-color: var(--ok); }
body[data-rag="dot"] td.cell.t-warn{ --rag-color: var(--warn); }
body[data-rag="dot"] td.cell.t-bad{ --rag-color: var(--bad); }
body[data-rag="fill"] td.cell::before{ display:none; }
body[data-rag="fill"] td.cell.t-ok{ background:var(--ok-soft); }
body[data-rag="fill"] td.cell.t-warn{ background:var(--warn-soft); }
body[data-rag="fill"] td.cell.t-bad{ background:var(--bad-soft); }
body[data-rag="loud"] td.cell::before{ display:none; }
body[data-rag="loud"] td.cell.t-ok{ background:oklch(0.88 0.10 150); color:oklch(0.30 0.10 150); }
body[data-rag="loud"] td.cell.t-warn{ background:oklch(0.88 0.11 75); color:oklch(0.30 0.10 75); }
body[data-rag="loud"] td.cell.t-bad{ background:oklch(0.85 0.13 28); color:oklch(0.32 0.13 28); }

/* Cells aren't text — a drag SELECTS cells, it must not paint a text range. */
td.cell{ user-select:none; -webkit-user-select:none; }
td.cell:hover{ background:var(--hover); }
td.cell.cur:hover{ background:color-mix(in oklch, var(--accent-soft) 70%, var(--surface)); }
td.cell:focus{ outline:none; }
td.cell.sel{ outline:2px solid var(--accent); outline-offset:-2px; z-index:3; position:relative; background:color-mix(in oklch, var(--accent-soft) 60%, var(--surface)); }

/* Multi-cell selection (drag / shift-extend). Cells in the range get a soft
   tint; the active cell keeps the bolder .sel ring + fill on top, so it stays
   the obvious focus within the block. :not(.sel) keeps the active cell darker
   than the range, and outranks the .cur tint via the extra :not() class. */
td.cell.in-range:not(.sel){ background:color-mix(in oklch, var(--accent-soft) 55%, var(--surface)); }

/* Off-screen clipboard proxy: ⌘C/⌘V focus this so the browser's native
   copy/paste fire here (see grid_controller). Must stay focusable — hence
   off-screen rather than display:none. */
textarea.grid-clip{
  position:fixed; left:-9999px; top:0; width:1px; height:1px;
  opacity:0; padding:0; border:0; margin:0; resize:none; pointer-events:none;
  /* must stay selectable — execCommand("copy") copies the proxy's selection. */
  user-select:text; -webkit-user-select:text;
}
td.cell.editing{ outline:2px solid var(--accent); outline-offset:-2px; background:var(--surface) !important; z-index:6; position:relative; box-shadow:var(--shadow-2); }
td.cell.editing .v{ visibility:hidden; }
td.cell input.cell-inp{ position:absolute; inset:0; width:100%; height:100%; border:none; background:transparent; outline:none; font-family:var(--mono); font-size:12.5px; font-weight:500; text-align:right; padding:0 12px; color:var(--ink); }
td.cell .cmt-dot{ position:absolute; top:5px; right:5px; width:5px; height:5px; border-radius:50%; background:var(--accent); }

/* ---- trailing trend column ("13 WK" / "12 MO"), pinned right ---- */
th.spark-h, td.spark-c{
  position:sticky; right:0; min-width:116px; width:116px; padding:0 14px;
  border-left:1px solid var(--rule);
}
th.spark-h{ z-index:6; letter-spacing:0.12em; }
td.spark-c{ z-index:4; }
td.spark-c svg{ display:block; margin-left:auto; }

/* ---- status bar: floating card under the grid ---- */
.statusbar{
  display:flex; align-items:center; gap:18px; height:36px; padding:0 16px;
  background:var(--surface); border:1px solid var(--rule-2); border-radius:9px;
  font-family:var(--mono); font-size:11px; color:var(--ink-3); letter-spacing:0.02em;
}
.statusbar .ref{ color:var(--accent); font-weight:500; text-transform:uppercase; }
.statusbar .v-now{ color:var(--ink); }
.statusbar .sb-stat{ display:flex; align-items:center; gap:5px; text-transform:uppercase; }
.statusbar .sb-dot{ width:6px; height:6px; border-radius:50%; flex-shrink:0; }
.statusbar .sb-dot.ok{ background:var(--ok); }
.statusbar .sb-dot.warn{ background:var(--warn); }
.statusbar .sb-dot.bad{ background:var(--bad); }
.statusbar .sb-dot.empty{ background:transparent; border:1px dashed var(--ink-4); }
.statusbar .sb-dot.none{ display:none; }
.statusbar .sp{ flex:1; }
.statusbar .kb-hints{ font-size:10.5px; color:var(--ink-4); text-transform:uppercase; white-space:nowrap; }

/* row filter dim */
tr.metric-row.dim{ opacity:0.28; transition:opacity .15s; }
tr.group.dim{ opacity:0.45; }

/* ============ DISPLAY (tweaks) PANEL ============ */
.tweaks-panel{
  position:fixed; right:16px; bottom:16px; z-index:200; width:280px;
  background:var(--surface); border:1px solid var(--rule-2);
  border-radius:10px; box-shadow:var(--shadow-pop); display:none; overflow:hidden;
}
.tweaks-panel.on{ display:block; }
.tweaks-head{ display:flex; align-items:center; gap:8px; padding:10px 12px; border-bottom:1px solid var(--rule); }
.tweaks-head h4{ margin:0; font-size:13px; font-weight:500; }
.tweaks-head .sp{ flex:1; }
.tweaks-body{ padding:12px; }
.tw-field{ margin-bottom:12px; }
.tw-field:last-child{ margin-bottom:0; }
.tw-field > label{ display:block; font-family:var(--mono); font-size:10px; color:var(--ink-3); text-transform:uppercase; letter-spacing:0.05em; margin-bottom:6px; }
.tw-field .seg-input, .seg-input{ display:inline-flex; align-items:center; background:var(--surface-2); border-radius:5px; padding:2px; width:100%; }
.seg-input .si{ flex:1; height:26px; padding:0 10px; display:flex; align-items:center; justify-content:center; gap:5px; font-size:12px; color:var(--ink-3); font-weight:450; border-radius:4px; cursor:pointer; }
.seg-input .si.on{ background:var(--surface); color:var(--ink); font-weight:500; box-shadow:0 1px 2px rgba(21,36,47,0.06); }
.tw-swatches{ display:flex; gap:6px; }
.tw-sw{ width:20px; height:20px; border-radius:5px; cursor:pointer; border:2px solid transparent; }
.tw-sw.on{ border-color:var(--ink); }

/* ============================================================
   Grid micro-interactions (slice B1 — grid-motion).
   Additive polish on top of the grid above. All motion is gated
   behind prefers-reduced-motion.
   ============================================================ */

/* The selection ring snaps cell→cell, exactly like a real spreadsheet — no
   paint-tier outline-color/background-color transition (and faster to read). */

/* Crisp keyboard-only focus ring (mouse selection still uses .sel). */
td.cell:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; z-index:3; }

/* Sparkline reveal-on-load: fade the grid sparkline in once on render.
   Opacity is compositor-tier (S); animating stroke-dashoffset would repaint the
   SVG path every frame (C). */
@keyframes grid-spark-draw{ from{ opacity:0; } to{ opacity:1; } }
td.spark-c svg path{
  animation:grid-spark-draw .5s ease-out both;
}

@media (prefers-reduced-motion: reduce){
  td.spark-c svg path{ animation:none; opacity:1; }
}
