/* =========================================================================
   Feature-panel styling: settings editors, lists, leaderboards, logs,
   overview, accounts, tickets, daily-dono. Depends on tokens/components.
   ========================================================================= */

/* nested card inside a card (used for grouped toggle rows) */
.card .card { box-shadow: none; background: var(--bg-card-2); }
.card .card .toggle-row { padding-left: var(--s-4); padding-right: var(--s-4); }

.action-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); margin-top: var(--s-4); }
.action-row .btn { margin-left: auto; }
.action-status { color: var(--text-2); font-size: var(--fs-sm); }
.action-status.ready { color: var(--success); }
.form-row { display: flex; flex-wrap: wrap; gap: var(--s-4); }

/* send-message embed field grid + Discord-style live preview */
.embed-fields-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); margin: var(--s-3) 0; padding: var(--s-3); border-radius: var(--r-sm); background: var(--bg-card-2); }
.embed-fields-grid .field.wide { grid-column: 1 / -1; }
.embed-fields-grid input[type="color"] { width: 100%; height: 38px; padding: 2px; border-radius: var(--r-sm); border: 1px solid var(--border); background: transparent; cursor: pointer; }
.embed-extra-fields-list { display: flex; flex-direction: column; gap: var(--s-2); margin-bottom: var(--s-2); }
.embed-extra-field-row { display: grid; grid-template-columns: 1fr 2fr auto auto; gap: var(--s-2); align-items: start; padding: var(--s-2); border-radius: var(--r-sm); background: var(--bg-card); }
.embed-extra-field-row .field.wide { grid-column: unset; }
.embed-extra-field-inline { display: flex; align-items: center; gap: 4px; white-space: nowrap; font-size: var(--fs-sm); color: var(--text-2); }

.dm-preview-embed-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 8px 0; }
.dm-preview-embed-fields:empty { display: none; }
.dm-preview-embed-field { grid-column: 1 / -1; }
.dm-preview-embed-field.inline { grid-column: span 1; }
.dm-preview-embed-field-name { color: var(--text); font-size: var(--fs-sm); font-weight: 600; }
.dm-preview-embed-field-value { color: var(--text-2); font-size: var(--fs-sm); white-space: pre-wrap; overflow-wrap: anywhere; }

.dm-preview { display: flex; gap: var(--s-3); padding: var(--s-3); border-radius: var(--r-sm); background: var(--bg-card-2); }
.dm-preview-avatar { flex: none; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--brand, #5865f2); color: #fff; font-weight: 700; }
.dm-preview-body { min-width: 0; flex: 1; }
.dm-preview-head { display: flex; align-items: baseline; gap: 7px; margin-bottom: 3px; }
.dm-preview-name { color: var(--text); font-size: var(--fs-sm); }
.dm-preview-tag { padding: 1px 4px; border-radius: 3px; background: var(--brand, #5865f2); color: #fff; font-size: 10px; font-weight: 700; line-height: 15px; text-transform: uppercase; }
.dm-preview-time { color: var(--text-muted); font-size: var(--fs-xs); }
.dm-preview-content { color: var(--text-2); font-size: var(--fs-sm); white-space: pre-wrap; overflow-wrap: anywhere; margin-bottom: 4px; }
.dm-preview-mention { padding: 0 2px; border-radius: 3px; background: rgba(88, 101, 242, 0.3); color: #c9cdfb; font-weight: 500; }
.dm-preview-content .md-spoiler, .dm-preview-embed-desc .md-spoiler { padding: 0 2px; border-radius: 3px; background: #1a1a1e; color: transparent; cursor: pointer; transition: color 0.1s; }
.dm-preview-content .md-spoiler:hover, .dm-preview-embed-desc .md-spoiler:hover { color: inherit; }
.dm-preview-content .md-code-inline, .dm-preview-embed-desc .md-code-inline { padding: 0 3px; border-radius: 3px; background: rgba(0, 0, 0, 0.3); font-family: var(--font-mono, monospace); font-size: 0.9em; }
.dm-preview-content .md-code-block, .dm-preview-embed-desc .md-code-block { margin: 4px 0; padding: 6px 8px; border-radius: 4px; background: rgba(0, 0, 0, 0.35); font-family: var(--font-mono, monospace); font-size: 0.85em; overflow-x: auto; white-space: pre; }
.dm-preview-content .md-quote, .dm-preview-embed-desc .md-quote { display: block; padding-left: 8px; border-left: 3px solid var(--text-muted); color: var(--text-muted); }
.dm-preview-content .md-h1, .dm-preview-embed-desc .md-h1 { display: block; font-size: 1.25em; font-weight: 700; }
.dm-preview-content .md-h2, .dm-preview-embed-desc .md-h2 { display: block; font-size: 1.1em; font-weight: 700; }
.dm-preview-content .md-h3, .dm-preview-embed-desc .md-h3 { display: block; font-size: 1em; font-weight: 700; }
.dm-preview-embed { --embed-color: #5865f2; display: grid; grid-template-columns: minmax(0, 1fr) auto; width: min(440px, 100%); margin-top: 4px; overflow: hidden; border-left: 4px solid var(--embed-color); border-radius: 4px; background: var(--bg-card); }
.dm-preview-embed-main { min-width: 0; padding: 10px 12px; }
.dm-preview-embed-title { color: var(--text); font-size: var(--fs-sm); font-weight: 600; margin-bottom: 4px; }
.dm-preview-embed-desc { color: var(--text-2); font-size: var(--fs-sm); white-space: pre-wrap; overflow-wrap: anywhere; }
.dm-preview-embed-image { display: block; max-width: 100%; max-height: 220px; margin-top: 8px; border-radius: 4px; object-fit: contain; }
.dm-preview-embed-footer { margin-top: 8px; color: var(--text-muted); font-size: var(--fs-xs); }
.dm-preview-embed-thumb { width: 64px; height: 64px; margin: 10px 10px 0 0; border-radius: 4px; object-fit: cover; }

/* ---- compact settings navigation ---- */
.settings-tabs-shell { min-width: 0; }
.settings-tabs {
  position: sticky;
  top: calc(var(--topbar-h) + var(--s-3));
  z-index: 12;
  display: flex;
  gap: var(--s-1);
  min-height: 44px;
  padding: var(--s-1);
  overflow-x: auto;
  background: color-mix(in srgb, var(--bg-elevated) 97%, var(--bg) 3%);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-md);
  scrollbar-width: none;
  isolation: isolate;
}
.settings-tabs::-webkit-scrollbar { display: none; }
.settings-tabs::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: var(--s-1);
  bottom: var(--s-1);
  left: 0;
  width: var(--tab-w, 0px);
  border-radius: var(--r-xs);
  background: linear-gradient(135deg, var(--red-bright), var(--red));
  box-shadow: 0 5px 16px -8px var(--red-glow-strong);
  transform: translateX(var(--tab-x, 0px));
  transition: transform 340ms var(--ease-out), width 340ms var(--ease-out), opacity var(--t);
  opacity: 0;
}
.settings-tabs:has(.settings-tab.active)::before { opacity: 1; }
.settings-tab {
  position: relative;
  z-index: 1;
  flex: 1 0 84px;
  min-height: 34px;
  padding: 7px 14px;
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--text-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: color var(--t), background var(--t), box-shadow var(--t), transform var(--t);
}
.settings-tab:hover { color: var(--text); background: var(--bg-hover); }
.settings-tab.active {
  color: var(--text-on-red);
  background: transparent;
  box-shadow: none;
}
.settings-tab:active { transform: translateY(1px); }
.settings-tab-panes {
  position: relative;
  margin-top: var(--s-4);
  overflow-anchor: none;
}
.settings-tab-panes.is-resizing {
  /* Dropdown menus are allowed to escape while the pane height settles. */
  overflow: visible;
  transition: height 260ms cubic-bezier(0.22, 0.76, 0.28, 1);
  will-change: height;
}
.settings-tab-panel {
  scroll-margin-top: calc(var(--topbar-h) + 60px);
  animation: settingsPaneIn 240ms cubic-bezier(0.22, 0.76, 0.28, 1);
}
.settings-tab-panes.is-switching .settings-tab-panel.is-leaving {
  position: absolute;
  inset: 0 0 auto;
  width: 100%;
  pointer-events: none;
  animation: settingsPaneOut 150ms cubic-bezier(0.4, 0, 1, 1) forwards;
}
.settings-tab-panes.is-switching .settings-tab-panel.is-entering {
  position: relative;
  z-index: 1;
  animation: settingsPaneIn 240ms cubic-bezier(0.22, 0.76, 0.28, 1) both;
}
.settings-tab-panel > * + * { margin-top: var(--s-4); }
.settings-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 470px), 1fr));
  align-items: stretch;
  gap: var(--s-4);
  container-type: inline-size;
}
.settings-card-grid > * { min-width: 0; height: 100%; margin-top: 0 !important; }
.settings-card-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }

/* Keep Rules balanced: the compact regex editor lives directly below overrides. */
@media (min-width: 960px) {
  .settings-tab-panel.automod-rules-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
    gap: var(--s-4);
  }
  .settings-tab-panel.automod-rules-layout > * { min-width: 0; margin-top: 0 !important; }
}
.automod-rules-stack { display: flex; flex-direction: column; gap: var(--s-4); min-width: 0; }

/* Each detector stays grouped, using the same neutral editor treatment as other settings. */
.automod-spam-card { padding: var(--s-5); }
.automod-spam-card .card-head { margin-bottom: var(--s-4); }
/* A 2-col CSS grid locks every card to a row track shared with its opposite
   number, so a toggled-on card (taller, extra field row) forces blank space
   under its shorter row-mate. CSS multi-column flow avoids the row-lock but
   rebalances items across columns by height, scrambling the left/right
   pairing. Two independent flex columns (built in JS, alternating items)
   keep the original left/right order and let each column stack to its own
   natural height. */
.spam-signal-grid { display: flex; gap: var(--s-4); align-items: flex-start; }
.spam-signal-col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--s-4); }
.spam-signal {
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-card-2);
  transition: border-color var(--t), background var(--t);
}
.spam-signal:hover { border-color: var(--border-strong); background: var(--bg-hover); }
.spam-signal:has(input:checked) { border-color: var(--border-strong); }
.spam-signal .toggle-row { min-height: 60px; margin: 0; padding: 12px var(--s-4); border: 0; }
.spam-signal .toggle-row .t-name { font-size: var(--fs-sm); }
.spam-signal .toggle-row .t-desc { margin-top: 2px; font-size: var(--fs-xs); }
.spam-signal-controls { margin: 0 !important; border-top: 1px solid var(--border); }
.spam-signal-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4) var(--s-4);
}
.spam-signal-fields .field { margin: 0; }
.spam-signal-fields .field label { margin-bottom: 5px; font-size: var(--fs-xs); }
.spam-signal-fields .field input { min-height: 36px; padding: 8px 10px; }

/* Repeat escalation reads as one small policy rather than five unrelated fields. */
.automod-escalation-card {
  padding: var(--s-4);
  background:
    linear-gradient(135deg, rgba(229, 57, 69, 0.07), transparent 42%),
    linear-gradient(180deg, var(--bg-card), var(--bg-card-2));
}
.automod-escalation-card .card-head { display: block; margin-bottom: var(--s-3); }
.automod-escalation-card .card-head h3 { font-size: var(--fs-lg); }
.automod-escalation-card .card-sub { margin-top: 5px; max-width: 62ch; }
.automod-escalation-card .toggle-row {
  min-height: 54px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--bg-input);
}
.automod-escalation-card .toggle-row .t-name { font-size: var(--fs-sm); }
.automod-escalation-card .toggle-row .t-desc { font-size: var(--fs-xs); }
.automod-escalation-card .grid-2 { gap: var(--s-2); }
.automod-escalation-card .field { margin: 0; }
.automod-escalation-card .field label { margin-bottom: 5px; font-size: var(--fs-xs); }
.automod-escalation-card .field input { min-height: 36px; padding: 8px 10px; }

/* Suspicious activity is a compact monitoring policy with no unused grid cells. */
.claim-suspicious-card {
  padding: var(--s-4);
  background:
    linear-gradient(135deg, rgba(229, 57, 69, 0.05), transparent 42%),
    linear-gradient(180deg, var(--bg-card), var(--bg-card-2));
}
.claim-suspicious-card .card-head { display: block; margin-bottom: var(--s-3); }
.claim-suspicious-card .card-head h3 { font-size: var(--fs-lg); }
.claim-suspicious-card .card-sub { margin-top: 5px; }
.claim-suspicious-card .toggle-row {
  min-height: 50px;
  margin-bottom: var(--s-2);
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--bg-input);
}
.claim-suspicious-card .toggle-row .t-name { font-size: var(--fs-sm); }
.claim-suspicious-card .toggle-row .t-desc { font-size: var(--fs-xs); }
.claim-suspicious-card .grid-3 { gap: var(--s-2); }
.claim-suspicious-card .field { margin: 0; }
.claim-suspicious-card .field label { margin-bottom: 5px; font-size: var(--fs-xs); }
.claim-suspicious-card .field input { min-height: 36px; padding: 8px 10px; }

/* Welcome and leave are independent message flows, shown side by side. */
.greetings-settings-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
  gap: var(--s-4);
}
.greetings-settings-grid > .card { min-width: 0; }
.greetings-settings-grid > .card .toggle-row { margin-top: 0; }

@media (max-width: 720px) {
  /* Unwrap the two columns instead of stacking column1-then-column2 (which
     would reorder items 0,2,4,1,3,5) -- children fall back to the card's
     normal single-column flow in original 0..5 order. */
  .spam-signal-grid, .spam-signal-col { display: contents; }
  .spam-signal { margin-top: var(--s-4); }
  .claim-suspicious-card .grid-3 { grid-template-columns: 1fr; }
  .greetings-settings-grid { grid-template-columns: 1fr; }
}
@keyframes settingsPaneIn {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}
@keyframes settingsPaneOut {
  from { opacity: 1; transform: none; }
  to { opacity: 0; transform: translateY(-3px); }
}

/* ---- automod override editor ---- */
.override-editor, .regex-editor { display: flex; flex-direction: column; gap: var(--s-2); width: 100%; }
.override-list, .regex-list { display: flex; flex-direction: column; gap: var(--s-2); }
.override-row, .regex-row { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.override-target { flex: 1; min-width: 140px; min-height: 38px; display: flex; align-items: center; font-size: var(--fs-sm); background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--r-sm); padding: 0 12px; }
.override-action-select, .regex-action, .regex-severity { width: 132px; flex: none; }
.override-remove { width: 38px; height: 38px; flex: none; display: grid; place-items: center; border: 1px solid var(--border); border-radius: var(--r-sm); background: transparent; color: var(--text-2); cursor: pointer; font-size: 17px; line-height: 1; transition: background var(--t), color var(--t), border-color var(--t); }
.override-remove:hover { background: var(--error-bg); color: var(--error); border-color: var(--error); }
.override-empty, .regex-empty { padding: var(--s-1) 0; }
.override-add { display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap; padding-top: var(--s-3); }
.override-picker { flex: 1; min-width: 160px; }
/* keep the add button the same height as the pickers next to it */
.override-add-btn { height: 38px; padding: 0 16px; flex: none; }
.regex-pattern { flex: 1; min-width: 180px; }
.regex-pattern.invalid { border-color: var(--error); box-shadow: 0 0 0 3px var(--error-bg); }
.regex-enabled { flex: none; }
.regex-add-btn { align-self: flex-start; }

/* ---- automod bypass grid (and any other grouped-toggle grid) ---- */
.bypass-grid, .toggle-group-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--s-4); }
.bypass-group, .toggle-group { background: var(--bg-card-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-4); display: flex; flex-direction: column; gap: var(--s-3); }
.bypass-grid > .bypass-group, .toggle-group-grid > .toggle-group { height: 100%; }
.bypass-group h4, .toggle-group h4 { font-size: var(--fs-md); color: var(--red-bright); }
.bypass-row { display: flex; flex-direction: column; gap: var(--s-2); padding-bottom: var(--s-3); border-bottom: 1px solid var(--border); }
.bypass-row:last-child { padding-bottom: 0; border-bottom: none; }
.bypass-row-label { font-size: var(--fs-sm); font-weight: 600; color: var(--text-2); }
.bypass-row .field { margin: 0; }
.bypass-row .field label { font-size: var(--fs-xs); color: var(--text-muted); }

/* ---- automod tester ---- */
.tester-card { background: var(--bg-card-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-4); }
.automod-test-result { display: flex; flex-direction: column; gap: var(--s-2); margin-top: var(--s-2); }
/* One tester hit: rule name + badge on top, then why it matched. Stacked
   rather than one line, since the explanation is the point of the tester. */
.test-hit {
  display: flex; flex-direction: column; gap: 4px;
  padding: var(--s-2) var(--s-3);
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-left: 3px solid var(--red-bright);
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
}
.test-hit-head { display: flex; align-items: center; gap: var(--s-2); }
.test-hit-rule { font-weight: 600; }
.test-hit-detail { color: var(--text); }
.test-hit-why { color: var(--text-muted); line-height: 1.45; }
.test-hit code {
  padding: 1px 5px;
  border-radius: var(--r-xs);
  background: var(--red-tint);
  color: var(--red-bright);
  font-size: 0.94em;
  word-break: break-word;
}

/* ---- role grids (allowed roles / role give) ---- */
.role-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--s-4); }
.role-card { background: var(--bg-card-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-4); display: flex; flex-direction: column; gap: var(--s-3); }
.role-card h4 { font-size: var(--fs-md); }
/* Title + remove button share a row; the title truncates rather than pushing
   the button out of the card when a role name (or a raw id) is long. */
.role-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); }
.role-card-head h4 { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.role-card-head .access-rule-btn { flex: 0 0 auto; }
.add-role-card { border-style: dashed; }

/* ---- leaderboard / list rows ---- */
.lb-list { display: flex; flex-direction: column; gap: 7px; }
.lb-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--s-3); margin-bottom: var(--s-4); flex-wrap: wrap; }
.lb-kicker { margin-bottom: 4px; color: var(--red-bright); font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0; text-transform: uppercase; }
.lb-kicker.is-offline { color: var(--text-muted); }
.lb-head h1 { font-size: clamp(1.6rem, 3vw, 2.25rem); }
.lb-summary { flex: none; padding: 7px 10px; border: 1px solid var(--border-red); border-radius: 999px; background: var(--red-tint); color: var(--red-bright); font-size: var(--fs-xs); font-weight: 700; font-variant-numeric: tabular-nums; }
.lb-pager { display: flex; align-items: center; gap: var(--s-3); justify-content: flex-end; margin-top: var(--s-4); }
.lb-row {
  display: grid; grid-template-columns: 46px 34px minmax(0, 1fr) minmax(150px, 220px); align-items: center; gap: var(--s-3);
  position: relative; overflow: hidden;
  background: var(--bg-card-2); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 10px 16px;
  transition: border-color var(--t), background var(--t), transform var(--t);
  content-visibility: auto;
  contain-intrinsic-size: auto 58px;
}
.lb-row:hover { border-color: var(--border-red); background: var(--bg-hover); transform: translateX(2px); }
.weekly-lb-row { width: 100%; color: var(--text); text-align: left; cursor: pointer; font: inherit; }
.weekly-lb-row:focus-visible { outline: 2px solid var(--red-bright); outline-offset: 2px; }
.lb-search { width: min(100%, 360px); }
.xp-profile-head { display: flex; align-items: center; gap: var(--s-3); }
.xp-profile-head > div { min-width: 0; display: flex; flex-direction: column; }
.xp-profile-head strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.xp-profile-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2); }
.xp-profile-stat { display: flex; flex-direction: column; gap: 3px; padding: var(--s-3); border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--bg-card-2); }
.xp-profile-stat small { color: var(--text-2); }
.xp-profile-stat strong { font-size: var(--fs-md); font-variant-numeric: tabular-nums; }
.xp-level-progress { display: flex; flex-direction: column; gap: 7px; }
.xp-level-progress-label { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); color: var(--text-2); font-size: var(--fs-xs); }
.xp-level-progress-label strong { color: var(--text); font-weight: 650; font-variant-numeric: tabular-nums; text-align: right; }
.xp-level-track { height: 7px; overflow: hidden; border-radius: 999px; background: var(--border); }
.xp-level-track span { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--red-hover), var(--red-bright)); transition: width 300ms var(--ease-out); }
/* The Squad Log keeps its toolbar fixed while a newly selected tab's results
   rise into place. This remains enabled in reduced-motion Windows/RDP
   sessions for consistency with the explicitly requested page transitions. */
.squad-tab-content.is-entering { animation: squadTabIn 300ms cubic-bezier(0.22, 0.76, 0.28, 1) both; }
@keyframes squadTabIn {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}
/* Squad Log rows stagger in on every tab switch / search / refresh (see
   squad.js, which sets --row-i per row) -- other .lb-row users (weekly/staff
   leaderboards) are unaffected since only squad.js adds this class. */
.lb-row.squad-row-in {
  animation: fadeUp 320ms var(--ease-out) both;
  animation-delay: calc(min(var(--row-i, 0), 14) * 22ms);
}
/* Animating an entire 100+ member roster creates a large burst of compositor
   work for rows that are not visible. Keep the entrance treatment to the
   initial viewport; later rows are rendered lazily as the user scrolls. */
.lb-list .squad-row-in:nth-child(n + 21) { animation: none; }
/* Rows with no rank/avatar (squad log has neither) -- name + stats only. */
.lb-row.lb-row-simple { grid-template-columns: minmax(0, 1fr) minmax(150px, 220px); }
/* Squad log's Members tab, owner view -- adds a 3rd column for the
   promote/demote/kick action group. */
.lb-row.lb-row-simple.has-actions { grid-template-columns: minmax(0, 1fr) minmax(120px, 180px) auto; }
.squad-row-actions { display: flex; align-items: center; gap: 6px; justify-content: flex-end; }
/* Staff leaderboard, owner view -- hide/delete buttons after the stats cell. */
.lb-row.has-actions { grid-template-columns: 46px 34px minmax(0, 1fr) minmax(120px, 180px) auto; }
.lb-row-actions { display: flex; align-items: center; gap: 6px; justify-content: flex-end; }
.lb-note { margin-bottom: var(--s-3); }
.squad-icon-flip { transform: rotate(180deg); }
/* Rows with a rank but no avatar (squad log Points tab). */
.lb-row.lb-row-ranked { grid-template-columns: 46px minmax(0, 1fr) minmax(150px, 220px); }
.lb-rank { display: grid; place-items: center; width: 38px; height: 30px; border-radius: var(--r-xs); background: var(--red-tint); color: var(--red-bright); font-size: var(--fs-sm); font-weight: 750; font-variant-numeric: tabular-nums; }
.lb-top { border-color: rgba(229, 57, 69, 0.38); background: linear-gradient(90deg, rgba(229, 57, 69, 0.09), var(--bg-card-2) 30%); }
.lb-top .lb-rank { color: var(--text); background: var(--red); }
.lb-top-1 .lb-rank { box-shadow: 0 0 18px rgba(229, 57, 69, 0.35); }
.lb-name { min-width: 0; display: flex; flex-direction: column; }
.lb-name strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-name small { color: var(--text-2); font-size: var(--fs-xs); }
.squad-name-row { display: flex; align-items: center; gap: 7px; min-width: 0; }
.squad-name-row strong { min-width: 0; }
.squad-leader-row {
  isolation: isolate;
  border-color: rgba(231, 190, 88, 0.38);
  background: linear-gradient(90deg, rgba(202, 157, 54, 0.1), var(--bg-card-2) 38%);
}
/* Overrides the generic .lb-row:hover red border -- the leader row goes
   shinier gold on hover instead, not red like every other row. */
.lb-row.squad-leader-row:hover {
  border-color: rgba(255, 222, 133, 0.85);
  background: linear-gradient(90deg, rgba(212, 168, 60, 0.18), var(--bg-card-2) 38%);
  box-shadow: 0 0 22px rgba(231, 190, 88, 0.35);
}
.squad-retired-leader-row {
  isolation: isolate;
  border-color: rgba(0, 255, 255, 0.4);
  background: linear-gradient(90deg, rgba(0, 255, 255, 0.13), #000 38%);
}
.lb-row.squad-retired-leader-row:hover {
  border-color: rgba(0, 255, 255, 0.9);
  background: linear-gradient(90deg, rgba(0, 255, 255, 0.22), #000 38%);
  box-shadow: 0 0 22px rgba(0, 255, 255, 0.34);
}
.squad-retired-leader-row::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: 0;
  bottom: 0;
  left: -42%;
  width: 34%;
  pointer-events: none;
  background: linear-gradient(105deg, transparent, rgba(0, 255, 255, 0.14) 42%, rgba(210, 255, 255, 0.4) 50%, rgba(0, 255, 255, 0.14) 58%, transparent);
  transform: translate3d(0, 0, 0) skewX(-12deg);
  animation: squadRetiredLeaderRowSweep 3.8s linear infinite;
}
.squad-retired-leader-row > * { position: relative; z-index: 1; }
@keyframes squadRetiredLeaderRowSweep {
  to { transform: translate3d(430%, 0, 0) skewX(-12deg); }
}
.squad-leader-row::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: 0;
  bottom: 0;
  left: -42%;
  width: 34%;
  pointer-events: none;
  background: linear-gradient(105deg, transparent, rgba(255, 222, 133, 0.12) 42%, rgba(255, 245, 207, 0.24) 50%, rgba(255, 222, 133, 0.12) 58%, transparent);
  transform: translate3d(0, 0, 0) skewX(-12deg);
  animation: squadLeaderRowSweep 3.8s linear infinite;
}
.squad-leader-row > * { position: relative; z-index: 1; }
@keyframes squadLeaderRowSweep {
  to { transform: translate3d(430%, 0, 0) skewX(-12deg); }
}
.squad-leader-crown {
  position: relative;
  z-index: 1;
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 22px;
  height: 22px;
  color: #f4c95d;
  filter: drop-shadow(0 2px 4px rgba(244, 185, 51, 0.3));
  transform-origin: 50% 75%;
  animation: squadCrownFloat 2.6s ease-in-out infinite;
}
.squad-leader-crown svg { stroke-width: 1.75; }
@keyframes squadCrownFloat {
  0%, 100% { transform: translateY(0) rotate(-3deg); }
  50% { transform: translateY(-2px) rotate(3deg); }
}
.squad-rank-badge { flex: none; padding: 1px 7px; border-radius: 999px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; color: var(--text-2); background: var(--bg-hover); border: 1px solid var(--border); }
.squad-verified-badge { flex: none; display: inline-flex; align-items: center; gap: 3px; padding: 1px 7px 1px 5px; border-radius: 999px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; color: #7ee0a8; background: rgba(46, 204, 113, 0.12); border: 1px solid rgba(46, 204, 113, 0.35); }
/* Leader-tier only (real Leader + the honorary Vice) -- the tilted blue
   checkmark badge instead of the classic green pill everyone else gets. */
.squad-verified-badge-icon { flex: none; display: inline-flex; align-items: center; }
.squad-rank-2 { color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55); border-color: rgba(158, 107, 255, 0.5); background: linear-gradient(135deg, #9e6bff, #222b3b); }
/* Elder+ (rank 3+) get progressively more emphasis -- the ranks that
   actually carry kick/promote/demote authority in-game. */
.squad-rank-3 { color: #f1f7ff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); border-color: rgba(241, 247, 255, 0.35); background: linear-gradient(135deg, #020202, #f1f7ff); }
.squad-rank-4 { color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55); border-color: rgba(249, 0, 54, 0.5); background: linear-gradient(135deg, #f90036, #060000); }
.squad-rank-retired { color: #f1f7ff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7); border-color: rgba(0, 255, 255, 0.58); background: linear-gradient(135deg, #00ffff, #000000); }
/* Leader: a stable gold base with an off-screen-to-off-screen light pass.
   Transform-only motion keeps the loop smooth and cheap to composite. */
.squad-rank-5 {
  position: relative;
  overflow: hidden;
  color: #2e2003;
  border-color: rgba(212, 175, 90, 0.6);
  background: linear-gradient(135deg, #f0cd70, #bc8b29);
  box-shadow: inset 0 1px rgba(255, 246, 205, 0.45), 0 2px 8px rgba(177, 123, 20, 0.18);
}
.squad-rank-5::after {
  content: "";
  position: absolute;
  top: -30%;
  bottom: -30%;
  left: -65%;
  width: 44%;
  pointer-events: none;
  background: linear-gradient(105deg, transparent, rgba(255, 250, 225, 0.82), transparent);
  transform: translate3d(0, 0, 0) skewX(-15deg);
  animation: squadGoldSweep 2.8s linear infinite;
}
@keyframes squadGoldSweep {
  to { transform: translate3d(410%, 0, 0) skewX(-15deg); }
}
.squad-online { display: inline-flex; align-items: center; gap: 5px; color: #3ddc84; }
.squad-online-dot { width: 6px; height: 6px; border-radius: 50%; background: #3ddc84; box-shadow: 0 0 6px rgba(61, 220, 132, 0.7); }
.squad-presence-detail { color: var(--text-muted); }
.squad-presence-sort-note { margin: calc(var(--s-2) * -1) 0 var(--s-3); }
.squad-audit-status { display: inline-block; padding: 1px 7px; border-radius: 999px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; }
.squad-audit-pending { color: var(--text-2); background: var(--bg-hover); border: 1px solid var(--border); }
.squad-audit-done { color: #3ddc84; background: rgba(61, 220, 132, 0.12); border: 1px solid rgba(61, 220, 132, 0.35); }
.squad-audit-failed { color: var(--red-bright); background: var(--red-tint); border: 1px solid rgba(229, 57, 69, 0.4); }
.squad-audit-actor { display: inline-flex; align-items: baseline; gap: 7px; margin-right: 2px; }
.squad-audit-actor small { color: var(--text-muted); font-size: var(--fs-xs); font-weight: 500; }

.squad-section-title { margin: var(--s-5) 0 var(--s-3); color: var(--text-2); font-size: var(--fs-sm); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; }
.squad-section-title:first-child { margin-top: 0; }
.squad-totals { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-bottom: var(--s-4); }
.squad-total-chip { display: flex; flex-direction: column; gap: 2px; padding: var(--s-3) var(--s-4); border: 1px solid var(--border); border-radius: var(--r-md); background: var(--bg-card-2); min-width: 140px; }
.squad-total-chip small { color: var(--text-2); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.03em; }
.squad-total-chip strong { font-size: 1.1rem; font-variant-numeric: tabular-nums; }
.squad-sort { margin-bottom: var(--s-3); width: fit-content; }
/* War tab -- designed layout mirrors the in-game Squad War GUI; the plain
   key/value grid below is only the leftover/diagnostic fallback (see
   squad.js's drawWar) for whatever GetWarStatus sends that isn't one of
   the recognized fields yet. */
.squad-war-fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--s-2); }
.squad-war-field { display: flex; justify-content: space-between; gap: var(--s-2); padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--bg-card-2); }
.squad-war-field-key { color: var(--text-2); font-size: var(--fs-sm); }
.squad-war-field-value { font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }

.squad-war-card {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: var(--s-4);
  padding: clamp(18px, 3vw, 30px); margin-bottom: var(--s-4);
  border: 1px solid rgba(61, 220, 132, 0.2); border-radius: var(--r-lg);
  background:
    radial-gradient(circle at 14% 5%, rgba(61, 220, 132, 0.13), transparent 34%),
    radial-gradient(circle at 88% 100%, rgba(229, 57, 69, 0.09), transparent 34%),
    linear-gradient(145deg, color-mix(in srgb, var(--bg-card-2) 94%, #0d2318 6%), var(--bg-card-2));
  box-shadow: inset 0 1px rgba(255, 255, 255, 0.025), 0 18px 44px rgba(0, 0, 0, 0.16);
}
.squad-war-trailing { border-color: rgba(229, 57, 69, 0.22); }
.squad-war-tied { border-color: var(--border-strong); }
.squad-war-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.squad-war-title { display: flex; align-items: center; gap: 8px; color: var(--text); font-size: var(--fs-sm); font-weight: 750; letter-spacing: 0.02em; text-transform: uppercase; }
.squad-war-title > svg { color: #e8bd52; }
.squad-war-status { padding: 3px 8px; border-radius: 999px; font-size: 10px; line-height: 1.2; letter-spacing: 0.04em; }
.squad-war-status-winning { color: #5bea99; background: rgba(61, 220, 132, 0.12); border: 1px solid rgba(61, 220, 132, 0.3); }
.squad-war-status-trailing { color: var(--red-bright); background: var(--red-tint); border: 1px solid rgba(229, 57, 69, 0.32); }
.squad-war-status-tied { color: var(--text-2); background: var(--bg-hover); border: 1px solid var(--border); }
.squad-war-matchup { display: grid; grid-template-columns: minmax(0, 1fr) 52px minmax(0, 1fr); align-items: center; gap: var(--s-3); }
.squad-war-team { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.squad-war-team small { color: var(--text-muted); font-size: 10px; font-weight: 650; letter-spacing: 0.08em; text-transform: uppercase; }
.squad-war-team strong { overflow: hidden; color: var(--text); font-size: clamp(1.05rem, 2vw, 1.4rem); line-height: 1.2; text-overflow: ellipsis; white-space: nowrap; }
.squad-war-team-us { align-items: flex-start; text-align: left; }
.squad-war-team-us strong, .squad-war-team-us .squad-war-score { color: #3ddc84; }
.squad-war-team-them { align-items: flex-end; text-align: right; }
.squad-war-score { font-size: clamp(1.4rem, 3vw, 2rem); font-weight: 800; font-variant-numeric: tabular-nums; letter-spacing: -0.03em; }
.squad-war-vs-emblem { display: grid; place-items: center; width: 46px; height: 46px; border: 1px solid var(--border-strong); border-radius: 50%; background: var(--bg-elevated); color: var(--text-2); font-size: 11px; font-weight: 800; letter-spacing: 0.12em; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.22); }
.squad-war-bar { display: flex; width: 100%; height: 18px; border-radius: 999px; overflow: hidden; background: #14161c; border: 1px solid var(--border); box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.28); }
.squad-war-bar-fill {
  display: flex; align-items: center; padding-left: 10px; min-width: 0;
  background: linear-gradient(90deg, #2fbf4f, #3ddc84);
  color: #06210f; font-weight: 800; font-size: 10px;
  white-space: nowrap; transition: width 420ms var(--ease-out);
}
.squad-war-bar-rest { flex: 1; display: flex; align-items: center; justify-content: flex-end; padding-right: 10px; min-width: 0; color: var(--text-2); font-weight: 800; font-size: 10px; }
.squad-war-control { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); margin-top: -9px; font-size: 11px; font-weight: 650; font-variant-numeric: tabular-nums; }
.squad-war-score-us { color: #3ddc84; }
.squad-war-score-them { color: var(--text-2); }
.squad-war-timer { display: inline-flex; flex: none; align-items: center; gap: 7px; padding: 6px 11px; border-radius: 999px; background: rgba(229, 138, 42, 0.1); border: 1px solid rgba(229, 138, 42, 0.28); color: #f0ad54; font-size: var(--fs-sm); font-weight: 750; font-variant-numeric: tabular-nums; }
@media (max-width: 560px) {
  .squad-war-head { align-items: flex-start; }
  .squad-war-title { flex-wrap: wrap; }
  .squad-war-matchup { grid-template-columns: minmax(0, 1fr) 38px minmax(0, 1fr); gap: 8px; }
  .squad-war-vs-emblem { width: 36px; height: 36px; }
  .squad-war-timer { font-size: var(--fs-xs); }
}
.squad-upgrade-group-title { margin: var(--s-4) 0 var(--s-2); color: var(--text); font-size: var(--fs-sm); font-weight: 700; }
.squad-upgrade-group-title:first-of-type { margin-top: 0; }
.squad-upgrade-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--s-3); margin-bottom: var(--s-4); }
.squad-upgrade-card {
  display: flex; flex-direction: column; gap: 8px;
  padding: var(--s-4); border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--bg-card-2);
  animation: fadeUp 320ms var(--ease-out) both;
  animation-delay: calc(min(var(--row-i, 0), 14) * 22ms);
}
.squad-upgrade-card.is-maxed { opacity: 0.7; }
.squad-upgrade-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); }
.squad-upgrade-head strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.squad-upgrade-level-badge { flex: none; padding: 3px 11px; border-radius: 999px; font-size: 13px; font-weight: 800; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; color: var(--text-on-red); background: linear-gradient(135deg, var(--red-hover), var(--red-bright)); box-shadow: 0 2px 8px -2px var(--red-glow-strong, rgba(229, 57, 69, 0.5)); }
.squad-upgrade-level-badge.is-maxed { color: #3a2703; background: linear-gradient(135deg, #b8912f, #e8c774); box-shadow: 0 2px 8px -2px rgba(212, 175, 90, 0.5); text-transform: uppercase; }
.squad-upgrade-bar { display: block; width: 100%; height: 4px; overflow: hidden; border-radius: 999px; background: var(--border); }
.squad-upgrade-bar::before {
  content: ""; display: block; height: 100%; width: var(--fill, 0%);
  border-radius: inherit;
  background: linear-gradient(90deg, var(--red-hover), var(--red-bright));
  transition: width 400ms var(--ease-out);
}
.squad-upgrade-card.is-maxed .squad-upgrade-bar::before { background: linear-gradient(90deg, #b8912f, #e8c774); }
.squad-upgrade-desc { margin: 0; font-size: var(--fs-xs); }
.squad-upgrade-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); margin-top: auto; }
.squad-upgrade-cost { color: var(--text-2); font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
/* Buy button goes green once the squad's current Ticks/SP balance actually
   covers this upgrade's next_cost (see squad.js's drawUpgradeCatalog). */
.btn-affordable { color: #0d2b16; background: #3ddc84; border-color: #3ddc84; }
.btn-affordable:hover { background: #4be894; border-color: #4be894; }
/* Auto-upgrade toggle next to Buy -- refresh-icon button that goes active
   (spinning, accent-colored) once turned on for that upgrade. */
.squad-upgrade-actions { display: flex; align-items: center; gap: 6px; }
.squad-upgrade-actions .btn-icon.is-active { color: var(--red-bright, #ff4d5e); border-color: var(--red-bright, #ff4d5e); background: rgba(255, 77, 94, 0.1); }
.squad-upgrade-actions .btn-icon.is-active svg { animation: squadAutoUpgradeSpin 1.6s linear infinite; }
@keyframes squadAutoUpgradeSpin { to { transform: rotate(360deg); } }
.squad-upgrade-auto-position { flex: none; padding: 1px 6px; border-radius: 999px; font-size: 10px; font-weight: 700; color: var(--text-2); background: var(--bg-hover); border: 1px solid var(--border); font-variant-numeric: tabular-nums; }
.lb-stats { min-width: 0; text-align: right; display: flex; flex-direction: column; align-items: flex-end; }
.lb-stats strong { font-variant-numeric: tabular-nums; }
.lb-stats small { color: var(--text-2); font-size: var(--fs-xs); }
/* Total Power stands out from TPM/base -- bigger, colored, its own line --
   instead of blending in as another muted <small> stat. */
.squad-power-value { display: block; margin-top: 2px; color: #f1f7ff; font-size: 1.05em; text-shadow: 0 0 12px rgba(241, 247, 255, 0.18); }
.lb-progress { display: block; width: 100%; max-width: 180px; height: 3px; margin-top: 7px; overflow: hidden; border-radius: 999px; background: var(--border); }
/* Fill grows from zero to its share on render. Animating the transform of a
   full-width bar (not its width) keeps this on the compositor. */
.lb-progress::before {
  content: ""; display: block; width: var(--lb-progress); height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--red-hover), var(--red-bright));
  box-shadow: 0 0 8px rgba(229, 57, 69, 0.45);
  transform-origin: left center;
  animation: lbFill 900ms var(--ease-out) both;
}
@keyframes lbFill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* top three get a slow shimmer travelling along the filled portion */
.lb-row.lb-top .lb-progress::before {
  background-image: linear-gradient(90deg, var(--red-hover), var(--red-bright), #ffd9dd, var(--red-bright));
  background-size: 100% 100%;
  animation: lbFill 900ms var(--ease-out) both;
}
@media (max-width: 620px) {
  .lb-head { display: block; }
  .lb-summary { display: inline-flex; margin-top: var(--s-2); }
  .squad-tabs { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); width: 100%; }
  .squad-tabs button { min-width: 0; padding-inline: 3px; font-size: var(--fs-xs); }
  .lb-row { grid-template-columns: 38px 32px minmax(0, 1fr); gap: var(--s-2); padding: 9px 10px; }
  .lb-row.lb-row-ranked { grid-template-columns: 38px minmax(0, 1fr); }
  .lb-row.lb-row-ranked .lb-stats { grid-column: 2; }
  .lb-row.lb-row-simple { grid-template-columns: minmax(0, 1fr); }
  .lb-row.lb-row-simple .lb-stats { grid-column: 1; }
  .lb-row.lb-row-simple.has-actions { grid-template-columns: minmax(0, 1fr); }
  .lb-row.has-actions { grid-template-columns: 38px 32px minmax(0, 1fr); }
  .lb-row.has-actions .lb-row-actions { grid-column: 1 / -1; justify-content: flex-start; }
  .squad-row-actions { grid-column: 1; justify-content: flex-start; margin-top: var(--s-2); }
  .lb-rank { width: 32px; height: 28px; }
  .lb-stats { grid-column: 3; align-items: flex-start; text-align: left; }
  .lb-progress { max-width: none; }
  .xp-profile-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- logs ---- */
.logs-toolbar { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; margin-bottom: var(--s-4); }
.logs-toolbar-right { margin-left: auto; display: flex; gap: var(--s-2); align-items: center; }
.seg-count { margin-left: 6px; font-size: var(--fs-xs); opacity: 0.7; font-variant-numeric: tabular-nums; }
.logs-list { display: flex; flex-direction: column; gap: var(--s-2); }
.log-entry { display: flex; gap: var(--s-3); align-items: flex-start; background: var(--bg-card-2); border: 1px solid var(--border); border-left-width: 3px; border-radius: var(--r-md); padding: var(--s-3) var(--s-4); transition: border-color var(--t), background var(--t), transform var(--t); content-visibility: auto; contain-intrinsic-size: auto 68px; }
.log-entry:hover { background: var(--bg-hover); transform: translateX(2px); }
.log-entry-in { animation: logEntryIn 360ms cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: var(--log-delay, 0ms); }
.log-entry-in .log-kind { animation: logKindIn 420ms ease-out both; animation-delay: calc(var(--log-delay, 0ms) + 45ms); }
.log-entry.log-moderation { border-left-color: var(--warning); }
.log-entry.log-automod { border-left-color: var(--error); }
.log-entry.log-website { border-left-color: var(--red); }
.log-entry.log-bot { border-left-color: var(--text-muted); }
.log-kind { flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: var(--r-xs); background: var(--bg-input); color: var(--text-2); }
.log-copy { flex: 1; min-width: 0; }
.log-copy p { font-size: var(--fs-sm); margin-top: 2px; }
.log-details { overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.log-people { display: flex; gap: var(--s-4); font-size: var(--fs-xs); color: var(--text-2); margin: 3px 0; flex-wrap: wrap; }
.log-people b { color: var(--text-muted); font-weight: 600; margin-right: 4px; }
.log-entry time { font-size: var(--fs-xs); color: var(--text-muted); flex: none; white-space: nowrap; }
@keyframes logEntryIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes logKindIn {
  from { opacity: 0; transform: scale(0.82); }
  to { opacity: 1; transform: scale(1); }
}

/* ---- overview ---- */
.overview-2col { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4); margin: var(--s-5) 0; }
/* Grid children default to min-width:auto, so a long channel/message id can
   widen an entire stacked overview card past the mobile viewport. */
.overview-2col > * { min-width: 0; }
.module-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2); }
.module-chip { display: flex; align-items: center; gap: var(--s-2); background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--r-sm); padding: 9px 11px; cursor: pointer; text-align: left; transition: border-color var(--t), background var(--t); }
.module-chip:hover { border-color: var(--border-red); background: var(--bg-hover); }
.module-chip.on { border-color: var(--border-red); }
.module-ic { display: grid; place-items: center; color: var(--text-2); }
.module-chip.on .module-ic { color: var(--red-bright); }
.module-name { flex: 1; font-size: var(--fs-sm); font-weight: 500; }
.quick-grid { display: flex; flex-direction: column; gap: var(--s-2); }
.quick-action { display: flex; align-items: center; gap: var(--s-3); background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--r-sm); padding: 11px 13px; cursor: pointer; text-align: left; transition: border-color var(--t), background var(--t), transform var(--t); }
.quick-action:hover { border-color: var(--border-red); background: var(--bg-hover); }
.quick-ic { display: grid; place-items: center; width: 32px; height: 32px; border-radius: var(--r-xs); background: var(--red-tint); color: var(--red-bright); }
.quick-action span:nth-child(2) { flex: 1; font-weight: 500; }
.quick-arrow { color: var(--text-muted); transition: transform var(--t), color var(--t); }
.quick-action:hover .quick-arrow { color: var(--red-bright); transform: translateX(3px); }
.activity-list { display: flex; flex-direction: column; }
.activity-row { display: flex; align-items: flex-start; gap: var(--s-3); padding: var(--s-3) 0; border-bottom: 1px solid var(--border); }
.activity-row:last-child { border-bottom: none; }
.activity-copy { flex: 1; min-width: 0; }
.activity-summary { font-size: var(--fs-sm); font-weight: 550; }
.activity-detail { font-size: var(--fs-xs); overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.activity-time { font-size: var(--fs-xs); white-space: nowrap; }

/* ---- accounts ---- */
.accounts-list { display: flex; flex-direction: column; gap: var(--s-2); }
.account-row { display: flex; align-items: center; gap: var(--s-3); background: var(--bg-card-2); border: 1px solid var(--border); border-radius: var(--r-sm); padding: var(--s-3) var(--s-4); }
.account-info { flex: 1; min-width: 0; }
.account-name { display: flex; align-items: center; gap: var(--s-2); font-weight: 600; }
.account-meta { font-size: var(--fs-xs); }
.account-form { display: flex; flex-direction: column; gap: var(--s-4); }
.check-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--s-2); max-height: 180px; overflow-y: auto; padding: var(--s-2); background: var(--bg-input); border: 1px solid var(--border); border-radius: var(--r-sm); }

/* ---- dash nav scroll ---- */
.dash-nav { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; }

/* ---- ticket + person lists (used by tickets/dailydono panels) ---- */
.ticket-list { display: flex; flex-direction: column; gap: var(--s-3); margin: var(--s-3) 0; }

/* ---- transcripts: filter bar + username cells ---- */
.transcript-filterbar {
  margin: var(--s-3) 0 var(--s-4);
  padding: var(--s-4);
  background: linear-gradient(160deg, var(--red-tint-2), transparent 60%), var(--bg-card-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  transition: border-color var(--t);
}
.transcript-filterbar.is-active { border-color: var(--border-red); }
.transcript-filter-row {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: var(--s-4);
}
.transcript-filter-group { display: flex; gap: var(--s-4); flex-wrap: wrap; }
.transcript-filter { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.transcript-filter-label {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.055em;
  text-transform: uppercase;
}

/* search box: same pill treatment as the guild-picker search elsewhere */
.transcript-search-box { flex: 1 1 260px; position: relative; padding-right: 4px; }
.transcript-search-box input { padding-right: 22px; }
.transcript-search-clear {
  display: none;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  margin-left: -26px;
  flex: none;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--t), color var(--t);
}
.transcript-search-clear.show { display: flex; }
.transcript-search-clear:hover { background: var(--red-tint); color: var(--red-bright); }

/* date / hour pickers -- both are the themed .dd dropdowns from picker.js,
   which draw their own pill chrome via .dd-toggle, so the filter bar just
   sizes and positions them rather than drawing a second border. */
.transcript-date-picker { width: 170px; }
.transcript-date-picker .dd-toggle { min-height: 38px; }

/* transcripts: ticket-category filter. Sized to match the date picker so the
   three filter controls read as one row rather than three widths. */
.transcript-category-picker { width: 190px; }
.transcript-category-picker .dd-toggle { min-height: 38px; }
/* Shown in place of the dropdown when every transcript shares one category --
   a one-option filter is a label, not a choice. */
.transcript-filter-none {
  display: flex;
  align-items: center;
  min-height: 38px;
  padding: 0 var(--s-3);
  border: 1px dashed var(--border);
  border-radius: var(--r-sm);
  color: var(--text-muted);
  font-size: var(--fs-sm);
}
/* Category cell in the table. A quiet pill, not a badge: it is data, and 50
   loud badges down a column is just noise. */
.transcript-type {
  display: inline-block;
  max-width: 22ch;
  overflow: hidden;
  padding: 2px var(--s-2);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--bg-elevated);
  color: var(--text-2);
  font-size: var(--fs-xs);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.transcript-hour-range { display: flex; align-items: center; gap: var(--s-2); }
.transcript-hour-arrow { color: var(--text-muted); font-size: var(--fs-sm); }
.transcript-hour-box { display: flex; align-items: center; gap: 8px; color: var(--text-muted); }
.transcript-hour-box .dd-hour { width: 100px; }

/* themed hour picker: typeable input + dropdown list, replacing a bare
   <select> (unstyleable native popup, mouse-only) */
.dd-hour-toggle { align-items: stretch; padding: 0 0 0 11px; cursor: text; }
.dd-hour-input {
  flex: 1; min-width: 0; align-self: center;
  border: 0; background: transparent; color: var(--text);
  font-family: inherit; font-size: var(--fs-sm); padding: 0;
}
.dd-hour-input:focus { outline: none; }
.dd-hour-input::placeholder { color: var(--text-muted); }
.dd-hour-caret {
  display: flex; align-items: center; justify-content: center;
  flex: none; width: 28px; margin: 0; padding: 0;
  border: 0; border-left: 1px solid var(--border);
  background: transparent; color: var(--text-2); cursor: pointer;
}
.dd-hour-caret:hover { color: var(--text); }
.dd.dd-open .dd-hour-caret { color: var(--red-bright); }
.dd-hour-menu { max-height: 264px; overflow-y: auto; padding: var(--s-2); }

.transcript-filter-foot {
  display: none;
  align-items: center;
  gap: var(--s-3);
  margin-top: var(--s-3);
  padding-top: var(--s-3);
  border-top: 1px solid var(--border);
}
.transcript-filterbar.is-active .transcript-filter-foot { display: flex; }
.transcript-filter-summary {
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--red-tint);
  color: var(--red-bright);
  font-size: var(--fs-xs);
  font-weight: 700;
}
.transcript-filter-summary:empty { display: none; }
.transcript-reset { margin-left: auto; }
.transcript-reset.hidden { display: none; }

/* Username (or raw id) that copies the Discord user id on click: dotted
   underline signals "there is more here", revealed by hover (title) on
   desktop and long-press on touch. */
.transcript-user {
  border-bottom: 1px dotted var(--text-muted);
  cursor: pointer;
  /* Long-press must reach our handler instead of raising the OS text-selection
     callout on iOS/Android. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}
.transcript-user:hover, .transcript-user:focus-visible { color: var(--text); border-bottom-color: var(--text); }

.ticket-card { background: var(--bg-card-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-4); display: flex; flex-direction: column; gap: var(--s-3); }
.ticket-card-head { display: flex; align-items: center; gap: var(--s-3); }
.ticket-card-head h4 { flex: 1; min-width: 0; }
.ticket-card-actions { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.ticket-edit-toolbar { display: flex; align-items: center; margin-bottom: var(--s-2); }
.editor-card { background: linear-gradient(180deg, var(--bg-card), var(--bg-card-2)); border: 1px solid var(--border); border-radius: var(--r-lg); padding: var(--s-6); margin: var(--s-4) 0; display: flex; flex-direction: column; gap: var(--s-3); transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease); }
.editor-card:focus-within { border-color: var(--border-red); box-shadow: var(--shadow-red); }
.editor-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); }
.editor-row.three-col { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.editor-row .wide { grid-column: 1 / -1; }
.ticket-option-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-2);
}
/* ---- ticket-option tiles (checkbox square, used by tickets.js's own
   ticketOption() with a real <input type=checkbox>, separate from
   checkField below) -- unchanged. */
:root { --opt-h: 48px; }
.ticket-option-field { min-width: 0; margin: 0; }
.ticket-option-check {
  display: flex;
  width: 100%;
  min-height: var(--opt-h);
  justify-content: space-between;
  align-items: center;
  gap: var(--s-3);
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--bg-input);
  cursor: pointer;
  transition: background var(--t), border-color var(--t), box-shadow var(--t), transform var(--t-fast) var(--ease-out);
}
.ticket-option-check:hover { background: var(--bg-hover); border-color: var(--border-strong); }
.ticket-option-check:has(input:checked) {
  background: linear-gradient(105deg, var(--red-tint), var(--bg-input) 70%);
  border-color: var(--border-red);
  box-shadow: inset 3px 0 0 var(--red-bright);
}
.ticket-option-check:active { transform: translateY(1px); }
.ticket-option-check:has(input:focus-visible) { box-shadow: var(--ring-focus); }
.ticket-option-copy { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ticket-option-title { color: var(--text); font-size: var(--fs-sm); font-weight: 600; line-height: 1.25; }
.ticket-option-description { color: var(--text-2); font-size: var(--fs-xs); font-weight: 400; line-height: 1.35; }
.ticket-option-check > input[type="checkbox"] { margin-left: auto; flex: none; }

/* ---- opt-tile: checkField's card. Same bordered-card + real toggle switch
   language as the automod "Anti-spam signals" grid (.spam-signal), so a
   boolean setting reads identically everywhere in the dashboard instead of
   two different conventions (checkbox square vs. switch) competing. */
.opt-field { min-width: 0; margin: 0; }
.opt-tile {
  display: flex;
  width: 100%;
  min-height: var(--opt-h);
  align-items: center;
  gap: var(--s-3);
  padding: 8px var(--s-3);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-card-2);
  transition: border-color var(--t), background var(--t);
}
.opt-tile:hover { border-color: var(--border-strong); background: var(--bg-hover); }
.opt-tile:has(input:focus-visible) { box-shadow: var(--ring-focus); }
.opt-tile .toggle-copy { min-width: 0; flex: 1; }
.opt-tile .t-name { font-size: var(--fs-sm); }
.opt-tile .t-desc { margin-top: 2px; font-size: var(--fs-xs); }
.opt-tile > .switch { margin-left: auto; flex: none; }
/* A tile sharing a grid row with normal label+input fields stretches to the
   row height, so a boolean never sits visually short next to a text field
   (the mismatch visible on the Tickets multi-panel row). */
.grid-2 > .opt-field, .grid-3 > .opt-field, .grid-auto > .opt-field,
.editor-row > .opt-field, .ticket-option-grid > .opt-field { align-self: stretch; }
.grid-auto:has(> .opt-field), .ticket-option-grid:has(> .opt-field) { grid-auto-rows: 1fr; }
.grid-2 > .opt-field > .opt-tile, .grid-3 > .opt-field > .opt-tile,
.grid-auto > .opt-field > .opt-tile, .editor-row > .opt-field > .opt-tile,
.ticket-option-grid > .opt-field > .opt-tile { height: 100%; }
.optional-pill { font-size: var(--fs-xs); color: var(--text-muted); background: var(--bg-input); padding: 1px 7px; border-radius: var(--r-pill); font-weight: 500; }
.ticket-color-control {
  width: 100%;
  min-height: 42px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 10px 5px 6px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--bg-input);
  cursor: pointer;
  transition: background var(--t), border-color var(--t), box-shadow var(--t);
}
.ticket-color-control:hover { background: var(--bg-hover); border-color: var(--border-strong); }
.ticket-color-control:focus-within { border-color: var(--border-red); box-shadow: var(--ring); }
.ticket-color-input {
  width: 32px;
  height: 32px;
  flex: none;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
  overflow: hidden;
}
.ticket-color-input::-webkit-color-swatch-wrapper { padding: 0; }
.ticket-color-input::-webkit-color-swatch { border: 1px solid rgba(255, 255, 255, 0.16); border-radius: 7px; }
.ticket-color-input::-moz-color-swatch { border: 1px solid rgba(255, 255, 255, 0.16); border-radius: 7px; }
.ticket-color-value { color: var(--text); font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: 600; }
.ticket-color-action { margin-left: auto; color: var(--text-muted); font-size: var(--fs-xs); font-weight: 600; }
.ticket-color-control:hover .ticket-color-action { color: var(--red-bright); }

.person-list { display: flex; flex-direction: column; gap: var(--s-2); }
.person-row { display: flex; align-items: center; gap: var(--s-3); background: var(--bg-card-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-3) var(--s-4); flex-wrap: wrap; }
.person-row .p-name { flex: 1; min-width: 120px; font-weight: 550; }
.person-row .p-amount { font-variant-numeric: tabular-nums; }
.pill { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: var(--r-pill); font-size: var(--fs-xs); font-weight: 600; }
.pill-paid { background: var(--success-bg); color: var(--success); }
.pill-owes { background: var(--error-bg); color: var(--error); }

.list-heading { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--s-3); margin: var(--s-5) 0 var(--s-3); flex-wrap: wrap; }
.list-actions { display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap; }
.application-format-filter .dd-toggle { min-width: 160px; min-height: 38px; }
.summary-row { display: flex; gap: var(--s-2); margin-top: var(--s-2); }

/* daily-dono list rows */
.daily-control-input {
  width: min(100%, 280px);
  height: 40px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--bg-input);
  color: var(--text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02);
  transition: border-color var(--t), box-shadow var(--t), background var(--t);
}
.daily-control-input:hover { border-color: var(--border-strong); }
.daily-control-input:focus { border-color: var(--border-red); background: var(--bg-elevated); box-shadow: var(--ring); }
.daily-amount-input { width: 180px; }
.person-actions { display: flex; gap: var(--s-2); align-items: center; margin-left: auto; }
.warn-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--s-3); row-gap: var(--s-2); padding: var(--s-3) var(--s-4); }
.warn-card .warn-head { grid-column: 1 / -1; width: auto !important; }
.warn-actions { display: inline-flex; gap: 4px; flex-wrap: nowrap; margin: 0; align-self: center; }
.warn-adjust-btn { min-width: 32px; padding: 0 8px; font-variant-numeric: tabular-nums; }
.warn-clear-btn { padding: 0 10px; }
.next-action-row { width: auto !important; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-sm); }
.next-action-row .muted { margin-right: 4px; }
.warn-history { grid-column: 1 / -1; width: 100%; margin-top: 0; font-size: var(--fs-sm); }
.warn-history summary { cursor: pointer; color: var(--text-2); }
.warn-history ul { list-style: none; margin-top: var(--s-2); display: flex; flex-direction: column; gap: 6px; }
.warn-history li { display: flex; justify-content: space-between; gap: var(--s-3); padding: 6px 10px; background: var(--bg-input); border-radius: var(--r-xs); }
.warn-when { font-size: var(--fs-xs); white-space: nowrap; }
.skip-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--s-3); width: 100%; margin: var(--s-2) 0; }
.skip-meta-item { display: flex; flex-direction: column; gap: 2px; }
.skip-meta-item small { color: var(--text-muted); font-size: var(--fs-xs); }
.skip-meta-item span { font-size: var(--fs-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.skip-reason { width: 100%; font-size: var(--fs-sm); }

/* pause panel (daily dono live) */
.pause-panel { display: flex; align-items: center; gap: var(--s-3); background: var(--bg-card-2); border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--s-4); flex-wrap: wrap; }
.pause-copy { flex: 1; min-width: 160px; display: flex; flex-direction: column; }
.pause-title { font-weight: 600; }

@media (max-width: 620px) {
  .daily-control-input, .daily-amount-input { width: 100%; }
  .pause-panel .daily-control-input { flex: 1 1 170px; }
  .warn-card { grid-template-columns: 1fr; }
  .warn-actions { grid-row: 3; justify-self: start; }
  .log-entry time { display: none; }
}

/* ---- ticket editors ---- */
.editor-heading { display: flex; align-items: flex-start; gap: var(--s-3); margin-bottom: var(--s-2); }
.editor-heading > div { flex: 1; min-width: 0; }
.editor-heading h3 { margin-top: 4px; }
.editor-heading .btn { flex: none; }
.ticket-section-title { font-size: var(--fs-md); font-weight: 650; color: var(--red-bright); margin-top: var(--s-3); padding-top: var(--s-3); border-top: 1px solid var(--border); }

/* One line under a ticket-editor section heading saying what the section is
   for. Muted and small: it explains, it does not compete with the heading. */
.ticket-section-note {
  margin: calc(var(--s-2) * -1) 0 var(--s-1);
  max-width: 78ch;
  color: var(--text-2);
  font-size: var(--fs-sm);
  line-height: var(--lh);
}
/* "Changes save as you make them." Stated once, at the top of an editor whose
   fields have no save button of their own. */
.ticket-autosave-note {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin: 0;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--border);
  border-left: 2px solid var(--success);
  border-radius: var(--r-sm);
  background: var(--success-bg);
  color: var(--text-2);
  font-size: var(--fs-sm);
}
.ticket-autosave-note svg { color: var(--success); flex: none; }

/* Sticky action bar. These editors are taller than any viewport, so the
   primary action used to sit several scrolls below whatever you were editing.
   Bled to the card's edges (the card carries --s-6 of padding) so it reads as
   a bar rather than a floating strip. */
.ticket-actionbar {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3) var(--s-4);
  margin: var(--s-4) calc(var(--s-6) * -1) calc(var(--s-6) * -1);
  padding: var(--s-4) var(--s-6);
  border-top: 1px solid var(--border-strong);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  background: var(--bg-elevated);
  box-shadow: 0 -10px 24px -18px rgba(0, 0, 0, 0.9);
}
.ticket-actionbar-end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-3);
  margin-left: auto;
}
.ticket-actionbar-end .action-status { max-width: 46ch; }
.ticket-mode-choice { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* Says what each mode will actually do, so "Reusable only" is not a guess. */
.ticket-mode-note {
  margin: 0;
  max-width: 52ch;
  color: var(--text-muted);
  font-size: var(--fs-xs);
  line-height: 1.45;
}
/* Validation message for a form that submits rather than sitting disabled. */
.form-error {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin: 0;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--error);
  border-radius: var(--r-sm);
  background: var(--error-bg);
  color: var(--error);
  font-size: var(--fs-sm);
}
.form-error.hidden { display: none; }
.ticket-card-emoji { max-width: 110px; }
.notice { background: var(--red-tint); border: 1px solid var(--border-red); border-radius: var(--r-sm); padding: var(--s-3) var(--s-4); font-size: var(--fs-sm); color: var(--text); margin: var(--s-3) 0; }
.notice-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.flex-shrink-0 { flex-shrink: 0; }

/* ---- leaderboard control row ---- */
.lb-controls { display: flex; gap: var(--s-3); flex-wrap: wrap; margin-bottom: var(--s-4); }
.lb-controls .picker { min-width: 160px; }

/* ---- access rules editor ---- */
.access-rule-row { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; margin-bottom: var(--s-2); }
.access-rule-target { flex: 1; min-width: 160px; }
.access-rule-action { min-width: 120px; }
.access-rule-btn { width: 30px; height: 30px; flex: none; border: 1px solid var(--border); border-radius: var(--r-xs); background: transparent; color: var(--text-2); cursor: pointer; transition: background var(--t), color var(--t); }
.access-rule-btn:hover { background: var(--bg-hover); color: var(--text); }

@media (max-width: 900px) {
  .overview-2col { grid-template-columns: 1fr; }
  .editor-row, .editor-row.three-col { grid-template-columns: 1fr; }
  .ticket-option-grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .logs-toolbar { min-width: 0; width: 100%; }
  .logs-toolbar .segmented {
    display: flex;
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: thin;
  }
  .logs-toolbar .segmented button { flex: 0 0 auto; }
  .module-grid { grid-template-columns: 1fr; }
  .lb-stats { text-align: left; }

  /* Transcript rows become readable cards on phones instead of a six-column
     desktop table that forces the whole page to scroll sideways. */
  .transcript-table-wrap {
    overflow: visible;
    border: 0;
    border-radius: 0;
  }
  table.data.transcript-table {
    display: block;
    width: 100%;
    min-width: 0;
  }
  table.data.transcript-table thead { display: none; }
  table.data.transcript-table tbody {
    display: grid;
    width: 100%;
    gap: var(--s-3);
  }
  table.data.transcript-table tr {
    display: grid;
    width: 100%;
    min-width: 0;
    padding: var(--s-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    background: linear-gradient(145deg, rgba(229,57,69,0.045), transparent 58%), var(--bg-card-2);
    box-shadow: inset 3px 0 0 rgba(229,57,69,0.35);
  }
  table.data.transcript-table td {
    display: grid;
    grid-template-columns: minmax(76px, 0.34fr) minmax(0, 1fr);
    gap: var(--s-2);
    align-items: start;
    width: 100%;
    min-width: 0;
    padding: 7px 4px;
    border: 0;
    overflow-wrap: anywhere;
  }
  table.data.transcript-table td::before {
    content: attr(data-label);
    color: var(--text-muted);
    font-family: var(--font);
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: 0.055em;
    text-transform: uppercase;
  }
  table.data.transcript-table .transcript-action {
    display: block;
    padding-top: var(--s-2);
  }
  table.data.transcript-table .transcript-action::before { display: none; }
  table.data.transcript-table .transcript-action .btn { width: 100%; }

  /* Filter bar stacks: search gets its own row, day + hour range wrap under
     it full-width. Every flex item along the way gets an explicit
     min-width: 0 -- a flex item's default min-width is "auto" (its own
     content size), not 0, so without this a long placeholder or a bare
     <input>'s intrinsic width can refuse to shrink and push the row past
     the card's edge instead of wrapping. */
  .transcript-filterbar { padding: var(--s-3); max-width: 100%; box-sizing: border-box; overflow: hidden; }
  .transcript-filter-row { gap: var(--s-3); min-width: 0; }
  .transcript-search-box { flex: 1 0 100%; min-width: 0; }
  .transcript-search-box input { min-width: 0; }
  .transcript-filter-group { flex: 1 0 100%; gap: var(--s-3); min-width: 0; }
  .transcript-filter { flex: 1 1 100%; min-width: 0; }
  .transcript-category-picker,
  .transcript-date-picker,
  .transcript-hour-range { width: 100%; min-width: 0; box-sizing: border-box; }
  .transcript-hour-box { flex: 1; min-width: 0; }
  .transcript-hour-box .dd-hour { width: auto; flex: 1; min-width: 0; }
  .ticket-actionbar { flex-direction: column; align-items: stretch; padding: var(--s-3) var(--s-6); }
  .ticket-actionbar-end { justify-content: stretch; margin-left: 0; }
  .ticket-actionbar-end .btn { flex: 1 1 100%; justify-content: center; }
  .transcript-filter-foot { flex-wrap: wrap; }
  .transcript-filter-summary { flex: 1 0 100%; order: 2; }
  .transcript-reset { margin-left: 0; order: 1; }
}

/* ---- reaction roles ---- */
.rr-binding { display: flex; align-items: center; gap: var(--s-2); margin-bottom: var(--s-2); }
.rr-binding select { flex: 1; min-width: 0; }
.rr-arrow { color: var(--text-muted); flex: none; }
.rr-bindings { margin-bottom: var(--s-2); }
.rr-menu {
  padding: var(--s-4);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-card-2);
  margin-bottom: var(--s-3);
}
.rr-menu-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; }
.rr-menu-head .muted { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
.rr-bindings-view { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); margin-top: var(--s-3); }
.rr-binding-view { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); }
.rr-emoji { font-size: var(--fs-md); }

/* =======================================================================
   Send-message composer: full Discord markdown preview + emoji picker.
   The older .md-* rules above cover spoiler/code/quote/h1-h3; these add the
   syntax that renderer did not previously support, plus the picker chrome.
   Scoped to the preview surfaces so .md-* can never leak into panel chrome.
   ======================================================================= */
.dm-preview-content, .dm-preview-embed-desc, .dm-preview-embed-title { overflow-wrap: anywhere; }

.dm-preview-content .md-subtext,
.dm-preview-embed-desc .md-subtext { display: block; font-size: 0.8em; color: var(--text-muted); }

/* Was a <span> per line; now one <blockquote> per run of > lines. */
.dm-preview-content blockquote.md-quote,
.dm-preview-embed-desc blockquote.md-quote {
  display: block; margin: 2px 0; padding-left: 10px;
  border-left: 4px solid var(--border-strong); color: inherit;
}
.dm-preview-content .md-list,
.dm-preview-embed-desc .md-list { margin: 2px 0; padding-left: 22px; }
.dm-preview-content .md-list li,
.dm-preview-embed-desc .md-list li { margin: 1px 0; }

.dm-preview-content .md-link,
.dm-preview-embed-desc .md-link,
.dm-preview-embed-title .md-link { color: #00a8fc; text-decoration: none; }
.dm-preview-content .md-link:hover,
.dm-preview-embed-desc .md-link:hover { text-decoration: underline; }

/* Mentions get Discord's own tinted-pill treatment. */
.dm-preview-content .md-mention,
.dm-preview-embed-desc .md-mention {
  padding: 0 2px; border-radius: 3px; font-weight: 500;
  background: rgba(88, 101, 242, 0.3); color: #dee0fc; cursor: pointer;
}
.dm-preview-content .md-mention-everyone,
.dm-preview-embed-desc .md-mention-everyone { background: rgba(250, 166, 26, 0.3); color: #ffd899; }
.dm-preview-content .md-mention-command,
.dm-preview-embed-desc .md-mention-command { background: rgba(88, 101, 242, 0.22); }
.dm-preview-content .md-timestamp,
.dm-preview-embed-desc .md-timestamp { padding: 0 2px; border-radius: 3px; background: rgba(255, 255, 255, 0.06); }

.dm-preview-content .md-emoji,
.dm-preview-embed-desc .md-emoji,
.dm-preview-embed-title .md-emoji {
  width: 1.375em; height: 1.375em; object-fit: contain;
  vertical-align: bottom; margin: 0 1px;
}
/* Discord enlarges a message that is nothing but emoji. */
.dm-preview-content.is-jumbo { font-size: 2.6em; line-height: 1.2; }
.dm-preview-content.is-jumbo .md-emoji { width: 1em; height: 1em; }

.dm-preview-content .md-code-block { position: relative; }
.dm-preview-content .md-code-lang {
  display: block; margin-bottom: 4px; font-size: 0.85em;
  color: var(--text-muted); text-transform: lowercase;
}

/* ---- composer: textarea with a tool strip in its bottom-right corner */
.message-box { position: relative; }
.message-box textarea { width: 100%; padding-right: 44px; }
.message-box-tools { position: absolute; right: 6px; bottom: 8px; display: flex; gap: 4px; }
.emoji-trigger { width: 30px; height: 30px; padding: 0; font-size: 1rem; line-height: 1; border-radius: var(--r-xs); }

/* ---- picker popover */
.emoji-panel {
  position: absolute; right: 0; bottom: 42px; z-index: var(--z-dropdown);
  width: min(340px, 88vw);
  display: flex; flex-direction: column; gap: var(--s-2);
  padding: var(--s-3);
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  animation: ddIn 160ms var(--ease-out);
}
.emoji-search { width: 100%; }
.emoji-tabs { display: flex; gap: 2px; overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; }
.emoji-tabs::-webkit-scrollbar { display: none; }
.emoji-tab {
  flex: none; padding: 4px 9px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--text-2);
  font-size: var(--fs-xs); font-weight: 550; cursor: pointer; white-space: nowrap;
}
.emoji-tab:hover { background: var(--bg-hover); color: var(--text); }
.emoji-tab.active { background: var(--red-tint); color: var(--red-bright); }
.emoji-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
  gap: 2px; max-height: 240px; overflow-y: auto;
}
.emoji-cell {
  display: grid; place-items: center;
  width: 34px; height: 34px; padding: 0;
  border: 0; border-radius: var(--r-xs);
  background: transparent; font-size: 1.25rem; line-height: 1; cursor: pointer;
}
.emoji-cell:hover { background: var(--bg-hover); }
.emoji-cell img { width: 22px; height: 22px; object-fit: contain; }
.emoji-empty { grid-column: 1 / -1; padding: var(--s-3); text-align: center; font-size: var(--fs-sm); }

/* =========================================================================
   Applications: question builder, answer blocks, single-choice control and
   the pending-review row. Built only from existing tokens, so the light
   theme follows for free.
   ========================================================================= */
/* ---- question builder (Format editor) ---- */
.q-list{display:flex;flex-direction:column;gap:var(--s-2);}
.q-item{background:var(--bg-card-2);border:1px solid var(--border);border-radius:var(--r-md);padding:var(--s-3);}
.q-item.is-open{border-color:var(--border-red);box-shadow:0 0 0 3px var(--red-tint-2);}
.q-head{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap;}
.q-order{display:flex;flex-direction:column;gap:2px;flex:none;}
.q-index{width:24px;flex:none;text-align:center;color:var(--text-muted);font-size:var(--fs-xs);
  font-variant-numeric:tabular-nums;}
.q-type{width:172px;flex:none;}
.q-label-input{flex:1;min-width:200px;}
.q-req{display:inline-flex;align-items:center;gap:var(--s-2);font-size:var(--fs-xs);
  color:var(--text-2);white-space:nowrap;flex:none;}
.q-detail{margin-top:var(--s-3);padding-top:var(--s-3);border-top:1px dashed var(--border);
  display:flex;flex-direction:column;gap:var(--s-2);}
.q-opt-row{display:flex;align-items:center;gap:var(--s-2);}
.q-opt-handle{width:18px;flex:none;text-align:center;color:var(--text-muted);font-size:var(--fs-xs);}
.q-num{width:118px;flex:none;}
.q-pair{display:flex;align-items:flex-end;gap:var(--s-3);flex-wrap:wrap;}

/* ---- answers (Apply + Pending) ---- */
.ans-list{display:flex;flex-direction:column;gap:var(--s-2);width:100%;}
.ans-item{min-width:0;background:var(--bg-input);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:10px var(--s-4);}
.ans-q{font-size:var(--fs-sm);font-weight:600;line-height:1.35;color:var(--text-2);margin-bottom:5px;}
.ans-a{min-width:0;font-size:var(--fs-sm);line-height:1.5;white-space:pre-line;overflow-wrap:anywhere;word-break:break-word;}

/* ---- single-choice control (Apply) ---- */
.application-format-choices { gap: var(--s-4); }
.radio-row{display:flex;flex-direction:column;gap:var(--s-2);}
.radio-opt{display:flex;align-items:center;gap:var(--s-3);padding:11px var(--s-4);
  border:1px solid var(--border);border-radius:var(--r-sm);background:var(--bg-input);
  cursor:pointer;font-size:var(--fs-md);min-height:44px;}
.radio-opt.is-picked{border-color:var(--border-red);background:var(--red-tint-2);box-shadow:var(--ring);}
.radio-mark{width:18px;height:18px;border-radius:50%;border:1.5px solid var(--border-strong);
  flex:none;display:grid;place-items:center;}
.radio-opt.is-picked .radio-mark{border-color:var(--red-bright);}
.radio-opt.is-picked .radio-mark::after{content:"";width:9px;height:9px;border-radius:50%;
  background:var(--red-bright);}

/* ---- yes / no confirmation (Apply) ---- */
.boolean-field{gap:var(--s-2);}
.boolean-choices{display:grid;grid-template-columns:repeat(2,104px);gap:var(--s-2);}
.boolean-choice{min-height:36px;border:1px solid var(--border);border-radius:var(--r-sm);
  background:var(--bg-input);color:var(--text-2);font:inherit;font-size:var(--fs-sm);font-weight:650;
  cursor:pointer;transition:transform var(--t) var(--ease),border-color var(--t),background var(--t),color var(--t);}
.boolean-choice:hover{border-color:var(--border-strong);background:var(--bg-hover);color:var(--text);}
.boolean-choice.is-picked{border-color:var(--border-red);background:var(--red-tint-2);color:var(--text);box-shadow:var(--ring);}
.boolean-choice--yes.is-picked{border-color:var(--success);background:linear-gradient(135deg,rgba(50,213,131,.26),rgba(50,213,131,.09));box-shadow:0 0 0 3px var(--success-bg);}
.boolean-choice:active{transform:scale(.98);}
.boolean-choice:focus-visible{outline:none;box-shadow:var(--ring-focus);}

/* ---- application availability (Apply) ---- */
.application-status{display:flex;align-items:flex-start;gap:var(--s-3);padding:var(--s-4);border:1px solid var(--border);border-radius:var(--r-md);background:var(--bg-input);}
.application-status-icon{display:grid;place-items:center;width:34px;height:34px;flex:none;border-radius:50%;background:var(--red-tint-2);color:var(--red-bright);}
.application-status.is-pending .application-status-icon{background:var(--success-bg);color:var(--success);}

/* ---- submission row (Pending) ---- */
.sub-card{display:flex;flex-direction:column;align-items:stretch;gap:var(--s-2);}
.sub-head{display:flex;align-items:center;gap:var(--s-3);width:100%;}
.sub-who{flex:1;min-width:0;}
.sub-foot{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap;width:100%;
  padding-top:var(--s-3);border-top:1px solid var(--border);}
.sub-foot .warn-actions{margin-left:auto;}

/* Shared quiet hover: a stationary highlight fades in, like the stat cards. */
:is(.editor-card, .ticket-card, .role-card, .module-chip, .quick-action, .opt-tile, .settings-tab) {
  position: relative;
  transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease), transform 180ms var(--ease), background 180ms var(--ease);
}
:is(.editor-card, .ticket-card, .role-card, .module-chip, .quick-action, .opt-tile, .settings-tab)::after {
  content: ""; position: absolute; inset: 0 8px auto; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--red-bright), transparent);
  opacity: 0; transition: opacity 180ms var(--ease);
}
:is(.editor-card, .ticket-card, .role-card, .module-chip, .quick-action, .opt-tile, .settings-tab):hover::after { opacity: 1; }
:is(.ticket-card, .role-card, .module-chip, .quick-action):hover { transform: translateY(-2px); border-color: var(--border-red); box-shadow: var(--shadow-red); }
.settings-tabs::before { display: none; }
.settings-tab.active { background: var(--red-tint); color: var(--red-bright); box-shadow: inset 0 0 0 1px var(--border-red); }
.nav-item:hover, .nav-subitem:hover { background: linear-gradient(180deg, var(--bg-card), var(--bg-card-2)); box-shadow: inset 0 1px var(--border-red); }
.opt-tile { padding: 8px 12px; border-radius: var(--r-sm); }
.opt-tile:has(input:checked) { border-color: var(--border-red); background: color-mix(in srgb, var(--bg-card-2) 94%, var(--red)); }
.toggle-row { padding-top: 8px; padding-bottom: 8px; }
.toggle-row .toggle-copy .t-name { font-size: var(--fs-sm); }
.ticket-editor-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 340px); align-items: start; gap: var(--s-4); }
.ticket-editor-layout .editor-card { min-width: 0; }
.ticket-editor-layout .editor-row.three-col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ticket-preview { position: sticky; top: calc(var(--topbar-h) + 16px); padding: 18px; border: 1px solid var(--border); border-radius: var(--r-lg); background: linear-gradient(180deg, var(--bg-card), var(--bg-card-2)); }
.ticket-preview-heading { font-size: var(--fs-md); font-weight: 650; }
.ticket-preview > p { font-size: var(--fs-xs); margin: 5px 0 16px; }
.ticket-preview-embed { display: flex; flex-direction: column; gap: 10px; padding: 14px; background: var(--bg-elevated); border-left: 3px solid var(--embed-color); border-radius: 4px; overflow-wrap: anywhere; }
.ticket-preview-embed .dm-preview-embed-desc { font-size: 13px; line-height: 1.55; }
.ticket-preview-image { max-width: 100%; max-height: 220px; object-fit: contain; border-radius: 6px; }
.ticket-preview-thumb { width: 56px; height: 56px; object-fit: cover; align-self: flex-end; border-radius: 6px; }
.ticket-preview-buttons { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 14px; }
.ticket-preview-button { background: var(--red-tint); color: var(--text); border: 1px solid var(--border-red); border-radius: 5px; padding: 6px 10px; font-size: 12px; }
.ticket-section-nav { display: flex; flex-wrap: wrap; gap: 4px; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.ticket-section-nav .btn { height: 28px; font-size: 11px; padding: 0 8px; }
.ticket-section-title { scroll-margin-top: calc(var(--topbar-h) + 20px); }
.activity-copy, .activity-detail { min-width: 0; overflow-wrap: anywhere; }
.activity-detail .mention { max-width: 100%; }
@media (max-width: 1100px) {
  .ticket-editor-layout { grid-template-columns: minmax(0, 1fr); }
  .ticket-preview { position: static; }
}
@media (max-width: 600px) {
  .ticket-editor-layout .editor-row.three-col { grid-template-columns: 1fr; }
  .activity-row { flex-wrap: wrap; }
}
@media (prefers-reduced-motion: reduce) {
  :is(.stat, .card, .server-card, .ticket-card, .role-card, .module-chip, .quick-action, .settings-tab):hover { transform: none; }
  .switch .slider::before { transition: none; }
}
