/* =========================================================================
   NPI Tab Manager - launcher styles
   Palette: deep slate surfaces, a single signal-amber accent (a nod to the
   radio/signal world), monospace for every data field because this tool is
   for someone who lives in spreadsheets and terminals.
   100% local: no web fonts, no CDNs - uses the OS font stack.
   ========================================================================= */
:root {
  --bg:        #14171c;
  --surface:   #1b1f26;
  --surface-2: #232832;
  --surface-3: #2b313c;
  --border:    #2c333f;
  --border-2:  #3a424f;
  --text:      #e6e9ee;
  --text-dim:  #9aa3b2;
  --text-faint:#6b7484;
  --accent:    #f2a541;   /* signal amber */
  --accent-dk: #c9882f;
  --danger:    #e5484d;
  --ok:        #46b366;
  --radius:    10px;
  --ui:   system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "Cascadia Code", "Consolas", "Courier New", monospace;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--ui);
  font-size: 14px;
  display: grid;
  grid-template-columns: 248px 1fr;
  grid-template-rows: 56px 1fr;
  grid-template-areas: "brand topbar" "sidebar main";
  height: 100vh;
  overflow: hidden;
}
/* Connectivity banners - a persistent row reserved above everything else
   (rather than overlaying it and risking hiding real content) for one of two
   mutually-exclusive messages decided in app.js's renderConnectivityBanner():
     .offline-banner     - NO Internet access at all (navigator.onLine false)
     .maintenance-banner - Internet's fine, but NPI Tab Manager's server/
                            database specifically can't be reached right now
                            (an explicit System Maintenance window, or any
                            other reason it's just unreachable)
   Both explain what still works locally while queued, so the wording is
   longer than a single line - auto height (with a sensible minimum) instead
   of the old fixed 34px so it can wrap to 2-3 lines without clipping. */
body.offline, body.maintenance {
  grid-template-rows: auto 56px 1fr;
  grid-template-areas: "banner banner" "brand topbar" "sidebar main";
}
.offline-banner, .maintenance-banner {
  display: none;
  grid-area: banner;
  align-items: center; justify-content: center;
  background: var(--accent); color: #1a1408;
  font-weight: 600; font-size: 13px;
  min-height: 34px; line-height: 1.4;
  padding: 6px 24px; text-align: center;
}
body.offline .offline-banner { display: flex; }
body.maintenance .maintenance-banner { display: flex; }

/* Plan-limit banner - a separate reserved row (own grid area, "planbanner")
   from the connectivity banners above so it can show at the same time as
   either of those without the two overlapping - see renderPlanLimitBanner()
   in app.js. Red rather than the connectivity banners' amber, since this
   one means "action needed" (delete something or upgrade) rather than
   "temporarily degraded". */
body.plan-limit {
  grid-template-rows: auto 56px 1fr;
  grid-template-areas: "planbanner planbanner" "brand topbar" "sidebar main";
}
body.offline.plan-limit, body.maintenance.plan-limit {
  grid-template-rows: auto auto 56px 1fr;
  grid-template-areas: "banner banner" "planbanner planbanner" "brand topbar" "sidebar main";
}
.plan-limit-banner {
  display: none;
  grid-area: planbanner;
  align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 4px 10px;
  background: var(--danger); color: #fff;
  font-weight: 600; font-size: 13px;
  min-height: 34px; line-height: 1.4;
  padding: 6px 24px; text-align: center;
}
.plan-limit-banner a { color: #fff; text-decoration: underline; font-weight: 700; }
body.plan-limit .plan-limit-banner { display: flex; }

/* ---- Brand corner ---- */
.brand {
  grid-area: brand;
  display: flex; align-items: center; gap: 10px;
  padding: 0 18px;
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
  background: var(--surface);
}
.brand .mark {
  width: 26px; height: 26px; border-radius: 6px;
  background: var(--accent);
  display: grid; place-items: center;
  font-weight: 800; color: #1a1408; font-size: 12px; letter-spacing: -0.5px;
}
.brand .name { font-weight: 650; letter-spacing: 0.2px; }
.brand .name small { display:block; font-size: 10px; color: var(--text-faint);
  font-weight: 500; letter-spacing: 0.5px; }

/* ---- Top bar ---- */
.topbar {
  grid-area: topbar;
  display: flex; align-items: center; gap: 14px;
  padding: 0 18px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.view-title { font-size: 16px; font-weight: 650; }
.view-title .count { color: var(--text-faint); font-family: var(--mono);
  font-size: 12px; margin-left: 8px; font-weight: 500; }
.topbar .spacer { flex: 1; }
.search {
  background: var(--bg); border: 1px solid var(--border-2);
  border-radius: 8px; padding: 8px 12px; color: var(--text);
  font-family: var(--ui); width: 240px; outline: none;
}
.search:focus { border-color: var(--accent-dk); }

.btn {
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border-2); border-radius: 8px;
  padding: 8px 12px; cursor: pointer; font-family: var(--ui); font-size: 13px;
  display: inline-flex; align-items: center; gap: 6px;
}
.btn:hover { background: var(--surface-3); }
.btn.accent { background: var(--accent); color: #1a1408; border-color: var(--accent); font-weight: 600; }
.btn.accent:hover { background: var(--accent-dk); }
.btn.ghost { background: transparent; }
.btn.danger { color: var(--danger); border-color: #4a2a2c; }
.btn.danger:hover { background: #2a1d1e; }
.btn:disabled { opacity: 0.4; cursor: default; }

/* AI/LLM features hidden at the user's request (not removed - just flip this
   one rule off to bring everything back). Applied via class="... ai-feature"
   on every AI/LLM/Ollama-related element across index.html and add.html. */
.ai-feature { display: none !important; }

#setAuthEmail { color: var(--accent); font-weight: 600; }

.llm-pill {
  font-family: var(--mono); font-size: 11px; color: var(--text-dim);
  display: flex; align-items: center; gap: 7px;
  padding: 6px 10px; border: 1px solid var(--border); border-radius: 20px;
  background: var(--bg);
}
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); }
.dot.on { background: var(--ok); box-shadow: 0 0 6px var(--ok); }
.dot.off { background: var(--danger); }

/* ---- Sidebar ---- */
.sidebar {
  grid-area: sidebar;
  background: var(--surface);
  border-right: 1px solid var(--border);
  overflow-y: auto; padding: 12px 8px 56px;   /* bottom room for .side-identity */
}
/* Company identity line pinned to the bottom of the sidebar column. Fixed (not
   a new grid row) so it can't disturb the banner/plan-limit grid layouts
   above; width matches the 248px sidebar column. Sits below modals (z 200). */
.side-identity {
  position: fixed; left: 0; bottom: 0; width: 248px; box-sizing: border-box;
  padding: 7px 14px; z-index: 5;
  font-size: 11px; line-height: 1.5; color: var(--text-faint);
  background: var(--surface);
  border-top: 1px solid var(--border); border-right: 1px solid var(--border);
}
.side-identity a { color: var(--text-faint); text-decoration: none; }
.side-identity a:hover { color: var(--text); text-decoration: underline; }
.side-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 1.2px;
  color: var(--text-faint); padding: 12px 12px 6px; font-weight: 700;
}
/* Divider between the fixed built-in Pinned rows (Live Update, Auto-Open,
   Reading / Watch List, Favorites, Timeout Closed) and the user's own
   pinned categories underneath them. */
.side-sep { height: 1px; margin: 6px 12px; background: var(--border); }
.tag-row {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 12px; border-radius: 8px; cursor: pointer;
  color: var(--text-dim); user-select: none;
}
.tag-row:hover { background: var(--surface-2); color: var(--text); }
.tag-row.active { background: var(--surface-3); color: var(--text); }
.tag-row.active .tag-name { font-weight: 600; }
.tag-row .swatch { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.tag-row .tag-name { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tag-row .tag-count { font-family: var(--mono); font-size: 11px; color: var(--text-faint); }
.tag-row .tag-edit { opacity: 0; font-size: 12px; padding: 0 4px; }
.tag-row:hover .tag-edit { opacity: 0.6; }
.tag-row .tag-edit:hover { opacity: 1; color: var(--accent); }
.sidebar .sys-mark { color: var(--accent); }

/* ---- Main ---- */
.main { grid-area: main; overflow-y: auto; padding: 18px; }
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
}

.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  display: flex; flex-direction: column;
  transition: border-color .12s, transform .12s;
  position: relative;
}
.card:hover { border-color: var(--border-2); }
.card.selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }

.card .thumb-wrap {
  position: relative; aspect-ratio: 16 / 10; background: var(--surface-2);
  overflow: hidden; cursor: pointer;
}
.card .thumb-wrap img { width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; }
.card .thumb-fallback {
  width:100%; height:100%; display:grid; place-items:center;
  color: var(--text-faint); font-family: var(--mono); font-size: 12px; gap: 8px;
}
.card .thumb-fallback img { width: 40px; height: 40px; object-fit: contain; }

.card .select-box {
  position: absolute; top: 8px; left: 8px;
  width: 22px; height: 22px; border-radius: 6px;
  background: rgba(0,0,0,.55); border: 1px solid var(--border-2);
  display: none; place-items: center; cursor: pointer; z-index: 2;
}
body.select-mode .card .select-box { display: grid; }
.card.selected .select-box { background: var(--accent); border-color: var(--accent); }
.card .select-box .chk { color: #1a1408; font-weight: 800; opacity: 0; }
.card.selected .select-box .chk { opacity: 1; }

.card .video-badge {
  position: absolute; bottom: 8px; right: 8px;
  background: rgba(0,0,0,.7); color: var(--accent);
  font-family: var(--mono); font-size: 11px; padding: 3px 7px; border-radius: 5px;
}
.card .pending-badge {
  position: absolute; top: 8px; right: 8px;
  background: rgba(0,0,0,.6); color: var(--accent);
  font-family: var(--mono); font-size: 10px; padding: 3px 7px; border-radius: 5px;
  text-transform: uppercase; letter-spacing: .5px;
}

.card .body { padding: 12px 13px 13px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.card .title { font-weight: 600; font-size: 14px; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.card .desc { color: var(--text-dim); font-size: 12.5px; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.card .chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip {
  font-size: 10.5px; font-family: var(--mono);
  background: var(--surface-3); color: var(--text-dim);
  padding: 2px 7px; border-radius: 4px; border: 1px solid var(--border);
}
.chip.gen { color: var(--accent); border-color: var(--accent-dk); }
.card .meta {
  margin-top: auto; padding-top: 8px; border-top: 1px solid var(--border);
  display: flex; justify-content: space-between;
  font-family: var(--mono); font-size: 10.5px; color: var(--text-faint);
}
/* Live Update cards' second meta row (open count + "Next: ...") - sits
   directly under .meta with no extra border. */
.card .meta-next {
  display: flex; justify-content: space-between; margin-top: 2px;
  font-family: var(--mono); font-size: 10.5px; color: var(--text-faint);
}

/* ---- Empty state (also covers #loading - the initial "waiting for the
   first real data" placeholder shown before boot() has anything to render
   yet, see index.html) ---- */
.empty, .loading {
  display: grid; place-items: center; height: 70%;
  color: var(--text-faint); text-align: center; gap: 10px;
}
.empty .big, .loading .big { font-size: 17px; color: var(--text-dim); }

/* ---- Context menu ---- */
.ctx {
  position: fixed; z-index: 100; min-width: 200px;
  background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: 8px; padding: 5px; box-shadow: 0 10px 30px rgba(0,0,0,.5);
  display: none;
}
.ctx.show { display: block; }
.ctx-item {
  padding: 8px 11px; border-radius: 6px; cursor: pointer; font-size: 13px;
  display: flex; align-items: center; gap: 9px;
}
.ctx-item:hover { background: var(--surface-3); }
.ctx-item.danger { color: var(--danger); }
.ctx-sep { height: 1px; background: var(--border); margin: 5px 6px; }
.ctx-sub { font-size: 10px; text-transform: uppercase; letter-spacing: 1px;
  color: var(--text-faint); padding: 7px 11px 3px; }
.ctx-scroll { max-height: 260px; overflow-y: auto; overscroll-behavior: contain;
  margin: 2px 0; padding-right: 2px; }
.ctx-scroll::-webkit-scrollbar { width: 9px; }
.ctx-scroll::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 5px; }
.ctx-check { display: inline-block; width: 14px; text-align: center; color: var(--accent); }
.ctx-done { justify-content: center; font-weight: 600; color: var(--accent);
  background: var(--surface-3); margin-top: 3px; }
.ctx-done:hover { background: var(--surface-4, var(--surface-3)); filter: brightness(1.15); }

/* ---- Modal ---- */
.modal-bg {
  position: fixed; inset: 0; background: rgba(0,0,0,.6);
  display: none; place-items: center; z-index: 200;
}
.modal-bg.show { display: grid; }
.modal {
  background: var(--surface); border: 1px solid var(--border-2);
  border-radius: 12px; width: 480px; max-width: 92vw; max-height: 88vh;
  overflow-y: auto; padding: 22px;
}
.modal h3 { margin: 0 0 4px; font-size: 17px; }
.modal .sub { color: var(--text-faint); font-family: var(--mono); font-size: 11px;
  margin-bottom: 18px; word-break: break-all; }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 12px; color: var(--text-dim);
  margin-bottom: 6px; font-weight: 600; }
.field input, .field textarea {
  width: 100%; background: var(--bg); border: 1px solid var(--border-2);
  border-radius: 8px; padding: 9px 11px; color: var(--text); font-family: var(--ui);
  font-size: 14px; outline: none; resize: vertical;
}
.field input:focus, .field textarea:focus { border-color: var(--accent-dk); }
.field .hint { font-size: 11px; color: var(--text-faint); margin-top: 5px; font-family: var(--mono); }
.field .hint a { display: block; margin-top: 4px; color: var(--accent); text-decoration: none; }
.field .hint a:hover { text-decoration: underline; }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 8px; }

/* selection action bar */
.selbar {
  position: fixed; bottom: 0; left: 248px; right: 0;
  background: var(--surface-2); border-top: 1px solid var(--border-2);
  padding: 12px 18px; display: none; align-items: center; gap: 14px; z-index: 50;
}
body.select-mode .selbar { display: flex; }
.selbar .count { font-family: var(--mono); color: var(--accent); }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 6px;
  border: 3px solid var(--surface); }
::-webkit-scrollbar-track { background: transparent; }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* =========================================================================
   v1.1 additions: nested categories, drag-and-drop, custom confirm,
   category modal with parent, recommend checkboxes
   ========================================================================= */

/* nested category indent + expand toggle */
.tag-row.child { padding-left: 30px; }
.tag-row.child2 { padding-left: 48px; }
.tag-row .twisty {
  width: 14px; flex: none; text-align: center; color: var(--text-faint);
  font-size: 10px; cursor: pointer; user-select: none;
}
.tag-row .twisty:hover { color: var(--accent); }
.tag-row .twisty.placeholder { visibility: hidden; }

/* drag-and-drop */
.card[draggable="true"] { cursor: grab; }
.card.dragging { opacity: 0.45; }
.tag-row.drop-target { outline: 2px dashed var(--accent); outline-offset: -2px;
  background: var(--surface-3); color: var(--text); }
.tag-row.drop-target .tag-name { color: var(--accent); }

/* custom confirm dialog (so we control button order: No is leftmost) */
.confirm-box { width: 420px; }
.confirm-box .msg { color: var(--text-dim); line-height: 1.5; margin-bottom: 4px; }
.confirm-box .detail { font-family: var(--mono); font-size: 12px; color: var(--text-faint);
  word-break: break-all; margin-bottom: 18px; }

/* structured move/copy dialog (single-website drag-and-drop) - labeled
   Website / From Category / To Category rows instead of one hand-written
   sentence. See moveCopyDialog()'s `structured` branch in app.js. */
.movecopy-box h3 { margin-bottom: 18px; }
.movecopy-box .mc-site-title { font-weight: 600; margin-bottom: 2px; }
.movecopy-box .mc-site-url { margin-bottom: 16px; }
.movecopy-box .mc-cats { margin-bottom: 18px; }
.movecopy-box .mc-row { display: flex; gap: 6px; font-size: 13px; line-height: 1.7; }
.movecopy-box .mc-row + .mc-row { margin-top: 12px; }
.movecopy-box .mc-label { color: var(--text-dim); flex: 0 0 100px; }
.movecopy-box .mc-value { color: var(--text); font-weight: 600; }

/* generic faint helper text used inside dynamically-built modals (restore
   dialogs, plan-selection gate, device-limit gate) */
.hint { font-size: 11px; color: var(--text-faint); font-family: var(--mono); }

/* Small "i in a circle" info badge - hover shows a native tooltip via its
   title attribute. Placeholder text for now (see index.html); swap the
   title="..." on each one for the real explanation whenever it's written. */
.info-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 50%; flex-shrink: 0;
  border: 1px solid var(--text-faint); color: var(--text-faint);
  font-size: 10px; font-family: var(--mono); font-style: italic;
  cursor: default; user-select: none;
}
.info-icon:hover { border-color: var(--accent); color: var(--accent); }

/* mandatory tier-selection gate + device-limit gate (see ensurePlanGate() /
   showPlanSelectionGate() / showDeviceLimitGate() in app.js) */
.plan-row {
  display: block; border: 1px solid var(--border-2); border-radius: 8px;
  padding: 10px 12px; margin-bottom: 8px; background: var(--surface-2);
  cursor: pointer;
}
.plan-row:has(input:checked) { border-color: var(--accent); background: var(--surface-3); }
.plan-row-head { display: flex; align-items: center; gap: 8px; }
.plan-row-head input[type="radio"] { margin: 0; }

/* checkbox list for recommended categories */
.checklist { display: flex; flex-direction: column; gap: 2px; max-height: 260px;
  overflow-y: auto; margin-top: 4px; }
.check-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px;
  border-radius: 8px; cursor: pointer; border: 1px solid transparent;
}
.check-item:hover { background: var(--surface-2); }
.check-item.on { background: var(--surface-2); border-color: var(--border-2); }
.check-item .box {
  width: 20px; height: 20px; border-radius: 5px; border: 1px solid var(--border-2);
  display: grid; place-items: center; flex: none; background: var(--bg);
}
.check-item.on .box { background: var(--accent); border-color: var(--accent); }
.check-item .box .tick { color: #1a1408; font-weight: 800; font-size: 12px; opacity: 0; }
.check-item.on .box .tick { opacity: 1; }
.check-item .label { flex: 1; }
.check-item .label .path { color: var(--text-faint); font-size: 11px; font-family: var(--mono); }
.check-item .label.sys-mark { color: var(--accent); }
.check-item.child { padding-left: 30px; }
.check-item.recommended .label::after {
  content: "suggested"; font-family: var(--mono); font-size: 9.5px; color: var(--accent);
  border: 1px solid var(--accent-dk); border-radius: 4px; padding: 1px 5px; margin-left: 8px;
  text-transform: uppercase; letter-spacing: .5px;
}
.new-cat-row { display: flex; gap: 8px; margin-top: 10px; }
.new-cat-row input { flex: 1; }

/* small select styled like inputs */
.field select {
  width: 100%; background: var(--bg); border: 1px solid var(--border-2);
  border-radius: 8px; padding: 9px 11px; color: var(--text); font-family: var(--ui);
  font-size: 14px; outline: none;
}
.field select:focus { border-color: var(--accent-dk); }

/* ---- Model download progress ---- */
.progress-track { height: 11px; background: var(--surface-3); border: 1px solid var(--border);
  border-radius: 7px; overflow: hidden; margin: 12px 0 6px; }
.progress-fill { height: 100%; width: 0%; background: var(--accent); transition: width .3s ease; }
#setLlm { width: 100%; padding: 8px 10px; border-radius: 7px; background: var(--surface-2);
  color: var(--text); border: 1px solid var(--border); font-size: 13px; }

/* ---- Backfill queue badge ---- */
.queue-badge {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: 999px; font-size: 12px; font-weight: 600;
  background: rgba(242,165,65,.14); color: var(--accent);
  border: 1px solid rgba(242,165,65,.35); white-space: nowrap;
}
.queue-badge::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent); animation: queuePulse 1.4s ease-in-out infinite;
}
@keyframes queuePulse { 0%,100% { opacity: .35; } 50% { opacity: 1; } }

/* ---- Category drag-and-drop (reorder / nest) ---- */
.tag-row[draggable="true"] { cursor: grab; }
.tag-row.drop-before { box-shadow: inset 0 2px 0 0 var(--accent); }
.tag-row.drop-after  { box-shadow: inset 0 -2px 0 0 var(--accent); }
.tag-row.drop-nest   { background: rgba(242,165,65,.18);
  outline: 1px dashed var(--accent); outline-offset: -2px; border-radius: 6px; }

/* ---- AutoTags (AI-suggested) vs Categories ---- */
.chip.auto { background: rgba(242,165,65,.16); color: var(--accent);
  border: 1px solid rgba(242,165,65,.4); font-weight: 600; }
.chip.cat { background: var(--surface-2); color: var(--text-faint);
  border: 1px solid var(--border); }
/* Video progress "(place / duration)" - same gold as the live-freq/never-close
   indicators (actively tracked data, not an AI feature), shown as the
   leftmost chip ahead of the categories. */
.chip.dur { background: rgba(227,179,65,.14); color: #e3b341;
  border: 1px solid rgba(227,179,65,.4); font-weight: 700; }

/* ---- Collapsible sidebar sections (Categories / AutoTags) ---- */
.side-section {
  display: flex; align-items: center; gap: 6px;
  padding: 10px 12px 4px; cursor: pointer; user-select: none;
  font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-faint);
}
.side-section:hover { color: var(--text); }
.side-section .sec-twisty { width: 12px; font-size: 10px; }
.side-empty { padding: 4px 12px 8px 30px; color: var(--text-faint); font-size: 12px; font-style: italic; }
.autotag-row .tag-name { color: var(--accent); }

/* ---- Search box + scope dropdown ---- */
.search-wrap { position: relative; }
.search { padding-right: 30px; }
.search-clear {
  position: absolute; top: 50%; right: 7px; transform: translateY(-50%);
  border: none; background: transparent; color: #e5484d; font-size: 13px;
  font-weight: 800; cursor: pointer; padding: 3px 6px; line-height: 1; z-index: 41;
  border-radius: 6px;
}
.search-clear:hover { color: #ff6369; background: rgba(229,72,77,.12); }
.cat-ctx {
  position: fixed; z-index: 300; min-width: 170px;
  background: var(--surface); border: 1px solid var(--border-2);
  border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.4); padding: 5px;
}
.cat-ctx .item {
  padding: 8px 12px; font-size: 13px; border-radius: 7px; cursor: pointer;
  color: var(--text); white-space: nowrap;
}
.cat-ctx .item:hover { background: var(--surface-2, rgba(255,255,255,.06)); }
.cat-ctx-header {
  padding: 6px 12px 8px; margin-bottom: 4px; font-size: 12px; line-height: 1.4;
  color: var(--text-faint, #9aa); white-space: normal; max-width: 230px;
  border-bottom: 1px solid var(--border-2);
}
.search-scopes {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 40;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 8px 26px rgba(0,0,0,.35); overflow: hidden;
}
.scope-opt {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 12px; font-size: 13px; cursor: pointer; color: var(--text);
}
.scope-opt:hover { background: var(--surface-2); }
.scope-opt .dot {
  width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid var(--text-faint); flex: 0 0 auto;
}
.scope-group { padding: 8px 12px 3px; font-size: 10px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-faint); font-family: var(--mono); }
.scope-div { height: 1px; background: var(--border); margin: 3px 0; }
.search-banner { margin: 0 0 12px; padding: 8px 12px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--text-faint); font-size: 12px; }
.search-banner b { color: var(--accent); font-weight: 600; }
.scope-opt.active .dot { border-color: var(--accent); background:
  radial-gradient(circle, var(--accent) 0 40%, transparent 45%); }
.scope-opt.active { color: var(--accent); font-weight: 600; }

/* ---- Bulk move control in the selection bar ---- */
.move-group { display: inline-flex; align-items: center; gap: 6px; }
body:not(.select-mode) .selbar { /* unchanged */ }

/* ---- Toast ---- */
#afdToast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%) translateY(12px);
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); border-radius: 9px;
  padding: 11px 16px; font-size: 13.5px; max-width: 460px; z-index: 200;
  box-shadow: 0 10px 30px rgba(0,0,0,.4); opacity: 0; pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
}
#afdToast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---- Quiet Live Update notifications ---- */
.lu-star {
  margin-left: 6px;
  color: var(--star-color, #4169e1);
  font-size: 13px;
  animation: lu-star-pulse 1.1s ease-in-out infinite;
}
@keyframes lu-star-pulse {
  0%, 100% { opacity: .18; text-shadow: 0 0 3px currentColor; }
  50%      { opacity: 1;  text-shadow: 0 0 10px currentColor; }
}

/* Changed page's thumbnail breathes from full brightness down to ~50% and back. */
.thumb-wrap.changed-glow {
  position: relative;
  animation: thumb-breathe 1.6s ease-in-out infinite;
  box-shadow: 0 0 0 2px var(--star-color, #4169e1), 0 0 14px var(--star-color, #4169e1);
  border-radius: 8px;
}
@keyframes thumb-breathe {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(.5); }
}

/* ---- "New Category" box in the right-click menu ---- */
.ctx-newcat {
  width: calc(100% - 16px); margin: 4px 8px 2px; padding: 6px 8px;
  background: var(--surface-2); border: 1px dashed var(--border);
  border-radius: 6px; color: var(--text); font-size: 12.5px; outline: none;
}
.ctx-newcat::placeholder { color: var(--text-faint); font-style: italic; }
.ctx-newcat:focus { border-style: solid; border-color: var(--accent); }

/* ---- Category checklist inside the Edit modal ---- */
.edit-catlist {
  max-height: 200px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 8px; padding: 4px;
  display: flex; flex-direction: column; gap: 1px;
}
.edit-check {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 6px; cursor: pointer; font-size: 13px;
}
.edit-check:hover { background: var(--surface-2); }
.edit-check .box {
  width: 16px; height: 16px; border: 1.5px solid var(--text-faint);
  border-radius: 4px; display: inline-flex; align-items: center;
  justify-content: center; flex: 0 0 auto;
}
.edit-check .tick { font-size: 11px; color: #fff; opacity: 0; }
.edit-check.on .box { background: var(--accent); border-color: var(--accent); }
.edit-check.on .tick { opacity: 1; }
.edit-check .path { color: var(--text-faint); font-size: 11px; margin-left: 6px; }
.edit-newcat { width: 100%; margin-top: 6px; }

/* ---- Thumbnail picker inside the Edit modal ---- */
.edit-thumb-row { display: flex; gap: 12px; align-items: center; }
.edit-thumb-preview {
  width: 108px; height: 72px; flex: 0 0 auto; border-radius: 8px;
  overflow: hidden; background: var(--surface-2); border: 1px solid var(--border);
}
.edit-thumb-preview img { width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; }
.edit-thumb-preview .thumb-fallback {
  width: 100%; height: 100%; display: grid; place-items: center;
  color: var(--text-faint); font-family: var(--mono); font-size: 11px;
}
.edit-thumb-actions { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }

/* Drag-to-reorder within a category: a colored insertion line above/below the
   card the dragged item will land next to. */
.card.reorder-before, .card.reorder-after { position: relative; }
.card.reorder-before::before, .card.reorder-after::after {
  content: ""; position: absolute; left: 0; right: 0; height: 3px;
  background: var(--accent); border-radius: 2px; z-index: 6; pointer-events: none;
}
.card.reorder-before::before { top: -3px; }
.card.reorder-after::after  { bottom: -3px; }

/* Settings "title bar" — product branding at the very top of the Settings modal. */
.npi-titlebar {
  margin: -4px 0 14px; padding: 12px 14px; border-radius: 10px;
  background: linear-gradient(135deg, rgba(65,105,225,.18), rgba(65,105,225,.05));
  border: 1px solid rgba(65,105,225,.35); text-align: center;
}
.npi-title1 { font-size: 18px; font-weight: 700; letter-spacing: .3px; color: var(--text, #e8ecf5); }
.npi-title2 { font-size: 14px; opacity: .85; margin-top: 2px; }
.npi-title2 span { opacity: .7; font-size: 12px; }

/* Live Update check-frequency badge shown in gold before the card description. */
.live-freq { color: #e3b341; font-weight: 700; }

/* "Never close" gold indicators: on the card (before the description) and the
   "● ACTIVE" marker in the right-click menu. */
.desc .never-close { color: #e3b341; font-weight: 700; }
.ctx-item .nc-tag { color: #e3b341; font-weight: 700; margin-left: 4px; }

/* Hostname tooltip that appears above the cursor after it holds still over a
   card for a bit (see wireHoverTooltip in app.js) - handy when a card's title
   or thumbnail alone doesn't make it obvious which site it actually is. */
.hover-host-tip {
  position: fixed;
  transform: translate(-50%, calc(-100% - 10px));
  background: var(--surface-2, var(--surface));
  border: 1px solid var(--border-2, var(--border));
  color: var(--text);
  font-family: var(--mono);
  font-size: 11.5px;
  padding: 4px 9px;
  border-radius: 6px;
  pointer-events: none;
  z-index: 500;
  box-shadow: 0 4px 14px rgba(0,0,0,.35);
  white-space: nowrap;
}

/* =========================================================================
   Settings: left-nav / right-pane layout (mirrors a typical app preferences
   screen instead of one long scrolling list). Every field inside keeps the
   exact same #id it always had - only its container changed - so nothing in
   app.js needed to change to read/write these values.
   ========================================================================= */
/* Fixed height (not just a max), via a selector specific enough to beat the
   base .modal rule's own max-height/overflow-y regardless of source order -
   so the window is the SAME size on every tab. Without this, a tab with few
   fields (e.g. Videos) made the whole dialog shrink, then jump back to full
   size on a tab with more fields (e.g. General) - felt like the window was
   bouncing around just from clicking between left-nav items. Scales with the
   screen (min() with a screen-relative unit) but never exceeds 3/4 of it;
   panes with less content just leave blank space at the bottom instead of
   resizing anything. Only .settings-panes scrolls internally when a tab's
   content doesn't fit - the titlebar, nav, and Close/Save buttons stay put. */
.modal.settings-modal {
  width: 760px;
  height: min(75vh, 760px);
  max-height: min(75vh, 760px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.settings-body {
  display: flex; gap: 20px; align-items: stretch;
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border);
  flex: 1; min-height: 0;
}
.settings-nav {
  flex: 0 0 168px; display: flex; flex-direction: column; gap: 2px;
}
.settings-nav-item {
  display: block; width: 100%; text-align: left; background: transparent;
  border: none; color: var(--text-dim); padding: 10px 12px; border-radius: 8px;
  cursor: pointer; font-size: 13.5px; font-weight: 600; font-family: var(--ui);
}
.settings-nav-item:hover { background: var(--surface-2); color: var(--text); }
.settings-nav-item.active { background: var(--accent); color: #1a1408; }
.settings-panes { flex: 1; min-width: 0; min-height: 0; overflow-y: auto; padding-right: 6px; }
.settings-pane { display: none; }
.settings-pane.active { display: block; }

/* Sub-section headers WITHIN a pane (e.g. "Trash" / "Rescan" / "Automated
   Clean Up" inside the Clean Up tab) - was previously unstyled (plain text),
   now reads clearly as a small caps label like the sidebar's own headers. */
.section-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 1px;
  font-weight: 700; color: var(--text-faint); margin: 18px 0 8px;
}
.settings-pane .section-label:first-child { margin-top: 0; }

/* "Never auto-close" rows: Specific websites / Whole websites, each with an
   edit (pencil) and remove (trash) icon button instead of the old flat list
   with a single text "Remove" button. */
.nc-subhead {
  font-size: 12px; font-weight: 600; color: var(--text-dim); margin: 10px 0 6px;
}
.nc-subhead:first-child { margin-top: 0; }
/* Each of the two lists in the Configure Never Auto-Close window (Specific
   websites / Whole websites) scrolls on its own within a capped height,
   rather than the window itself growing without bound as rules pile up. */
.nc-list {
  max-height: 200px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 8px; padding: 6px;
  display: flex; flex-direction: column; gap: 6px;
}
.nc-row {
  display: flex; align-items: center; gap: 8px; justify-content: space-between;
  padding: 7px 9px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface-2);
}
.nc-row .nc-value {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-family: var(--mono); font-size: 12px; color: var(--text-dim);
}
.nc-row .nc-actions { display: flex; gap: 4px; flex: none; }
.nc-icon-btn {
  background: transparent; border: 1px solid var(--border-2); color: var(--text-faint);
  border-radius: 6px; width: 26px; height: 26px; display: grid; place-items: center;
  cursor: pointer; font-size: 12px; padding: 0;
}
.nc-icon-btn:hover { color: var(--accent); border-color: var(--accent-dk); background: var(--surface-3); }
.nc-icon-btn.danger:hover { color: var(--danger); border-color: #4a2a2c; background: var(--surface-3); }

/* Yes/No toggle switch - used by Bug Recorder's "Allow screen capture"
   (Settings > My Account, Tester tier only). Plain checkbox underneath for
   real accessibility/keyboard support; the pill/slider is just its skin. */
.switch { position: relative; display: inline-block; width: 42px; height: 24px; flex: none; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch .slider {
  position: absolute; inset: 0; background: var(--surface-3); border: 1px solid var(--border-2);
  border-radius: 999px; transition: background .15s, border-color .15s;
}
.switch .slider::before {
  content: ""; position: absolute; width: 16px; height: 16px; left: 3px; top: 50%;
  transform: translateY(-50%); background: var(--text-dim); border-radius: 50%;
  transition: transform .15s, background .15s;
}
.switch input:checked + .slider::before { transform: translate(18px, -50%); background: var(--accent); }
.switch input:focus-visible + .slider { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Bug Recorder's always-on-top "Stop Recording" overlay - z-index 900 sits
   above every modal (200), toast (200), and tooltip (500) in this app, so
   it's reachable no matter what's open on screen while a recording runs. */
.bugrec-overlay {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
  z-index: 900; display: flex; align-items: center; gap: 10px;
  background: var(--surface); border: 1px solid var(--danger);
  border-radius: 999px; padding: 8px 10px 8px 16px;
  box-shadow: 0 6px 20px rgba(0,0,0,.45);
}
.bugrec-overlay #bugRecOverlayLabel {
  font-size: 13px; color: var(--text); font-weight: 600;
}
.bugrec-overlay #bugRecOverlayLabel::before {
  content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 8px;
  border-radius: 50%; background: var(--danger); vertical-align: middle;
  animation: bugrec-pulse 1.2s ease-in-out infinite;
}
@keyframes bugrec-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
