:root {
  --bg: #f4f6f8;
  --bg-elevated: #ffffff;
  --text: #1c2530;
  --text-secondary: #5b6b7c;
  --border: #d8dee5;
  --accent: #2f6fed;
  --accent-text: #ffffff;
  --sidebar-bg: #ffffff;
  --sidebar-text: #4b5768;
  --sidebar-text-hover: #0f1620;
  --sidebar-hover-bg: rgba(15, 22, 32, 0.06);
  --sidebar-text-active: #ffffff;
  --sidebar-active-bg: #2f6fed;
  --sidebar-border: #e2e6eb;
  --input-bg: #ffffff;
  --danger: #d64545;
  --success: #2f9e5c;
  --warning: #c98500;
  --shadow: 0 1px 3px rgba(20, 30, 45, 0.08);
  --sidebar-width: 240px;
  --topbar-height: 56px;
  /* Shared height for every .btn/.btn-sm and the search-field input they sit next to in a
     toolbar — one knob instead of three separately hardcoded 36px fallbacks. */
  --btn-height: 30px;
  /* Validated categorical palette (fixed hue order — never cycled/reordered per-chart) for
     pie/multi-series charts on the Reports page. */
  --series-1: #2a78d6;
  --series-2: #eb6834;
  --series-3: #1baf7a;
  --series-4: #eda100;
  --series-5: #e87ba4;
  --series-6: #008300;
  --series-7: #4a3aa7;
  --series-8: #e34948;
  --series-other: #94a3b8;
}

:root[data-theme="dark"] {
  --bg: #12161c;
  --bg-elevated: #1a2029;
  --text: #e6eaf0;
  --text-secondary: #96a2b2;
  --border: #2a323e;
  --accent: #518af8;
  --accent-text: #0b0f14;
  --sidebar-bg: #0d1219;
  --sidebar-text: #97a3b4;
  --sidebar-text-hover: #ffffff;
  --sidebar-hover-bg: rgba(255, 255, 255, 0.08);
  --sidebar-text-active: #ffffff;
  --sidebar-active-bg: #2f6fed;
  --sidebar-border: #1d2530;
  --input-bg: #1a2029;
  --danger: #ef6a6a;
  --success: #4fc07d;
  --warning: #eda100;
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  --series-1: #3987e5;
  --series-2: #d95926;
  --series-3: #199e70;
  --series-4: #c98500;
  --series-5: #d55181;
  --series-6: #008300;
  --series-7: #9085e9;
  --series-8: #e66767;
  --series-other: #52627a;
}

:root[data-theme="dark"][data-theme-variant="deep"] {
  --bg: #101512;
  --bg-elevated: #151c19;
  --border: #27322e;
  --sidebar-bg: #0b100e;
  --sidebar-border: #1b2721;
  --input-bg: #151c19;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
}

body {
  margin: 0;
  font-family: var(--font-family, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
}

a { color: var(--accent); text-decoration: none; }

/* Themed scrollbars everywhere (Firefox + WebKit) — otherwise every scrollable panel shows the
   OS's default light scrollbar even in dark mode, standing out against the rest of the UI. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border) var(--bg-elevated);
}

*::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

*::-webkit-scrollbar-track {
  background: transparent;
}

*::-webkit-scrollbar-thumb {
  background-color: var(--border);
  border-radius: 6px;
  border: 2px solid var(--bg-elevated);
}

*::-webkit-scrollbar-thumb:hover {
  background-color: var(--text-secondary);
}

/* One consistent focus treatment for every button/link in the app, instead of each browser's own
   default outline (Chrome's blue ring, Firefox's dotted line, etc. — inconsistent across elements
   and, worse, showing on a plain mouse click in most browsers, not just keyboard navigation,
   which is what made a row of icon buttons look randomly "stuck" highlighted after being clicked).
   :focus-visible only fires for keyboard/assistive-tech focus, so a mouse click stays clean while
   tabbing through the page still gets a clear, uniform ring. Elements with their own deliberate
   focus style (form fields, etc.) already set their own outline and are unaffected. */
button:focus,
a:focus {
  outline: none;
}

button:focus-visible,
a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.app-shell {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

/* ---------- Top bar ---------- */

.topbar {
  height: var(--topbar-height);
  min-height: var(--topbar-height);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--border);
  z-index: 10;
}

.topbar-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.brand {
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0.02em;
}

.brand-wordmark {
  display: inline-block;
  line-height: 1;
  font-weight: 800;
  font-style: italic;
  font-size: 26px;
  letter-spacing: -0.015em;
  color: var(--accent);
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 6px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
}

.icon-btn:hover {
  background: var(--bg);
  border-color: var(--border);
  color: var(--text);
}

.icon-btn svg { width: 18px; height: 18px; }

.topbar-right {
  display: flex;
  align-items: center;
  gap: 6px;
}

.font-size-control {
  position: relative;
}

.font-size-popover {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 6px;
  z-index: 30;
  width: 220px;
  padding: 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.font-size-popover.open {
  display: block;
}

.font-size-popover-section {
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

.font-size-popover-section:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.font-size-popover-reset-row {
  display: flex;
  gap: 8px;
  justify-content: center;
}

.font-size-popover-section label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

.font-size-checkbox-label {
  display: flex !important;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  font-size: 13px !important;
  text-transform: none !important;
  font-weight: 500 !important;
  color: var(--text) !important;
  cursor: pointer;
  margin-bottom: 0 !important;
}

.font-size-checkbox-label input {
  accent-color: var(--accent);
}

.font-size-popover-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.font-size-popover-row input[type="range"] {
  flex: 1 1 auto;
  accent-color: var(--accent);
}

.font-size-popover-row input[type="number"] {
  width: 52px;
  flex: 0 0 auto;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 6px;
  color: var(--text);
  font-size: 13px;
  text-align: center;
}

.topbar-alerts { position: relative; }
.alerts-panel {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 340px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
  z-index: 30;
  overflow: hidden;
}
.alerts-panel.open { display: block; }
.alerts-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 13px;
  font-weight: 600;
  padding: 10px 12px 10px 16px;
  border-bottom: 1px solid var(--border);
}
.alerts-clear-btn {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-weight: 500;
  font-size: 12px;
  color: var(--accent);
  cursor: pointer;
}
.alerts-clear-btn:hover { text-decoration: underline; }
.alerts-list { max-height: 360px; overflow-y: auto; }
.alerts-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 16px;
  border: none;
  border-bottom: 1px solid var(--border);
  background: none;
  cursor: pointer;
  color: inherit;
  font: inherit;
}
.alerts-item:last-child { border-bottom: none; }
.alerts-item:hover { background: var(--bg); }
.alerts-item.unread { background: color-mix(in srgb, var(--accent) 7%, transparent); }
.alerts-item-subject { font-size: 13px; font-weight: 600; margin-bottom: 2px; }
.alerts-item-body {
  font-size: 12px;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.alerts-item-time { font-size: 11px; color: var(--text-secondary); margin-top: 4px; }

/* ---------- Body layout: sidebar + main ---------- */

.app-body {
  flex: 1;
  display: flex;
  min-height: 0;
}

.sidebar {
  position: relative;
  width: var(--sidebar-width);
  min-width: 64px;
  max-width: 480px;
  flex-shrink: 0;
  background: var(--sidebar-bg);
  color: var(--sidebar-text);
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--sidebar-border);
  transition: width 0.12s ease;
}

.sidebar.dragging { transition: none; }

.sidebar.collapsed {
  width: 64px !important;
}

.sidebar .icon-btn {
  color: var(--sidebar-text);
}
.sidebar .icon-btn:hover {
  background: var(--sidebar-hover-bg);
  border-color: transparent;
  color: var(--sidebar-text-hover);
}

.sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
  zoom: var(--sidebar-zoom, 1);
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 10px;
  border-radius: 6px;
  color: var(--sidebar-text);
  white-space: nowrap;
  overflow: hidden;
  margin-bottom: 2px;
}

.nav-group-toggle {
  width: 100%;
  appearance: none;
  background: none;
  border: none;
  font: inherit;
  cursor: pointer;
  text-align: left;
}

.nav-group-chevron {
  margin-left: auto;
  width: 14px !important;
  height: 14px !important;
  flex-shrink: 0;
  transition: transform 0.12s ease;
}

.nav-group-toggle.open .nav-group-chevron {
  transform: rotate(90deg);
}

.nav-subgroup {
  display: none;
  flex-direction: column;
  padding-left: 30px;
  margin-bottom: 2px;
}

.nav-group-toggle.open + .nav-subgroup {
  display: flex;
}

.nav-subitem {
  display: block;
  padding: 7px 10px;
  border-radius: 6px;
  color: var(--sidebar-text);
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 2px;
}

.nav-subitem:hover {
  background: var(--sidebar-hover-bg);
  color: var(--sidebar-text-hover);
}

.nav-subitem.active {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-text-active);
}

.sidebar.collapsed .nav-subgroup {
  display: none !important;
}

.nav-item svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.nav-item:hover {
  background: var(--sidebar-hover-bg);
  color: var(--sidebar-text-hover);
}

.nav-item.active {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-text-active);
}

.sidebar.collapsed .nav-label {
  display: none;
}

.sidebar.collapsed .kb-page-tree {
  display: none;
}

.account-menu {
  position: relative;
}

.account-menu-trigger {
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: 160px;
  background: none;
  border: none;
  padding: 6px 8px;
  border-radius: 6px;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}

.account-menu-trigger:hover,
.account-menu.open .account-menu-trigger {
  background: var(--sidebar-hover-bg);
}

.account-menu-trigger .sidebar-footer-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-menu-trigger svg {
  flex: none;
  opacity: 0.7;
  transition: transform 0.15s ease;
}

.account-menu.open .account-menu-trigger svg {
  transform: rotate(180deg);
}

.account-menu-list {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 200px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  padding: 6px;
  z-index: 50;
}

.account-menu.open .account-menu-list {
  display: block;
}

.account-menu-list a,
.account-menu-list button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border-radius: 6px;
  border: none;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  box-sizing: border-box;
}

.account-menu-list a svg,
.account-menu-list button svg {
  flex: none;
  width: 16px;
  height: 16px;
  color: var(--text-secondary);
}

.account-menu-list a:hover,
.account-menu-list button:hover {
  background: var(--bg);
}

.account-menu-list form {
  margin: 0;
}

.account-menu-divider {
  height: 1px;
  margin: 6px 4px;
  background: var(--border);
}

.sidebar-resize-handle {
  position: absolute;
  top: 0;
  right: -3px;
  width: 6px;
  height: 100%;
  cursor: col-resize;
  z-index: 5;
}

.sidebar.collapsed .sidebar-resize-handle {
  display: none;
}

.main-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 16px 24px 24px;
  min-width: 0;
  zoom: var(--page-zoom, 1);
}

.page-header {
  margin-bottom: 8px;
}

.page-header h1 {
  margin: 0 0 4px 0;
  font-size: 20px;
}

.record-header-title {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.back-nav {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  padding: 6px 10px 6px 7px;
  border-radius: 6px;
  box-shadow: var(--shadow);
  transition: border-color 120ms ease, background 120ms ease, color 120ms ease;
}

.back-nav svg {
  width: 17px;
  height: 17px;
}

.back-nav:hover,
.back-nav:focus-visible {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-text);
}

.queue-detail-header {
  min-height: 48px;
}

.queue-detail-header .record-header-title {
  flex: 0 0 auto;
  height: 32px;
}

.queue-detail-header #ticket-header-actions {
  flex: 0 0 auto;
}

.queue-bulk-select-col {
  display: none;
  width: 42px !important;
  min-width: 42px !important;
  max-width: 42px !important;
  padding-left: 10px !important;
  padding-right: 10px !important;
}

#queue-table.queue-bulk-mode .queue-bulk-select-col,
#queue-table.queue-bulk-mode thead .queue-bulk-select-col,
#queue-table.queue-bulk-mode tbody .queue-bulk-select-col {
  display: table-cell !important;
}

.queue-context-nav {
  flex: 0 0 92px;
  width: 92px;
  height: 32px;
  justify-content: flex-start;
}

.release-detail-header {
  min-height: 48px;
}

.release-detail-header .record-header-title {
  flex: 0 0 auto;
  height: 32px;
}

.release-context-nav {
  flex: 0 0 92px;
  width: 92px;
  height: 32px;
  justify-content: flex-start;
}


.page-header .subtitle {
  color: var(--text-secondary);
  font-size: 13px;
}

/* ---------- Cards / forms ---------- */

.card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 20px;
  /* width: 100% (not just max-width) so a .card that's a flex item — like the ticket layout
     editor's, sitting next to a resize handle — fills its row and gets capped at 900px, instead
     of shrinking to whatever its content's natural width happens to be (flex items don't
     stretch to fill by default the way block-level elements do). */
  width: 100%;
  max-width: 900px;
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-bottom: 14px;
}

.field-row.single {
  grid-template-columns: 1fr;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  position: relative;
}

/* Themed stand-in for the browser's native "Please select an item in the list" validation
   bubble (form has novalidate, so that native, unstyled popup never fires) — same message text
   (field.validationMessage), same anchor-below-the-field placement, just drawn with our own
   colors instead of OS chrome. */
.field-validation-tooltip {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  padding: 8px 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: var(--shadow);
  font-size: 13px;
  color: var(--text);
  box-sizing: border-box;
  width: auto;
}

.field-validation-tooltip::before {
  content: '';
  position: absolute;
  top: -6px;
  left: 16px;
  width: 10px;
  height: 10px;
  background: var(--bg-elevated);
  border-left: 1px solid var(--border);
  border-top: 1px solid var(--border);
  transform: rotate(45deg);
}

.field-validation-tooltip-icon {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  background: var(--danger);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
}

.field label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.field-required-mark {
  color: var(--danger, #ef4d61);
}

.field-inline-custom {
  display: none;
  gap: 6px;
  margin-top: 6px;
}

.field-inline-custom input {
  flex: 1;
}

.field-inline-custom select {
  flex: 0 0 90px;
}

.field input[type="text"],
.field input[type="password"],
.field input[type="email"],
.field input[type="url"],
.field input[type="search"],
.field input[type="date"],
.field input[type="datetime-local"],
.field input[type="number"],
.field input[type="time"],
.field select,
.field textarea {
  width: 100%;
  box-sizing: border-box;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
}

.field input[type="text"],
.field input[type="password"],
.field input[type="email"],
.field input[type="url"],
.field input[type="search"],
.field input[type="date"],
.field input[type="datetime-local"],
.field input[type="number"],
.field input[type="time"],
.field select {
  height: 36px;
}

.field input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
}

/* Tightens the native dropdown list's row height (Chromium/Firefox both honor padding on
   <option>) — the default row height makes a long list (e.g. the Hide After/Show for presets)
   taller than it needs to be. */
.field select option {
  padding: 3px 8px;
  background: var(--bg-elevated);
  color: var(--text);
}

:root[data-theme="dark"] .field input[type="date"],
:root[data-theme="dark"] .filter-condition-row input[type="date"] {
  color-scheme: dark;
}

/* Without this, the native up/down spin buttons on every number input (e.g. the SLA hours
   fields) render as a plain white box regardless of the rest of the page's dark styling — the
   browser draws them from its own light-mode UI chrome unless told the color scheme in use. */
:root[data-theme="dark"] input[type="number"] {
  color-scheme: dark;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 111, 237, 0.15);
}

.field .readonly-value {
  padding: 8px 10px;
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: 6px;
  color: var(--text-secondary);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.field .readonly-value.copyable-value {
  cursor: pointer;
}

.field .readonly-value.copyable-value.copied {
  color: var(--success);
  border-color: var(--success);
}

.copy-toast {
  position: fixed;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: var(--success);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  border-radius: 6px;
  box-shadow: var(--shadow);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.copy-toast.show {
  opacity: 1;
}

.copy-toast svg {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
}

.helptext { font-size: 12px; color: var(--text-secondary); }

/* Thin, seamless SLA progress bar under a ticket's field grid — deliberately understated (no
   border/shadow/rounded pill chrome) so it reads as a quiet status strip, not another input. */
.sla-bar-track {
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  overflow: hidden;
}

.sla-bar-fill {
  height: 100%;
  border-radius: 2px;
}

.sla-bar-fill.status-ok { background: var(--accent); }
.sla-bar-fill.status-warning { background: var(--warning); }
.sla-bar-fill.status-critical { background: var(--danger); }

.sla-bar-caption { margin: 4px 0 0; }
.errorlist { list-style: none; margin: 4px 0 0; padding: 0; color: var(--danger); font-size: 12px; }

.form-actions {
  margin-top: 20px;
  display: flex;
  gap: 10px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: var(--btn-height, 36px);
  white-space: nowrap;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
  color: var(--text);
  padding: 0 12px;
  border-radius: 6px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
}

.btn:hover { background: var(--bg); }

.btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.btn:disabled:hover {
  background: var(--bg-elevated);
}

.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 16px;
  padding: 12px 4px;
}

.pagination-info {
  font-size: 12px;
  color: var(--text-secondary);
}

.pagination-controls {
  display: flex;
  align-items: center;
  gap: 12px;
}

.pagination-page-label {
  font-size: 13px;
  color: var(--text-secondary);
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
}

.btn-primary:hover { filter: brightness(1.08); }

/* Matches the sidebar's active-nav-item look (solid #2f6fed fill, white text) exactly, rather than
   the theme-variable-based --accent/--accent-text every other .btn-primary uses — --accent-text is
   dark in the dark theme, which read as barely-visible on these Attach buttons' fill. Scoped to
   just these two buttons, not changed app-wide. */
#child-attach-btn,
#root-attach-btn {
  background: #2f6fed;
  border-color: #2f6fed;
  color: #fff;
}

#child-attach-btn:hover,
#root-attach-btn:hover {
  background: #2f6fed;
  filter: brightness(1.08);
}

.messages { list-style: none; padding: 0; margin: 0 0 16px; }
.messages li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 6px;
  margin-bottom: 8px;
  font-size: 13px;
  border: 1px solid var(--border);
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.messages li.success { border-color: var(--success); color: var(--success); }
.messages li.error { border-color: var(--danger); color: var(--danger); }
.messages li.message-fading { opacity: 0; transform: translateY(-4px); }

/* ---------- Owner Console announcement banners ---------- */

.app-banner-stack {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 16px;
  background: var(--bg);
}

@keyframes app-banner-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Same light-tint/darker-border card formula as the Owner Console's owner-tenant-notice —
   a single admin-picked color (--app-banner-color) stands in for --owner-warn in that formula,
   so any color picked reads as the same flat, readable notice style, never a solid/gradient strip. */
.app-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 11px 48px 11px 20px;
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: 0.01em;
  position: relative;
  text-align: center;
  color: var(--text);
  background: color-mix(in srgb, var(--app-banner-color, #c98500) 8%, var(--bg-elevated));
  border: 1px solid color-mix(in srgb, var(--app-banner-color, #c98500) 45%, var(--border));
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  animation: app-banner-in 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.app-banner-text {
  max-width: 900px;
}

/* Any URL typed into the message becomes a link automatically (Django's urlize filter) — styled
   as a small pill/chip rather than plain underlined text, the way most product announcement bars
   (GitHub, Linear, Vercel, ...) treat their call-to-action link. */
.app-banner-text a {
  display: inline-flex;
  margin-left: 2px;
  padding: 2px 10px;
  color: var(--text);
  font-weight: 700;
  text-decoration: none;
  background: color-mix(in srgb, var(--app-banner-color, #c98500) 16%, var(--bg-elevated));
  border: 1px solid color-mix(in srgb, var(--app-banner-color, #c98500) 45%, var(--border));
  border-radius: 999px;
  transition: background 0.15s ease;
}

.app-banner-text a:hover {
  background: color-mix(in srgb, var(--app-banner-color, #c98500) 28%, var(--bg-elevated));
}

.app-banner-close {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 50%;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  opacity: 0.85;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  transition: background 0.15s ease, opacity 0.15s ease, transform 0.15s ease;
}

.app-banner-close:hover {
  opacity: 1;
  background: color-mix(in srgb, var(--app-banner-color, #c98500) 16%, var(--bg-elevated));
  transform: translateY(-50%) scale(1.08);
}

.message-close-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 100px;
  border: none;
  background: transparent;
  color: inherit;
  cursor: pointer;
  opacity: 0.8;
}
.message-close-btn:hover { opacity: 1; background: currentColor; }
.message-close-btn:hover svg { color: var(--bg-elevated); }
.message-close-btn svg { width: 18px; height: 18px; stroke-width: 2.5; }

.change-toolbar { justify-content: flex-start; }
.change-filter-form {
  display: flex;
  flex: 0 1 auto;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 12px;
  min-width: 0;
  margin: 0;
}
.change-search-field { flex: 0 0 260px !important; width: 260px; }
.change-search-field input[type="search"] { width: 260px; box-sizing: border-box; }
.change-toolbar-button,
.change-filter-control,
.change-view-control,
.change-bulk-control { flex: 0 0 auto !important; width: auto !important; position: relative; }
.change-filter-control .btn,
.change-view-control .btn { display: inline-flex; align-items: center; gap: 6px; }
.change-filter-control.open .header-popover { display: block; }
.change-filter-popover { width: 300px; max-width: calc(100vw - 32px); max-height: min(70vh, 560px); overflow-y: auto; }
.change-filter-popover .field { flex: 1 1 auto; width: 100%; margin-bottom: 10px; }
.change-filter-popover .field select { width: 100%; }
.change-filter-actions { justify-content: space-between; margin-top: 8px; }
.change-view-popover { width: 240px; max-width: calc(100vw - 32px); }
.change-view-popover .checkbox-field { margin: 0; padding: 5px 0; }
.change-view-control.open .header-popover { display: block; }
.change-bulk-control.open .header-popover { display: block; }
.change-bulk-control .header-popover { width: 260px; max-width: calc(100vw - 32px); }
.change-bulk-select-col {
  display: none;
  width: 42px !important;
  min-width: 42px !important;
  max-width: 42px !important;
  padding-left: 10px !important;
  padding-right: 10px !important;
}
#change-table.change-bulk-mode .change-bulk-select-col { display: table-cell !important; }

@media (max-width: 640px) {
  .change-search-field,
  .change-search-field input[type="search"] { width: min(260px, 100%); }
  .change-search-field { flex: 1 1 220px !important; }
}

table.data-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

table.data-table th, table.data-table td {
  text-align: left;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
}

table.data-table th {
  color: var(--text-secondary);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

table.data-table tbody tr:hover { background: var(--bg); }
table.data-table tbody tr:last-child td { border-bottom: none; }

.queue-expand-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: none;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 0;
}

.queue-expand-toggle .chevron {
  width: 14px;
  height: 14px;
  transition: transform 0.12s ease;
}

.queue-expand-toggle.expanded .chevron {
  transform: rotate(90deg);
}

.queue-child-group {
  display: none;
}

.queue-child-group.open {
  display: table-row;
}

.queue-child-group > td {
  padding: 0 0 0 34px;
  background: var(--bg);
}

.queue-child-table {
  border: none;
  border-radius: 0;
  background: transparent;
}

.queue-child-table td {
  border-bottom: 1px solid var(--border);
  font-size: 12.5px;
}

.queue-child-table tr:last-child td {
  border-bottom: none;
}

.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 100px;
  font-size: 13px;
  font-weight: 600;
  border: 1px solid var(--border);
  color: var(--text-secondary);
}

.master-badge {
  border-color: var(--accent);
  background: rgba(47, 111, 237, 0.12);
  color: var(--accent);
}

/* Compact "M" glyph used where the full "Master" word pill reads too loud — the queue list, one
   per row across potentially hundreds of rows. Sized and colored to sit quietly next to the
   ticket number instead of competing with it. */
.master-icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 4px;
  border: 1px solid var(--accent);
  background: rgba(47, 111, 237, 0.15);
  color: var(--accent);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  vertical-align: middle;
  position: relative;
  top: -1px;
  margin-left: 5px;
}

.master-badge-clickable {
  font-family: inherit;
  cursor: pointer;
}

.master-badge-clickable:hover {
  background: rgba(47, 111, 237, 0.22);
  border-color: var(--accent);
}

/* The whole "attached tickets" block gets a distinct accent tint, so a master ticket's own
   attached-children section reads as a real, established part of the record — not a flimsy,
   about-to-be-undone list — while each row is still fully clickable through to that ticket. */
.master-children-section {
  margin-top: 8px;
  padding: 16px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
}

/* Border-only accent so every card belonging to a master ticket (main form, Sub-Incidents panel,
   Notes) reads as visibly different from a regular ticket's cards at a glance — just the outline,
   not the whole card's background (a full-fill tint was tried and explicitly rejected: only the
   line around the card should change color). */
.master-card-tint {
  border-color: var(--accent);
  border-width: 2px;
}

/* Same border-only treatment for a converted Problem ticket, in its own color so Root and Problem
   read as distinct at a glance. Problem takes priority when both classes land on the same card
   (a Problem is always also a master, but the Problem identity is the more specific one to show). */
.problem-card-tint {
  border-color: var(--warning);
  border-width: 2px;
}

.master-children-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 12px;
}

.master-child-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.master-child-link {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
  padding: 10px 12px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
  text-decoration: none;
  color: var(--text);
}

.master-child-link:hover {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--bg-elevated));
}

.master-child-number {
  flex: 0 0 auto;
  font-weight: 600;
  color: var(--accent);
}

.master-child-desc {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.master-child-state {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--text-secondary);
}

.badge-button {
  font-family: inherit;
  background: none;
  cursor: pointer;
}

/* ---------- Auth pages ---------- */

.auth-page {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
}

.auth-card {
  width: 360px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 28px;
}

.auth-card h1 {
  font-size: 18px;
  margin: 0 0 4px;
}

.auth-card .subtitle {
  color: var(--text-secondary);
  font-size: 13px;
  margin-bottom: 16px;
}

.auth-card form .field { margin-bottom: 10px; }

.auth-card form .checkbox-field { margin: 4px 0 16px; }

.field-hint-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--border);
  color: var(--text-secondary);
  font-size: 10px;
  font-weight: 700;
  cursor: help;
  vertical-align: middle;
}

.auth-tabs {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 3px;
  margin-bottom: 20px;
}

.auth-tabs a {
  flex: 1;
  text-align: center;
  padding: 7px 0;
  font-size: 13px;
  border-radius: 6px;
  color: var(--text-secondary);
  text-decoration: none;
}

.auth-tabs a.active {
  background: var(--accent, #4f8cff);
  color: #fff;
}

.org-id-box {
  border: 1px dashed var(--border);
  border-radius: 8px;
  padding: 14px;
  text-align: center;
  margin-bottom: 16px;
}

.org-id-name { color: var(--text-secondary); font-size: 13px; }
.org-id-value { font-size: 22px; font-weight: 600; letter-spacing: 1px; margin-top: 4px; user-select: all; }

.auth-card .btn-primary { width: 100%; justify-content: center; }

.auth-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 16px 0;
  color: var(--text-secondary);
  font-size: 12px;
}

.auth-divider::before,
.auth-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

.btn-social {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.btn-social + .btn-social {
  margin-top: 10px;
}

.btn-social:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.auth-footer {
  margin-top: 16px;
  font-size: 13px;
  text-align: center;
  color: var(--text-secondary);
}

/* ---------- Compact CRUD toolbar / small buttons ---------- */

.btn-sm {
  height: var(--btn-height, 36px);
  padding: 0 9px;
  font-size: 12px;
  font-weight: 500;
}

.toolbar {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.toolbar .field {
  flex: 0 1 320px;
  min-width: 0;
  margin-bottom: 0;
}

.toolbar .field.search-field {
  min-width: 220px;
}

.field.search-field input {
  height: var(--btn-height, 36px);
  padding: 0 10px;
  box-sizing: border-box;
}

.toolbar form.field-row {
  flex: 1;
  min-width: 260px;
  margin-bottom: 0;
  display: flex;
  gap: 8px;
  align-items: flex-end;
}

/* ---------- Filter builder (ServiceNow-style condition list) ---------- */

.filter-panel {
  display: none;
  margin-bottom: 16px;
  padding: 16px;
  max-width: 700px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.filter-panel.open {
  display: block;
}

.filter-conditions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
}

.filter-connector-btn {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 1px 9px;
  margin-left: 2px;
  border-radius: 100px;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
  color: var(--text-secondary);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
}

.filter-connector-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.filter-connector-btn.is-or {
  border-color: var(--accent);
  background: rgba(47, 111, 237, 0.12);
  color: var(--accent);
}

.filter-condition-row {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-right: 30px;
}

.filter-condition-remove-btn {
  position: absolute;
  top: 2px;
  right: 0;
}

.filter-condition-row select,
.filter-condition-row input[type="text"],
.filter-condition-row input[type="date"] {
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 9px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
}

.filter-value-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
}

.filter-panel-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.filter-saved-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

.filter-saved-row label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  flex-shrink: 0;
}

.filter-saved-row select {
  flex: 1;
  box-sizing: border-box;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 8px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
}

.saved-filter-dropdown {
  position: relative;
  flex: 1;
}

.saved-filter-dropdown-btn {
  width: 100%;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 8px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  text-align: left;
}

.saved-filter-dropdown-btn svg {
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  color: var(--text-secondary);
}

.saved-filter-dropdown-list {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 4px;
  z-index: 30;
  max-height: 240px;
  overflow-y: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.saved-filter-dropdown-list.open {
  display: block;
}

.saved-filter-dropdown-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  cursor: pointer;
}

.saved-filter-dropdown-row:hover {
  background: var(--bg);
}

.saved-filter-dropdown-name {
  flex: 1;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.saved-filter-dropdown-empty {
  padding: 10px 8px;
  font-size: 13px;
  color: var(--text-secondary);
}

.filter-multiselect {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  max-height: 130px;
  overflow-y: auto;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--input-bg);
  min-width: 220px;
}

.filter-multiselect-option {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 13px;
  white-space: nowrap;
}

.filter-value-wrap-fill {
  flex: 1 1 100%;
  min-width: 0;
}

.user-group-picker {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}

.user-group-add-area {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.user-group-add-area select {
  flex: 1;
  min-width: 160px;
  width: 100%;
  box-sizing: border-box;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
}

.user-group-picker .user-picker {
  flex: 1;
  min-width: 160px;
  display: block;
}

.user-group-picker .user-picker-input {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 10px;
  font-size: 14px;
}

.user-group-picker .user-picker-suggestions {
  width: 100%;
}

.user-group-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 22px;
}

.user-group-chips:empty {
  display: none;
}

.user-group-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 3px 6px 3px 10px;
  font-size: 12px;
  color: var(--text);
}

.user-group-chip-group {
  background: rgba(47, 111, 237, 0.12);
  border-color: var(--accent);
  color: var(--accent);
}

.user-group-chip button {
  border: none;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0 2px;
}

.user-group-chip button:hover {
  color: var(--text);
}

.user-picker {
  position: relative;
  display: inline-block;
}

.user-picker-input {
  width: 160px;
}

.user-picker-suggestions {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 4px;
  z-index: 35;
  width: 200px;
  max-height: 220px;
  overflow-y: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: var(--shadow);
}

.user-picker-suggestions.open {
  display: block;
}

.user-picker-suggestion {
  display: block;
  width: 100%;
  text-align: left;
  padding: 7px 10px;
  border: none;
  background: none;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
}

.user-picker-suggestion:hover {
  background: var(--bg);
}

.user-picker-empty {
  padding: 7px 10px;
  font-size: 12px;
  color: var(--text-secondary);
}

.search-input-wrap {
  position: relative;
}

.search-input-wrap svg {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 15px;
  height: 15px;
  color: var(--text-secondary);
  pointer-events: none;
}

.search-input-wrap input {
  padding-left: 32px !important;
}

/* ---------- Tabs (Users / Groups / Roles) ---------- */

.tab-bar {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
}

.tab-btn {
  appearance: none;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 10px 16px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  cursor: pointer;
  margin-bottom: -1px;
}

.tab-btn:hover {
  color: var(--text);
}

.tab-btn.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* Settings page only: matches the reference app's own Settings tabs — inactive tabs are normal
   weight and muted, the active tab is bold and full-brightness text with just the underline
   colored, instead of coloring the active tab's text itself. Scoped here rather than changed on
   the shared .tab-btn, which every other tabbed page in the app also uses. */
.settings-tab-bar .tab-btn {
  font-weight: 400;
  color: var(--text-secondary);
}

.settings-tab-bar .tab-btn.active {
  color: var(--text);
  font-weight: 600;
}

.tab-panel {
  display: none;
}

.tab-panel.active {
  display: block;
}

/* A lighter-weight tab pair scoped inside a single card (e.g. Security's Devices/Activity split)
   — kept visually close to .tab-bar/.tab-btn but a separate class so the page-level tab script
   (which queries .tab-btn globally) never picks these up. */
.card-subtab-bar {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 16px;
}

.card-subtab-btn {
  appearance: none;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 8px 14px;
  margin-bottom: -1px;
  font-size: 13px;
  font-weight: 400;
  color: var(--text-secondary);
  cursor: pointer;
}

.card-subtab-btn:hover {
  color: var(--text);
}

.card-subtab-btn.active {
  color: var(--text);
  font-weight: 600;
  border-bottom-color: var(--accent);
}

.card-subtab-panel {
  display: none;
}

.card-subtab-panel.active {
  display: block;
}

/* ---------- Record cards (categories, groups) ---------- */

.record-card-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.record-card {
  position: relative;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 16px;
  min-width: 0;
  box-shadow: var(--shadow);
}

.record-card-delete-form {
  position: absolute;
  top: 8px;
  right: 12px;
}

.record-card.hidden-by-search {
  display: none;
}

.record-card-header {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding-right: 30px;
}

.record-card-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  padding: 6px 8px;
  margin: -6px 0;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text);
  font: inherit;
  text-align: left;
}

.record-card-toggle:hover {
  background: var(--bg);
}

.record-card-toggle .chevron {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
  color: var(--text-secondary);
  transition: transform 0.12s ease;
}

.record-card.expanded .record-card-toggle .chevron {
  transform: rotate(90deg);
}

.record-card-title {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 120px;
}

.record-card-name {
  font-size: 14px;
  font-weight: 700;
}

.record-card-name-display {
  font-size: 14px;
  font-weight: 700;
}

.record-card.editing-name .record-card-name-display,
.layout-row.editing-name .record-card-name-display {
  display: none;
}

.record-card-name-input {
  display: none;
  font-size: 15px;
  font-weight: 700;
  font-family: inherit;
  color: var(--text);
  background: var(--input-bg);
  border: 1px solid var(--accent);
  border-radius: 6px;
  padding: 3px 6px;
  width: 160px;
}

/* The accent border above is meant to signal "you just unlocked this to edit it" (Groups/Roles
   still work that way). Categories' name input is always editable with no unlock step, so it
   should look like an ordinary input at rest — accent border only on actual focus. */
.always-editable-name-input {
  border-color: var(--border);
  /* The shared .record-card-name-input size (15px/700) was calibrated for the brief "you just
     unlocked this to edit it" moment on Groups/Roles — this input is visible permanently instead,
     so it should read at the same size as ordinary text/headings elsewhere, not stand out as
     bigger than the rest of the app. Matches .record-card-name-display's old at-rest size. */
  font-size: 14px;
  font-weight: 700;
}

.always-editable-name-input:focus {
  outline: none;
  border-color: var(--accent);
}

.record-card.editing-name .record-card-name-input,
.layout-row.editing-name .record-card-name-input {
  display: inline-block;
}

.record-card-count {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--bg);
  border-radius: 100px;
  padding: 2px 8px;
}

.record-card-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

/* Categories page — an indented tree (category -> subcategories), same pattern as the Knowledge
   Base page tree (see .kb-settings-tree below): one flat bordered container, subcategories indent
   under their category and expand/collapse, instead of each category sitting in its own
   separately-boxed/accordioned card. Buttons here are the same chip-icon-btn used for row actions
   everywhere else (KB tree, Groups/Roles rows) — not oversized relative to a compact row. */
.category-tree-node + .category-tree-node {
  margin-top: 6px;
}

.category-tree-node.hidden-by-search {
  display: none;
}

.category-tree-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
}

/* Each category is its own small card (background + border), not a stack of giant boxes and not
   just a hairline between rows — a bit of separation without extra whitespace. Subcategory rows
   (inside .category-tree-children) stay plain list rows, not their own cards. */
.category-tree-node > .category-tree-row {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
}

.category-tree-row:hover {
  background: var(--bg-elevated);
}

.category-tree-node > .category-tree-row:hover {
  border-color: var(--text-secondary);
}

.category-tree-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--text-secondary);
}

.category-tree-toggle .chevron {
  width: 13px;
  height: 13px;
  transition: transform 0.12s ease;
}

.category-tree-node.expanded > .category-tree-row .category-tree-toggle .chevron {
  transform: rotate(90deg);
}

.category-tree-name-input {
  flex: 1;
  min-width: 0;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  padding: 4px 6px;
}

.category-tree-name-input:hover {
  border-color: var(--border);
}

.category-tree-name-input:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--input-bg);
}

.category-tree-type-pills {
  flex-shrink: 0;
}

.category-tree-children {
  display: none;
  margin-left: 26px;
  border-left: 1px dashed var(--border);
  padding-left: 12px;
}

.category-tree-node.expanded > .category-tree-children {
  display: block;
}

.category-tree-subrow .category-tree-name-input {
  font-weight: 400;
  font-size: 12.5px;
  width: auto;
}

.category-tree-empty-row {
  padding: 6px 8px;
  margin: 0;
}

.category-tree-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 2px 0 4px;
  padding: 4px 8px;
  border: none;
  background: none;
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  border-radius: 6px;
}

.category-tree-add-btn:hover {
  background: var(--bg-elevated);
}

.icon-btn-sm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 6px;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  flex-shrink: 0;
}

.icon-btn-sm:hover {
  background: var(--bg);
  color: var(--text);
}

.icon-btn-sm svg {
  width: 14px;
  height: 14px;
}

/* Type pills (which record type a category applies to) */

.type-pill-form {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

.type-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px 4px 8px;
  border-radius: 100px;
  border: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}

.type-pill.disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.type-pill input {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  width: 12px;
  height: 12px;
  border: 1.5px solid var(--border);
  border-radius: 3px;
  background: transparent;
  position: relative;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}

.type-pill input:checked {
  background: var(--accent);
  border-color: var(--accent);
}

.type-pill input:checked::after {
  content: '';
  position: absolute;
  left: 3px;
  top: 0px;
  width: 3px;
  height: 6px;
  border: solid #fff;
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}

.type-pill.active {
  border-color: var(--accent);
  background: rgba(47, 111, 237, 0.12);
  color: var(--accent);
}

.type-pill.danger {
  border-color: var(--danger);
  color: var(--danger);
}

.type-pill.danger input {
  accent-color: var(--danger);
}

.status-pill {
  border-color: var(--danger);
  color: var(--danger);
  width: 76px;
  justify-content: center;
}

.status-pill input {
  display: none;
}

.status-pill.active {
  border-color: var(--success);
  background: rgba(47, 158, 92, 0.12);
  color: var(--success);
}

.sla-policy-card-disabled {
  opacity: 0.5;
}

.sla-policy-card table.data-table th,
.sla-policy-card table.data-table td {
  padding: 6px 12px;
}

.sla-hours-input {
  width: 70px;
  box-sizing: border-box;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 8px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
}

.sla-hours-input:focus {
  outline: none;
  border-color: var(--accent);
}

.sla-reset-rules-options-disabled {
  opacity: 0.5;
  pointer-events: none;
}

.cab-settings-options-disabled {
  opacity: 0.5;
  pointer-events: none;
}

.cab-settings-section {
  padding-top: 28px;
  margin-top: 28px;
  border-top: 1px solid var(--border);
}

.cab-settings-section:first-child {
  padding-top: 0;
  margin-top: 0;
  border-top: none;
}

.theme-card-row { display: flex; gap: 12px; }
.theme-card {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  background: none; border: 2px solid var(--border); border-radius: 10px;
  padding: 8px; cursor: pointer; color: var(--text-secondary); font-size: 13px; width: 110px;
  font-family: inherit;
}
.theme-card:hover { border-color: var(--text-secondary); }
.theme-card.active { border-color: var(--accent); color: var(--text); }
.theme-card-preview { display: block; width: 100%; height: 60px; border-radius: 6px; }
.theme-card-preview-light { background: linear-gradient(135deg, #f4f6fb 0%, #f4f6fb 55%, #d8deed 55%, #d8deed 100%); }
.theme-card-preview-dark { background: linear-gradient(135deg, #161c2e 0%, #161c2e 55%, #0d1120 55%, #0d1120 100%); }
.theme-card-preview-deep-dark { background: linear-gradient(135deg, #1a2029 0%, #1a2029 55%, #101512 55%, #101512 100%); }
.theme-card-preview-system { background: linear-gradient(90deg, #f4f6fb 0%, #f4f6fb 50%, #161c2e 50%, #161c2e 100%); }

.cab-settings-section h4 {
  margin: 0 0 12px;
}

/* Recurrence-picker-style rows: fields sized to what they actually hold (a 1-2 digit number, a
   short dropdown, a date/time) instead of the app-wide .field-row grid, which stretches every
   field to half the row's full width regardless of content. */
.cab-inline-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin-bottom: 14px;
}

.cab-inline-row .field {
  flex: 0 0 auto;
}

.field.cab-field-xs input, .field.cab-field-xs select { width: 70px; }
.field.cab-field-sm select { width: 150px; }
.field.cab-field-md select { width: 260px; }
/* input[type="time"]'s native control (hour:minute + AM/PM) gets clipped below ~120px — the
   generic .cab-field-xs width (70px, sized for a 1-2 digit number) is too narrow for it. */
.field.cab-field-time input { width: 130px; }
.cab-field-auto { align-self: flex-end; }

.sla-reset-rule-row {
  display: grid;
  grid-template-columns: 240px 180px 1fr;
  gap: 16px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}

.sla-reset-rule-header {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
}

.sla-reset-rule-action {
  width: 100%;
  box-sizing: border-box;
  height: 32px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0 8px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
}

.sla-reset-rule-amount {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ---------- Toggle switch (on/off, e.g. SLA tracking) ---------- */

.toggle-switch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
}

/* This element is a <label> sitting inside a .field wrapper (same markup shape as the "Search
   Users" field label above it) — ".field label" (class+type = 0,0,1,1) otherwise outranks a
   plain ".toggle-switch" (0,0,1,0) and its uppercase/letter-spacing/12px styling wins the
   cascade even though this rule is declared later. Matching on both .field and .toggle-switch
   (0,0,2,0) is unambiguously higher, so the reset actually takes effect. */
.field .toggle-switch {
  text-transform: none;
  letter-spacing: normal;
  font-size: 13px;
  color: var(--text);
}

.toggle-switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.toggle-switch-track {
  position: relative;
  width: 36px;
  height: 20px;
  border-radius: 100px;
  background: var(--border);
  flex-shrink: 0;
  transition: background 0.15s ease;
}

.toggle-switch-track::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.15s ease;
}

.toggle-switch input:checked + .toggle-switch-track {
  background: var(--success);
}

.toggle-switch input:checked + .toggle-switch-track::after {
  transform: translateX(16px);
}

.toggle-switch-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

/* ---------- Chip picker (multi-select as removable chips + an add dropdown) ---------- */

.chip-picker {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.chip-picker-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-height: 28px;
}

select.chip-picker-source,
.chip-picker-everyone-source {
  display: none;
}

.kb-visibility-add-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.kb-visibility-add-btn {
  justify-content: center;
  /* Matches the natural height of ".field input[type=date]" (padding: 8px 10px + border) —
     going this direction instead of shrinking the date input, since native date/time controls
     render their internal spinner/icon at different minimum sizes per browser and don't reliably
     honor a smaller explicit height the way a plain button does. */
  height: 36px;
}

/* Wins over the more specific ".field input[type=text]" global rule, which would otherwise
   stretch this to the full width of the Visible column instead of a compact search box. */
#kb-visibility-search-wrap .user-picker-input {
  width: 200px;
}

.kb-visibility-add-btn.active {
  border-color: var(--accent);
  color: var(--accent);
}

.chip-picker-add {
  width: 100%;
}

/* Member chips (Groups & Users) — simple display-only badges */

.chip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.chip {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 3px 12px;
  font-size: 12.5px;
}

.chip-label {
  color: var(--text);
  white-space: nowrap;
}

.chip-empty {
  font-size: 12px;
  color: var(--text-secondary);
}

/* Subcategory table (Categories) — collapsed by default, one row per subcategory */

.subcategory-table-wrap {
  display: none;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.record-card.expanded .subcategory-table-wrap {
  display: block;
}

table.subcategory-table th, table.subcategory-table td {
  padding: 7px 10px;
  font-size: 12.5px;
}

table.subcategory-table td.subcategory-id-col,
table.subcategory-table th.subcategory-id-col {
  color: var(--text-secondary);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  width: 1%;
  white-space: nowrap;
}

.subcategory-name-cell {
  display: flex;
  align-items: center;
  gap: 2px;
}

.subcategory-name-input {
  font-family: inherit;
  color: var(--text);
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 7px;
  font-size: 12.5px;
  width: 140px;
}

.subcategory-row.marked-for-delete {
  opacity: 0.4;
}

.subcategory-row.marked-for-delete .subcategory-name-input {
  text-decoration: line-through;
}

.member-row.marked-for-delete {
  opacity: 0.4;
  text-decoration: line-through;
}

.section-heading {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
  margin: 24px 0 8px;
}

.section-heading:first-of-type {
  margin-top: 8px;
}

.subcategory-row-actions {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
}

.subcategory-row-actions .chip-icon-btn {
  width: 26px;
  height: 26px;
}

.subcategory-row-actions .chip-icon-btn svg {
  width: 13px;
  height: 13px;
}

.chip-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  flex-shrink: 0;
}

.chip-icon-btn:hover {
  background: var(--border);
  color: var(--text);
}

.chip-icon-btn svg {
  width: 11px;
  height: 11px;
}

.chip-icon-btn-danger {
  width: 26px;
  height: 26px;
  color: var(--danger);
}

.chip-icon-btn-danger:hover {
  background: color-mix(in srgb, var(--danger) 16%, transparent);
  color: var(--danger);
}

.chip-icon-btn-danger svg {
  width: 13px;
  height: 13px;
}

/* ---------- Modal ---------- */

.modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(10, 14, 20, 0.55);
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 20px;
}

.modal-overlay.open {
  display: flex;
}

.modal-box {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px;
  width: 100%;
  max-width: 420px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);
}

.api-key-modal .field input {
  background-color: var(--input-bg) !important;
  border-color: var(--border) !important;
  color: var(--text) !important;
}

:root[data-theme="dark"] .api-key-modal .field input {
  color-scheme: dark;
}

.api-key-copy-field {
  position: relative;
}

.api-key-copy-field > input {
  padding-right: 42px !important;
}

.api-key-copy-btn {
  position: absolute;
  top: 50%;
  right: 4px;
  width: 30px;
  height: 30px;
  border-radius: 5px;
  transform: translateY(-50%);
}

.api-key-copy-btn svg {
  width: 16px;
  height: 16px;
}

.api-key-action-btn {
  width: 34px;
  height: 34px;
  border: 1px solid transparent;
  border-radius: 6px;
}

.api-key-action-btn svg {
  width: 16px;
  height: 16px;
}

.api-key-action-delete:hover {
  color: var(--danger);
  border-color: var(--danger);
  background: rgba(214, 69, 69, 0.12);
}

.modal-box h3 {
  margin: 0 0 10px;
  font-size: 15px;
}

.modal-box p {
  margin: 0 0 16px;
  font-size: 13px;
  color: var(--text-secondary);
}

/* Set via .textContent (not innerHTML), so a literal "\n" needs pre-line to actually break the
   line — lets a longer explanatory confirm message (e.g. converting to a Problem) use a blank
   line between its summary and its detail instead of running together. */
#confirm-modal-message {
  white-space: pre-line;
}

.btn-danger {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}

.btn-danger:hover {
  filter: brightness(1.08);
}

.btn-success {
  background: var(--success);
  border-color: var(--success);
  color: #fff;
}

.btn-success:hover {
  filter: brightness(1.08);
}

.btn-warning {
  background: var(--warning);
  border-color: var(--warning);
  color: #fff;
}

.btn-warning:hover {
  filter: brightness(1.08);
}

/* ---------- Layout & Custom Fields ---------- */

.layout-row-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.layout-row {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-elevated);
}

.layout-row-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
}

.layout-field-badge {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-radius: 100px;
  padding: 2px 8px;
  flex: 0 0 auto;
}

.layout-field-badge.builtin {
  background: var(--bg);
  color: var(--text-secondary);
}

.layout-field-badge.custom {
  background: var(--accent);
  color: var(--accent-text);
}

.layout-field-name {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 200px;
  min-width: 160px;
}

.layout-field-name .record-card-name-display,
.layout-field-name .record-card-name-input {
  font-size: 13px;
  font-weight: 600;
}

.layout-row.unclaimed .record-card-name-display {
  color: var(--text-secondary);
  font-style: italic;
  font-weight: 500;
}

.layout-row-actions {
  flex: 0 0 auto;
  margin-left: auto;
}

/* ---------- Master ticket sub-tickets panel (New Incident/Request) ---------- */

#master-children-panel h3 {
  font-size: 15px;
}

.child-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
}

/* Explicit color/hover for every state (not "inherit") so a staged sub-ticket reads as a real
   link at a glance instead of blending into plain text, and hovering doesn't fall back to the
   browser's unstyled default (which read as the text going flat black). */
.child-row-link {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--accent);
  text-decoration: none;
  border-radius: 4px;
  padding: 2px 4px;
  margin: -2px -4px;
}

.child-row-link:visited {
  color: var(--accent);
}

.child-row-link:hover {
  text-decoration: underline;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.child-row input[type="text"],
#child-search-input,
#root-search-input,
.release-change-search-input {
  flex: 1;
  width: 100%;
  box-sizing: border-box;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
}

.child-row input[type="text"]:focus,
#child-search-input:focus,
#root-search-input:focus,
.release-change-search-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 111, 237, 0.15);
}

.child-search-suggestions {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 4px;
  max-height: 220px;
  overflow-y: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
  z-index: 40;
}

.child-search-suggestions.open {
  display: block;
}

.child-search-suggestion {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 10px;
  border: none;
  background: none;
  cursor: pointer;
  font-family: inherit;
}

.child-search-suggestion:hover {
  background: var(--bg);
}

.child-search-suggestion .suggestion-number {
  font-weight: 600;
  font-size: 13px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--text);
}

.child-search-suggestion .suggestion-desc {
  font-size: 12px;
  color: var(--text-secondary);
  margin-left: 8px;
}

.child-search-empty {
  padding: 8px 10px;
  font-size: 12px;
  color: var(--text-secondary);
}

/* ---------- Ticket field grid (New Incident/Request) ---------- */

.ticket-field-grid {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 16px;
}

.ticket-grid-item {
  /* flex-basis is deliberately auto (not a % baked into the `flex` shorthand) so the `width`
     property actually controls sizing — that's what lets the layout editor's resize handle
     (which sets tile.style.width directly, same as the Dashboard tile resize it's ported from)
     take effect live during drag, instead of being silently overridden by a fixed flex-basis. */
  flex: 0 1 auto;
  width: calc(50% - 8px);
  min-width: 220px;
  max-width: 500px;
}

/* Caps how wide the visible input/textarea gets on a very wide canvas — capped here (not on
   .ticket-grid-item itself) so a full-width field's row-reservation stays the full row (forcing
   a real line break after it) even though the box drawn inside it stops growing past this. */
.ticket-grid-item .field {
  max-width: 900px;
}

/* "Classic view" — labels sit to the left of their input (right-aligned), dense rows, no
   uppercase/letter-spacing — closer to a traditional enterprise ticket form. Toggled per user via
   #ticket-view-toggle-btn.

   The container switches from the ordinary flex-wrap (which packs 2 OR 3 items per row depending
   on viewport width — see .ticket-grid-item's width/max-width) to a strict 2-column CSS grid.
   Classic View's field order is a fixed, deliberately-authored sequence (built in JS — see
   queue_detail.html/record_new.html) that pairs specific fields left/right and leaves blank grid
   cells (.classic-spacer) where the reference layout's field doesn't exist in FasTicks; that pairing
   only holds together if the row width is never allowed to fit a 3rd column. */
.ticket-field-grid.classic-layout {
  --classic-col-gap: 16px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px var(--classic-col-gap);
  /* The grid container carries an inline min-height (JS-set, reserving room for Standard View's
     free canvas) that's never cleared on switching views — left in place, CSS Grid's default
     row-stretching spreads that reserved height across every auto-sized row, ballooning each
     compact field row into a huge gap instead of the real page's tight spacing. */
  min-height: auto !important;
  align-content: start;
}

.ticket-field-grid.classic-layout .ticket-grid-item {
  /* Fields placed via the free-canvas Layout editor carry position:absolute + left/top/height as
     an inline style (see _ticket_field_grid.html) — needed for Standard View's canvas, but never
     meant to survive into Classic View's grid. Without this override those inline values win
     over the grid entirely: each item renders at its raw canvas Y coordinate instead of flowing
     into the grid's own compact rows, which is what was producing the huge gaps between fields. */
  position: static !important;
  left: auto !important;
  top: auto !important;
  height: auto !important;
  width: auto;
  min-width: 0;
  max-width: none;
}

.ticket-field-grid.classic-layout .classic-spacer {
  visibility: hidden;
}

.ticket-field-grid.classic-layout .field {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  /* Overrides ".ticket-grid-item .field { max-width: 900px }" — in a 2-column grid each field
     already only gets one column's worth of width, so the 900px cap (there to stop an ordinary
     field from stretching absurdly wide) is never the thing that should be limiting it here. */
  width: 100%;
  max-width: none;
}

.ticket-field-grid.classic-layout .field > label {
  flex: 0 0 130px;
  text-align: right;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
  font-size: 13px;
  color: var(--text);
}

.ticket-field-grid.classic-layout .field > input,
.ticket-field-grid.classic-layout .field > select,
.ticket-field-grid.classic-layout .field > textarea,
.ticket-field-grid.classic-layout .field > .readonly-value,
.ticket-field-grid.classic-layout .field > .chip-picker,
.ticket-field-grid.classic-layout .field > div:not(.errorlist):not(#master-relation-group) {
  /* Half the column's width, not a full fill — the paired fields (Number, State, Caller, ...)
     read as too wide/sparse at full column width; leaving the other half of the column blank
     reads closer to the reference layout's proportions. Short Description/Description are
     excluded below — they still fill their whole (both-column) row. */
  flex: 0 1 50%;
  width: 50%;
  min-width: 0;
}

/* Short Description / Description span both grid columns, sitting on their own full-width row
   at the bottom of the strict pairing above (see the JS reorder) — a real grid-column span
   instead of the old flex "claim 100% of the row" trick, since the container is grid now. */
.ticket-field-grid.classic-layout .ticket-grid-item:has(textarea),
.ticket-field-grid.classic-layout .ticket-grid-item[data-field-key="short_description"] {
  grid-column: 1 / -1;
  /* Short Description/Description are marked full_width by the view, so the template gives them
     an inline "max-width: 900px" (the old flex-based full-row trick) — that inline style still
     wins over grid-column alone and caps the item well short of the actual spanned cell, so it
     needs to be defeated explicitly here too. */
  max-width: none !important;
}

/* ...and their input/textarea ends exactly where a paired row's right-hand field would end —
   i.e. Number's width + the column gap + State's width — not the full spanned row. Since every
   paired field is 50% of its own column (see the halving rule above), that combined length
   works out to 75% of this field's own (both-column) span, plus a quarter of the column gap:
   let W = one column's width and g = the column gap; this item's own width is 2W + g = 100%, and
   the target length is 1.5W + g, which substituting W = (100% - g)/2 reduces to 75% + g/4. */
.ticket-field-grid.classic-layout .ticket-grid-item:has(textarea) .field > textarea,
.ticket-field-grid.classic-layout .ticket-grid-item:has(textarea) .field > input,
.ticket-field-grid.classic-layout .ticket-grid-item[data-field-key="short_description"] .field > input {
  flex: 0 1 calc(75% + var(--classic-col-gap) / 4);
  width: calc(75% + var(--classic-col-gap) / 4);
}

/* Stack the Notes card below the field grid, full width, instead of beside it — matching the
   single-column position of the comments/work-notes area in the reference layout, and matching
   the New Incident/Request create page's own Classic View spacing (a normal card-to-card gap,
   each card keeping its own full border/corners — not merged into one seamless block). The
   !important calls out that they're overriding inline styles the resize-handle JS sets directly
   (drag-to-resize width/flex-basis) — nothing to do with CSS-source specificity. */
#ticket-main-notes-row.classic-layout {
  flex-direction: column;
  align-items: stretch !important;
  gap: 24px !important;
}

#ticket-main-notes-row.classic-layout #panel-main-card {
  flex: 1 1 auto !important;
  width: auto !important;
  max-width: none !important;
}

#ticket-main-notes-row.classic-layout #panel-notes-card {
  width: auto !important;
  flex: 1 1 auto !important;
}

/* The New Incident/Request create page has no #ticket-panels-row (it's a single standalone
   card, not a two-panel split with Notes) — this covers its card the same way, so Classic View
   looks identical there too, not capped at the ordinary .card max-width: 900px. */
#layout-editor-card:has(#ticket-field-grid.classic-layout) {
  max-width: none;
}

/* ~15% smaller than the button's normal rendered size — same id/rule on both the create form's
   Submit button and the existing-ticket edit page's Save Changes button, so the two stay
   consistent with each other. Toggled directly via JS (not a ":has()" lookup).
   Deliberately NOT using the "zoom" property here (an earlier version did): zoom is non-standard
   and at least one Chromium build has shown real paint bugs with it on a dynamically-toggled flex
   child — the computed layout geometry is correct but what actually gets drawn can go stale or
   render at the wrong size/darkness. Shrinking via ordinary padding/font-size has no such history
   and is what every other sized-down button in this app already uses. */
#record-create-submit-btn.classic-shrink {
  padding: 5px 10px;
  font-size: 11px;
  align-self: flex-start;
}

#ticket-main-notes-row.classic-layout #ticket-tile-resize-handle {
  display: none;
}

/* The Notes card sits outside #layout-editor-card entirely (a sibling section below the whole
   row, not a descendant), so the max-width override above never reached it — same 900px-cap
   mismatch as the main card had, just needing a different selector to catch it: any element
   anywhere in the body counts as "in Classic View" for this purpose. */
body:has(#ticket-field-grid.classic-layout) #record-notes-card {
  max-width: none;
}

/* The attachments/watchers/link-to-KB cluster, relocated into the page header for Classic View
   (see the JS in queue_detail.html/record_new.html) — it no longer needs the grid item's
   50%-of-row sizing once it's sitting in a header flex row instead. */
#ticket-header-actions .ticket-grid-item.in-header {
  /* This item can carry a stale position:absolute/left/width inline style from the free-canvas
     Layout editor (see _ticket_field_grid.html) — width:auto here needs !important to actually
     win over that inline width, otherwise the relocated item collapses to its old canvas width
     (often 0) and its icons, still trying to right-align inside that collapsed box, spill out
     over whatever sits to its left instead of taking up their own real space in the header row. */
  position: static !important;
  left: auto !important;
  top: auto !important;
  width: auto !important;
  min-width: 0;
  max-width: none;
  flex: 0 0 auto;
}

/* The "Last updated ..." label above these icons makes sense inline in the field grid (another
   field among fields) but not in the page header — it was pushing the icon row down below the
   header's own vertical center, so it no longer lined up with the Standard/Classic switch beside
   it. Hidden only in this relocated (Classic View) context; Standard View still shows it normally
   inside the grid. */
#ticket-header-actions .ticket-grid-item.in-header .field > label {
  display: none;
}

/* Make Master (create page) / Convert to Master (existing-ticket page), in Classic View: moved
   into the State field itself, right after the dropdown — genuinely on the same line as State
   (not just visually near it), pushed to the far right of that field's own space. */
/* Sits right next to the State dropdown, not pinned to the far edge of the field's box — Classic
   View's card has no max-width (see the create page's own uncapped card rule below), so on a wide
   screen "push to the far edge" left a huge, disconnected-looking gap between the two. */
.in-state-field {
  margin-left: 16px;
  flex: 0 0 auto;
}

/* Root Ticket / Connect to Root Ticket read fine at the normal .type-pill size everywhere else,
   but stacked together next to State in Classic View their combined width was shoving State's
   own dropdown much narrower than every other field's — shrink the pill text/padding here only,
   so State goes back to matching the rest instead of resizing the pills app-wide. */
.in-state-field .type-pill {
  padding: 2px 7px 2px 6px;
  font-size: 10px;
  gap: 4px;
}

.in-state-field .type-pill input[type="checkbox"] {
  width: 10px;
  height: 10px;
}

.in-state-field .type-pill input[type="checkbox"]:checked::after {
  left: 2px;
  top: 0px;
  width: 2.5px;
  height: 5px;
}

/* The State field normally wraps (".field { flex-wrap: wrap }") when its contents overflow, which
   is fine for an ordinary label+input pair but wrong here: label (130px) + select (50%) + the
   pill together often exceed the field's width, and wrapping dropped the pill onto its own line
   below State instead of keeping it inline. Forcing nowrap lets the select (min-width: 0) shrink
   to make room instead, so the pill always stays on the same line as State. */
.ticket-field-grid.classic-layout .ticket-grid-item[data-field-key="state"] .field {
  flex-wrap: nowrap;
}

/* ---------- Ticket detail page: header utility icons (attachments / watchers / KB) ---------- */

.header-util-group {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 4px;
  vertical-align: middle;
}

.header-util-control {
  position: relative;
  display: inline-flex;
}

.header-util-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 36px;
  height: 36px;
  border-radius: 100px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
}

.header-util-btn:hover {
  background: var(--bg);
  color: var(--text);
}

.header-util-btn svg {
  width: 18px;
  height: 18px;
}

.header-util-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 100px;
  background: var(--accent);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
}

.header-popover {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 8px;
  z-index: 30;
  width: 280px;
  padding: 14px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
  text-align: left;
}

.header-popover.open {
  display: block;
}

.header-popover h4 {
  margin: 0 0 10px;
  font-size: 13px;
}

.ticket-field-settings-list {
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
}

.ticket-field-settings-row {
  display: grid;
  grid-template-columns: 1fr 44px 64px;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  font-size: 12px;
  border-bottom: 1px solid var(--border);
}

.ticket-field-settings-row:last-child {
  border-bottom: none;
}

.ticket-field-settings-row span:first-child {
  color: var(--text);
}

.ticket-field-settings-head {
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  font-size: 10px;
  letter-spacing: 0.03em;
  background: var(--bg);
}

.ticket-field-settings-row input[type="checkbox"] {
  justify-self: center;
  accent-color: var(--accent);
  width: 15px;
  height: 15px;
}

.notes-panel {
  flex: 1;
  min-width: 280px;
}

.resizable-tile {
  max-width: none;
  min-width: 320px;
  display: flex;
  flex-direction: column;
}

.notes-panel.resizable-tile {
  flex: 1 1 auto;
}

.ticket-tile-resize-handle {
  flex-shrink: 0;
  align-self: stretch;
  width: 24px;
  cursor: col-resize;
  z-index: 5;
}

/* ---------- Ticket detail page: Attachments / Watchers / Notes ---------- */

.ticket-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.ticket-section-header h3 {
  margin: 0;
  font-size: 15px;
}

.attachment-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.attachment-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.attachment-list svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--text-secondary);
}

.attachment-list a {
  font-size: 13px;
  font-weight: 600;
}

.attachment-meta {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-secondary);
  white-space: nowrap;
}

.watcher-chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.note-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.note-list li {
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.note-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 12px;
  color: var(--text-secondary);
  margin-bottom: 4px;
}

.note-meta-date {
  flex-shrink: 0;
  white-space: nowrap;
}

.note-body {
  font-size: 13px;
  color: var(--text);
  white-space: pre-wrap;
}

.note-image-attachment {
  max-width: 100%;
  max-height: 220px;
  border-radius: 6px;
  border: 1px solid var(--border);
  display: block;
  margin-top: 4px;
}

.note-file-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 28px 6px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-elevated);
  font-size: 13px;
}

.note-file-chip svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

#note-form.note-drop-active,
#record-notes-card.note-drop-active {
  outline: 2px dashed var(--accent);
  outline-offset: 4px;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}

.note-image-lightbox-box {
  position: relative;
  max-width: 90vw;
  max-height: 90vh;
}

.note-image-lightbox-box img {
  display: block;
  max-width: 90vw;
  max-height: 90vh;
  border-radius: 8px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}

.note-image-lightbox-box .chip-icon-btn {
  position: absolute;
  top: -14px;
  right: -14px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
}

/* ---------- Reports & Dashboards ---------- */

.empty-state {
  max-width: 460px;
  margin: 48px auto;
  text-align: center;
  padding: 32px;
}

.layout-embed-iframe {
  display: block;
  width: 100%;
  height: 600px;
  border: none;
}

.empty-state h3 {
  margin: 0 0 8px;
  font-size: 16px;
}

.empty-state .helptext {
  font-size: 13px;
  margin-bottom: 20px;
}

.report-card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

/* Flat (non-drag-and-drop) tile grids stretch each row's tiles to fill the full row width —
   unlike the fixed-width flex tiles above, this guarantees the last tile in every row always
   reaches the same right edge as the toolbar buttons above it, at any screen width. */
.kb-flat-tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

.report-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-top: 3px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 0 1 240px;
  min-width: 200px;
}

.report-card-header {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

/* ---------- KB Homepage: containers + pinned pages ---------- */

.kb-home-breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-secondary);
}

.kb-home-breadcrumb a { color: var(--text-secondary); text-decoration: none; padding: 2px 4px; border-radius: 4px; }
.kb-home-breadcrumb a:hover { color: var(--accent); }
.kb-home-breadcrumb a:last-child { color: var(--text); font-weight: 600; }
.kb-home-breadcrumb-sep { color: var(--border); }

.report-card.dragging {
  opacity: 0.4;
}

.kb-home-drop-target.drop-target {
  background: color-mix(in srgb, var(--accent) 16%, var(--bg-elevated));
  outline: 2px dashed var(--accent);
  outline-offset: -2px;
}

.kb-home-breadcrumb a.drop-target {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  outline: 2px dashed var(--accent);
  color: var(--accent);
}

.kb-home-tile-grid {
  gap: 4px;
}

.kb-view-menu-control {
  position: relative;
}

.kb-view-menu-popover {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 6px;
  z-index: 30;
  width: 280px;
  padding: 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.kb-view-menu-popover.open {
  display: block;
}

.kb-view-menu-divider {
  height: 1px;
  background: var(--border);
  margin: 10px 0;
}

.kb-view-menu-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 220px;
  overflow-y: auto;
}

.kb-view-menu-row {
  display: flex;
  align-items: center;
  gap: 2px;
  border-radius: 6px;
}

.kb-view-menu-row.active {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.kb-view-menu-row-name {
  flex: 1;
  min-width: 0;
  text-align: left;
  background: none;
  border: none;
  padding: 7px 8px;
  color: var(--text);
  font: inherit;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-radius: 6px;
}

.kb-view-menu-row-name:hover {
  background: var(--bg);
}

.kb-view-edit-btn {
  flex-shrink: 0;
}

.kb-view-share-options {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 0;
  font-size: 12px;
}

.kb-view-share-option {
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
}

.kb-view-share-btn {
  margin-left: auto;
  padding: 4px 10px;
  font-size: 12px;
  gap: 6px;
}

.kb-view-share-panel {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 4px 0 8px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
}

.kb-view-share-panel-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  border: none;
  background: none;
  color: var(--text-secondary);
  font-size: 13px;
  text-align: left;
  cursor: not-allowed;
}

.kb-view-share-panel-option svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.kb-view-group-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}

.kb-view-group-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.kb-view-group-chip-remove {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  padding: 0;
  font-size: 14px;
  line-height: 1;
}

.kb-unorganized-heading {
  font-size: 13px;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin: 20px 0 12px;
}

.kb-home-insert-slot {
  width: 8px;
  flex-shrink: 0;
  align-self: stretch;
  border-radius: 4px;
  transition: width .1s, background .1s;
}

.kb-home-insert-slot.active {
  width: 28px;
  background: color-mix(in srgb, var(--accent) 25%, transparent);
  outline: 2px dashed var(--accent);
}

.kb-home-container-card,
.report-card {
  position: relative;
}

.kb-home-remove-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  opacity: 0;
  transition: opacity .1s;
}

.kb-home-tile-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  gap: 4px;
  opacity: 0;
  transition: opacity .1s;
}

.kb-home-tile-actions .kb-home-remove-btn {
  position: static;
  opacity: 1;
}

.report-card:hover .kb-home-remove-btn,
.report-card:hover .kb-home-tile-actions {
  opacity: 1;
}

.kb-home-choice-row {
  display: flex;
  gap: 12px;
}

.kb-home-choice-btn {
  flex: 1;
  flex-direction: column;
  gap: 8px;
  padding: 20px 12px;
  justify-content: center;
}

.kb-home-back-btn {
  margin-bottom: 8px;
}

.kb-home-container-icon {
  width: 28px;
  height: 28px;
}

.modal-box-wide {
  max-width: 640px;
}

.kb-home-icon-settings-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 320px;
  overflow-y: auto;
}

.kb-home-icon-settings-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  text-align: left;
  font: inherit;
}

.kb-home-icon-settings-row:hover {
  border-color: var(--accent);
}

.kb-home-icon-settings-row svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--text-secondary);
}

.kb-home-icon-picker-groups {
  max-height: 380px;
  overflow-y: auto;
  padding-right: 4px;
}

.kb-home-icon-group {
  margin-bottom: 14px;
}

.kb-home-icon-group-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-secondary);
  margin-bottom: 6px;
}

.kb-home-icon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
  gap: 6px;
}

.kb-home-icon-option {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text-secondary);
  cursor: pointer;
}

.kb-home-icon-option:hover {
  background: var(--bg-elevated);
  color: var(--accent);
  border-color: var(--accent);
}

.kb-home-icon-option svg {
  width: 17px;
  height: 17px;
}

.kb-home-color-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.kb-home-color-option {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 2px solid var(--border);
  cursor: pointer;
  padding: 0;
}

.kb-home-color-option:hover {
  border-color: var(--text);
}

.kb-home-color-option.selected {
  border-color: var(--text);
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.kb-home-color-option-default {
  width: auto;
  height: 34px;
  border-radius: 17px;
  padding: 0 14px;
  background: var(--bg);
  color: var(--text-secondary);
  font-size: 12px;
  font-weight: 600;
}

/* Containers are tinted by nesting depth (a top-level container vs. one nested inside it)
   so the tree structure reads at a glance; plain pinned KB tiles never get a level tint,
   so every KB tile stays visually identical regardless of where it sits in the tree. */
.kb-home-level-0 { border-top-color: var(--series-1); }
.kb-home-level-0 .kb-home-container-icon { color: var(--series-1); }
.kb-home-level-1 { border-top-color: var(--series-2); }
.kb-home-level-1 .kb-home-container-icon { color: var(--series-2); }
.kb-home-level-2 { border-top-color: var(--series-3); }
.kb-home-level-2 .kb-home-container-icon { color: var(--series-3); }
.kb-home-level-3 { border-top-color: var(--series-4); }
.kb-home-level-3 .kb-home-container-icon { color: var(--series-4); }
.kb-home-level-4 { border-top-color: var(--series-5); }
.kb-home-level-4 .kb-home-container-icon { color: var(--series-5); }
.kb-home-level-5 { border-top-color: var(--series-6); }
.kb-home-level-5 .kb-home-container-icon { color: var(--series-6); }
.kb-home-level-6 { border-top-color: var(--series-7); }
.kb-home-level-6 .kb-home-container-icon { color: var(--series-7); }
.kb-home-level-7 { border-top-color: var(--series-8); }
.kb-home-level-7 .kb-home-container-icon { color: var(--series-8); }

.report-card-title {
  margin: 0;
  font-size: 15px;
}

.report-card-desc {
  margin: 0;
  font-size: 13px;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.report-card-meta {
  font-size: 12px;
  color: var(--text-secondary);
}

.report-card-actions {
  display: flex;
  gap: 8px;
  margin-top: auto;
  padding-top: 8px;
}

.report-card.hidden-by-search {
  display: none;
}

/* ---------- Report tiles (list page): each card is a live mini-preview of its own chart,
   with Edit/Delete tucked away as hover-only icon buttons so the visual stays uncluttered. ---------- */

.report-tile {
  position: relative;
  flex: 0 0 auto;
  width: 280px;
  height: 220px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 0;
  box-shadow: var(--shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.report-tile.hidden-by-search {
  display: none;
}

.report-tile-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  color: inherit;
  text-decoration: none;
}

.report-tile-chart {
  flex: 1;
  min-height: 0;
  padding: 16px 28px 32px 28px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid var(--border);
}

/* The full chart partial includes its own card padding/shadow/data-table toggle, meant for a
   full-size page — none of that belongs in a compact tile preview, so it's stripped back here. */
.report-tile-chart .report-chart-wrap {
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
  margin-bottom: 0;
  width: 100%;
  height: 100%;
}

/* The chart itself grows/shrinks with the tile (drag-resize), not just the tile's empty space
   around a fixed-size chart — every chart type's own "data dimension" is re-anchored to 100% of
   the available tile height instead of the fixed pixel size it uses standalone on the full
   report page. Bar (horizontal) needs no override here: its data dimension is width, which
   already fills the tile via the row's 1fr track. */
.report-tile-chart .report-axis-and-columns,
.report-tile-chart .report-column-chart,
.report-tile-chart .report-histogram-chart {
  height: 100%;
}

.report-tile-chart .report-pie-svg,
.report-tile-chart .report-gauge-svg {
  width: 100%;
  height: 100%;
  max-width: 100%;
}

/* A stat tile is just one big number — it should dominate the card, not sit small in the middle
   of a lot of empty space (the fixed 42px full-page size looked lost in a typically much larger
   dashboard tile). */
.report-tile-chart .report-stat-value {
  font-size: 56px;
}

/* Line/Area's viewBox is a fixed 560:220 shape, which almost never matches a resized tile's own
   aspect ratio — constraining the svg to that same ratio (an earlier version of this rule did,
   via CSS aspect-ratio) left a lot of the tile as dead space above/below a chart that stayed
   small to preserve its proportions. Filling both dimensions and letting the svg's own
   preserveAspectRatio="none" (see the template) stretch the coordinate space non-uniformly
   instead means the chart actually fills the card whatever shape it's resized to — normal
   practice for a line chart, unlike a pie/gauge where distortion would actually look wrong. */
.report-tile-chart .report-line-svg {
  width: 100%;
  height: 100%;
}

.report-tile-chart .report-table-wrap,
.report-tile-chart .data-table {
  display: none;
}

.report-tile-chart .report-pie-legend {
  display: none;
}

.report-tile-chart .empty-state {
  padding: 0;
  border: none;
  box-shadow: none;
  background: none;
}

.report-tile-table-note {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--text-secondary);
  font-size: 12px;
}

.report-tile-table-note svg {
  width: 28px;
  height: 28px;
  opacity: 0.6;
}

/* Title sits in its own header at the top of the tile — kept out from under the top-right
   Edit/Delete icons via right padding, since those overlay on hover. */
.report-tile-header {
  flex-shrink: 0;
  padding: 8px 70px 4px 10px;
}

.report-tile-title {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.report-tile:hover .report-tile-title {
  color: var(--text);
}

.report-tile-footer {
  flex-shrink: 0;
  padding: 0 10px 8px;
}

/* The meta line (record types / chart type / total) only takes up space when hovered — the tile
   stays a clean, uncluttered chart the rest of the time. */
.report-tile-meta {
  font-size: 11px;
  color: var(--text-secondary);
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 0.15s, opacity 0.15s, margin-top 0.15s;
}

.report-tile:hover .report-tile-meta {
  max-height: 32px;
  opacity: 1;
}

/* Per-tile caption visibility (set via the tile's gear-icon settings) — "hover" is the base
   behavior above; "always" forces it visible with no hover needed, "hidden" removes it outright. */
.report-tile-caption-always .report-tile-meta {
  max-height: 32px;
  opacity: 1;
}

.report-tile-caption-hidden {
  display: none;
}

.report-tile-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  display: flex;
  gap: 4px;
  opacity: 0;
  transition: opacity 0.12s;
}

.report-tile:hover .report-tile-actions,
.report-tile-actions:focus-within {
  opacity: 1;
}

.report-tile-actions .chip-icon-btn {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

/* Drag-to-resize grip in the bottom-right corner — same idea as the resizable tiles elsewhere
   in the app, just a plain diagonal-lines affordance instead of an invisible hit zone, since this
   one needs to be discoverable sitting on top of a chart. */
.report-tile-resize-grip {
  position: absolute;
  right: 2px;
  bottom: 2px;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  padding: 2px;
  color: var(--text-secondary);
  opacity: 0;
  cursor: nwse-resize;
  transition: opacity 0.12s;
  z-index: 2;
  touch-action: none;
}

.report-tile-resize-grip svg {
  width: 12px;
  height: 12px;
}

.report-tile:hover .report-tile-resize-grip {
  opacity: 1;
}

/* ---------- Report form: 3-step layout (data -> filter -> visualize) ---------- */

.report-step {
  border-top: 1px solid var(--border);
  margin-top: 16px;
  padding-top: 16px;
}

.report-step-heading {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.report-step-heading h3 {
  margin: 0;
  font-size: 15px;
}

/* Record Type checkboxes: each stays a compact, evenly-sized pill instead of stretching to the
   full card width (the default flex-column behavior a plain wrapper div would otherwise give). */
.record-type-list {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding-top: 4px;
}

.record-type-list .type-pill {
  min-width: 180px;
}

.chart-option-group {
  margin-top: 16px;
}

.chart-option-group:first-child {
  margin-top: 0;
}

.field input[type="color"] {
  box-sizing: border-box;
  width: 56px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--input-bg);
  cursor: pointer;
}

.field input[type="range"] {
  width: 100%;
  accent-color: var(--accent);
  cursor: pointer;
}

.slider-value {
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--text-secondary);
  margin-left: 4px;
}

.checkbox-field {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  cursor: pointer;
}

.checkbox-field input {
  accent-color: var(--accent);
  width: 15px;
  height: 15px;
}

.settings-sidebar-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px 16px;
  max-width: 480px;
}

.series-customize-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.series-customize-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--input-bg);
}

.series-visible-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  cursor: pointer;
}

.series-visible-label input {
  accent-color: var(--accent);
  width: 15px;
  height: 15px;
}

.series-color-input {
  width: 40px;
  height: 28px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-elevated);
  cursor: pointer;
}

/* When a .report-step is the only thing on its wizard page, it doesn't need the divider that
   otherwise separates it from the section above it when it isn't the first thing on the page. */
.wizard-page > .report-step:first-child {
  border-top: none;
  margin-top: 0;
  padding-top: 0;
}

/* All four wizard pages share this one grid cell, so the card's height is always the tallest
   step's height — the JS hides inactive steps with visibility (not display), which keeps them
   sized within the grid without showing them, instead of the card resizing as you step through. */
.wizard-page-stack {
  display: grid;
}

.wizard-page-stack > .wizard-page {
  grid-area: 1 / 1;
  min-width: 0;
}

.wizard-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.wizard-nav-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
  color: var(--text);
  cursor: pointer;
}

.wizard-nav-arrow svg {
  width: 16px;
  height: 16px;
}

.wizard-nav-arrow:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

.wizard-nav-arrow:disabled {
  opacity: 0.35;
  cursor: default;
}

.wizard-nav-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  min-width: 90px;
  text-align: center;
}

.report-step-heading .helptext {
  font-weight: normal;
  font-size: 13px;
}

.report-step-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  flex-shrink: 0;
}

/* ---------- Report detail: chart + data table ---------- */

.report-chart-wrap {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 28px 44px 48px 44px;
  margin-bottom: 20px;
  overflow-x: auto;
}

.report-pie-svg {
  width: 220px;
  height: 220px;
  flex-shrink: 0;
}

.report-pie-slice.has-hover-effect {
  cursor: pointer;
  transform-box: view-box;
  transform-origin: center;
  transition: transform 140ms ease, filter 140ms ease, stroke-width 140ms ease;
}

.report-pie-slice.has-hover-effect:hover,
.report-pie-slice.has-hover-effect:focus-visible {
  filter: brightness(1.18) drop-shadow(0 0 4px rgba(255, 255, 255, .28));
  transform: scale(1.045);
}

.report-pie-slice.has-hover-effect:focus-visible {
  outline: none;
}

.report-gauge-svg {
  width: 240px;
  height: auto;
}

.report-line-svg {
  width: 100%;
  max-width: 560px;
  height: auto;
}

.report-stat-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 100%;
  height: 100%;
  text-align: center;
}

.report-stat-value {
  font-size: 42px;
  font-weight: 700;
  color: var(--text);
  line-height: 1;
}

.report-activity-ring-layout {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 22px;
}

.report-activity-ring-svg {
  width: 240px;
  height: 240px;
  flex: 0 1 240px;
  overflow: visible;
}

.report-activity-ring-tick {
  stroke: var(--text-secondary);
  stroke-opacity: .22;
  stroke-width: 1;
}

.report-activity-ring-tick.is-major {
  stroke-opacity: .42;
  stroke-width: 1.5;
}

.report-activity-ring-count {
  fill: var(--text);
  font-size: 22px;
  font-weight: 700;
}

.report-activity-ring-label {
  fill: var(--text-secondary);
  font-size: 12px;
}

.report-activity-ring-legend {
  min-width: 190px;
}

.report-kpi-sparkline-wrap {
  --report-kpi-color: #39c995;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 78px;
  padding: 14px 18px;
}

.report-kpi-sparkline-wrap.is-down {
  --report-kpi-color: #ed5267;
}

.report-kpi-sparkline-metric {
  min-width: 0;
}

.report-kpi-value {
  color: var(--text);
  font-size: 30px;
  font-weight: 650;
  letter-spacing: -.035em;
  line-height: 1.15;
}

.report-kpi-unit {
  margin-left: 5px;
  color: var(--text-secondary);
  font-size: 11px;
  font-weight: 450;
  letter-spacing: 0;
}

.report-kpi-trend {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 8px;
  color: #39c995;
  font-size: 12px;
  font-weight: 600;
}

.report-kpi-trend-down { color: #ed5267; }
.report-kpi-trend-flat { color: var(--text-secondary); }

.report-kpi-period {
  margin-left: 4px;
  color: var(--text-secondary);
  font-size: 10px;
  font-weight: 400;
}

.report-kpi-sparkline-svg {
  display: block;
  width: min(56%, 180px);
  height: 60px;
  flex: 0 1 180px;
  overflow: visible;
}

.report-bar-row {
  display: grid;
  grid-template-columns: 160px 1fr 60px;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  font-size: 13px;
}

.report-bar-row .report-bar-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-secondary);
}

.report-bar-track {
  background: var(--bg);
  border-radius: 4px;
  height: 18px;
  overflow: hidden;
}

.report-bar-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 4px;
}

.report-bar-count {
  text-align: right;
  font-weight: 600;
}

/* ---------- Optional axis overlay ("show axes" in Customize) ---------- */

.report-axis-and-columns {
  display: flex;
  align-items: flex-end;
}

/* Mirrors .report-column's own structure exactly (a spacer matching the count label's height,
   a flexible middle, a spacer matching the category label's height) so its tick marks line up
   with where the actual bar track starts and ends — not a guessed fixed height, which drifted
   out of alignment as soon as the track itself became fluid-height instead of a fixed 190px. */
.report-axis-col {
  display: flex;
  flex-direction: column;
  /* .report-axis-and-columns uses align-items: flex-end (so the bars/columns sit on their own
     natural, bottom-anchored height) — height: 100% on this sibling doesn't reliably resolve
     against a flex container's auto-computed height, which left it squashed to a shrunk size and
     pinned to the bottom instead of spanning the bars' full height. align-self: stretch is the
     actual spec-correct way to make one flex child match the row's tallest sibling regardless of
     the container's own align-items value. */
  align-self: stretch;
  margin-right: 8px;
  font-size: 10px;
  color: var(--text-secondary);
  text-align: right;
  flex-shrink: 0;
}

.report-axis-col-spacer {
  flex-shrink: 0;
  height: 20px;
}

.report-axis-col-ticks {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

/* The actual visible axis lines (not just the tick numbers) — only drawn when "Show axis
   values" is on, forming an L-shaped frame: a vertical rule (the value axis) beside the tick
   numbers, and a horizontal rule (the category axis) right where the bars meet their labels.
   Uses --text-secondary rather than the usual --border — plain --border is a subtle divider
   color (by design, for things like card edges) with barely any contrast against the dark theme's
   background, which made these lines functionally invisible; an axis is a piece of information,
   not a decorative divider, so it gets the same visible color as its own tick-value text. */
.report-axis-and-columns.has-axis-lines .report-axis-col {
  padding-right: 8px;
  border-right: 2px solid var(--text-secondary);
}

/* One continuous line spanning every bar (not a border per-track, which reads as a broken/dashed
   line with a visible gap under each bar) — positioned via the same 20px spacer height used by
   .report-axis-col-spacer, so it lands exactly at the bars' shared baseline, above the category
   labels rather than below them. .report-column-chart/.report-histogram-chart are position:
   relative specifically so this can anchor to them; left/right span the full scrollable width,
   not just the visible viewport, so it stays under every bar even when the chart scrolls. */
.report-axis-baseline {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 20px;
  border-top: 2px solid var(--text-secondary);
}

.report-bar-track.has-axis-line {
  border-left: 2px solid var(--text-secondary);
}

.report-axis-row {
  display: grid;
  grid-template-columns: 160px 1fr 60px;
  gap: 10px;
  margin-top: 4px;
}

.report-axis-row-line {
  border-top: 2px solid var(--text-secondary);
  padding-top: 4px;
}

.report-axis-row-ticks {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: var(--text-secondary);
}

.report-column-chart {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 14px;
  height: 260px;
  overflow-x: auto;
  padding-bottom: 4px;
}

.report-column {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: 100%;
  min-width: 56px;
  flex-shrink: 0;
}

.report-column-count {
  font-size: 12px;
  font-weight: 600;
  margin-bottom: 4px;
}

.report-column-track {
  position: relative;
  width: 32px;
  flex: 1;
  min-height: 0;
  background: var(--bg);
  border-radius: 4px 4px 0 0;
  overflow: hidden;
}

/* Anchored to the bottom with absolute positioning rather than a flexbox percentage-height —
   height:100% on a flex item can end up short of the container's full height depending on how
   the browser resolves the cross-axis percentage, which showed up as a dark, unfilled cap at the
   top of every bar (including the max-value one, which should render fully filled). Absolute
   positioning against an explicit bottom/left/right has no such ambiguity. */
.report-column-fill {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--accent);
  border-radius: 4px 4px 0 0;
}

/* Stacked Column: each segment absolutely positioned by its own bottom/height percentage (not a
   flex-item percentage height — see the .report-column-fill comment above for why that's
   unreliable here) so several segments can sit on top of each other within one track. */
.report-stacked-track {
  position: relative;
}

.report-stacked-segment {
  position: absolute;
  left: 0;
  right: 0;
}

.report-stacked-track .report-stacked-segment:last-child {
  border-radius: 4px 4px 0 0;
}

/* Stacked Bar: the horizontal mirror of the above — left/width percentages instead of
   bottom/height. */
.report-stacked-track-h {
  position: relative;
}

.report-stacked-segment-h {
  position: absolute;
  top: 0;
  bottom: 0;
}

.report-stacked-track-h .report-stacked-segment-h:last-child {
  border-radius: 0 4px 4px 0;
}

.report-histogram-chart {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 0;
  height: 260px;
  overflow-x: auto;
  padding-bottom: 4px;
  border-left: 1px solid var(--border);
}

.report-histogram-bar {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: 100%;
  flex: 1 0 56px;
  border-right: 1px solid var(--border);
}

.report-histogram-track {
  position: relative;
  width: 100%;
  flex: 1;
  min-height: 0;
  background: var(--bg);
  overflow: hidden;
}

.report-histogram-fill {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--accent);
}

.report-column-label {
  margin-top: 6px;
  font-size: 11px;
  color: var(--text-secondary);
  max-width: 70px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
}

.report-pie-legend {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
}

.report-pie-legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.report-pie-swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  flex-shrink: 0;
}

.report-pie-legend-count {
  margin-left: auto;
  color: var(--text-secondary);
}

/* ---------- Dashboards ---------- */
a.tab-btn {
  text-decoration: none;
  display: inline-block;
}

.dashboard-tab-bar {
  align-items: center;
}

/* Dashboard cards follow the compact, rounded analytics-card style while keeping the actual
   report chart selected by the user (stat, sparkline, donut/gauge, bars, or table). */
#dashboard-tile-grid {
  gap: 14px;
  align-items: flex-start;
}

.dashboard-report-tile {
  --dashboard-tile-accent: #3dc69a;
  container: dashboard-card / inline-size;
  border-radius: 14px;
  background: var(--bg-elevated);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.12);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.dashboard-report-tile:nth-child(6n + 1) { --dashboard-tile-accent: #e54d93; }
.dashboard-report-tile:nth-child(6n + 2) { --dashboard-tile-accent: #33b7e5; }
.dashboard-report-tile:nth-child(6n + 3) { --dashboard-tile-accent: #e9ae27; }
.dashboard-report-tile:nth-child(6n + 4) { --dashboard-tile-accent: #5284f3; }
.dashboard-report-tile:nth-child(6n + 5) { --dashboard-tile-accent: #9365e8; }
.dashboard-report-tile:nth-child(6n + 6) { --dashboard-tile-accent: #31bfa2; }

:root[data-theme="dark"] .dashboard-report-tile {
  border-color: #27322e;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.24);
}

.dashboard-report-tile:hover {
  border-color: color-mix(in srgb, var(--dashboard-tile-accent) 48%, var(--border));
  box-shadow: 0 9px 26px rgba(0, 0, 0, 0.2);
}

.dashboard-report-tile .report-tile-header {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 70px 7px 12px;
}

.dashboard-tile-icon {
  width: 29px;
  height: 29px;
  flex: 0 0 29px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  color: var(--dashboard-tile-accent);
  background: color-mix(in srgb, var(--dashboard-tile-accent) 17%, transparent);
}

.dashboard-tile-icon svg {
  width: 15px;
  height: 15px;
}

.dashboard-report-tile .report-tile-title {
  min-width: 0;
  color: var(--text);
  font-size: 13px;
  font-weight: 550;
}

.dashboard-report-tile .report-tile-chart {
  min-height: 0;
  padding: 5px 12px 10px;
  border-bottom: 0;
}

.dashboard-report-tile .report-tile-chart .report-chart-wrap {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

.dashboard-report-tile .report-stat-wrap {
  padding: 2px 5px;
}

/* Centered is the default (see .report-stat-wrap above) — this opts a tile back into the old
   always-left-aligned dashboard-card look, via the Customize step's "Center" checkbox. */
.report-stat-wrap-left {
  align-items: flex-start !important;
  text-align: left !important;
}

.dashboard-report-tile .report-stat-value {
  font-size: 34px;
  font-weight: 650;
  letter-spacing: -0.025em;
}

.dashboard-report-tile .report-pie-svg,
.dashboard-report-tile .report-gauge-svg {
  max-height: 100%;
}

.dashboard-report-tile.chart-activity_ring .report-activity-ring-layout {
  height: 100%;
  gap: 0;
}

.dashboard-report-tile.chart-activity_ring .report-activity-ring-svg {
  width: min(100%, 230px);
  height: auto;
  max-height: 100%;
  flex: 0 1 230px;
}

.dashboard-report-tile.chart-activity_ring .report-activity-ring-legend {
  display: none;
}

.dashboard-report-tile.chart-kpi_sparkline .report-kpi-sparkline-wrap {
  height: 100%;
  min-height: 0;
  padding: 8px 5px;
  border: 0;
  background: transparent;
}

.dashboard-report-tile.chart-kpi_sparkline .report-kpi-value {
  font-size: 30px;
}

.dashboard-report-tile.chart-kpi_sparkline .report-kpi-sparkline-svg {
  width: 55%;
  max-width: 180px;
  height: 58px;
}

.dashboard-report-tile.chart-line .report-line-svg,
.dashboard-report-tile.chart-stacked_line .report-line-svg,
.dashboard-report-tile.chart-stacked_line_pct .report-line-svg,
.dashboard-report-tile.chart-area .report-line-svg,
.dashboard-report-tile.chart-stacked_area .report-line-svg,
.dashboard-report-tile.chart-stacked_area_pct .report-line-svg {
  overflow: visible;
}

@container dashboard-card (max-width: 320px) {
  .dashboard-report-tile.chart-line .report-line-svg text,
  .dashboard-report-tile.chart-line .report-line-svg line,
  .dashboard-report-tile.chart-stacked_line .report-line-svg text,
  .dashboard-report-tile.chart-stacked_line .report-line-svg line,
  .dashboard-report-tile.chart-stacked_line_pct .report-line-svg text,
  .dashboard-report-tile.chart-stacked_line_pct .report-line-svg line,
  .dashboard-report-tile.chart-area .report-line-svg text,
  .dashboard-report-tile.chart-area .report-line-svg line,
  .dashboard-report-tile.chart-stacked_area .report-line-svg text,
  .dashboard-report-tile.chart-stacked_area .report-line-svg line,
  .dashboard-report-tile.chart-stacked_area_pct .report-line-svg text,
  .dashboard-report-tile.chart-stacked_area_pct .report-line-svg line {
    display: none;
  }
}

.dashboard-report-tile .report-tile-footer {
  padding: 0 12px 9px;
}

.dashboard-tab {
  display: flex;
  align-items: center;
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
}

.dashboard-tab.active {
  border-bottom-color: var(--accent);
}

.dashboard-tab .tab-btn {
  border-bottom: none;
  margin-bottom: 0;
}

.dashboard-tab-gear-wrap {
  position: relative;
  display: flex;
  align-items: center;
  margin-left: -14px;
}

.dashboard-tab-gear {
  appearance: none;
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 4px;
  margin-right: 4px;
  margin-top: 3px;
  display: flex;
  align-items: center;
}

.dashboard-tab-gear:hover {
  color: var(--accent);
}

.dashboard-tab-gear svg {
  width: 14px;
  height: 14px;
}

.dashboard-tab-gear-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 6px;
  z-index: 30;
  min-width: 140px;
  padding: 4px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.dashboard-tab-gear-menu.open {
  display: block;
}

.dashboard-tab-gear-menu-item {
  appearance: none;
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 8px 10px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  border-radius: 5px;
}

.dashboard-tab-gear-menu-item:hover:not(:disabled) {
  background: var(--bg);
}

.dashboard-tab-gear-menu-item:disabled {
  color: var(--text-secondary);
  cursor: not-allowed;
}

.dashboard-tab-gear-menu-item.active {
  color: var(--accent);
  font-weight: 700;
}

.dashboard-tab-gear-menu-item-danger {
  color: var(--danger);
}

.tab-btn-add {
  margin-left: auto;
  color: var(--accent);
}

.report-tile-insert {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 280px;
  height: 220px;
  border: 2px dashed var(--border);
  border-radius: 0;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
  flex: 0 0 auto;
  text-decoration: none;
}

.report-tile-insert:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.report-tile-insert svg {
  width: 28px;
  height: 28px;
}

/* ---------- Tile resize snap guides (Reports list + Dashboards) ---------- */
.tile-snap-guide {
  position: absolute;
  display: none;
  z-index: 5;
  pointer-events: none;
}

.tile-snap-guide-h {
  height: 0;
  border-top: 1px dashed var(--accent);
  opacity: 0.6;
}

.tile-snap-guide-v {
  width: 0;
  border-left: 1px dashed var(--accent);
  opacity: 0.6;
}

.tile-snap-label {
  position: absolute;
  display: none;
  z-index: 6;
  padding: 3px 8px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  border-radius: 4px;
  white-space: nowrap;
  pointer-events: none;
  transform: translate(-100%, -130%);
}

/* ---------- Insert Card pop-up (report-creation wizard in an iframe modal) ---------- */
.modal-box-large {
  position: relative;
  width: min(1080px, 92vw);
  max-width: none;
  height: min(680px, 88vh);
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}

.modal-box-large.modal-box-maximized {
  position: fixed;
  inset: 0;
  width: auto;
  height: auto;
  border-radius: 0;
}

.insert-card-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  cursor: move;
  user-select: none;
}

.insert-card-modal-header h3 {
  margin: 0;
}

.modal-box-close-btn {
  appearance: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 8px;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  flex-shrink: 0;
}

.modal-box-close-btn svg {
  width: 22px;
  height: 22px;
}

.modal-box-close-btn:hover {
  background: var(--bg);
  color: var(--text);
}

/* ---------- Queue table: type/status colors, sortable + reorderable columns, settings popover ---------- */
.queue-type-colored .badge-type-incident {
  border-color: var(--queue-color-incident, var(--border));
  background: var(--queue-color-incident-bg, transparent);
  color: var(--queue-color-incident, var(--text-secondary));
}

.queue-type-colored .badge-type-request {
  border-color: var(--queue-color-request, var(--border));
  background: var(--queue-color-request-bg, transparent);
  color: var(--queue-color-request, var(--text-secondary));
}

.queue-type-colored .badge-type-change {
  border-color: var(--queue-color-change, var(--border));
  background: var(--queue-color-change-bg, transparent);
  color: var(--queue-color-change, var(--text-secondary));
}

.queue-status-colored .badge-status-new {
  border-color: var(--queue-status-color-new, var(--border));
  background: var(--queue-status-color-new-bg, transparent);
  color: var(--queue-status-color-new, var(--text-secondary));
}

.queue-status-colored .badge-status-in_progress {
  border-color: var(--queue-status-color-in_progress, var(--border));
  background: var(--queue-status-color-in_progress-bg, transparent);
  color: var(--queue-status-color-in_progress, var(--text-secondary));
}

.queue-status-colored .badge-status-on_hold {
  border-color: var(--queue-status-color-on_hold, var(--border));
  background: var(--queue-status-color-on_hold-bg, transparent);
  color: var(--queue-status-color-on_hold, var(--text-secondary));
}

.queue-status-colored .badge-status-resolved {
  border-color: var(--queue-status-color-resolved, var(--border));
  background: var(--queue-status-color-resolved-bg, transparent);
  color: var(--queue-status-color-resolved, var(--text-secondary));
}

.queue-status-colored .badge-status-closed {
  border-color: var(--queue-status-color-closed, var(--border));
  background: var(--queue-status-color-closed-bg, transparent);
  color: var(--queue-status-color-closed, var(--text-secondary));
}

.queue-status-colored .badge-status-cancelled {
  border-color: var(--queue-status-color-cancelled, var(--border));
  background: var(--queue-status-color-cancelled-bg, transparent);
  color: var(--queue-status-color-cancelled, var(--text-secondary));
}

/* Change Request status keys that don't overlap with Incident/Request's (new/cancelled already
   do, and share those rules above). */
.queue-status-colored .badge-status-assessing {
  border-color: var(--queue-status-color-assessing, var(--border));
  background: var(--queue-status-color-assessing-bg, transparent);
  color: var(--queue-status-color-assessing, var(--text-secondary));
}

.queue-status-colored .badge-status-approved {
  border-color: var(--queue-status-color-approved, var(--border));
  background: var(--queue-status-color-approved-bg, transparent);
  color: var(--queue-status-color-approved, var(--text-secondary));
}

.queue-status-colored .badge-status-scheduled {
  border-color: var(--queue-status-color-scheduled, var(--border));
  background: var(--queue-status-color-scheduled-bg, transparent);
  color: var(--queue-status-color-scheduled, var(--text-secondary));
}

.queue-status-colored .badge-status-implementing {
  border-color: var(--queue-status-color-implementing, var(--border));
  background: var(--queue-status-color-implementing-bg, transparent);
  color: var(--queue-status-color-implementing, var(--text-secondary));
}

.queue-status-colored .badge-status-completed {
  border-color: var(--queue-status-color-completed, var(--border));
  background: var(--queue-status-color-completed-bg, transparent);
  color: var(--queue-status-color-completed, var(--text-secondary));
}

.queue-status-colored .badge-status-failed {
  border-color: var(--queue-status-color-failed, var(--border));
  background: var(--queue-status-color-failed-bg, transparent);
  color: var(--queue-status-color-failed, var(--text-secondary));
}

.col-sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  position: relative;
}

.col-sortable:hover {
  color: var(--text);
}

/* Drag-to-reorder + drag-to-resize columns directly on the table header, mirroring a real
   spreadsheet. table-layout switches to fixed only once each header's current (auto-computed)
   width has been frozen as an explicit pixel value in JS, so turning this on never changes how
   the table looks until someone actually drags something. */
#queue-table.col-resizable {
  table-layout: fixed;
}

#queue-table td {
  font-size: 13px;
}

#queue-table.col-resizable th,
#queue-table.col-resizable td {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.col-resize-handle {
  position: absolute;
  top: 0;
  right: 0;
  width: 8px;
  height: 100%;
  cursor: col-resize;
  z-index: 1;
}

.col-resize-handle:hover,
body.col-resizing .col-resize-handle {
  background: var(--accent);
  opacity: 0.4;
}

body.col-resizing {
  cursor: col-resize;
  user-select: none;
}

.col-drop-before {
  box-shadow: inset 3px 0 0 var(--accent);
}

.col-drop-after {
  box-shadow: inset -3px 0 0 var(--accent);
}

.col-sort-arrow {
  display: inline-block;
  width: 10px;
  margin-left: 2px;
  font-size: 10px;
  opacity: 0.7;
}

.queue-settings-control {
  position: relative;
}

.release-settings-control {
  position: relative;
}

.release-settings-popover {
  width: 300px;
}

.release-view-control {
  position: relative;
}

.queue-settings-popover {
  width: 300px;
  max-height: 80vh;
  overflow-y: auto;
}

.queue-settings-popover h4,
.queue-settings-popover .helptext,
.queue-settings-popover .checkbox-field,
.queue-settings-popover .queue-column-row label,
.queue-settings-popover .queue-color-row-label,
.queue-settings-popover summary {
  font-size: 12px;
}

.collapsible-details {
  margin-top: 16px;
}

.collapsible-details summary {
  cursor: pointer;
  font-weight: 600;
  margin-bottom: 10px;
}

.queue-bulk-control.open .header-popover {
  display: block;
}

.queue-column-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.queue-column-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 6px;
  border-radius: 5px;
  cursor: grab;
}

.queue-column-row:hover {
  background: var(--bg);
}

.queue-column-row-handle {
  display: flex;
  align-items: center;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.queue-column-row-handle svg {
  width: 14px;
  height: 14px;
}

.queue-column-row label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
  flex: 1;
  cursor: pointer;
}

.queue-color-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 0;
}

.queue-color-row-label {
  font-size: 13px;
  font-weight: 500;
}

.queue-type-color-list {
  margin-top: 4px;
  padding-left: 4px;
}

.queue-color-row input[type="color"],
.queue-status-color-row input[type="color"] {
  width: 36px;
  height: 26px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: none;
  cursor: pointer;
}

.queue-status-color-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
  padding-left: 4px;
}

.queue-status-color-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2px 0;
}

.queue-status-color-row-label {
  font-size: 12px;
  color: var(--text-secondary);
}

/* ---------- Change Portal (draft) ---------- */
.change-portal-date-heading {
  margin: 0 0 10px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-secondary);
}

/* ---------- Change Request: type picker (step 1 of New Change Request) ---------- */
.change-type-options {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}

.change-type-option {
  appearance: none;
  text-align: left;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 20px;
  width: 260px;
  cursor: pointer;
  color: var(--text);
}

.change-type-option:hover {
  border-color: var(--accent);
  background: rgba(47, 111, 237, 0.06);
}

.change-type-option h3 {
  margin: 0 0 8px;
  font-size: 16px;
}

.change-type-option p {
  margin: 0;
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.5;
}

/* ---------- Change Request decisions (detail page) ---------- */
.badge-decision-approved {
  border-color: #2fa76f;
  color: #2fa76f;
}

.badge-decision-rejected {
  border-color: #d6534f;
  color: #d6534f;
}

/* ---------- Change Portal ---------- */
.change-portal-topbar {
  display: flex;
  align-items: stretch;
  gap: 16px;
  margin-bottom: 20px;
}

.change-portal-count-tile {
  position: relative;
  flex-shrink: 0;
  width: 110px;
  min-width: 90px;
  min-height: 80px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 12px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.change-portal-count-resize-grip {
  position: absolute;
  right: 2px;
  bottom: 2px;
  width: 16px;
  height: 16px;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  padding: 2px;
  color: var(--text-secondary);
  opacity: 0;
  cursor: nwse-resize;
  transition: opacity 0.12s;
  touch-action: none;
}

.change-portal-count-tile:hover .change-portal-count-resize-grip {
  opacity: 1;
}

.change-portal-count-resize-grip svg {
  width: 11px;
  height: 11px;
}

.change-portal-count-number {
  font-size: 28px;
  font-weight: 700;
  line-height: 1.1;
}

.change-portal-count-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
  margin-top: 2px;
}

.change-portal-approver-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 500;
}

.change-portal-approver-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-secondary);
  opacity: 0.4;
  flex-shrink: 0;
}

.change-portal-approver-dot.online {
  background: #2fa76f;
  opacity: 1;
  box-shadow: 0 0 0 2px rgba(47, 167, 111, 0.2);
}

.change-portal-body {
  display: flex;
  gap: 0;
  align-items: stretch;
}

.change-portal-list {
  flex: 0 0 300px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 80vh;
  overflow-y: auto;
}

.change-portal-resize-handle {
  flex-shrink: 0;
  align-self: stretch;
  width: 17px;
  margin: 0 -1px;
  cursor: col-resize;
  z-index: 5;
}

.change-portal-list-item {
  display: block;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  color: var(--text);
  text-decoration: none;
  cursor: grab;
}

.change-portal-list-item:hover {
  border-color: var(--accent);
}

.change-portal-list-item.active {
  border-color: var(--accent);
  background: rgba(47, 111, 237, 0.08);
}

.change-portal-list-item-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}

.change-portal-list-item-desc {
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.change-portal-list-item-meta {
  font-size: 11px;
  color: var(--text-secondary);
}

.kb-revision-row {
  position: relative;
}

.kb-revision-row .change-portal-list-item {
  cursor: pointer;
  padding-right: 40px;
}

.kb-revision-options-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  opacity: 0;
  transition: opacity .1s;
}

.kb-revision-row:hover .kb-revision-options-btn {
  opacity: 1;
}

.kb-revision-note-text {
  font-weight: 600;
}

.change-portal-dots {
  display: inline-flex;
  gap: 4px;
}

.change-portal-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: transparent;
}

.change-portal-dot.filled {
  background: #2fa76f;
  border-color: #2fa76f;
}

.change-portal-dots.large .change-portal-dot {
  width: 12px;
  height: 12px;
}

.change-portal-detail {
  flex: 1;
  min-width: 0;
  max-width: none;
}

.change-portal-detail-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.change-portal-action-buttons {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
  flex-shrink: 0;
  max-width: 60%;
}

.change-portal-nav-buttons {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.change-portal-nav-buttons a[disabled] {
  pointer-events: none;
  opacity: 0.4;
}

.change-portal-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 12px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
}

/* ---------- Change Type badges (Standard/Normal/Emergency) — light, theme-aware tints ---------- */
.badge-type-standard {
  border-color: var(--success);
  background: color-mix(in srgb, var(--success) 14%, transparent);
  color: var(--success);
}

.badge-type-normal {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}

.badge-type-emergency {
  border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 14%, transparent);
  color: var(--danger);
}

/* ---------- Change status word (plain colored text, no badge/tile) — default colors for now;
   TODO.md notes making these configurable in settings later. ---------- */
.change-status-word {
  font-weight: 700;
  font-size: 13px;
  margin-top: 2px;
}

.change-status-word.status-not_requested {
  color: var(--text-secondary);
}

.change-status-word.status-pending {
  color: var(--accent);
}

.change-status-word.status-approved {
  color: var(--success);
}

.change-status-word.status-rejected {
  color: var(--danger);
}

/* ---------- Change Approval Board panel (Portal topbar's "big tile") ---------- */
.change-portal-cab-panel {
  flex: 1;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.change-portal-cab-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.change-portal-cab-title {
  margin: 0;
  font-size: 15px;
}

.change-portal-cab-meta {
  font-size: 12px;
  color: var(--text-secondary);
  margin-top: 2px;
}

.change-portal-cab-session-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.change-portal-cab-timer {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.change-portal-cab-timer.overtime {
  color: var(--danger);
}

.change-portal-cab-columns {
  display: flex;
  gap: 28px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}

.change-portal-cab-column {
  min-width: 160px;
}

.change-portal-cab-column-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
  margin-bottom: 6px;
}

.change-portal-cab-column .change-portal-approver-chip {
  display: flex;
  margin-bottom: 4px;
}

.change-portal-attendance-row {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  margin-bottom: 4px;
}

.change-portal-attendance-row.attended {
  color: var(--success);
  font-weight: 600;
}

.change-portal-cab-stats {
  display: flex;
  gap: 20px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-secondary);
  flex-wrap: wrap;
}

.change-portal-cab-stat-number {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  margin-right: 4px;
}

/* ---------- Right-hand "resolved this session" list ---------- */
.change-portal-resolved-list {
  flex: 0 0 260px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 80vh;
  overflow-y: auto;
}

/* ---------- Skipped list item: yellow hover instead of the default blue ---------- */
.change-portal-list-item.was-skipped:hover {
  border-color: var(--warning);
}

/* ==================== Knowledge Base ==================== */

.kb-search-row {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

/* The search input and the buttons beside it (Search/Filter/Clear) come from different base
   rules with different padding, so left alone they render at slightly different heights —
   pin them all to the same explicit height instead. */
.kb-toolbar-control {
  height: 36px;
  box-sizing: border-box;
}

.kb-tag-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
}

.badge-button.active {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: var(--accent);
  color: var(--accent);
}

.badge-kb-status-draft {
  color: var(--text-secondary);
}

.badge-kb-status-pending {
  border-color: var(--warning);
  background: color-mix(in srgb, var(--warning) 14%, transparent);
  color: var(--warning);
}

.badge-kb-status-approved {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}

.badge-kb-status-published {
  border-color: var(--success);
  background: color-mix(in srgb, var(--success) 14%, transparent);
  color: var(--success);
}

.badge-kb-status-archived {
  color: var(--text-secondary);
  background: color-mix(in srgb, var(--text-secondary) 10%, transparent);
}

.badge-kb-new {
  border-color: var(--series-2);
  background: color-mix(in srgb, var(--series-2) 14%, transparent);
  color: var(--series-2);
}

.kb-status-word {
  font-weight: 700;
  font-size: 14px;
}

.kb-status-word.status-draft {
  color: var(--text-secondary);
}

.kb-status-word.status-pending {
  color: var(--warning);
}

.kb-status-word.status-approved {
  color: var(--accent);
}

.kb-status-word.status-published {
  color: var(--success);
}

.kb-status-word.status-archived {
  color: var(--text-secondary);
  font-style: italic;
}

.kb-attachment-list {
  list-style: none;
  margin: 8px 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.kb-attachment-list li {
  display: flex;
  align-items: center;
  gap: 8px;
}

.kb-editor-toolbar.ql-toolbar.ql-snow {
  border-color: var(--border);
  border-radius: 8px 8px 0 0;
}

.kb-editor-container.ql-container.ql-snow {
  border-color: var(--border);
  border-radius: 0 0 8px 8px;
  min-height: 360px;
  font-size: 14px;
}

.kb-editor-container .ql-editor {
  min-height: 360px;
}

.kb-page-body {
  line-height: 1.6;
  font-size: 14px;
}

.kb-page-body img {
  max-width: 100%;
  border-radius: 6px;
}

.kb-page-body h1, .kb-page-body h2, .kb-page-body h3 {
  margin-top: 1.2em;
}

.kb-page-body pre {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 12px;
  overflow-x: auto;
}

.kb-page-body blockquote {
  border-left: 3px solid var(--border);
  margin: 0.8em 0;
  padding-left: 12px;
  color: var(--text-secondary);
}

.kb-view-toggle {
  display: flex;
  gap: 2px;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 2px;
}

.kb-view-toggle .icon-btn {
  width: 28px;
  height: 28px;
  border-radius: 4px;
}

.kb-view-toggle .icon-btn.active {
  background: var(--bg-elevated);
  border-color: var(--border);
  color: var(--accent);
}

.kb-line-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

.kb-line-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: var(--bg-elevated);
  color: var(--text);
  text-decoration: none;
}

.kb-line-row:hover {
  background: var(--bg);
}

.kb-line-row.dragging {
  opacity: 0.4;
}

.kb-page-drop-target.drop-target {
  background: color-mix(in srgb, var(--accent) 16%, var(--bg-elevated));
  outline: 2px dashed var(--accent);
  outline-offset: -2px;
}

.kb-line-title {
  font-size: 13px;
  font-weight: 600;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kb-line-tags {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}

.kb-line-meta {
  font-size: 12px;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.kb-page-tree {
  padding: 6px 8px 10px;
  border-top: 1px solid var(--border);
  margin-top: 6px;
}

.kb-tree-node {
  margin-left: 0;
}

.kb-tree-children {
  margin-left: 14px;
  border-left: 1px solid var(--border);
  padding-left: 8px;
}

.kb-tree-row {
  display: flex;
  align-items: center;
  gap: 4px;
}

.kb-tree-toggle {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--sidebar-text);
  cursor: pointer;
}

.kb-tree-toggle svg {
  width: 12px;
  height: 12px;
  transition: transform 0.12s ease;
  transform: rotate(90deg);
}

.kb-tree-node.collapsed > .kb-tree-row .kb-tree-toggle svg {
  transform: rotate(0deg);
}

.kb-tree-toggle-spacer {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
}

.kb-tree-node.collapsed > .kb-tree-children {
  display: none;
}

.kb-tree-link {
  flex: 1;
  min-width: 0;
  display: block;
  padding: 9px 10px;
  border-radius: 6px;
  color: var(--sidebar-text);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kb-tree-link:hover {
  background: var(--sidebar-hover-bg);
  color: var(--sidebar-text-hover);
}

.kb-tree-add-btn {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  color: var(--sidebar-text);
  background: transparent;
  border: none;
  cursor: pointer;
}

.kb-tree-add-btn:hover {
  background: var(--sidebar-hover-bg);
  color: var(--sidebar-text-hover);
}

.kb-sidebar-tabs {
  display: flex;
  flex-direction: column;
  padding: 4px 4px 10px;
}

/* ---------- Knowledge Base settings: tree management (delete + drag-and-drop reparent) ---------- */

.kb-settings-tree {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
}

.kb-settings-tree-node {
  margin-left: 0;
}

.kb-settings-tree-children {
  margin-left: 18px;
  border-left: 1px dashed var(--border);
  padding-left: 10px;
}

.kb-settings-tree-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  cursor: grab;
}

.kb-settings-tree-row:hover {
  background: var(--bg-elevated);
}

.kb-settings-tree-row.dragging {
  opacity: 0.4;
}

.kb-settings-tree-row.drop-target {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  outline: 2px dashed var(--accent);
}

.kb-settings-tree-drag-handle {
  color: var(--text-secondary);
  flex-shrink: 0;
  display: flex;
}

.kb-settings-tree-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
}

.kb-settings-tree-status {
  flex-shrink: 0;
}

.kb-settings-tree-root-drop {
  margin-top: 10px;
  padding: 10px;
  border: 1px dashed var(--border);
  border-radius: 8px;
  text-align: center;
  font-size: 12px;
  color: var(--text-secondary);
}

.kb-settings-tree-root-drop.drop-target {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-color: var(--accent);
  color: var(--accent);
}

.kb-search-headline mark {
  background: color-mix(in srgb, var(--warning) 45%, transparent);
  color: inherit;
  border-radius: 2px;
  padding: 0 1px;
}

.kb-version-preview-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
  padding: 10px 14px;
  border: 1px solid var(--warning);
  border-radius: 8px;
  background: color-mix(in srgb, var(--warning) 12%, transparent);
}

.kb-version-preview-banner strong {
  font-size: 13px;
}

.kb-version-preview-actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.link-btn {
  appearance: none;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--accent);
  cursor: pointer;
}

.link-btn:hover {
  text-decoration: underline;
}

/* Release timeline — a Gantt-style row per Change Request. Bar position/width is computed
   server-side (see _release_timeline in views.py), same approach as the SLA bar, so this is
   just plain positioned divs, no charting library. */
.release-timeline-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  font-size: 12px;
  color: var(--text-secondary);
}

.release-timeline-legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
}

.release-timeline-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
}

.release-timeline-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}

.release-timeline-row:last-child {
  border-bottom: none;
}

.release-timeline-label {
  flex: 0 0 240px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 12px;
}

.release-timeline-label a {
  color: var(--accent);
  font-weight: 600;
}

.release-timeline-desc {
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.release-timeline-dates {
  color: var(--text-secondary);
  font-size: 11px;
}

.release-timeline-track {
  position: relative;
  flex: 1 1 auto;
  height: 24px;
  background: var(--input-bg);
  border-radius: 4px;
}

.release-timeline-bar {
  appearance: none;
  position: absolute;
  top: 2px;
  bottom: 2px;
  border: none;
  border-radius: 4px;
  display: flex;
  align-items: center;
  padding: 0 8px;
  overflow: hidden;
  white-space: nowrap;
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  color: #fff;
  cursor: grab;
  touch-action: none;
}

/* An overview bar (Releases-page all-releases Timeline) is a plain click target, not a drag
   handle like a per-release change bar is — no grab cursor. */
button.release-timeline-bar {
  cursor: pointer;
}

.release-timeline-bar.dragging {
  cursor: grabbing;
  opacity: 0.85;
  z-index: 5;
}

/* Edge handles for resizing a bar's start/end independently (drag the bar body itself to move the
   whole window - see release_detail.html's pointer handlers for the mode split). Thin, invisible
   hit targets rather than a visible grip - the resize cursor on hover is the only affordance
   needed, matching how the rest of this timeline stays visually quiet. */
.release-timeline-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 8px;
  cursor: ew-resize;
  touch-action: none;
}
.release-timeline-handle-start { left: 0; }
.release-timeline-handle-end { right: 0; }

/* Status-change dropdown trigger on a bar - hidden until hover so the bars stay visually quiet
   at rest, same idea as the edge handles above. margin-left:auto pins it to the bar's right edge
   regardless of label length/bar width (the bar is a flex row) - it lands right up against the
   8px edge-resize handle's zone, never under it, since flex content already stops at the bar's
   own right padding. */
.release-timeline-status-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  margin-left: auto;
  padding: 0;
  border: none;
  background: rgba(255, 255, 255, 0.25);
  border-radius: 3px;
  color: inherit;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s;
  flex-shrink: 0;
}
.release-timeline-status-toggle svg { width: 11px; height: 11px; }
.release-timeline-bar:hover .release-timeline-status-toggle,
.release-timeline-status-toggle.open {
  opacity: 1;
}
.release-timeline-status-toggle:hover {
  background: rgba(255, 255, 255, 0.45);
}

/* The dropdown itself is a single shared element appended to <body> and repositioned per click
   (see release_detail.html) rather than one pre-rendered per bar, so it's never clipped by an
   ancestor's overflow/positioning and there's no per-row markup cost. */
.release-timeline-status-menu {
  display: none;
  position: absolute;
  z-index: 100;
  min-width: 160px;
  padding: 6px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
}
.release-timeline-status-menu.open { display: block; }
.release-timeline-status-option {
  display: block;
  width: 100%;
  text-align: left;
  padding: 7px 10px;
  border: none;
  background: none;
  border-radius: 5px;
  font-family: inherit;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
}
.release-timeline-status-option:hover { background: var(--bg); }
.release-timeline-status-option.current { font-weight: 600; color: var(--accent); }

/* One square per day, not just a divider line - each cell gets its own right border so the whole
   day's width reads as a distinct box to drag/click onto, not just an edge. */
.release-timeline-gridline {
  position: absolute;
  top: 0;
  bottom: 0;
  border-right: 1px solid var(--border);
  box-sizing: border-box;
}

.release-timeline-bar.status-good { background: var(--success); }
.release-timeline-bar.status-warning { background: var(--warning); }
.release-timeline-bar.status-critical { background: var(--danger); }
.release-timeline-bar.status-neutral { background: var(--text-secondary); }

.release-timeline-swatch.status-good { background: var(--success); }
.release-timeline-swatch.status-warning { background: var(--warning); }
.release-timeline-swatch.status-critical { background: var(--danger); }
.release-timeline-swatch.status-neutral { background: var(--text-secondary); }

.release-timeline-axis-row {
  border-bottom: none;
  padding-bottom: 4px;
}

.release-timeline-axis-track {
  background: none;
  height: 16px;
}

.release-timeline-daycell {
  position: absolute;
  top: 0;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border-left: 1px solid var(--border);
  padding-left: 3px;
  box-sizing: border-box;
}

/* Coarser 5-point axis for the all-releases overview (Releases page Timeline view), which can
   span months — a per-day grid there would be too dense to read, unlike a single release's. */
.release-timeline-axis-tick {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
}

.release-timeline-axis-tick:first-child {
  transform: translateX(0);
}

.release-timeline-axis-tick:last-child {
  transform: translateX(-100%);
}

.release-view {
  display: none;
}

.release-view.active {
  display: block;
}

/* "Expand" on the Change Requests card — lifts it out of the normal page flow into a full-
   viewport overlay so a wide timeline has real room, without needing a separate page/route. */
.release-panel-expanded {
  position: fixed;
  inset: 16px;
  z-index: 200;
  overflow-y: auto;
  box-shadow: 0 8px 40px rgba(0, 0, 0, 0.5);
}

/* ---------- AI Chat widget (draft shell — Customer Portal + ticket page) ---------- */
.ai-chat-widget {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 150;
}

.ai-chat-fab {
  border-radius: 50%;
  border: none;
  background: var(--accent);
  color: var(--accent-text);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: var(--shadow);
}

.ai-chat-fab:hover {
  filter: brightness(1.08);
}

/* Size is a per-chat setting (Customer Portal / Ticket each pick their own) — "Small" is the
   default, well under the original fixed 56px, per explicit feedback that it read as too big. */
.ai-chat-fab-small {
  width: 40px;
  height: 40px;
}

.ai-chat-fab-small svg {
  width: 18px;
  height: 18px;
}

.ai-chat-fab-medium {
  width: 48px;
  height: 48px;
}

.ai-chat-fab-medium svg {
  width: 22px;
  height: 22px;
}

.ai-chat-fab-large {
  width: 56px;
  height: 56px;
}

.ai-chat-fab-large svg {
  width: 26px;
  height: 26px;
}

.ai-chat-panel {
  display: none;
  flex-direction: column;
  position: absolute;
  right: 0;
  bottom: 68px;
  width: 320px;
  height: 420px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  overflow: hidden;
}

.ai-chat-panel.open {
  display: flex;
}

.ai-chat-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
  flex-shrink: 0;
}

.ai-chat-header-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

.ai-chat-header-btn {
  width: 26px;
  height: 26px;
}

.ai-chat-header-btn svg {
  width: 13px;
  height: 13px;
}

.ai-chat-panel-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ai-chat-bubble {
  max-width: 80%;
  padding: 8px 12px;
  border-radius: 12px;
  font-size: 13px;
  line-height: 1.4;
  word-wrap: break-word;
}

.ai-chat-bubble-user {
  align-self: flex-end;
  background: var(--accent);
  color: var(--accent-text);
  border-bottom-right-radius: 2px;
}

.ai-chat-bubble-bot {
  align-self: flex-start;
  background: var(--bg);
  border: 1px solid var(--border);
  border-bottom-left-radius: 2px;
}

.ai-chat-panel-footer {
  display: flex;
  gap: 8px;
  padding: 10px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}

/* Approve/Reject on the AI action proposal card — the chat bubble is only ~260px wide, so even
   the app's normal small button height reads oversized here; an explicit exception, not tied to
   the shared --btn-height. */
.ai-chat-action-btn {
  height: 26px;
  padding: 0 10px;
  font-size: 12px;
}

.ai-chat-panel-footer input {
  flex: 1;
  min-width: 0;
  box-sizing: border-box;
  background: var(--input-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
}

.ai-chat-panel-footer input:focus {
  outline: none;
  border-color: var(--accent);
}

/* ---------- Manage > AI Chat: collapsible settings sections ---------- */
.settings-section {
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 16px;
  max-width: 700px;
  overflow: hidden;
  background: var(--bg-elevated);
}

.settings-section-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  cursor: pointer;
  user-select: none;
}

.settings-section-chevron {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--text-secondary);
  transition: transform 0.15s;
}

.settings-section.open .settings-section-chevron {
  transform: rotate(90deg);
}

.settings-section-title {
  font-weight: 600;
}

.settings-section-summary {
  font-size: 12px;
  color: var(--text-secondary);
  margin-left: auto;
}

.settings-section-header .toggle-switch {
  margin-left: 10px;
}

.ai-actions-warning {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 12px;
  line-height: 1.45;
}

.ai-actions-warning > strong {
  font-size: 13px;
}

.settings-section-body {
  display: none;
  padding: 0 16px 16px;
  border-top: 1px solid var(--border);
}

.settings-section.open .settings-section-body {
  display: block;
  padding-top: 16px;
}
