:root {
  --navy: #16202c;
  --navy-light: #223244;
  --navy-border: #2c3d52;
  --paper: #f5f6f8;
  --white: #ffffff;
  --border: #e3e6ea;
  --ink: #1a2230;
  --muted: #6b7684;
  --accent: #2455c4;
  --accent-soft: #e8effc;
  --danger: #c4283f;
  --header-bg: #fafbfc;
  --hover-bg: #fbfcfe;
  /* Grid lines are deliberately lighter than --border (which is used for
     panel/card edges): the reference design keeps the table's internal
     lines very faint so the data reads first, not the grid. */
  --grid-line: #f0f1f3;
  /* Pill background. Deliberately a deeper blue than --accent-soft (the
     row-selection tint): pill labels are white, and white on
     --accent-soft is only ~1.15:1 contrast, i.e. unreadable. This keeps
     the light-blue family while carrying white text at ~4.45:1. */
  --pill-bg: #3778cc;
  --radius: 6px;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --sans: "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

html[data-theme="dark"] {
  --paper: #12161d;
  --white: #1c222c;
  --border: #313b48;
  --ink: #e6e9ed;
  --muted: #93a0b0;
  --accent: #5b8def;
  --accent-soft: #1e3a63;
  --danger: #e2495f;
  --header-bg: #232b37;
  --hover-bg: #222a35;
  /* Cell borders need real contrast against the --white (#1c222c) cell
     background or the grid effectively disappears in dark mode -- the
     previous value was only a few shades off it. */
  --grid-line: #3d4855;
  /* Navy pill, same family as the dark-mode row-selection tint
     (--accent-soft #1e3a63) but lifted slightly so it reads as a
     distinct chip against the row rather than blending into it. */
  --pill-bg: #24467a;
}
html[data-theme="dark"] body { background: var(--paper); }
/* Column headers and group names read as white in dark mode -- the muted
   grey they inherit from --muted is too dim against the dark board to
   scan comfortably. */
html[data-theme="dark"] table.grid th,
html[data-theme="dark"] .frozen-grid th,
html[data-theme="dark"] .group-name-editable,
html[data-theme="dark"] .group-count,
html[data-theme="dark"] .col-name-editable { color: #ffffff; }
html[data-theme="dark"] .updates-popover,
html[data-theme="dark"] .login-card { box-shadow: 0 20px 60px rgba(0,0,0,0.55); }

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--sans);
  color: var(--ink);
  background: var(--paper);
  height: 100%;
  display: flex;
  flex-direction: column;
}

.global-topbar {
  flex-shrink: 0;
  background: var(--white);
  border-bottom: 1px solid var(--border);
  padding: 8px 16px;
  display: flex;
  align-items: center;
  position: relative;
}
.global-topbar .global-search-wrapper {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}
.global-topbar .profile-menu-anchor { margin-left: auto; }

.global-search-wrapper {
  position: relative;
  width: 100%;
  max-width: 480px;
}

.profile-menu-anchor { position: relative; }

.profile-avatar-btn {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: 700;
  font-size: 13.5px;
  cursor: pointer;
  border: 2px solid transparent;
  transition: border-color 0.12s ease;
}
.profile-avatar-btn:hover { border-color: var(--border); }

.profile-dropdown {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 230px;
  background: var(--white);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.2);
  z-index: 80;
  overflow: hidden;
}
.profile-dropdown.hidden { display: none; }

.profile-dropdown-header { padding: 14px 16px; border-bottom: 1px solid var(--border); }
.profile-dropdown-name { font-weight: 700; font-size: 15px; color: var(--ink); }
.profile-dropdown-email { font-size: 13px; color: var(--muted); margin-top: 2px; }

.profile-dropdown-item {
  padding: 11px 16px;
  font-size: 14.5px;
  cursor: pointer;
  color: var(--ink);
}
.profile-dropdown-item:hover { background: var(--paper); }
.profile-dropdown-item.danger { color: var(--danger); }
.profile-dropdown-item.danger:hover { background: #fdecec; }

.global-search-icon {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 13px;
  opacity: 0.6;
  color: var(--muted);
}

#master-search-input {
  width: 100%;
  box-sizing: border-box;
  background: var(--paper);
  border: 1px solid var(--border);
  color: var(--ink);
  border-radius: 6px;
  padding: 7px 12px 7px 30px;
  font-size: 14px;
}
#master-search-input::placeholder { color: var(--muted); }
#master-search-input:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--white);
}

.master-search-results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0,0,0,0.18);
  max-height: 360px;
  overflow-y: auto;
  z-index: 50;
}
.master-search-results.hidden { display: none; }

.master-search-result {
  padding: 9px 12px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.master-search-result:last-child { border-bottom: none; }
.master-search-result:hover { background: var(--accent-soft); }
.master-search-result-name { font-weight: 600; font-size: 14px; color: var(--ink); }
.master-search-result-board { font-size: 12.5px; color: var(--muted); margin-top: 1px; }
.master-search-empty { padding: 14px 12px; color: var(--muted); font-size: 13.5px; text-align: center; }

#app {
  display: flex;
  flex: 1;
  overflow: hidden;
}

button { font-family: inherit; }

/* ---------------- Sidebar ---------------- */

.sidebar {
  width: var(--sidebar-width, 240px);
  flex-shrink: 0;
  background: var(--white);
  border-right: 1px solid var(--border);
  color: var(--muted);
  display: flex;
  flex-direction: column;
  padding: 18px 14px;
  overflow: hidden;
  transition: width 0.12s ease;
}
.sidebar.dragging { transition: none; }

.sidebar-drag-handle {
  width: 5px;
  flex-shrink: 0;
  cursor: ew-resize;
  background: transparent;
  position: relative;
  z-index: 5;
}
.sidebar-drag-handle:hover, .sidebar-drag-handle.dragging { background: var(--accent); }

.sidebar-expand-tab {
  position: fixed;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 44px;
  background: var(--white);
  border: 1px solid var(--border);
  border-left: none;
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0 6px 6px 0;
  cursor: pointer;
  z-index: 40;
  font-size: 12px;
}
.sidebar-expand-tab:hover { background: var(--paper); color: var(--accent); }
.sidebar-expand-tab.hidden { display: none; }

.sidebar-header {
  display: flex;
  align-items: center;
  padding: 0 4px 18px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 14px;
}

.sidebar-logo-plate {
  display: inline-flex;
  align-items: center;
}
html[data-theme="dark"] .sidebar-logo-plate {
  background: white;
  border-radius: 8px;
  padding: 6px 10px;
}

.sidebar-logo-img {
  height: 34px;
  width: auto;
  display: block;
}

.sidebar-section-label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  padding: 4px 8px 8px;
}

.board-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  overflow-y: auto;
}

.board-list-item {
  padding: 9px 10px;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 14.5px;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 6px;
}

.board-list-name {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.board-delete-btn {
  opacity: 0;
  cursor: pointer;
  font-size: 13px;
  flex-shrink: 0;
  color: var(--muted);
}
.board-list-item:hover .board-delete-btn { opacity: 0.7; }
.board-delete-btn:hover { opacity: 1 !important; color: var(--danger); }

.board-list-item:hover { background: var(--paper); color: var(--ink); }
.board-list-item.active { background: var(--accent); color: white; font-weight: 600; }
.board-list-item.active .board-delete-btn { color: rgba(255,255,255,0.7); }

.sidebar-add-btn {
  margin-top: 10px;
  background: transparent;
  border: 1px dashed var(--border);
  color: var(--muted);
  border-radius: var(--radius);
  padding: 8px;
  font-size: 13.5px;
  cursor: pointer;
}
.sidebar-add-btn:hover { border-color: var(--accent); color: var(--accent); }

.login-screen {
  position: fixed;
  inset: 0;
  background: var(--paper);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}
.login-screen.hidden { display: none; }

.login-card {
  width: 340px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.10);
  padding: 28px 26px;
}

.login-logo {
  display: flex;
  justify-content: center;
  margin-bottom: 24px;
}
html[data-theme="dark"] .login-logo {
  background: white;
  border-radius: 10px;
  padding: 10px 16px;
  display: inline-flex;
  margin: 0 auto 24px;
}
.login-logo-img {
  height: 56px;
  width: auto;
  display: block;
}

.login-card label {
  display: block;
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 5px;
}
.login-card input[type="email"], .login-card input[type="password"] {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 9px 10px;
  font-size: 15px;
  margin-bottom: 14px;
}
.login-card input:focus { outline: none; border-color: var(--accent); }

.login-submit { width: 100%; padding: 10px; font-size: 15px; margin-top: 8px; }

.login-hint {
  font-size: 12.5px;
  color: var(--muted);
  margin: -8px 0 14px;
}

.login-error {
  color: var(--danger);
  font-size: 13.5px;
  margin-top: 10px;
}
.login-error.hidden { display: none; }

/* ---------------- Main / topbar ---------------- */

.main {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.topbar {
  background: var(--white);
  border-bottom: 1px solid var(--border);
  padding: 16px 24px 0;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
}

.board-title-row { display: flex; align-items: center; margin-bottom: 12px; }

.topbar h1 {
  font-size: 22px;
  font-weight: 700;
  margin: 0;
  letter-spacing: -0.01em;
}

.board-tabs-row {
  display: flex;
  align-items: flex-end;
  border-bottom: 1px solid var(--border);
}
.board-tabs {
  display: flex;
  gap: 22px;
}
.board-tab {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 2px 10px;
  font-size: 15.5px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.board-tab:hover { color: var(--ink); }
.board-tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.board-tab-menu-btn {
  opacity: 0;
  font-size: 14px;
  padding: 0 3px;
  border-radius: 4px;
  color: var(--muted);
}
.board-tab:hover .board-tab-menu-btn, .board-tab.active .board-tab-menu-btn { opacity: 0.7; }
.board-tab-menu-btn:hover { opacity: 1 !important; background: var(--paper); }

.board-tab-dropdown {
  position: absolute;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.15);
  min-width: 140px;
  z-index: 60;
  margin-top: 4px;
  overflow: hidden;
}
.board-tab-dropdown.hidden { display: none; }
.board-tab-dropdown-item { padding: 9px 14px; font-size: 14px; cursor: pointer; }
.board-tab-dropdown-item:hover { background: var(--accent-soft); }
.board-tab-dropdown-item.danger { color: var(--danger); }
.board-tab-dropdown-item.danger:hover { background: #fdecec; }

.add-view-anchor { position: relative; padding-bottom: 8px; margin-bottom: -1px; }
.add-view-btn {
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  color: var(--muted);
  cursor: pointer;
  font-size: 17px;
  font-weight: 600;
}
.add-view-btn:hover { background: var(--paper); color: var(--ink); }

.add-view-menu {
  position: absolute;
  left: 0;
  top: calc(100% + 4px);
  width: 240px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.18);
  z-index: 60;
  padding: 6px 0;
  max-height: 70vh;
  overflow-y: auto;
}
.add-view-menu.hidden { display: none; }
.add-view-menu-header {
  padding: 8px 16px 6px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.add-view-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 16px;
  font-size: 14.5px;
  cursor: pointer;
  color: var(--ink);
}
.add-view-menu-item:hover { background: var(--accent-soft); }
.add-view-menu-item.disabled {
  color: var(--muted);
  cursor: default;
}
.add-view-menu-item.disabled:hover { background: none; }
.add-view-menu-item .view-icon { width: 18px; text-align: center; opacity: 0.8; }
.add-view-menu-item .soon-tag {
  margin-left: auto;
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 6px;
}

.topbar-actions { display: flex; gap: 8px; align-items: center; padding: 12px 0; flex-wrap: wrap; }
/* .btn-secondary is shared everywhere (reply composer, panel buttons,
   etc.) -- scoped here instead of bumping that class's own font-size, so
   only the toolbar's Filter/Sort/Export/Import/+Group/more-options
   buttons get bigger, not every other button in the app that happens to
   reuse the same class. */
.topbar-actions .btn-secondary { font-size: 15px; }

.toolbar-new-item-btn { padding: 7px 16px; font-size: 15px; border-radius: 6px; margin-right: 4px; }

.search-icon-wrapper { position: relative; display: inline-flex; align-items: center; }
.search-icon-wrapper .search-icon {
  position: absolute;
  left: 9px;
  font-size: 13px;
  opacity: 0.5;
  pointer-events: none;
}
.search-icon-wrapper #search-box { padding-left: 26px; }

#search-box {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 7px 10px;
  font-size: 15px;
  width: 200px;
}

.btn-secondary {
  border: 1px solid var(--border);
  background: var(--white);
  border-radius: var(--radius);
  padding: 7px 12px;
  font-size: 14px;
  color: var(--ink);
  cursor: pointer;
}
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); }

.count-badge {
  display: inline-block;
  background: var(--accent);
  color: white;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  padding: 1px 6px;
  margin-left: 3px;
}
.count-badge.hidden { display: none; }
.btn-secondary.filter-active, .btn-secondary.sort-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}

.dropdown-anchor { position: relative; }
.dropdown-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  padding: 14px;
  min-width: 420px;
  z-index: 30;
  font-size: 14px;
}
.dropdown-panel.hidden { display: none; }

.filter-condition-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
}
.filter-condition-row select, .filter-condition-row input {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 5px 6px;
  font-size: 13.5px;
  font-family: inherit;
}
.filter-where-label, .filter-connector-label {
  color: var(--muted);
  font-size: 13px;
  width: 42px;
  flex-shrink: 0;
}
/* Small inline word between paired inputs -- the "and" of "is between
   X and Y", or the "days" of "in the next N days". Unlike the labels
   above it isn't a fixed-width column, it just hugs its text. */
.filter-inline-label {
  color: var(--muted);
  font-size: 13px;
  flex-shrink: 0;
}
.filter-value-multi {
  min-width: 120px;
}
.filter-logic-select {
  width: 52px;
  flex-shrink: 0;
}
.filter-remove-btn {
  cursor: pointer;
  color: var(--muted);
  font-size: 17px;
  flex-shrink: 0;
  padding: 0 4px;
}
.filter-remove-btn:hover { color: var(--danger); }
.filter-panel-footer {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.filter-empty-state {
  color: var(--muted);
  font-size: 13.5px;
  padding: 4px 0 10px;
}

.sort-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.sort-row select {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 6px 8px;
  font-size: 13.5px;
  font-family: inherit;
}

.btn-primary {
  border: none;
  background: var(--accent);
  color: white;
  border-radius: var(--radius);
  padding: 7px 14px;
  font-size: 14px;
  cursor: pointer;
  font-weight: 600;
}
.btn-primary:hover { background: #1c45a8; }

/* ---------------- Board view ---------------- */

.board-view {
  flex: 1;
  overflow: auto;
  padding: 18px 24px 60px;
}

.form-view {
  flex: 1;
  overflow: auto;
  padding: 32px 24px 60px;
  display: flex;
  justify-content: center;
}
.form-view.hidden { display: none; }

.form-view-card {
  width: 560px;
  max-width: 100%;
}
.form-view-heading { font-size: 23px; font-weight: 700; margin-bottom: 6px; }
.form-view-subheading { font-size: 14.5px; color: var(--muted); margin-bottom: 28px; }

.form-field-group { margin-bottom: 20px; }
.form-field-group label {
  display: block;
  font-size: 13.5px;
  font-weight: 650;
  color: var(--ink);
  margin-bottom: 6px;
}
.form-field-group input,
.form-field-group select,
.form-field-group textarea {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 10px 12px;
  font-family: inherit;
  font-size: 15px;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.form-field-group textarea { resize: vertical; min-height: 70px; }
.form-field-group input:focus,
.form-field-group select:focus,
.form-field-group textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.form-view-submit-btn { padding: 11px 26px; font-size: 15px; border-radius: 7px; margin-top: 8px; }
.form-view-success {
  text-align: center;
  padding: 60px 20px;
}
.form-view-success .checkmark {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 29px;
  margin: 0 auto 16px;
}

.master-scrollbar-wrapper {
  position: fixed;
  bottom: 0;
  left: var(--sidebar-width, 240px); /* tracks the sidebar's current width, including collapsed */
  right: 0;
  height: 16px;
  overflow-x: auto;
  overflow-y: hidden;
  background: var(--white);
  border-top: 1px solid var(--border);
  z-index: 20;
  visibility: hidden;
  transition: left 0.12s ease;
}
#master-scrollbar-content { height: 1px; }

/* Populated and positioned by updateFloatingGroupHeader() in app.js.
   Deliberately position:fixed, not sticky -- see the note above
   table.grid th for why sticky positioning was dropped here. Hidden by
   default; shown only while some group's rows span the top of the
   visible board area. */
.floating-group-header {
  display: none;
  position: fixed;
  z-index: 21; /* above the master scrollbar (20), below dropdowns/popovers */
  background: var(--paper);
  overflow: hidden;
}
.floating-group-header .group-header { margin-bottom: 6px; }
.floating-group-header .board-panes { display: flex; align-items: flex-start; }
.floating-group-header .frozen-pane { border-bottom: none; }
.floating-group-header .grid-scroll { border-bottom: none; overflow-x: hidden; }

.group-block {
  position: relative;
  margin-bottom: 26px;
  padding-left: 14px;
}

/* Colored accent bar running the full height of the group (header +
   table), doubling as the click target for the color picker -- matches
   the left accent stripe in Monday's own group styling. */
.group-color-bar {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 6px;
  border-radius: 3px;
  cursor: pointer;
}
.group-color-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: none;
  padding: 0;
}

.group-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 4px;
  font-weight: 700;
  font-size: 17px;
  margin-bottom: 6px;
  background: var(--paper);
}

.group-menu-btn {
  cursor: pointer;
  font-size: 17px;
  color: var(--muted);
  width: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.group-menu-btn:hover { color: var(--ink); }

.group-name-editable { font-size: 20px; }
.group-count { color: var(--muted); font-weight: 500; font-size: 13px; }

.group-collapse-btn {
  cursor: pointer;
  font-size: 19px;
  width: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: filter 0.1s ease;
}
.group-collapse-btn:hover { filter: brightness(1.3); }

.group-menu-dropdown {
  position: fixed;
  background: var(--white);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.25);
  z-index: 65;
  overflow: hidden;
  padding: 4px;
  min-width: 180px;
}
.group-menu-item {
  padding: 9px 12px;
  border-radius: 5px;
  font-size: 14.5px;
  cursor: pointer;
  color: var(--ink);
}
.group-menu-item:hover { background: var(--hover-bg); }
.group-menu-item.danger { color: var(--danger); }
.group-menu-item.danger:hover { background: rgba(226,68,92,0.1); }

.board-panes { display: flex; align-items: flex-start; }

/* The frozen pane is deliberately never inside anything that scrolls
   horizontally -- that's what makes it reliable. position:sticky on
   table cells (the previous approach) is genuinely unreliable across
   browsers once a table needs more than one stacked offset; simply not
   being inside the scrolling element sidesteps that entirely, the same
   way Monday.com's own frozen columns actually work. */
.frozen-pane {
  flex-shrink: 0;
  width: 352px; /* 36 (checkbox) + 260 (item name) + 56 (updates) -- keep in sync with those three widths */
  border: 1px solid var(--border);
  border-right: none;
  border-radius: var(--radius) 0 0 0;
  background: var(--white);
  overflow: hidden;
}
/* Every group has its own frozen-pane, so the overflow:hidden above (for
   the pane's rounded top-left corner) clips vertically for a row sitting
   flush against its top or bottom edge -- the first or last row of any
   group. That's exactly where a focused cell's box-shadow ring (see
   .cell-editable:focus) paints past the row's own bounds, so without
   this override the ring's top or bottom edge silently disappears on
   those specific rows while every other row's shows fine. */
.frozen-pane:focus-within {
  overflow: visible;
}

.frozen-grid {
  border-collapse: collapse;
  width: 100%;
  font-size: 15px;
}

.grid-scroll { overflow-x: hidden; border: 1px solid var(--border); border-radius: var(--radius); background: var(--white); }

/* Inside the main board's split-pane layout specifically, the scrollable
   pane sits flush against the frozen pane -- flat on the left (no gap,
   no double border) and only rounded on the top-right, since add-item-row
   below it owns the bottom-right rounding. */
.board-panes .grid-scroll {
  border-radius: 0 var(--radius) 0 0;
  flex: 1;
  min-width: 0;
}

table.grid {
  border-collapse: collapse;
  width: 100%;
  font-size: 15px;
  min-width: max-content;
}

/* The main board's scrollable pane specifically should never stretch
   wider than its content needs -- .grid-scroll's flex:1 already lets it
   fill a wide browser window, and width:100% here would force the table
   itself to match that width even when its columns don't need the extra
   space, which the auto-layout algorithm was distributing into auto-fit
   columns (making them inexplicably wide) and fighting against explicit
   resize widths. */
.board-panes .grid-scroll table.grid {
  width: auto;
}

table.grid th {
  text-align: left;
  padding: 8px 12px;
  background: var(--header-bg);
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
  color: var(--muted);
  font-weight: 600;
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
  height: 36px; /* matches .frozen-grid th below -- same reason as the explicit row height on td: two independent tables need a shared value or their header rows drift apart */
  position: sticky;
  top: 0;
  z-index: 10;
}

/* The main board's own scrollable pane uses the floating header bar
   (see the .floating-group-header rules and updateFloatingGroupHeader()
   in app.js) instead of CSS sticky -- sticky positioning on table cells
   proved unreliable in practice (both for the horizontal freeze and for
   stacking correctly beneath the group name). */
.board-panes .grid-scroll table.grid th {
  position: relative;
}

/* The frozen pane's own header row -- a separate rule since .frozen-grid
   is a distinct table now, not nested inside the scrollable one. Static
   (not sticky) for the same reason as above: the floating header bar
   handles the freeze-while-scrolling behavior instead. */
.frozen-grid th {
  text-align: left;
  padding: 8px 12px;
  background: var(--header-bg);
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
  color: var(--muted);
  font-weight: 600;
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
  height: 36px;
}

/* Column options button ("..."), hidden until the header is hovered --
   same as Monday. Collapsing its width (rather than display:none) means
   the title gets the full column width at rest and shifts left to make
   room when the button appears, instead of the header jumping. */
.col-edit-btn {
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  color: var(--muted);
  display: inline-block;
  width: 0;
  opacity: 0;
  overflow: hidden;
  vertical-align: middle;
  transition: opacity 0.1s ease;
}
table.grid th:hover .col-edit-btn,
.frozen-grid th:hover .col-edit-btn {
  width: 16px;
  opacity: 0.7;
  margin-left: 3px;
}
.col-edit-btn:hover { opacity: 1 !important; color: var(--accent); }

.col-name-editable {
  cursor: text;
  display: inline-block;
  border-radius: 3px;
  padding: 1px 4px;
  margin: -1px -4px;
  outline: none;
  /* A title too long for its column truncates with "..." rather than
     overflowing into the gear icon and resize handle beside it (those
     sit outside this span, so they stay reachable). The full title is
     available via the header's title attribute on hover. */
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}
.col-name-editable:hover { background: var(--accent-soft); }
.col-name-editable:focus {
  background: var(--accent-soft);
  box-shadow: 0 0 0 1px var(--accent) inset;
  /* While renaming, show the whole title rather than a clipped version. */
  overflow: visible;
  text-overflow: clip;
  max-width: none;
}

.select-header-cell, .select-cell {
  min-width: 36px;
  width: 36px;
  text-align: center;
}
.select-header-cell { background: var(--header-bg); }
.select-cell { background: var(--white); }

.item-name-header, .item-name-cell {
  width: 260px;
  min-width: 260px;
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* This cell's overflow:hidden above (for the at-rest text-truncation
   ellipsis) would otherwise clip item-name-text's focus box-shadow ring
   the same way a resized column's own overflow would -- see the
   table.grid td:focus-within / .frozen-grid td:focus-within rule below,
   which already covers this <td> too. */
.item-name-header { background: var(--header-bg); }
.item-name-cell { background: var(--white); }

table.grid td {
  padding: 4px 12px;
  border-bottom: 1px solid var(--grid-line);
  border-right: 1px solid var(--grid-line);
  white-space: nowrap;
  vertical-align: middle;
  height: 28px; /* matches the frozen pane's row height below -- the two tables lay out independently now, so without an explicit shared height, rows with an avatar or pill compute taller than rows with plain text, and that difference compounds over many rows. Deliberately smaller than the 24px person/audit avatar and updates icon (+ this cell's own 4px top/bottom padding = 32px needed) -- a row with one of those is a couple px taller than a plain-text row as a result; that's the accepted tradeoff for keeping the avatar/icon a legible size while most rows stay this short. */
  /* Positioning anchor for a focused .cell-editable's absolutely
     positioned highlight box (see .cell-editable:focus) -- lets that box
     size itself from this cell's own real, currently-rendered box rather
     than a computed width/margin guess, so it always exactly matches
     what the column actually looks like right now, resize or no resize. */
  position: relative;
}
/* A manually resized column's cell has overflow:hidden written as this
   element's own inline style (applyColumnWidthToCells, JS), which would
   otherwise clip off the outer edge of the focus box-shadow ring above
   -- that ring paints just outside the (now edge-flush, see
   .cell-editable:focus) box's own edges, so there's no room left inside
   this cell's clip region for it to render into. !important since an
   inline style otherwise always wins over a stylesheet rule. */
table.grid td:focus-within,
.frozen-grid td:focus-within {
  overflow: visible !important;
}

/* The frozen pane's own cells -- .frozen-grid is a distinct table from
   table.grid now, so it never automatically inherited the base cell
   styling above. Matches it exactly, including the explicit height, so
   a row's checkbox/name/updates cell is always exactly as tall as its
   counterpart in the scrollable pane, regardless of what either side's
   content actually needs. */
.frozen-grid td {
  padding: 4px 12px;
  border-bottom: 1px solid var(--grid-line);
  border-right: 1px solid var(--grid-line);
  white-space: nowrap;
  vertical-align: middle;
  height: 28px;
  position: relative;
}

/* Small fixed-size visuals (person avatars, checkboxes) -- center them in
   the column rather than leaving them hugging the left edge. Tighter
   vertical padding than the base 4px too: the 26px person avatar needs
   this column's content area to be at least 26px, and this row's own
   28px height only leaves 26px after 1px top/bottom -- the base 4px
   would leave just 20px, forcing this specific row taller than every
   other row regardless of the declared row height. */
table.grid td.cell-center {
  text-align: center;
  padding-top: 1px;
  padding-bottom: 1px;
}

/* Status/dropdown/date cells whose content fills the whole cell: drop the
   padding so the colored fill reaches the cell edges, Monday-style. */
table.grid td.cell-fill {
  padding: 0;
}

table.grid tr:hover td { background: var(--hover-bg); }
/* A filled cell supplies its own background colour -- the row-hover tint
   would otherwise wash over it and mute the colour. */
table.grid tr:hover td.cell-fill { background: transparent; }
.frozen-grid tr:hover td { background: var(--hover-bg); }

/* JS mirrors hover state across the frozen/scrollable pane pair via this
   class (see wireRowHoverSync in app.js), since native :hover on one
   table's row has no way to reach into the other table's matching row. */
table.grid tr.row-hover-sync td,
.frozen-grid tr.row-hover-sync td { background: var(--hover-bg); }

tr.selected-row td { background: var(--accent-soft) !important; }
tr.selected-row:hover td { background: var(--accent-soft) !important; }

/* JS mirrors this across the frozen/scrollable pane pair too (see
   wireRowFocusSync in app.js), same reason as row-hover-sync above --
   clicking into a cell to edit it highlights its whole row, same tint as
   an actually-selected row. */
tr.row-focus-sync td { background: var(--accent-soft) !important; }
tr.row-focus-sync:hover td { background: var(--accent-soft) !important; }

.item-name-cell {
  font-weight: 400;
  color: var(--ink);
  overflow: hidden;
}

/* The flex layout lives on this inner wrapper, not the <td> itself --
   giving a table cell its own `display: flex` stops it behaving like a
   table cell (no more auto-stretch/vertical-align to the row's height),
   which showed up as the name floating at the top of a row tall from
   wrap-text elsewhere in it, with a dead gap below. The <td> stays a
   plain cell so table layout centers this wrapper normally via the
   existing vertical-align:middle on .frozen-grid td. */
.item-name-inner {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  /* Deliberately NOT position:relative: item-name-text's focused
     highlight box (see .cell-editable:focus) needs its containing block
     to be the actual <td> (already position:relative, see
     .frozen-grid td), not this wrapper. This wrapper's own height is
     driven by its content (the text, and the ESO child-tag when
     present), and the text becomes position:absolute -- and therefore
     removed from normal flow -- while focused, which would collapse
     this wrapper to ~0 height and pull the highlight box's positioning
     context down with it if it were the anchor. Letting
     position:absolute escalate past this wrapper to the <td> avoids
     that collapse entirely. */
}

.item-name-text {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: inherit;
  color: inherit;
}

.item-name-inner .child-tag {
  display: inline-block;
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--muted);
  margin-left: 6px;
  font-weight: 500;
}

.cell-editable {
  min-width: 90px;
  outline: none;
  /* A text caret makes it obvious the cell is directly editable rather
     than something you click to open a picker. */
  cursor: text;
  /* Keeps a long value inside its own cell instead of spilling over the
     next column -- especially visible now that neighbouring status/date
     cells have solid colour fills. The full text is still available on
     hover via the title attribute set in renderCell. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-radius: 4px;
  transition: box-shadow 0.12s ease, background-color 0.12s ease;
}

/* An empty text cell shows a "+ T" hint on hover, so a blank cell reads
   as editable. Rendered as a pseudo-element (not placeholder text) so
   the contenteditable stays genuinely empty -- and hidden on focus so it
   never sits behind what's being typed. */
.cell-editable.cell-text-empty::before {
  content: "+ T";
  color: var(--muted);
  font-size: 13px;
  opacity: 0;
  transition: opacity 0.1s ease;
  pointer-events: none;
}
.cell-editable.cell-text-empty:hover::before { opacity: 0.7; }
.cell-editable.cell-text-empty:focus::before { opacity: 0; }
.cell-editable:focus {
  background: var(--white);
  /* Modern "active cell" look, Monday-style: the cell's own border turns
     a solid rectangular blue, like a spreadsheet's active-cell outline --
     not a rounded/blurred pill, so it reads as "this cell" rather than
     a floating badge. The browser's own click caret placement is
     untouched -- this is purely the focus styling. */
  border-radius: 0;
  box-shadow: 0 0 0 2px var(--accent);
  /* While actively editing, show the whole value rather than a clipped
     version -- truncation is for display, not for typing into.
     !important because a column with a manually-set width has these
     same properties (plus max-width, below) written as this element's
     own inline style by applyColumnWidthToCells (JS), specifically so
     resizing takes effect immediately without a full re-render -- an
     inline style otherwise always wins over a stylesheet rule, focused
     or not, so without !important a resized column's cell would stay
     truncated and un-bled while being edited. */
  overflow: visible !important;
  white-space: normal !important;
  z-index: 5;
  /* Flex+center keeps a single short line vertically centered within
     whatever height this ends up with below, and still lets multi-line
     text grow past it while editing. */
  display: flex;
  align-items: center;
  box-sizing: border-box;
  /* Same inline-style problem as above -- a resized column's cell also
     gets max-width:100%, which caps this box at the cell's un-bled
     content width and defeats the edge-to-edge bleed below entirely. */
  max-width: none !important;
  /* This box's positioned ancestor is its own <td> (see table.grid td /
     .frozen-grid td's position:relative above) -- inset:0 stretches it
     to exactly that cell's padding-box edges, i.e. right up to the
     gridline. Deliberately position:absolute + inset rather than a
     computed width/margin: sizing is then derived live from the cell's
     real current box on every layout, not a one-time guess, so it can't
     drift out of sync with whatever the column actually looks like --
     verified this was a real problem with a margin/width version: a
     manually resized column's cell can render wider than its own resize
     handle's pixel value (auto table layout still considers unrelated
     content elsewhere in that column), and that drift broke the bleed. */
  position: absolute;
  inset: 0;
}
.long-text-cell {
  max-width: 260px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* No separate :focus rule needed here anymore -- .cell-editable:focus
   above already covers everything (overflow/white-space with
   !important, the border, and position:absolute/inset for the bleed),
   and long-text cells carry that class too. A stray position:relative
   here previously would have silently overridden that rule's
   position:absolute for this element specifically, same specificity,
   later in the file -- worth remembering if this ever needs its own
   focus rule again. */

.mono { font-family: var(--mono); font-size: 13.5px; }

.cell-updates-btn {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 5px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  background: var(--accent-soft);
  color: var(--accent);
}
.cell-updates-btn.cell-updates-empty {
  background: transparent;
  color: var(--muted);
  border: 1px dashed var(--border);
}
.cell-updates-btn:hover { background: var(--accent); color: white; border-color: var(--accent); }

.cell-audit-btn {
  display: inline-block;
  font-size: 13px;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 1px dotted var(--border);
}
.cell-audit-btn:hover { color: var(--accent); border-bottom-color: var(--accent); }
.cell-audit-btn.cell-audit-empty { color: #b8bec8; font-style: italic; }

.updates-popover {
  width: 560px;
  max-width: 92vw;
  height: 100vh;
  background: var(--white);
  box-shadow: -8px 0 32px rgba(0,0,0,0.14);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.updates-popover-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  border-bottom: 1px solid var(--border);
  font-weight: 700;
  font-size: 20px;
  flex-shrink: 0;
  background: var(--white);
}
.updates-popover-close {
  cursor: pointer;
  color: var(--muted);
  font-size: 23px;
  line-height: 1;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: background 0.12s ease, color 0.12s ease;
}
.updates-popover-close:hover { background: var(--paper); color: var(--ink); }

.updates-popover-composer {
  padding: 18px 24px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  background: var(--paper);
}
.updates-popover-composer textarea {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  font-family: inherit;
  font-size: 15px;
  resize: none;
  min-height: 64px;
  background: var(--white);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.updates-popover-composer textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.updates-popover-composer textarea:focus { outline: none; border-color: var(--accent); }
.updates-popover-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 10px;
}
.updates-popover-attach-btn {
  cursor: pointer;
  font-size: 20px;
  color: var(--muted);
  padding: 6px 8px;
  border-radius: 6px;
  transition: background 0.12s ease, color 0.12s ease;
}
.updates-popover-attach-btn:hover { color: var(--accent); background: var(--accent-soft); }
.updates-popover-actions .btn-primary { padding: 8px 22px; font-size: 14.5px; border-radius: 7px; }

.updates-popover-feed {
  flex: 1;
  overflow-y: auto;
  padding: 20px 24px;
}
.updates-popover-empty { color: var(--muted); font-size: 14px; text-align: center; padding: 60px 0; }

.mention-highlight {
  color: var(--accent);
  font-weight: 600;
  background: var(--accent-soft);
  padding: 1px 5px;
  border-radius: 4px;
}

.mention-dropdown {
  position: absolute;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.16);
  z-index: 70;
  max-width: 220px;
  overflow: hidden;
  margin-top: 4px;
}
.mention-dropdown.hidden { display: none; }
.mention-dropdown-item { padding: 8px 14px; font-size: 14px; cursor: pointer; }
.mention-dropdown-item:hover { background: var(--accent-soft); }

.update-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
}
.update-action-btn {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  padding: 5px 10px;
  border-radius: 6px;
  transition: background 0.12s ease, color 0.12s ease;
}
.update-action-btn:hover { color: var(--accent); background: var(--accent-soft); }
.update-like-btn.liked { color: var(--accent); background: var(--accent-soft); }
.update-view-count {
  font-size: 13.5px;
  color: var(--muted);
  padding: 5px 10px;
  border-radius: 6px;
}

.update-replies {
  margin-top: 14px;
  padding-left: 18px;
  border-left: 2px solid var(--border);
}
.update-replies .update-entry { margin-bottom: 14px; }
.update-replies .update-avatar { width: 26px; height: 26px; font-size: 11.5px; }
/* A reply to a reply nests another .update-replies inside this one --
   without this, each additional level would add its own 18px indent and
   2px border on top of the last, stair-stepping further right and
   heavier-bordered the deeper a thread goes. Capping it here keeps every
   reply depth past the first visually flat at the same indent, same as
   Slack/GitHub-style threads, while the underlying data (and the API)
   still supports genuinely arbitrary depth. */
.update-replies .update-replies {
  padding-left: 0;
  border-left: none;
  margin-top: 10px;
}

.reply-composer { margin-top: 10px; }
.reply-composer.hidden { display: none; }
.reply-input {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 8px 11px;
  font-family: inherit;
  font-size: 14px;
  resize: none;
  min-height: 40px;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.reply-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.hover-tooltip-trigger { position: relative; }
.hover-tooltip-trigger:hover::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: 100%;
  left: 0;
  transform: translateY(-4px);
  background: #1a1a1a;
  color: white;
  padding: 6px 10px;
  border-radius: 5px;
  font-size: 12.5px;
  z-index: 100;
  max-width: 260px;
  white-space: normal;
}

.update-entry {
  display: flex;
  gap: 12px;
  margin-bottom: 22px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--border);
}
.update-replies .update-entry { border-bottom: none; padding-bottom: 0; margin-bottom: 14px; }
.person-cell-trigger {
  position: relative;
  display: inline-block;
  width: 28px;
  height: 28px;
  cursor: pointer;
}
.person-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  color: white;
  font-size: 11.5px;
  font-weight: 700;
  cursor: pointer;
}
/* A grid cell's own `vertical-align: middle` centers based on the whole
   row's shared baseline/font metrics across every column, not just this
   cell's own box -- with a row this short, the sub-pixel rounding that
   falls out of that (measured: ~1px off top vs bottom) reads as a
   visibly uneven gap around a small circle. inset:0 + margin:auto
   instead centers this element directly against its own <td> (already
   position:relative, see table.grid td), independent of the row's other
   columns entirely -- pixel-perfect regardless of what else is in the
   row. Scoped to the grid specifically: .person-avatar is also reused
   in the person-picker popover's option list, which must stay normal
   in-flow layout, not absolutely positioned. */
table.grid td.cell-center .person-avatar {
  position: absolute;
  inset: 0;
  margin: auto;
}
.person-avatar-empty {
  background: var(--paper);
  color: var(--muted);
  border: 1.5px dashed var(--border);
}

.person-popover {
  position: fixed;
  width: 240px;
  max-height: 320px;
  background: var(--white);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.25);
  z-index: 65;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.person-popover-search {
  border: none;
  border-bottom: 1px solid var(--border);
  padding: 10px 12px;
  font-size: 14.5px;
  outline: none;
  background: var(--white);
  color: var(--ink);
}
.person-popover-search:focus { background: var(--accent-soft); }
#person-popover-list {
  overflow-y: auto;
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.person-popover-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border-radius: 5px;
  cursor: pointer;
  font-size: 14.5px;
  color: var(--ink);
}
.person-popover-option .person-avatar { width: 24px; height: 24px; font-size: 11px; flex-shrink: 0; margin-right: 2px; }
.person-popover-option:hover { background: var(--hover-bg); }
.person-popover-option.current { background: var(--accent-soft); }
.person-popover-clear { border-top: 1px solid var(--border); margin-top: 4px; padding-top: 9px; color: var(--muted); }
.person-popover-empty { padding: 10px 8px; color: var(--muted); font-size: 13.5px; text-align: center; }

.update-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: 700;
  font-size: 13.5px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}
.update-entry-body { flex: 1; min-width: 0; }
.update-meta { font-size: 14.5px; margin-bottom: 5px; }
.update-meta .update-author { font-weight: 700; color: var(--ink); }
.update-meta .update-when { color: var(--muted); margin-left: 7px; font-weight: 400; font-size: 13.5px; }
.update-text { font-size: 15px; color: var(--ink); line-height: 1.5; white-space: pre-wrap; }

.popover-photo-thumb {
  max-width: 100%;
  max-height: 320px;
  border-radius: 10px;
  margin-top: 10px;
  display: block;
  border: 1px solid var(--border);
  box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}
.popover-file-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  background: var(--white);
  transition: border-color 0.12s ease, background 0.12s ease;
}
.popover-file-link:hover { border-color: var(--accent); background: var(--accent-soft); }

th[data-draggable-column-id] { cursor: default; position: relative; }
th[data-draggable-column-id]::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  cursor: grab;
}
th[data-draggable-column-id].drag-over-col { background: var(--accent-soft); box-shadow: inset 2px 0 0 var(--accent); }

.column-resize-handle {
  position: absolute;
  top: 0;
  right: 0;
  width: 6px;
  height: 100%;
  cursor: col-resize;
  z-index: 3;
}
.column-resize-handle:hover, .column-resize-handle.resizing { background: var(--accent); }

.add-column-header-cell {
  width: 36px;
  min-width: 36px;
  max-width: 36px;
  text-align: center;
  cursor: pointer;
  color: var(--muted);
  font-size: 17px;
  font-weight: 700;
}
.add-column-header-cell:hover { background: var(--accent-soft); color: var(--accent); }

/* Body-row counterpart to the "+" add-column header cell above. Without
   a matching cell in every data row, the header row has one more cell
   than the rows beneath it, so the table's columns don't line up -- only
   noticeable at the far right end of the scroll, where that extra header
   cell actually sits. Width is pinned to match exactly. */
.add-column-spacer-cell {
  width: 36px;
  min-width: 36px;
  max-width: 36px;
  padding: 0;
}

.add-col-type-menu {
  position: fixed;
  width: 280px;
  max-height: 420px;
  overflow-y: auto;
  background: var(--white);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.25);
  z-index: 65;
  padding: 10px;
}
.add-col-type-search {
  display: block;
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 9px 11px;
  font-size: 14px;
  margin-bottom: 8px;
  outline: none;
  color: var(--ink);
  background: var(--white);
}
.add-col-type-search:focus { border-color: var(--accent); }
.add-col-type-section-label {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 10px 2px 6px;
}
.add-col-type-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
}
.add-col-type-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  color: var(--ink);
}
.add-col-type-option:hover { background: var(--hover-bg); }
.add-col-type-icon {
  width: 22px;
  height: 22px;
  border-radius: 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 13px;
  font-weight: 700;
  flex-shrink: 0;
}
.add-col-type-empty { padding: 12px 8px; color: var(--muted); font-size: 13.5px; text-align: center; }

/* Row reordering already works via native drag events (see
   wireRowDragDrop) -- this is the affordance for it. A visible grip
   appears on the left edge on hover, wide enough to actually grab,
   rather than the invisible 4px strip that was here before. */
tr[data-draggable-item-id] { cursor: default; }
tr[data-draggable-item-id] .select-cell { position: relative; }
tr[data-draggable-item-id] .select-cell::before {
  content: "⠿";
  position: absolute;
  left: 1px;
  top: 0;
  bottom: 0;
  width: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  line-height: 1;
  color: var(--muted);
  opacity: 0;
  cursor: grab;
  transition: opacity 0.1s ease;
}
tr[data-draggable-item-id]:hover .select-cell::before { opacity: 0.55; }
tr[data-draggable-item-id] .select-cell::before:hover { opacity: 1; }
tr[data-draggable-item-id] .select-cell:active::before { cursor: grabbing; }
tr[data-draggable-item-id].drag-over-row td { box-shadow: inset 0 2px 0 var(--accent); }

.updates-icon-wrapper {
  /* Same reasoning as table.grid td.cell-center .person-avatar above:
     centers directly against this element's own <td> (position:relative,
     see .frozen-grid td) rather than via vertical-align:middle's row-wide
     baseline math, which leaves a visible sub-pixel top/bottom gap on a
     row this short. Still position:absolute (not relative) here despite
     needing to itself be the positioning anchor for the badge below --
     any position other than static works as that anchor, absolute
     included. translateX replaces the old margin-left as the badge's
     rightward-overflow compensation, since margin can't coexist with
     the inset:0/margin:auto centering trick above. */
  position: absolute;
  inset: 0;
  margin: auto;
  transform: translateX(-3px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  cursor: pointer;
  color: #6b7684;
  flex-shrink: 0;
  vertical-align: middle;
  transition: color 0.12s ease;
}
.updates-icon-wrapper:hover { color: var(--accent); }
.updates-icon-wrapper:hover .updates-icon-badge { background: var(--accent); }

/* A row that actually has comments shows its chat icon and count badge in
   the accent blue, so active discussions stand out against the muted
   grey of rows with nothing on them. */
.updates-icon-wrapper.has-comments { color: var(--accent); }
.updates-icon-wrapper.has-comments .updates-icon-badge { background: var(--accent); }

.updates-icon-bubble, .updates-icon-plus {
  width: 20px;
  height: 20px;
}

.updates-icon-badge {
  position: absolute;
  top: -3px;
  right: -5px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 8px;
  background: #6b7684;
  color: white;
  font-size: 10.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border: 1.5px solid var(--white);
  box-sizing: border-box;
  transition: background 0.12s ease;
}

.updates-column-header, .updates-column-cell {
  width: 56px;
  min-width: 56px;
  max-width: 56px;
  text-align: center;
  /* This cell holds nothing but the icon (no text baseline to preserve),
     so zeroing the inherited line-height collapses the few px of leading
     the browser otherwise reserves around an inline-flex child -- without
     it this column renders visibly taller than every other column now
     that rows are this short, since that leading used to be a much
     smaller fraction of a taller row. */
  line-height: 0;
}
.updates-column-header { background: var(--header-bg); }
.updates-column-cell { background: var(--white); }
/* Same reasoning as table.grid td.cell-center above: the 26px updates
   icon needs at least 26px of content area, which the base 4px top/
   bottom padding doesn't leave inside a 28px row. Scoped past
   .frozen-grid td's own padding (higher specificity) rather than
   touching the shared header rule above, which doesn't need this. */
.frozen-grid td.updates-column-cell {
  padding-top: 1px;
  padding-bottom: 1px;
}

.pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 5px;
  font-size: 13px;
  font-weight: 600;
  color: white;
  white-space: nowrap;
}

.bulk-actions-bar {
  position: fixed;
  top: 90px;
  left: 50%;
  transform: translateX(-50%);
  /* Deliberately var(--navy), not var(--ink) -- --ink flips to near-white
     in dark mode (it's the main text color there), which made this bar
     nearly invisible against a dark page background. --navy is a fixed
     hex, not theme-dependent, so this stays a dark floating toolbar with
     readable white text in both themes. */
  background: var(--navy);
  color: white;
  border-radius: 10px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.28);
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 14px;
  z-index: 55;
  font-size: 14.5px;
}
.bulk-actions-bar.hidden { display: none; }
#bulk-actions-count { font-weight: 700; white-space: nowrap; }
.bulk-actions-divider { width: 1px; height: 20px; background: rgba(255,255,255,0.2); }
.bulk-action-item {
  display: flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 6px;
  white-space: nowrap;
}
.bulk-action-item:hover { background: rgba(255,255,255,0.12); }
.bulk-action-item.danger:hover { background: rgba(226,68,92,0.25); color: #ff9aa8; }
.bulk-action-item.hidden { display: none; }
.bulk-actions-close {
  cursor: pointer;
  font-size: 19px;
  padding: 0 4px;
  opacity: 0.7;
}
.bulk-actions-close:hover { opacity: 1; }

/* Status/dropdown cells fill the entire cell edge-to-edge, Monday-style:
   the color reads as the cell's own background rather than a small pill
   floating in whitespace. The <td> zeroes its padding for these types
   (see td.cell-fill below) so there's no white gutter around the fill. */
/* Shared by both variants -- only the shape/sizing differs below. */
.status-cell-trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.01em;
  box-sizing: border-box;
}
.status-cell-trigger:hover { filter: brightness(0.94); }

/* Status: a single-choice state, so the colour is the signal and fills
   the whole cell edge-to-edge (its <td> drops its padding via
   td.cell-fill). */
/* Status: a single-choice state, so the colour is the signal and fills
   the whole cell edge-to-edge (its <td> drops its padding via
   td.cell-fill). The label sits in an inner span so it can truncate from
   the end with an ellipsis -- the flex container itself can't, and would
   clip from both sides. */
.status-cell-fill {
  width: 100%;
  height: 100%;
  min-height: 28px;
  border-radius: 0;
  padding: 0 10px;
}
/* Solid white label on a filled status cell in both themes. Scoped to
   cells that actually have a value via :not(:empty) on the label, so an
   empty cell keeps its muted placeholder colour instead of turning
   white-on-near-white. */
.status-cell-fill > .status-label:not(:empty) { color: #ffffff; }
.status-cell-fill > .status-label,
.status-cell-pill > .status-label {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Dropdown: can hold multiple values, which need to read as separate
   chips -- so a pill inset inside a normally-padded cell rather than a
   full-cell fill. Softly rectangular (not fully rounded) and slightly
   see-through, matching the reference, so pills read as lighter-weight
   than a status column's solid fill. Opacity is used rather than an rgba
   background because the colour arrives as an inline hex from the
   column's own options -- there's no single value to rewrite here. */
/* Dropdown: can hold multiple values, which need to read as separate
   chips -- so a pill inset inside a normally-padded cell rather than a
   full-cell fill. Softly rectangular (not fully rounded) and slightly
   see-through, matching the reference, so pills read as lighter-weight
   than a status column's solid fill. Opacity is used rather than an rgba
   background because the colour arrives as an inline hex from the
   column's own options -- there's no single value to rewrite here.
   inline-block (not inline-flex) and left-aligned on purpose: a centered
   flex container clips overflow from BOTH sides, which looks like the
   start of the label being chopped off, and text-overflow:ellipsis has
   no effect on a flex container's own text. A block text context
   truncates from the end and shows the "..." properly. */
.status-cell-pill {
  display: inline-block;
  max-width: 100%;
  border-radius: 4px;
  padding: 3px 10px;
  font-size: 13.5px;
  line-height: 16px;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
  /* One consistent pill colour per theme rather than each option's own
     colour. !important is required because renderCell sets the option
     colour as an inline style, which beats any class selector. Full
     opacity (not the previous 0.82) so the colour lands exactly as
     specified and white text keeps its measured contrast rather than
     being washed toward the row background. */
  background: var(--pill-bg) !important;
  color: #ffffff !important;
  opacity: 1;
}
.status-cell-pill:hover { filter: brightness(1.08); }

.status-popover {
  position: fixed;
  width: 200px;
  background: var(--white);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.25);
  z-index: 65;
  overflow: hidden;
  padding: 6px;
}
#status-popover-options { display: flex; flex-direction: column; gap: 4px; }
.status-popover-search {
  display: block;
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 8px 10px;
  font-size: 14px;
  margin-bottom: 6px;
  outline: none;
  color: var(--ink);
  background: var(--white);
}
.status-popover-search:focus { border-color: var(--accent); }
.status-popover-create-btn {
  margin-top: 4px;
  padding: 10px 12px;
  border-radius: 5px;
  background: var(--accent);
  color: white;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
}
.status-popover-create-btn:hover { filter: brightness(1.08); }
.status-popover-option {
  padding: 10px 12px;
  border-radius: 5px;
  color: white;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  transition: filter 0.1s ease;
}
.status-popover-option:hover { filter: brightness(1.08); }
.status-popover-option.current { box-shadow: 0 0 0 2px var(--ink) inset; }
.status-popover-clear {
  background: var(--paper) !important;
  border: 1px dashed var(--border);
  color: var(--muted) !important;
  min-height: 18px;
}
.status-popover-footer {
  margin-top: 6px;
  padding: 10px 12px;
  border-top: 1px solid var(--border);
  text-align: center;
  font-size: 13.5px;
  color: var(--muted);
  cursor: pointer;
}
.status-popover-footer:hover { color: var(--accent); }

.move-to-group-popover { width: 220px; }
.move-to-popover-header {
  padding: 6px 10px 8px;
  font-size: 13px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
#move-to-group-options { display: flex; flex-direction: column; gap: 2px; }
.move-to-group-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
  border-radius: 5px;
  cursor: pointer;
  font-size: 14.5px;
  color: var(--ink);
}
.move-to-group-option .group-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; margin-right: 4px; }
.move-to-group-option:hover { background: var(--hover-bg); }
.move-to-group-name { font-weight: 550; }

.add-item-row {
  padding: 8px 12px;
  color: var(--muted);
  font-size: 14px;
  cursor: pointer;
  border: 1px solid var(--border);
  border-top: none;
  border-radius: 0 0 var(--radius) var(--radius);
}
.add-item-row:hover { color: var(--accent); background: var(--hover-bg); }

select.cell-select {
  border: none;
  background: transparent;
  font-size: 14px;
  font-family: inherit;
  width: 100%;
}

input.cell-number {
  border: none;
  background: transparent;
  font-size: 14px;
  font-family: inherit;
  width: 100%;
  color: var(--ink);
}

/* Date cells are filled edge-to-edge like status cells (see td.cell-fill),
   with a soft tint rather than a strong colour so dates stay readable as
   data rather than reading like a status. Empty date cells get their own
   fainter tint instead of plain white, which is what keeps a sparse date
   column from looking like holes in the grid. */
.cell-date-trigger {
  font-size: 14px;
  color: var(--ink);
  width: 100%;
  height: 100%;
  min-height: 28px;
  padding: 0 10px;
  cursor: pointer;
  display: flex;
  align-items: center;
  box-sizing: border-box;
  position: relative;
}
/* Clear button for a filled date cell -- hidden until the cell is
   hovered, and absolutely positioned so it overlays the right edge
   instead of taking up flex space next to the date text (which would
   otherwise shift the text left the instant you hover, the same
   "layout jump on hover" problem the property column's old expand
   icon had). */
.cell-date-clear-btn {
  display: none;
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  border-radius: 50%;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
}
.cell-date-trigger:hover .cell-date-clear-btn { display: flex; }
.cell-date-clear-btn:hover { background: var(--hover-bg); color: var(--danger); }
/* An empty date cell shows nothing at rest, then a "+ 📅" hint on hover
   so it's clear the cell is clickable rather than just blank. */
.cell-date-trigger.cell-date-empty {
  color: var(--muted);
  justify-content: center;
}
.cell-date-trigger.cell-date-empty::after {
  content: "+ \1F4C5";
  font-size: 13px;
  opacity: 0;
  transition: opacity 0.1s ease;
}
.cell-date-trigger.cell-date-empty:hover::after { opacity: 0.75; }

.date-picker-popover {
  position: fixed;
  width: 280px;
  background: var(--white);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  border: 1px solid var(--border);
  z-index: 70;
  padding: 14px;
  font-size: 14px;
}

.date-picker-top-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.date-picker-today-btn {
  padding: 5px 14px;
  border-radius: 16px;
  background: var(--paper);
  border: none;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  font-family: inherit;
}
.date-picker-today-btn:hover { background: var(--hover-bg); }

.date-picker-clock-icon { width: 18px; height: 18px; color: var(--muted); flex-shrink: 0; }

.date-picker-input {
  width: 100%;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  margin-bottom: 12px;
  box-sizing: border-box;
  font-family: inherit;
  color: var(--ink);
}
.date-picker-input:focus { outline: none; border-color: var(--accent); }

.date-picker-nav-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.date-picker-month-year { display: flex; gap: 2px; }

.date-picker-select {
  border: none;
  background: transparent;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  padding: 2px 2px;
  font-family: inherit;
}

.date-picker-arrows { display: flex; gap: 2px; }
.date-picker-arrow-btn {
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  border-radius: 4px;
  cursor: pointer;
  color: var(--muted);
  font-size: 15px;
  font-family: inherit;
}
.date-picker-arrow-btn:hover { background: var(--hover-bg); color: var(--ink); }

.date-picker-weekdays {
  display: flex;
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 4px;
}
.date-picker-weekdays span { width: 14.2857%; }

.date-picker-grid {
  display: flex;
  flex-wrap: wrap;
}

.date-picker-day {
  width: 14.2857%;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 13.5px;
  cursor: pointer;
  color: var(--ink);
  box-sizing: border-box;
}
.date-picker-day:hover { background: var(--hover-bg); }
.date-picker-day.other-month { color: var(--muted); opacity: 0.45; }
.date-picker-day.is-today:not(.is-selected) { border: 1.5px solid var(--accent); }
.date-picker-day.is-selected { background: var(--accent); color: white; font-weight: 700; }

.date-picker-footer {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  text-align: center;
  font-size: 13.5px;
  color: var(--muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.date-picker-footer:hover { color: var(--accent); }
.date-picker-footer-icon { width: 15px; height: 15px; flex-shrink: 0; }


input.cell-checkbox {
  width: 18px;
  height: 18px;
  cursor: pointer;
  accent-color: var(--accent);
}

/* ---------------- Item detail panel ---------------- */

.panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 27, 38, 0.35);
  display: flex;
  justify-content: flex-end;
  z-index: 50;
}
.panel-overlay.hidden { display: none; }


.item-panel {
  width: 460px;
  max-width: 90vw;
  height: 100%;
  background: var(--white);
  box-shadow: -8px 0 24px rgba(0,0,0,0.12);
  overflow-y: auto;
  padding: 24px;
}

.item-panel h2 {
  font-size: 19px;
  margin: 0 0 4px;
}

.panel-close {
  float: right;
  cursor: pointer;
  color: var(--muted);
  font-size: 21px;
  line-height: 1;
  background: none;
  border: none;
}

.panel-field {
  margin-bottom: 14px;
}
.panel-field label {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 4px;
}

.panel-section-label {
  font-size: 13.5px;
  font-weight: 650;
  margin: 20px 0 10px;
  border-top: 1px solid var(--border);
  padding-top: 16px;
}

.update-input {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px;
  font-family: inherit;
  font-size: 14px;
  resize: vertical;
  min-height: 60px;
}

.empty-state {
  color: var(--muted);
  padding: 60px 20px;
  text-align: center;
  font-size: 15px;
}

/* ------------------------------------------------------------------ board "..." menu */

/* The three-dots toolbar button -- square rather than the usual
   text-button shape, since it holds a single glyph. */
.btn-icon-only {
  padding: 6px 10px;
  line-height: 1;
  font-size: 17px;
  letter-spacing: 1px;
}

/* The "..." panel is a short menu, not a form like Filter/Sort, so it
   overrides the shared .dropdown-panel min-width and sits right-aligned
   under the button (it's the last item in the toolbar, so a left-aligned
   panel would run off-screen). */
#board-more-panel {
  min-width: 240px;
  padding: 6px;
  left: auto;
  right: 0;
}
.more-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius);
  cursor: pointer;
  color: var(--ink);
}
.more-menu-item:hover { background: var(--hover-bg); }
.more-menu-icon { color: var(--muted); font-size: 15px; }

/* ------------------------------------------------------------------ conditional coloring panel */

.cond-color-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.18);
  z-index: 80;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 90px;
}
.cond-color-panel {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.22);
  padding: 18px 20px;
  width: 860px;
  max-width: 94vw;
  max-height: 70vh;
  overflow-y: auto;
  font-size: 14px;
}
.cond-color-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.cond-color-title { font-weight: 650; font-size: 16px; color: var(--ink); }
.cond-color-close {
  cursor: pointer;
  color: var(--muted);
  font-size: 21px;
  line-height: 1;
}
.cond-color-close:hover { color: var(--ink); }

.cond-color-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.cond-color-row select,
.cond-color-row input {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 6px 8px;
  font-size: 13.5px;
  font-family: inherit;
  background: var(--white);
  color: var(--ink);
}
.cond-color-swatch {
  width: 26px;
  height: 26px;
  border-radius: 5px;
  cursor: pointer;
  flex-shrink: 0;
  border: 1px solid rgba(0, 0, 0, 0.12);
}
.cond-color-when { color: var(--muted); flex-shrink: 0; }
.cond-color-inline { color: var(--muted); font-size: 13px; flex-shrink: 0; }
.cond-color-value-spacer { width: 1px; }
.cond-color-remove {
  cursor: pointer;
  color: var(--muted);
  font-size: 18px;
  line-height: 1;
  padding: 0 4px;
  margin-left: auto;
}
.cond-color-remove:hover { color: var(--danger); }
.cond-color-add {
  color: var(--accent);
  cursor: pointer;
  padding: 8px 2px 2px;
  font-weight: 550;
}
.cond-color-add:hover { text-decoration: underline; }
.cond-color-empty {
  color: var(--muted);
  padding: 10px 2px 16px;
}

.color-rule-swatch-picker {
  position: fixed;
  z-index: 90;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
  padding: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  width: 178px;
}
.color-rule-swatch-option {
  width: 26px;
  height: 26px;
  border-radius: 5px;
  cursor: pointer;
  border: 1px solid rgba(0, 0, 0, 0.12);
}
.color-rule-swatch-option:hover { transform: scale(1.12); }

/* An empty status/dropdown cell shows no colour at all -- the pill and
   fill backgrounds are suppressed so the cell reads as genuinely blank
   rather than as a small stray coloured chip. */
.status-cell-trigger.status-cell-blank {
  background: transparent !important;
}
/* A blank cell still needs to be clickable to reopen the picker. Without
   this the pill collapses to almost nothing (no padding, just an nbsp),
   leaving a target only a couple of pixels wide -- so clearing a value
   effectively stranded the cell. Filling the cell makes the whole area
   clickable, the same as a populated one. */
.status-cell-pill.status-cell-blank {
  display: block;
  width: 100%;
  min-height: 28px;
  padding: 0;
}

/* ------------------------------------------------------------------ dropdown label picker */

/* Used by dropdown columns instead of the status colour-swatch popover
   (see openDropdownLabelPopover). A dropdown is a set of labels rather
   than a single coloured state, so the picker shows the current
   selection as a removable chip over a search/create field, with plain
   uncoloured rows beneath. */
.dropdown-label-popover {
  position: fixed;
  width: 240px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
  z-index: 65;
  padding: 10px;
  font-size: 13.5px;
}

.dd-chip-row:not(:empty) { margin-bottom: 8px; }
.dd-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--pill-bg);
  color: #ffffff;
  border-radius: 4px;
  padding: 3px 8px;
  font-size: 13px;
  max-width: 100%;
}
.dd-chip-x {
  cursor: pointer;
  opacity: 0.75;
  font-size: 15px;
  line-height: 1;
}
.dd-chip-x:hover { opacity: 1; }

.dd-search {
  width: 100%;
  box-sizing: border-box;
  padding: 7px 9px;
  border: 1px solid var(--accent);
  border-radius: 5px;
  font-size: 13.5px;
  font-family: inherit;
  background: var(--white);
  color: var(--ink);
  outline: none;
}
.dd-search::placeholder { color: var(--muted); }

.dd-options {
  margin-top: 6px;
  max-height: 220px;
  overflow-y: auto;
}
.dd-option {
  padding: 8px 9px;
  border-radius: 5px;
  cursor: pointer;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dd-option:hover { background: var(--hover-bg); }
.dd-create {
  padding: 8px 9px;
  border-radius: 5px;
  cursor: pointer;
  color: var(--accent);
  font-weight: 550;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dd-create:hover { background: var(--accent-soft); }
.dd-empty { padding: 8px 9px; color: var(--muted); }

.dd-footer {
  margin-top: 8px;
  padding-top: 9px;
  border-top: 1px solid var(--border);
  text-align: center;
  cursor: pointer;
  color: var(--ink);
}
.dd-footer:hover { color: var(--accent); }

/* Inline label editor inside the dropdown picker (see renderLabelEditor).
   Reuses the picker's own popover shell, so it inherits the same width,
   border and shadow -- only the contents swap. */
.dd-editor-title {
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 8px;
}
.dd-editor-rows { max-height: 240px; overflow-y: auto; }
.dd-editor-row {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 6px;
}
.dd-editor-swatch {
  width: 22px;
  height: 22px;
  border-radius: 4px;
  flex-shrink: 0;
  border: 1px solid rgba(0, 0, 0, 0.15);
  cursor: pointer;
  transition: transform 0.1s ease;
}
.dd-editor-swatch:hover { transform: scale(1.08); }
.dd-editor-input {
  flex: 1;
  min-width: 0;
  padding: 5px 7px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 13px;
  font-family: inherit;
  background: var(--white);
  color: var(--ink);
  outline: none;
}
.dd-editor-input:focus { border-color: var(--accent); }
.dd-editor-remove {
  cursor: pointer;
  color: var(--muted);
  font-size: 16px;
  line-height: 1;
  flex-shrink: 0;
  padding: 0 2px;
}
.dd-editor-remove:hover { color: var(--danger); }
.dd-editor-add {
  color: var(--accent);
  cursor: pointer;
  padding: 6px 2px;
  font-weight: 550;
}
.dd-editor-add:hover { text-decoration: underline; }
.dd-editor-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  margin-top: 8px;
  padding-top: 9px;
  border-top: 1px solid var(--border);
}
.dd-editor-cancel { cursor: pointer; color: var(--muted); }
.dd-editor-cancel:hover { color: var(--ink); }
.dd-editor-apply { cursor: pointer; color: var(--accent); font-weight: 600; }
.dd-editor-apply:hover { text-decoration: underline; }

/* Applied by renderLabelEditor to whichever popover it's rendering into.
   Needed because the status popover is a narrow 200px list with
   overflow:hidden -- too tight for label rows, and it would clip the
   colour picker that opens from a swatch. */
.label-editor-mode {
  width: 250px !important;
  overflow: visible !important;
  padding: 10px !important;
  border: 1px solid var(--border);
}

/* Colour picker opened from a label's swatch in the editor. */
.label-color-picker {
  position: fixed;
  z-index: 90;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
  padding: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  /* Sized for exactly 6 swatches per row (6*26px + 5*6px gap + padding
     + border), so the 12-colour palette lays out as an even 6x2 grid
     rather than leaving a ragged partial row. */
  width: 204px;
}
.label-color-option {
  width: 26px;
  height: 26px;
  border-radius: 5px;
  cursor: pointer;
  border: 1px solid rgba(0, 0, 0, 0.12);
}
.label-color-option:hover { transform: scale(1.12); }
