/* ============================================================
   AGX WIP Tracker — Workspace Spreadsheet Styles (v3)
   Excel-like dark theme spreadsheet
   ============================================================ */

/* ──────────────────────────────────────────────────────────────
   Excel-style theme — workspace operates as its own visual unit
   independent of the app's light/dark mode. Mimics Excel's actual
   palette: white cell area, light-gray ribbon, Excel-green accent
   on active cells / selected sheet tab, light-gray row + column
   headers. The .ws-excel-theme class is attached to the workspace
   container in initWorkspace() so every var() reference inside the
   workspace picks up these values; body.light-mode and
   body:not(.light-mode) rules don't override because this scope
   has higher specificity (class + class beats class alone).
   ────────────────────────────────────────────────────────────── */
.ws-excel-theme {
  /* Surface tier */
  --bg: #ffffff;
  --surface: #fafafa;
  --surface2: #f3f2f1;
  --card-bg: #ffffff;
  --input-bg: #ffffff;
  /* Borders */
  --border: #d4d4d4;
  /* Type */
  --text: #252525;
  --text-dim: #605e5c;
  /* Accent — Excel green (matches the active-cell border + selected
     sheet tab color in modern Office) */
  --accent: #107C41;
  --accent-dim: #185F3D;
  --green: #107C41;
  /* Grid + tables */
  --cell-bg: #ffffff;
  --cell-border: #d4d4d4;
  --row-alt: #f8f8f8;
  --row-hover: #f3f2f1;
  --grid-header-bg: #f3f2f1;
  --grid-header-text: #252525;
  --grid-border: #d4d4d4;
  /* Misc */
  --scrollbar-thumb: #c8c6c4;
  --shadow: rgba(0,0,0,0.08);
  --overlay-light: rgba(0,0,0,0.04);

  background: #fafafa;
  color: #252525;
}

/* Ribbon stays dark (Outlook style) even when the Excel theme is
   active on the rest of the workspace — the user wants dark-mode
   toolbar chrome with a light grid below. The grid + headers + cell
   colors keep their Excel skin via the rules further down; only the
   ribbon override is suppressed here.
   (Old white-skin ribbon rules removed; the dark base styling in
   the main .ws-ribbon block below applies regardless of theme.) */

/* Formula bar + cell-ref */
.ws-excel-theme .ws-cell-ref,
.ws-excel-theme .ws-formula-bar {
  background: #ffffff;
  color: #252525;
  border-color: #d4d4d4;
}
.ws-excel-theme .ws-cell-ref { font-weight: 700; }

/* Grid wrapper + inner table */
.ws-excel-theme .ws-grid-wrapper {
  background: #ffffff;
}
.ws-excel-theme .ws-grid {
  background: #ffffff;
  color: #252525;
}
.ws-excel-theme .ws-grid td,
.ws-excel-theme .ws-grid th {
  border-color: #d4d4d4;
  color: #252525;
}

/* Row + column headers */
.ws-excel-theme .ws-grid th,
.ws-excel-theme .ws-grid .ws-row-header,
.ws-excel-theme .ws-grid .ws-col-header {
  background: #f3f2f1;
  color: #252525;
  font-weight: 600;
}

/* Sheet tabs — white with green active tab matching Excel */
.ws-excel-theme .ws-sheet-tabs {
  background: #f3f2f1;
  border-top-color: #d4d4d4;
}
.ws-excel-theme .ws-sheet-tab {
  background: #f3f2f1;
  color: #252525;
  border-color: #d4d4d4;
}
.ws-excel-theme .ws-sheet-tab:hover {
  background: #ffffff;
  color: #107C41;
}
.ws-excel-theme .ws-sheet-tab.active {
  background: #ffffff;
  color: #107C41;
  border-bottom-color: #ffffff;
}
.ws-excel-theme .ws-workbook-tab {
  background: rgba(16, 124, 65, 0.08);
  border-color: rgba(16, 124, 65, 0.4);
  color: #107C41;
}
.ws-excel-theme .ws-workbook-tab.active {
  background: #ffffff;
  border-color: rgba(16, 124, 65, 0.6);
  border-bottom-color: #ffffff;
}
.ws-excel-theme .ws-workbook-tab-count {
  background: rgba(16, 124, 65, 0.18);
  color: #107C41;
}

/* Inner workbook tab strip */
.ws-excel-theme .ws-workbook-inner-tabs {
  background: #ffffff;
  border-color: #d4d4d4;
}
.ws-excel-theme .ws-workbook-inner-tabs-label {
  color: #107C41;
  border-right-color: #d4d4d4;
}
.ws-excel-theme .ws-workbook-inner-tab {
  color: #605e5c;
}
.ws-excel-theme .ws-workbook-inner-tab:hover {
  color: #252525;
  background: #f3f2f1;
}
.ws-excel-theme .ws-workbook-inner-tab.active {
  color: #107C41;
  background: #ffffff;
  border-color: #d4d4d4;
  border-bottom-color: #ffffff;
}

/* Status bar */
.ws-excel-theme .ws-statusbar {
  background: #f3f2f1;
  color: #252525;
  border-top-color: #d4d4d4;
}

/* Link panel — sits between the toolbar and grid */
.ws-excel-theme .ws-link-panel {
  background: #ffffff;
  border-color: #d4d4d4;
  color: #252525;
}
.ws-excel-theme .ws-link-title { color: #605e5c; }
.ws-excel-theme .ws-link-opt {
  background: #ffffff;
  border-color: #d4d4d4;
  color: #252525;
}
.ws-excel-theme .ws-link-opt:hover {
  background: #f3f2f1;
  border-color: #107C41;
  color: #107C41;
}
.ws-excel-theme .ws-link-opt.active {
  background: rgba(16, 124, 65, 0.15);
  border-color: #107C41;
  color: #107C41;
}

/* Borders preset menu */
.ws-excel-theme .ws-border-preset {
  color: #252525;
}
.ws-excel-theme .ws-border-preset:hover {
  background: #f3f2f1;
  border-color: #d4d4d4;
}

/* ── Toolbar ────────────────────────────────────────────── */

.ws-toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px;
  background: var(--surface2, #242836);
  border: 1px solid var(--border, #2e3346);
  border-radius: 6px 6px 0 0;
  flex-wrap: nowrap;
}

/* ── Excel-style Ribbon ─────────────────────────────────── */
/* Single grouped toolbar row that mirrors Excel's Home tab. Each
   .ws-ribbon-group is a column: controls on top, small uppercase
   label underneath, separated from neighboring groups by a 1px
   divider on the right edge. Lets the user scan the toolbar by
   purpose (Font, Alignment, Number…) instead of one big flat
   stripe of buttons. */
/* Outlook-style ribbon — dark fixed strip, grouped sections with
   small uppercase captions underneath, vertical 1px dividers
   between groups. Buttons stay compact (icon-only or short label)
   so the whole strip fits without wrapping. */
.ws-ribbon {
  display: flex;
  align-items: stretch;
  gap: 0;
  padding: 6px 6px 0;
  background: var(--surface2, #242836);
  border: 1px solid var(--border, #2e3346);
  border-top: none;
  border-radius: 0 0 6px 6px;
  flex-wrap: nowrap;
  /* Horizontal scroll on narrow viewports rather than wrapping mid-
     group (which looks broken). */
  overflow-x: auto;
  scrollbar-width: thin;
}
.ws-ribbon-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 0 0 auto;
  padding: 0 6px;
  /* Caption divider replaces the right-side line — Outlook draws
     a faint vertical between groups via the .ws-ribbon-sep span /
     the caption\'s top border. Drop the inter-group right border
     and let the section caption + caption-top-border carry the
     visual divide. */
  border-right: 1px solid var(--border, #2e3346);
  min-width: 0;
}
.ws-ribbon-group:last-child {
  border-right: none;
}
.ws-ribbon-controls {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 2px 0 6px;
  flex-wrap: nowrap;
}
.ws-ribbon-label {
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-dim, #8b90a5);
  padding: 3px 4px 4px;
  border-top: 1px solid var(--border, #2e3346);
  white-space: nowrap;
  text-align: center;
  width: 100%;
}
/* Spacer pushes the Editing group to the far right of the ribbon
   so secondary controls sit against the right edge — Outlook does
   the same with Quick Steps / Tags / Print on its right side. */
.ws-ribbon .ws-toolbar-spacer {
  flex: 1 1 auto;
  border-right: none;
  min-width: 8px;
}

/* Excel-style flat ribbon buttons. The base .ws-btn rule ships with a
   dark fill (var(--surface)) which fights the ribbon's surface2 bg —
   buttons end up looking like dark lozenges instead of icons. Scope
   a transparent override + brighter hover so the ribbon reads as a
   row of icons that lift on interaction. */
.ws-ribbon .ws-btn {
  background: transparent;
  border-color: transparent;
  color: var(--text, #e4e6f0);
}
.ws-ribbon .ws-btn:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.14);
  color: var(--text, #e4e6f0);
}
.ws-ribbon .ws-btn:active,
.ws-ribbon .ws-btn.ws-active {
  background: rgba(79, 140, 255, 0.18);
  border-color: rgba(79, 140, 255, 0.45);
  color: var(--text, #fff);
}
/* Save button keeps its accent so the primary action still pops. */
.ws-ribbon .ws-btn.ws-btn-save {
  background: rgba(27, 133, 65, 0.18);
  border-color: rgba(27, 133, 65, 0.5);
  color: #5ddb7e;
}
.ws-ribbon .ws-btn.ws-btn-save:hover {
  background: rgba(27, 133, 65, 0.32);
  border-color: #1B8541;
}

/* ── Borders dropdown panel ───────────────────────────────
   Vertical menu of preset buttons (All / Outside / Inside /
   Top / Bottom / etc). Each button is icon + label, full
   width within the panel for easy clicking. */
.ws-border-panel {
  min-width: 180px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 4px;
}
.ws-border-preset {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--text, #e4e6f0);
  font-size: 12px;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.1s;
}
.ws-border-preset:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.14);
}

/* Subsequent toolbar rows (data ops, file ops) share the same chrome
   but have no top radius — they stack flush against the formula bar
   row above them. Single-line layout: no wrap. */
.ws-toolbar + .ws-toolbar {
  border-top: none;
  border-radius: 0;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: thin;
}

/* Spacer pushes file-ops to the right side of the action row */
.ws-toolbar-spacer { flex: 1; }

/* Compact freeze-panes select — width-of-content (~32px) when closed,
   expands when the user opens the dropdown. Matches ws-btn visual.
   Hover uses var(--row-hover) so it picks up the right neutral
   overlay on both dark and Excel themes. */
.ws-select-compact {
  padding: 4px 4px 4px 6px;
  background: var(--card-bg, #0c0c14);
  color: var(--text);
  border: 1px solid var(--border, #2e3346);
  border-radius: 4px;
  font-size: 12px;
  height: 26px;
  width: 38px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  text-align-last: center;
}
.ws-select-compact:hover {
  background: var(--row-hover, rgba(255, 255, 255, 0.04));
  border-color: var(--text-dim, rgba(255, 255, 255, 0.18));
}
/* Native option dropdown — limited cross-browser styling but bg +
   color get applied. Critical for Excel theme since the default
   browser-chrome dropdown otherwise inherits OS dark gray on
   Windows. */
.ws-select-compact option {
  background: var(--card-bg, #ffffff);
  color: var(--text, #252525);
  padding: 4px 8px;
}

/* ── Formatting Toolbar ────────────────────────────────── */

.ws-toolbar-fmt {
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 3px 6px;
  background: var(--surface2, #242836);
  border: 1px solid var(--border, #2e3346);
  border-top: none;
  flex-wrap: wrap;
}

/* When formatting toolbar follows main toolbar, remove rounded bottom corners */
.ws-toolbar:has(+ .ws-toolbar-fmt),
.ws-toolbar + .ws-toolbar:has(+ .ws-toolbar-fmt) {
  border-bottom: none;
}

.ws-btn-icon {
  font-size: 13px;
  min-width: 24px;
  text-align: center;
  padding: 2px 4px;
  line-height: 1.2;
}

.ws-fmt-toggle,
.ws-fmt-align {
  font-size: 12px;
  min-width: 24px;
  text-align: center;
  padding: 2px 5px;
  line-height: 1.4;
}

.ws-fmt-toggle.ws-active,
.ws-fmt-align.ws-active {
  background: rgba(79, 140, 255, 0.2);
  border-color: var(--accent);
  color: var(--text);
}

/* Color dropdown */
.ws-color-dropdown {
  position: relative;
  display: inline-flex;
}

.ws-color-trigger {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.ws-color-icon {
  font-size: 14px;
  line-height: 1;
}

.ws-color-icon-text {
  font-weight: 700;
  font-size: 12px;
}

.ws-color-panel {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 200;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.4);
  min-width: 180px;
}

.ws-color-grid {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 2px;
  margin-bottom: 6px;
}

.ws-palette-nofill {
  grid-column: 1 / -1;
  font-size: 10px;
  color: var(--text-dim);
  padding: 3px 6px;
  cursor: pointer;
  border: 1px dashed var(--border);
  border-radius: 3px;
  text-align: center;
  margin-bottom: 4px;
  transition: all 0.12s;
}

.ws-palette-nofill:hover {
  color: var(--text);
  border-color: var(--accent);
  background: var(--surface2);
}

.ws-palette-swatch {
  width: 16px;
  height: 16px;
  border-radius: 2px;
  cursor: pointer;
  transition: transform 0.1s;
}

.ws-palette-swatch:hover {
  transform: scale(1.3);
  z-index: 1;
}

.ws-color-recent-label {
  font-size: 9px;
  color: var(--text-dim);
  text-transform: uppercase;
  margin-bottom: 3px;
}

.ws-color-recent {
  display: flex;
  gap: 3px;
  margin-bottom: 6px;
}

.ws-color-custom {
  border-top: 1px solid var(--border);
  padding-top: 5px;
  font-size: 10px;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  gap: 4px;
}

.ws-color-custom input[type="color"] {
  width: 20px;
  height: 16px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 2px;
  cursor: pointer;
  background: none;
}

/* Cell style presets */
.ws-style-panel {
  min-width: 140px;
}

.ws-style-preset {
  padding: 4px 8px;
  font-size: 11px;
  border-radius: 3px;
  cursor: pointer;
  margin-bottom: 2px;
  border: 1px solid var(--border);
  transition: opacity 0.1s;
}

.ws-style-preset:hover {
  opacity: 0.8;
}

.ws-color-swatch {
  width: 14px;
  height: 14px;
  border: 1px solid rgba(255,255,255,0.15);
  border-radius: 2px;
  display: inline-block;
}

/* Cell move indicator */
.ws-cell.ws-move-target {
  outline: 2px dashed var(--accent) !important;
  outline-offset: -1px;
}

/* Merged cells */
.ws-cell.ws-merged {
  z-index: 1;
  overflow: hidden;
}

.ws-cell-ref {
  font-family: 'Courier New', monospace;
  font-size: 12px;
  font-weight: 600;
  color: var(--text, #e4e6f0);
  background: var(--bg, #0f1117);
  border: 1px solid var(--border, #2e3346);
  border-radius: 3px;
  padding: 4px 8px;
  min-width: 44px;
  text-align: center;
}

.ws-formula-bar {
  flex: 1;
  min-width: 120px;
  font-family: 'Courier New', monospace;
  font-size: 12px;
  color: var(--text, #e4e6f0);
  background: var(--bg, #0f1117);
  border: 1px solid var(--border, #2e3346);
  border-radius: 3px;
  padding: 4px 8px;
  outline: none;
  transition: border-color 0.15s;
}

.ws-formula-bar:focus {
  border-color: var(--accent, #4f8cff);
}

/* ── Reference Mode ────────────────────────────────────── */

.ws-formula-bar.ws-ref-mode {
  border-color: #f59e0b;
  background: rgba(245, 158, 11, 0.04);
}

.ws-formula-bar.ws-ref-mode:focus {
  border-color: #f59e0b;
}

.ws-cell.ws-ref-highlight {
  border-width: 2px !important;
  border-style: solid !important;
  background: rgba(255, 255, 255, 0.04);
}

.ws-toolbar-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}

.ws-separator {
  width: 1px;
  height: 18px;
  background: var(--border, #2e3346);
  margin: 0 3px;
}

/* ── Buttons ───────────────────────────────────────────── */

.ws-btn {
  font-size: 11px;
  padding: 3px 8px;
  border: 1px solid var(--border, #2e3346);
  border-radius: 3px;
  background: var(--surface, #1a1d27);
  color: var(--text-dim, #8b90a5);
  cursor: pointer;
  transition: all 0.12s;
  white-space: nowrap;
  line-height: 1.4;
}

.ws-btn:hover {
  background: var(--surface2, #242836);
  color: var(--text, #e4e6f0);
  border-color: var(--accent-dim, #2a4a8a);
}

.ws-btn-fmt {
  font-weight: 700;
  font-family: 'Courier New', monospace;
  min-width: 24px;
  text-align: center;
  padding: 3px 5px;
  font-size: 12px;
}

.ws-btn-save {
  background: rgba(27, 133, 65, 0.12);
  border-color: rgba(27, 133, 65, 0.3);
  color: #34d399;
}

.ws-btn-save:hover {
  background: rgba(27, 133, 65, 0.25);
  border-color: #1B8541;
}

/* ── Link Panel ──────────────────────────────────────── */

.ws-link-panel {
  /* Default-closed. The Link button (▾) toggles the .ws-link-panel-open
     class to reveal. Class-based instead of inline display so a stale
     inline style left over from a prior session can't strand the panel
     visible — every workspace render starts hidden, period. */
  display: none;
  padding: 8px 10px;
  background: var(--surface, #1a1d27);
  border: 1px solid var(--border, #2e3346);
  border-top: none;
  max-height: 280px;
  overflow-y: auto;
}
.ws-link-panel.ws-link-panel-open {
  display: block;
}

.ws-link-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.ws-link-title {
  font-size: 11px;
  color: var(--text-dim, #8b90a5);
  white-space: nowrap;
}

.ws-link-active {
  display: none;
}

.ws-link-title span {
  color: var(--accent, #4f8cff);
  font-weight: 600;
  font-family: 'Courier New', monospace;
}

.ws-link-options {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.ws-link-group {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  align-items: center;
  padding: 3px 0;
  border-bottom: 1px solid rgba(46, 51, 70, 0.5);
}

.ws-link-group:last-child {
  border-bottom: none;
}

.ws-link-group-header {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-dim, #8b90a5);
  width: 100%;
  margin-bottom: 1px;
  opacity: 0.7;
}

/* Expandable link level groups (buildings, phases, subs, COs) */
.ws-link-level {
  margin: 4px 0;
}

.ws-link-level-header {
  font-size: 10px;
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
  padding: 3px 0;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

.ws-link-target {
  margin-left: 8px;
  margin-bottom: 2px;
}

.ws-link-target-header {
  font-size: 10px;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  padding: 2px 0;
}

.ws-link-target-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin: 2px 0 4px 8px;
}

.ws-link-opt {
  font-size: 10px;
  padding: 2px 7px;
  border: 1px solid var(--border, #2e3346);
  border-radius: 10px;
  background: transparent;
  color: var(--text-dim, #8b90a5);
  cursor: pointer;
  transition: all 0.12s;
}

.ws-link-opt:hover {
  border-color: var(--accent, #4f8cff);
  color: var(--accent, #4f8cff);
}

.ws-link-opt.active {
  background: rgba(79, 140, 255, 0.15);
  border-color: var(--accent, #4f8cff);
  color: var(--accent, #4f8cff);
}

.ws-link-badge {
  display: inline-block;
  font-size: 10px;
  padding: 1px 6px;
  background: rgba(27, 133, 65, 0.2);
  border: 1px solid rgba(27, 133, 65, 0.4);
  border-radius: 8px;
  color: #34d399;
  font-weight: 500;
}

.ws-btn-unlink {
  font-size: 10px;
  padding: 2px 7px;
  color: var(--red, #f87171);
  border-color: rgba(248, 113, 113, 0.3);
  margin-top: 4px;
}

.ws-btn-unlink:hover {
  background: rgba(248, 113, 113, 0.1);
  border-color: var(--red, #f87171);
}

/* ── Grid — Excel-like ─────────────────────────────────── */

.ws-grid-wrapper {
  overflow: auto;
  max-height: 500px;
  border: 1px solid var(--grid-border);
  border-top: none;
  background: var(--surface);
  scrollbar-width: thin;
  scrollbar-color: var(--scrollbar-thumb) var(--surface);
}

.ws-grid-wrapper::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
.ws-grid-wrapper::-webkit-scrollbar-track {
  background: var(--surface);
}
.ws-grid-wrapper::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border-radius: 4px;
}

.ws-grid {
  border-collapse: collapse;
  width: max-content;
  font-family: 'Segoe UI', 'Calibri', -apple-system, sans-serif;
  font-size: 12px;
  user-select: none;
}

/* ── Headers — Excel-style ─────────────────────────────── */

.ws-grid thead {
  position: sticky;
  top: 0;
  z-index: 3;
}

.ws-corner {
  width: 40px;
  min-width: 40px;
  background: var(--grid-header-bg);
  border: 1px solid var(--grid-border);
  border-bottom: 2px solid var(--grid-border);
  position: sticky;
  left: 0;
  z-index: 4;
}

.ws-col-header {
  background: var(--grid-header-bg);
  color: var(--grid-header-text);
  font-weight: 600;
  font-size: 11px;
  text-align: center;
  padding: 4px 4px;
  border: 1px solid var(--grid-border);
  border-bottom: 2px solid var(--grid-border);
  cursor: pointer;
  position: relative;
  letter-spacing: 0.5px;
  user-select: none;
}

/* Resize handle on the right edge of the column header. The strip
   is the only spot where cursor switches to col-resize; the rest of
   the header is the click-to-select-column hit zone. */
.ws-col-header::after {
  content: '';
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  cursor: col-resize;
  background: transparent;
  transition: background 0.15s;
}

.ws-col-header:hover::after {
  background: var(--accent-dim, #2a4a8a);
}

.ws-row-header {
  background: var(--grid-header-bg);
  color: var(--grid-header-text);
  font-weight: 500;
  font-size: 11px;
  text-align: center;
  padding: 3px 6px;
  border: 1px solid var(--grid-border);
  border-right: 2px solid var(--grid-border);
  position: sticky;
  left: 0;
  z-index: 2;
  width: 40px;
  min-width: 40px;
}

/* ── Cells — Excel-like ────────────────────────────────── */

.ws-cell {
  padding: 2px 6px;
  border: 1px solid var(--cell-border);
  color: var(--text);
  /* min-height keeps the comfortable click area, but the row can grow
     beyond it via explicit row height (drag-resize / AutoFit). */
  min-height: 24px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: top; /* content lines up at the top when row grows */
  cursor: cell;
  transition: background 0.08s;
  position: relative;
  background: var(--cell-bg);
  font-size: 12px;
  line-height: 1.4;
}

/* When a row has been resized (rowHeights[r] is set), cells in that
   row wrap their content. Pulling a row taller now visibly wraps the
   text to fill the available space — which is what the user expects
   from a "make it bigger" gesture. */
.ws-grid tbody tr[style*="height"] .ws-cell {
  white-space: normal;
  word-break: break-word;
}

.ws-cell:hover {
  background: var(--row-hover);
}

.ws-cell.ws-selected {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  background: rgba(79, 140, 255, 0.1);
  z-index: 1;
}

.ws-cell.ws-editing {
  outline: 2px solid var(--green);
  outline-offset: -1px;
  background: var(--surface);
  color: var(--text);
  overflow: visible;
  white-space: pre;
  cursor: text;
  z-index: 1;
}

.ws-cell.ws-number {
  text-align: right;
}

.ws-cell.ws-formula {
  /* subtle indicator */
}

.ws-cell.ws-linked {
  /* Only the corner triangle indicates linked status — no bg/border override */
}

.ws-cell.ws-linked::before {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 0;
  height: 0;
  border-bottom: 5px solid #1B8541;
  border-right: 5px solid transparent;
}

/* Cell note indicator — red triangle top-right (like Excel) */
.ws-cell.ws-has-note::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 0;
  height: 0;
  border-top: 6px solid #ef4444;
  border-left: 6px solid transparent;
  pointer-events: none;
}

.ws-cell.ws-error {
  color: #f87171;
  font-style: italic;
}

/* Alternating row tint for readability (only when no custom bg via inline style) */
.ws-grid tbody tr:nth-child(even) .ws-cell:not([style*="background"]) {
  background: var(--row-alt);
}
.ws-grid tbody tr:nth-child(even) .ws-cell:not([style*="background"]):hover {
  background: var(--row-hover);
}

/* ── Row resize handle ─────────────────────────────────── */
/* Thin invisible strip at the bottom of each row header that acts as
   the drag affordance. Cursor becomes row-resize on hover. */
.ws-row-header { position: relative; }
.ws-row-resize {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 5px;
  cursor: row-resize;
  z-index: 2;
}
.ws-row-resize:hover { background: rgba(79, 140, 255, 0.4); }

/* Selected column / row headers — a subtle accent so the user can
   tell at a glance which column they clicked. */
.ws-col-header.ws-col-selected,
.ws-row-header.ws-row-selected {
  background: rgba(79, 140, 255, 0.18) !important;
  color: var(--text, #e4e6f0) !important;
}

/* Full row selection: every cell in the row wraps text instead of
   ellipsing, so a click on the row number expands content downward.
   Row height stays unset so the table grows the row to fit. */
.ws-grid tbody tr.ws-row-fullselected .ws-cell {
  white-space: normal;
  word-break: break-word;
  overflow: visible;
  text-overflow: clip;
}

/* Floating "120px" tooltip that follows the cursor while resizing
   a column or row. Position is set inline in JS. */
.ws-resize-tip {
  position: fixed;
  display: none;
  z-index: 100000;
  background: var(--surface, #1a1d27);
  color: var(--text, #fff);
  border: 1px solid rgba(79, 140, 255, 0.45);
  border-radius: 4px;
  padding: 3px 8px;
  font-size: 11px;
  font-family: 'SF Mono', Consolas, monospace;
  font-weight: 600;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
  pointer-events: none;
}

/* ── Tables (styled ranges) ────────────────────────────── */
/* Six preset themes layered on top of the cell renderer via
   ws-table-<style> + ws-table-<role> classes. Cell-level style still
   overrides if explicitly set. */

/* CLASSIC — clean blue header, gentle banding */
.ws-table-classic.ws-table-header  { background:#2563eb !important; color:#fff !important; font-weight:700 !important; }
.ws-table-classic.ws-table-body-even { background:rgba(79,140,255,0.04) !important; }
.ws-table-classic.ws-table-body-odd  { background:rgba(255,255,255,0.02) !important; }
.ws-table-classic.ws-table-total   { background:#1f2937 !important; color:#4f8cff !important; font-weight:700 !important; border-top:2px solid #4f8cff !important; }

/* PROFESSIONAL — slate gray header, no banding, subtle borders */
.ws-table-professional.ws-table-header { background:#1f2937 !important; color:#e4e6f0 !important; font-weight:700 !important; border-bottom:2px solid #4f8cff !important; }
.ws-table-professional.ws-table-body-even,
.ws-table-professional.ws-table-body-odd { background:transparent !important; }
.ws-table-professional.ws-table-total { background:rgba(79,140,255,0.06) !important; font-weight:700 !important; border-top:2px solid #4f8cff !important; }

/* MINIMAL — header underline only, no fills */
.ws-table-minimal.ws-table-header { background:transparent !important; color:var(--text,#fff) !important; font-weight:700 !important; border-bottom:2px solid var(--text,#fff) !important; }
.ws-table-minimal.ws-table-body-even,
.ws-table-minimal.ws-table-body-odd { background:transparent !important; }
.ws-table-minimal.ws-table-total { background:transparent !important; font-weight:700 !important; border-top:1px solid var(--text-dim,#aaa) !important; }

/* BOLD — dark blue + heavier banding, white text */
.ws-table-bold.ws-table-header { background:#1e40af !important; color:#fff !important; font-weight:700 !important; text-transform:uppercase !important; letter-spacing:0.5px !important; }
.ws-table-bold.ws-table-body-even { background:rgba(30,64,175,0.10) !important; }
.ws-table-bold.ws-table-body-odd  { background:rgba(30,64,175,0.04) !important; }
.ws-table-bold.ws-table-total { background:#1e40af !important; color:#fff !important; font-weight:700 !important; }

/* COLORFUL — green header, salmon banding */
.ws-table-colorful.ws-table-header { background:#059669 !important; color:#fff !important; font-weight:700 !important; }
.ws-table-colorful.ws-table-body-even { background:rgba(5,150,105,0.06) !important; }
.ws-table-colorful.ws-table-body-odd  { background:rgba(254,202,202,0.05) !important; }
.ws-table-colorful.ws-table-total { background:#065f46 !important; color:#d1fae5 !important; font-weight:700 !important; }

/* FINANCE — black/gold for proposal totals & summary tables */
.ws-table-finance.ws-table-header { background:#000 !important; color:#fbbf24 !important; font-weight:700 !important; text-transform:uppercase !important; letter-spacing:0.4px !important; border-bottom:2px solid #fbbf24 !important; }
.ws-table-finance.ws-table-body-even { background:rgba(251,191,36,0.04) !important; }
.ws-table-finance.ws-table-body-odd  { background:transparent !important; }
.ws-table-finance.ws-table-total { background:#000 !important; color:#fbbf24 !important; font-weight:700 !important; border-top:2px solid #fbbf24 !important; }

/* Style picker swatch buttons (fallback so unstyled buttons still look ok) */
.ws-table-style-classic { border-left:4px solid #2563eb !important; }
.ws-table-style-professional { border-left:4px solid #4f8cff !important; }
.ws-table-style-minimal { border-left:4px solid var(--text-dim,#888) !important; }
.ws-table-style-bold { border-left:4px solid #1e40af !important; }
.ws-table-style-colorful { border-left:4px solid #059669 !important; }
.ws-table-style-finance { border-left:4px solid #fbbf24 !important; }

/* ── Freeze panes ────────────────────────────────────── */
/* The column-letter header (thead) is already position:sticky in the
   default styles. Excel's "Freeze Top Row" means freeze the first
   DATA row — the one carrying the user's column titles, like Row 1
   in their spreadsheet. We pin tbody tr:first-child + offset it by
   the thead height so it sits just below the column letters. */
.ws-grid.ws-freeze-row tbody tr:first-child td {
  position: sticky;
  top: 28px; /* matches default ROW_HEIGHT = thead row height */
  z-index: 2;
  background: var(--surface,#181820);
  box-shadow: 0 1px 0 var(--grid-border,#2e3346); /* subtle separator */
}
.ws-grid.ws-freeze-row tbody tr:first-child td.ws-row-header {
  z-index: 3; /* row-header corner stacks above the regular cells */
}

/* Freeze first column — pin the row-header column AND the actual
   first data column (which is th[data-col=0] / td[data-c=0]). */
.ws-grid.ws-freeze-col tbody td.ws-row-header,
.ws-grid.ws-freeze-col thead th.ws-row-corner,
.ws-grid.ws-freeze-col tbody td[data-c="0"],
.ws-grid.ws-freeze-col thead th[data-col="0"] {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface,#181820);
}
/* Stack the corner cells above everything else when both axes freeze */
.ws-grid.ws-freeze-row.ws-freeze-col tbody tr:first-child td.ws-row-header,
.ws-grid.ws-freeze-row.ws-freeze-col tbody tr:first-child td[data-c="0"] {
  z-index: 4;
}

/* ── Sheet Tab Strip ────────────────────────────────────── */
/* Excel-style tabs at the bottom of the workspace, above the status bar. */
.ws-sheet-tabs {
  background: var(--grid-header-bg);
  border-left: 1px solid var(--grid-border);
  border-right: 1px solid var(--grid-border);
  padding: 2px 4px 0;
  user-select: none;
}
.ws-sheet-tabs-list {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  overflow-x: auto;
  scrollbar-width: thin;
}
.ws-sheet-tab {
  position: relative;
  padding: 6px 14px 6px 12px;
  background: rgba(255,255,255,0.02);
  border: 1px solid var(--grid-border);
  border-bottom: none;
  border-radius: 4px 4px 0 0;
  font-size: 11px;
  color: var(--text-dim, #aaa);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.12s, color 0.12s;
  margin-bottom: -1px;
}
.ws-sheet-tab:hover {
  background: rgba(255,255,255,0.05);
  color: var(--text, #fff);
}
.ws-sheet-tab.active {
  background: var(--surface, #181820);
  color: var(--text, #fff);
  font-weight: 600;
  border-bottom: 1px solid var(--surface, #181820);
  z-index: 1;
}
.ws-sheet-tab-name { display: inline-block; }
.ws-sheet-tab-icon {
  display: inline-block;
  margin-right: 4px;
  font-size: 11px;
  opacity: 0.85;
}

/* Workbook tab — represents a multi-sheet xlsx import in the bottom
   strip. Folder icon + sheet count badge so the user sees there's
   more behind the tab. AGX-green accent so it stands out from
   regular sheets and pinned built-ins. */
.ws-workbook-tab {
  border-color: rgba(27, 133, 65, 0.45);
  color: #a8dcb6;
  background: rgba(27, 133, 65, 0.06);
}
.ws-workbook-tab:hover {
  border-color: rgba(27, 133, 65, 0.7);
  color: #d6f0dd;
}
.ws-workbook-tab.active {
  color: #5ddb7e;
  border-color: rgba(27, 133, 65, 0.85);
  background: var(--surface, #181820);
  border-bottom-color: var(--surface, #181820);
}
.ws-workbook-tab-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 6px;
  padding: 0 6px;
  height: 16px;
  background: rgba(27, 133, 65, 0.25);
  color: #5ddb7e;
  border-radius: 8px;
  font-size: 9px;
  font-weight: 700;
  min-width: 16px;
}

/* Inner workbook tabs — secondary strip above the grid that lets the
   user navigate between sheets within an active workbook. Sits flush
   below the toolbar; its tabs are smaller and lighter than the
   bottom main strip so they read as nested. */
.ws-workbook-inner-tabs {
  background: var(--bg, #0f1117);
  border: 1px solid var(--border, #2e3346);
  border-top: none;
  padding: 4px 8px;
}
.ws-workbook-inner-tabs-list {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-wrap: wrap;
}
.ws-workbook-inner-tabs-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: #5ddb7e;
  margin-right: 8px;
  padding: 4px 8px;
  border-right: 1px solid var(--border, #2e3346);
}
.ws-workbook-inner-tab {
  padding: 4px 12px;
  font-size: 11px;
  color: var(--text-dim, #8b90a5);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px 4px 0 0;
  cursor: pointer;
  transition: all 0.12s;
  white-space: nowrap;
  position: relative;
}
.ws-workbook-inner-tab:hover {
  color: var(--text, #e4e6f0);
  background: rgba(255, 255, 255, 0.04);
}
.ws-workbook-inner-tab.active {
  color: #5ddb7e;
  background: var(--surface, #1a1d27);
  border-color: var(--border, #2e3346);
  border-bottom-color: var(--surface, #1a1d27);
  font-weight: 600;
}
.ws-workbook-inner-tab-unhide {
  margin-left: 8px;
  font-style: italic;
  color: var(--text-dim, #8b90a5);
  border-color: rgba(255, 255, 255, 0.08);
}
.ws-workbook-inner-tab-unhide:hover {
  color: var(--text, #e4e6f0);
  border-color: rgba(255, 255, 255, 0.18);
}
/* Pinned built-in views (e.g. Detailed Costs, Attachments) — each
   built-in gets its own accent color so the user can tell them
   apart at a glance. Default pinned styling falls back to the blue
   QB Costs accent. */
.ws-sheet-tab-pinned {
  border-color: rgba(79, 140, 255, 0.45);
  color: #a6c4ff;
}
.ws-sheet-tab-pinned.active {
  color: #4f8cff;
  border-color: rgba(79, 140, 255, 0.7);
  border-bottom-color: var(--surface, #181820);
}
/* Detailed Costs — blue (kept as default) */
.ws-sheet-tab-qb-costs {
  border-color: rgba(79, 140, 255, 0.45);
  color: #a6c4ff;
}
.ws-sheet-tab-qb-costs.active {
  color: #4f8cff;
  border-color: rgba(79, 140, 255, 0.7);
  border-bottom-color: var(--surface, #181820);
}
/* Attachments — purple/violet to distinguish from Detailed Costs */
.ws-sheet-tab-attachments {
  border-color: rgba(167, 139, 250, 0.45);
  color: #ddd0ff;
}
.ws-sheet-tab-attachments:hover {
  background: rgba(167, 139, 250, 0.08);
  color: #c4b5fd;
}
.ws-sheet-tab-attachments.active {
  color: #a78bfa;
  border-color: rgba(167, 139, 250, 0.75);
  border-bottom-color: var(--surface, #181820);
  background: linear-gradient(180deg, rgba(167, 139, 250, 0.10), var(--surface, #181820));
}
/* Embed host inside the workspace flex column — fills space between
   formatting toolbars (or instead of the grid) and the sheet tabs.
   Visual surface is owned by the inner .qb-costs-embed so this stays
   transparent and out of the way. */
#wsEmbedHost {
  color: var(--text, #e4e6f0);
  background: transparent;
}

/* QB Detailed Costs — per-line dollar amounts. Default green so the
   amount is the visual anchor of each row at a glance; light mode
   swaps to plain text color so the page reads like a clean ledger
   (the user found the green hard to read on white). */
.qb-line-amount {
  color: #34d399;
}
body.light-mode .qb-line-amount {
  color: var(--text, #111827);
}

/* Estimate editor amounts — same dark-green/light-mode-black pattern
   as the QB Costs page. Covers the per-line client-price column,
   section subtotals, and the Proposal Total in both the totals strip
   and the detailed breakdown. */
.ee-line-amount,
.ee-section-total,
.ee-grand-total {
  color: #34d399;
}
body.light-mode .ee-line-amount,
body.light-mode .ee-section-total,
body.light-mode .ee-grand-total {
  color: var(--text, #111827);
}
.ws-sheet-tab-add {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-dim, #888);
  padding: 4px 10px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  border-radius: 4px;
  margin-bottom: 1px;
  transition: background 0.12s, color 0.12s;
}
.ws-sheet-tab-add:hover {
  background: rgba(255,255,255,0.06);
  color: var(--text, #fff);
}

/* ── Status Bar ─────────────────────────────────────────── */

.ws-statusbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 3px 8px;
  background: var(--grid-header-bg);
  border: 1px solid var(--grid-border);
  border-top: none;
  border-radius: 0 0 4px 4px;
  font-size: 11px;
  color: var(--text-dim);
}

#wsQuickCalc {
  font-family: 'Courier New', monospace;
  color: var(--accent, #4f8cff);
}

/* ── Workspace Container ────────────────────────────────── */

#wsWorkspaceContainer {
  margin-top: 8px;
  outline: none;
}

/* ── Linked Input Badges ───────────────────────────────── */

.ws-linked-badge {
  display: inline-block;
  font-size: 10px;
  padding: 1px 6px;
  margin-left: 6px;
  background: rgba(27, 133, 65, 0.2);
  border: 1px solid rgba(27, 133, 65, 0.4);
  border-radius: 8px;
  color: #34d399;
  font-weight: 600;
  font-family: 'Courier New', monospace;
  vertical-align: middle;
  letter-spacing: 0.3px;
}

/* ── Range Selection ───────────────────────────────────── */

.ws-cell.ws-range-selected {
  background: rgba(79, 140, 255, 0.12);
}

.ws-cell.ws-range-top { border-top: 2px solid var(--accent) !important; }
.ws-cell.ws-range-bottom { border-bottom: 2px solid var(--accent) !important; }
.ws-cell.ws-range-left { border-left: 2px solid var(--accent) !important; }
.ws-cell.ws-range-right { border-right: 2px solid var(--accent) !important; }

/* ── Context Menu ──────────────────────────────────────── */

.ws-context-menu {
  position: fixed;
  z-index: 1000;
  background: var(--context-bg);
  border: 1px solid var(--grid-border);
  border-radius: 4px;
  padding: 4px 0;
  box-shadow: 0 4px 12px rgba(0,0,0,0.4);
  min-width: 160px;
}

.ws-context-menu-item {
  padding: 6px 16px;
  font-size: 12px;
  color: var(--text);
  cursor: pointer;
}

.ws-context-menu-item:hover {
  background: rgba(79, 140, 255, 0.15);
}

.ws-context-menu-separator {
  height: 1px;
  background: var(--scrollbar-thumb);
  margin: 4px 0;
}

/* ── Statusbar Actions ─────────────────────────────────── */

.ws-statusbar-actions {
  display: flex;
  gap: 4px;
}

.ws-btn-add {
  font-size: 10px;
  padding: 1px 6px;
}

/* ── Responsive ─────────────────────────────────────────── */

@media (max-width: 768px) {
  .ws-toolbar {
    flex-wrap: wrap;
  }

  .ws-toolbar-actions {
    flex-wrap: wrap;
  }

  .ws-formula-bar {
    min-width: 100%;
  }

  .ws-grid-wrapper {
    max-height: 350px;
  }

  .ws-link-panel {
    max-height: 200px;
  }
}
