/* ══════════════════════════════════════════════════════════════
   COMPONENTS — unified component library. Old class names used
   across the 64 templates are kept as aliases so existing markup
   keeps working without a find-and-replace pass on every page.
══════════════════════════════════════════════════════════════ */

/* ── CARD ──────────────────────────────────────────
   Canonical: .card / .card-head / .card-title / .card-badge / .card-body
   .card--accent (top gradient bar) === legacy .module-card ── */
.card,.module-card,.feat-card,.sp-card,.mw-card,.metric-card,.price-card{
  background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;transition:border-color var(--t)
}
.card:hover,.module-card:hover{border-color:var(--border3)}
.card--accent::before,.module-card::before{content:'';display:block;height:2px;background:linear-gradient(90deg,transparent,var(--accent,var(--c)),transparent)}
.card-head{padding:.75rem 1rem;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between}
.card-title{font-size:.68rem;letter-spacing:.15em;text-transform:uppercase;font-family:var(--mono);color:var(--accent,var(--c))}
.card-badge{font-size:.58rem;font-family:var(--mono);padding:1px 7px;border-radius:8px;background:var(--cg2);color:var(--accent,var(--c));border:1px solid var(--border2)}
.card-body{padding:.85rem 1rem;max-height:280px;overflow-y:auto}
.card-body::-webkit-scrollbar{width:3px}
.card-body::-webkit-scrollbar-thumb{background:rgba(34,184,212,.2);border-radius:2px}

/* Mission card v2 (dashboard-specific variant, kept as its own name) */
.mission-card-v2{position:relative;background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden;transition:border-color var(--t),transform var(--t),box-shadow var(--t)}
.mission-card-v2:hover{border-color:var(--border3);transform:translateY(-1px);box-shadow:var(--shadow-md)}
.mission-accent{position:absolute;left:0;top:0;bottom:0;width:3px}
.mission-accent.complete{background:var(--g)}.mission-accent.running{background:var(--a)}
.mission-accent.failed{background:var(--r)}.mission-accent.planning{background:var(--c)}
.glass{background:var(--bg-card);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid var(--border)}
.glass-panel{background:var(--bg-card);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm)}

/* ── STAT / KPI TILE ─────────────────────────────────
   Canonical: .stat / .stat-value / .stat-label
   Aliases: .metric-box/.metric-val/.metric-lbl (highest usage, module.css) ── */
.stat,.metric-box{text-align:center;background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius-md);padding:.75rem 1.2rem;min-width:100px}
.stat-value,.metric-val{font-family:var(--disp);font-size:1.6rem;font-weight:700;color:var(--accent,var(--c));line-height:1}
.stat-value.loading,.metric-val.loading{animation:pulse-val 1.2s infinite}
@keyframes pulse-val{0%,100%{opacity:.3}50%{opacity:.8}}
.stat-label,.metric-lbl{font-size:.58rem;color:var(--muted);letter-spacing:.12em;text-transform:uppercase;margin-top:.2rem}

/* ── BUTTONS ─────────────────────────────────────────
   Canonical: .btn + .btn--primary/ghost/pill/danger
   Aliases keep working: .action-btn, .dep-btn, .ob-btn, .conn-btn,
   .deploy-btn-big, .tb-pill, .new-btn ── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;cursor:pointer;border:1px solid var(--border2);border-radius:var(--radius-sm);background:var(--bg3);color:var(--text);font-family:var(--body);font-size:.82rem;padding:.6rem 1.2rem;transition:all .18s}
.btn:hover{border-color:var(--border3);background:var(--cg2)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn--primary{background:var(--c);color:var(--bg);border:none;font-family:var(--disp);font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.btn--primary:hover{background:#fff}
.btn--ghost{background:transparent;color:var(--muted)}
.btn--pill{border-radius:var(--radius-full)}
.btn--danger{color:var(--r);border-color:rgba(248,113,113,.35);background:rgba(248,113,113,.06)}
.btn--danger:hover{background:rgba(248,113,113,.15);border-color:rgba(248,113,113,.6)}

.action-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:.4rem;margin-bottom:.75rem}
.action-btn{background:var(--bg3);border:1px solid var(--border);color:var(--text);padding:.55rem .65rem;border-radius:var(--radius-sm);cursor:pointer;font-size:.73rem;text-align:left;transition:all .2s;line-height:1.4;font-family:var(--body);position:relative;overflow:hidden}
.action-btn:hover{border-color:var(--accent,var(--c));background:var(--cg2);transform:translateY(-1px);box-shadow:var(--shadow-md)}
.action-btn:active{transform:translateY(0);box-shadow:none}
.action-btn.loading{opacity:.6;cursor:not-allowed;pointer-events:none}
.action-btn::before{content:'';position:absolute;top:0;left:-100%;width:50%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.05),transparent);transition:left .5s ease;pointer-events:none}
.action-btn:hover::before{left:150%}
.action-btn b{color:var(--accent,var(--c));display:block;margin-bottom:.15rem;font-size:.68rem;letter-spacing:.04em}

.dep-btn,.ob-btn{background:var(--c);color:var(--bg);font-family:var(--disp);font-weight:700;font-size:.85rem;letter-spacing:.06em;text-transform:uppercase;padding:.65rem 1.6rem;border:none;border-radius:var(--radius-sm);cursor:pointer;transition:background .18s,transform .12s;display:flex;align-items:center;justify-content:center;gap:.5rem;min-height:40px}
.dep-btn:hover,.ob-btn:hover{background:#fff}
.dep-btn:active,.ob-btn:active{transform:scale(.98)}
.dep-btn:disabled,.ob-btn:disabled{opacity:.5;cursor:not-allowed}

.deploy-btn-big{width:100%;background:linear-gradient(135deg,var(--accent,var(--c)),var(--v));color:#000;border:none;border-radius:var(--radius-md);padding:.75rem;font-size:.85rem;font-weight:700;cursor:pointer;letter-spacing:.1em;margin-top:.75rem;transition:opacity .15s}
.deploy-btn-big:hover{opacity:.88}
.deploy-btn-big:disabled{opacity:.5;cursor:not-allowed;background:var(--bg3);color:var(--muted)}

.conn-btn{display:inline-flex;align-items:center;justify-content:center;background:var(--c);color:var(--bg);font-family:var(--disp);font-weight:700;font-size:.82rem;letter-spacing:.1em;text-transform:uppercase;padding:.6rem 1.4rem;border:none;cursor:pointer;clip-path:polygon(0 0,calc(100% - 8px) 0,100% 8px,100% 100%,8px 100%,0 calc(100% - 8px));transition:background .18s,opacity .18s;text-decoration:none}
.conn-btn:hover{background:#fff}
.conn-btn-ghost{background:transparent;border:1px solid var(--border2);color:var(--muted);font-size:.78rem;clip-path:none;border-radius:var(--radius-sm)}
.conn-btn-ghost:hover{border-color:var(--c);color:var(--c);background:var(--cg2)}
.conn-btn-sm{font-size:.72rem;padding:.45rem .9rem}
.conn-btn-row{display:flex;gap:.6rem;flex-wrap:wrap;margin-top:.75rem}

.tb-pill{font-family:var(--mono);font-size:.6rem;font-weight:600;letter-spacing:.1em;text-decoration:none;padding:.28rem .75rem;border-radius:20px;border:1px solid;transition:all .15s;white-space:nowrap;display:inline-flex;align-items:center;gap:.3rem}
button.tb-pill{cursor:pointer}
.tb-pill:active{transform:scale(.96);opacity:.88}
.tb-pill-red{color:var(--r);border-color:rgba(248,113,113,.35);background:rgba(248,113,113,.06)}
.tb-pill-red:hover{background:rgba(248,113,113,.15);border-color:rgba(248,113,113,.6)}
.tb-pill-cyan{color:var(--c);border-color:rgba(6,182,212,.35);background:rgba(6,182,212,.06)}
.tb-pill-cyan:hover{background:rgba(6,182,212,.15);border-color:rgba(6,182,212,.6)}
.tb-pill-violet{color:var(--v);border-color:rgba(139,92,246,.35);background:rgba(139,92,246,.06)}
.tb-pill-violet:hover{background:rgba(139,92,246,.15);border-color:rgba(139,92,246,.6)}
.tb-pill-green{color:var(--g);border-color:rgba(16,185,129,.35);background:rgba(16,185,129,.06)}
.tb-pill-green:hover{background:rgba(16,185,129,.15);border-color:rgba(16,185,129,.6)}
.tb-pill-amber{color:var(--a);border-color:rgba(245,158,11,.35);background:rgba(245,158,11,.06)}
.tb-pill-amber:hover{background:rgba(245,158,11,.18);border-color:rgba(245,158,11,.6)}
.tb-pill-teal{color:#14b8a6;border-color:rgba(20,184,166,.35);background:rgba(20,184,166,.06)}
.tb-pill-teal:hover{background:rgba(20,184,166,.18);border-color:rgba(20,184,166,.6)}

/* ── BADGES ────────────────────────────────────────── */
.badge{display:inline-flex;align-items:center;gap:.3rem;padding:2px 8px;border-radius:20px;font-size:.62rem;font-family:var(--mono);letter-spacing:.08em;font-weight:500}
.badge--success,.badge-complete{background:var(--gg);color:var(--g);border:1px solid rgba(52,211,153,.25)}
.badge--warning,.badge-running{background:rgba(251,191,36,.1);color:var(--a);border:1px solid rgba(251,191,36,.25)}
.badge--danger,.badge-failed{background:rgba(248,113,113,.1);color:var(--r);border:1px solid rgba(248,113,113,.25)}
.badge--info,.badge-standard{background:var(--cg2);color:var(--c);border:1px solid rgba(34,184,212,.2)}
.badge-complex{background:var(--vg);color:var(--v);border:1px solid rgba(139,124,246,.2)}
.badge-hyper{background:rgba(249,115,22,.08);color:#f97316;border:1px solid rgba(249,115,22,.2)}
.tag-pill{display:inline-flex;align-items:center;gap:.2rem;padding:1px 8px;border-radius:12px;font-size:.6rem;font-family:var(--mono);background:var(--vg);color:var(--v);border:1px solid rgba(139,124,246,.25);cursor:pointer;transition:all .15s}
.tag-pill:hover{background:rgba(139,124,246,.2)}
.role-badge{font-family:var(--mono);font-size:.55rem;letter-spacing:.08em;padding:1px 7px;border-radius:20px;border:1px solid;text-transform:uppercase;flex-shrink:0}
.role-badge.owner{color:var(--a);border-color:rgba(251,191,36,.3);background:rgba(251,191,36,.07)}
.role-badge.member{color:var(--muted);border-color:var(--border2);background:transparent}
.pri{font-family:var(--mono);font-size:.52rem;padding:2px 8px;border-radius:20px;border:1px solid;text-transform:uppercase}
.pri.high{color:var(--r);border-color:rgba(248,113,113,.3);background:rgba(248,113,113,.06)}
.pri.medium{color:var(--a);border-color:rgba(251,191,36,.3);background:rgba(251,191,36,.06)}
.pri.low{color:var(--muted);border-color:var(--border2)}

/* ── MODAL ─────────────────────────────────────────── */
.modal-overlay,.doc-modal{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:800;display:flex;align-items:center;justify-content:center;padding:1rem;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}
.modal-overlay.hidden,.doc-modal.hidden{display:none}
.modal-card,.doc-modal-card{background:var(--bg2);border:1px solid var(--border2);border-radius:var(--radius-lg);width:100%;max-width:620px;max-height:80vh;display:flex;flex-direction:column;overflow:hidden;box-shadow:var(--shadow-lg)}
.modal-head,.doc-modal-head{display:flex;align-items:center;justify-content:space-between;padding:.85rem 1.25rem;border-bottom:1px solid var(--border);background:var(--bg3)}
.modal-title,.doc-modal-title{font-family:var(--mono);font-size:.65rem;color:var(--c);letter-spacing:.18em;text-transform:uppercase}
.modal-close,.doc-modal-close{background:none;border:none;color:var(--muted);cursor:pointer;font-size:.9rem;padding:.2rem .4rem}
.modal-close:hover,.doc-modal-close:hover{color:var(--r)}
.modal-body,.doc-modal-body{padding:1.1rem 1.25rem;overflow-y:auto;display:flex;flex-direction:column;gap:.85rem}
.modal-foot{padding:.85rem 1.25rem;border-top:1px solid var(--border);display:flex;gap:.75rem;align-items:center}
@media(max-width:640px){
  .modal-card,.doc-modal-card{width:calc(100vw - 1.5rem);max-height:92vh;margin:0}
}

/* ── SIDEBAR nav rows (used inside .sidebar/.set-nav — see layout.css for shell) ── */
.integ-list{display:flex;flex-direction:column;gap:.35rem}
.integ-row{display:flex;align-items:center;gap:.5rem;font-family:var(--body);font-size:.74rem;color:var(--muted)}
.id-dot{width:6px;height:6px;border-radius:50%;background:var(--muted);flex-shrink:0}
.id-dot.on{background:var(--g);box-shadow:0 0 4px var(--g)}

/* ── TABLE — responsive table primitive ──────────────
   Add class "rtable" alongside a <table>'s existing class, wrap the
   <table> in .rtable-wrap. Below 640px each row reflows into a
   stacked card via data-label attributes on each <td>. ── */
.rtable-wrap{width:100%;overflow-x:auto}
@media(max-width:640px){
  .rtable thead{display:none}
  .rtable,.rtable tbody,.rtable tr,.rtable td{display:block;width:100%}
  .rtable tr{margin-bottom:.75rem;border:1px solid var(--border);border-radius:var(--radius-sm);overflow:hidden}
  .rtable td{display:flex;justify-content:space-between;gap:.75rem;padding:.55rem .8rem;border-bottom:1px solid var(--border);text-align:right}
  .rtable td:last-child{border-bottom:none}
  .rtable td::before{content:attr(data-label);font-family:var(--mono);font-size:.6rem;color:var(--muted);text-transform:uppercase;letter-spacing:.08em;text-align:left;flex-shrink:0}
}

/* ── EMPTY STATE — one definition replacing 45 local redeclarations ── */
.empty-state{text-align:center;padding:2rem;color:var(--muted);font-size:.76rem;font-family:var(--mono);line-height:2}
.empty-state a{color:var(--accent,var(--c));cursor:pointer;text-decoration:underline}
.feed-item{padding:.45rem 0;border-bottom:1px solid var(--border);display:flex;gap:.5rem;align-items:flex-start;transition:background .15s}
.feed-item:hover{background:rgba(128,128,128,.04);border-radius:4px;padding-left:.3rem;margin-left:-.3rem}
.feed-dot{width:6px;height:6px;border-radius:50%;background:var(--accent,var(--c));margin-top:5px;flex-shrink:0}
.feed-text{font-size:.74rem;color:var(--muted);line-height:1.5;flex:1}
.feed-text b{color:var(--text)}

/* ── FORM FIELDS — canonical .fg (fixes the dashboard.css/settings.css
   collision: this is settings.css's flex version, a strict superset —
   handles input/textarea/select, the dashboard.css version only handled
   block-layout <input>) ── */
.fg{display:flex;flex-direction:column;gap:.35rem;margin-bottom:1rem}
.fg label{font-family:var(--mono);font-size:.58rem;color:var(--c);letter-spacing:.18em;text-transform:uppercase}
.fg label .hint{color:var(--muted);text-transform:none;letter-spacing:0;font-size:.58rem}
.fg input,.fg textarea,.fg select{
  background:var(--bg);border:1px solid var(--border2);border-radius:var(--radius-sm);
  color:var(--text);font-family:var(--body);font-size:.85rem;padding:.6rem .9rem;
  outline:none;transition:border-color .18s,box-shadow .18s;width:100%;
}
.fg textarea{resize:vertical;min-height:140px;line-height:1.6;font-size:.82rem}
.fg select{cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%236b7280' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .75rem center}
.fg input:focus,.fg textarea:focus,.fg select:focus{border-color:var(--c);box-shadow:0 0 0 3px var(--cg)}
.fg input::placeholder,.fg textarea::placeholder{color:var(--muted)}
.persona-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.4rem}
.pb{background:var(--bg);border:1px solid var(--border2);border-radius:var(--radius-sm);color:var(--muted);font-family:var(--mono);font-size:.62rem;letter-spacing:.06em;padding:.5rem .4rem;cursor:pointer;transition:all .18s;text-align:center}
.pb:hover{color:var(--c);border-color:var(--border3);background:var(--cg2)}
.pb.active{color:var(--bg);border-color:var(--c);background:var(--c)}

/* ── MISC SHARED ROWS (used by several module/settings pages) ── */
.intel-item{padding:.5rem 0;border-bottom:1px solid var(--border);font-size:.76rem}
.intel-item:last-child{border-bottom:none}
.intel-time{font-size:.62rem;color:var(--muted);font-family:var(--mono);float:right}
.intel-text{color:var(--text);line-height:1.5;margin-bottom:.2rem}
.config-row{display:flex;align-items:center;gap:.75rem;padding:.45rem 0;border-bottom:1px solid var(--border);font-size:.76rem}
.config-row:last-child{border-bottom:none}
.config-label{color:var(--muted);flex:1}
.config-val{color:var(--text);font-family:var(--mono);font-size:.7rem}
.config-edit{background:var(--cg2);border:1px solid rgba(34,184,212,.2);color:var(--accent,var(--c));font-size:.62rem;padding:.15rem .5rem;border-radius:4px;cursor:pointer;font-family:var(--mono)}

.notif-toast{position:fixed;bottom:1.5rem;right:1.5rem;background:var(--bg2);border:1px solid rgba(34,184,212,.3);border-radius:9px;padding:.7rem 1rem;font-size:.76rem;color:var(--c);z-index:999;opacity:0;transform:translateY(10px);transition:all .3s;pointer-events:none}
.notif-toast.show{opacity:1;transform:translateY(0)}
.toast{position:fixed;bottom:2rem;right:2rem;background:var(--bg2);border:1px solid var(--border2);color:var(--c);font-family:var(--mono);font-size:.72rem;padding:.7rem 1.1rem;z-index:1000;letter-spacing:.08em;border-radius:var(--radius-sm);box-shadow:var(--shadow-md)}
.toast.hidden{display:none}
@media(max-width:640px){
  .notif-toast{right:.75rem;bottom:.75rem;left:.75rem;width:auto}
  .toast{left:.5rem;right:.5rem;width:auto;bottom:.5rem}
}

/* ── SKELETON LOADING ── */
.skeleton{background:linear-gradient(90deg,var(--bg-card) 25%,var(--bg-input) 50%,var(--bg-card) 75%);background-size:200% 100%;animation:shimmer-bg 1.5s infinite;border-radius:6px}
.skeleton-text{height:14px;margin-bottom:8px}
.skeleton-text.w60{width:60%}.skeleton-text.w80{width:80%}.skeleton-text.w40{width:40%}
@keyframes shimmer-bg{0%{background-position:200% 0}100%{background-position:-200% 0}}

/* ── THEME PICKER — shared popover opened by any #theme-btn (dashboard
   topbar, module .tb-links, settings .set-header, ar.html's HUD button).
   Built/positioned by static/js/theme.js. The same .theme-grid is also
   used inline (not as a popover) by settings.html's Appearance panel —
   grid-template-columns is auto-fill so it reflows correctly in both the
   narrow popover and the much wider Settings card.
   Each .theme-swatch previews its OWN theme's real colors via inline
   --sw-bg/--sw-fg custom properties (set from THEMES metadata in
   theme.js) so every swatch looks genuinely different — the bug this
   replaces had every button share the same background. ── */
.theme-picker{position:fixed;z-index:900;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);padding:.85rem;width:236px;max-width:calc(100vw - 1.5rem)}
.theme-picker.hidden{display:none}
.theme-picker-label{font-family:var(--mono);font-size:.6rem;color:var(--muted);letter-spacing:.18em;text-transform:uppercase;margin-bottom:.6rem;padding:0 .2rem}
.theme-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:.5rem}
/* The popover is a fixed 236px-wide widget, not a reflowing card — force its
   own grid to a steady 2 columns. (At that width auto-fill's minmax(110px,…)
   would resolve to only 1 column, which looked wrong: a tall single-file
   list instead of the compact grid this widget was designed as.) */
.theme-picker .theme-grid{grid-template-columns:repeat(2,1fr)}
.theme-swatch{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:.4rem;background:var(--sw-bg,var(--bg3));border:2px solid var(--border);border-radius:var(--radius-md);padding:.55rem .6rem;cursor:pointer;transition:border-color var(--t),transform .1s;text-align:left}
.theme-swatch:hover{border-color:var(--sw-fg,var(--c));transform:translateY(-1px)}
.theme-swatch.active{border-color:var(--sw-fg,var(--c));box-shadow:0 0 0 1px var(--sw-fg,var(--c))}
.theme-swatch-dot{width:20px;height:20px;border-radius:50%;background:var(--sw-fg,var(--c));box-shadow:0 0 8px var(--sw-fg,var(--c))}
.theme-swatch-label{font-family:var(--mono);font-size:.68rem;color:var(--sw-fg,var(--c));font-weight:600}
.theme-swatch-check{position:absolute;top:.4rem;right:.5rem;font-size:.7rem;color:var(--sw-fg,var(--c));opacity:0}
.theme-swatch.active .theme-swatch-check{opacity:1}
@media(max-width:420px){
  .theme-picker{width:calc(100vw - 1.5rem)}
}

/* Font size row, reused by the picker (dashboard/module) and Settings' own Appearance panel */
.font-size-grid{display:flex;gap:.5rem;margin-top:.5rem}
.font-size-btn{flex:1;background:var(--bg3);border:1px solid var(--border);color:var(--muted);padding:.4rem;border-radius:var(--radius-sm);cursor:pointer;font-size:.75rem;font-family:var(--body);transition:all .18s}
.font-size-btn:hover{border-color:var(--border3);color:var(--text)}
.font-size-btn.active{color:var(--bg);border-color:var(--c);background:var(--c)}

/* ── STATUS DOTS ── */
.dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.dot-live{background:var(--c-success);box-shadow:0 0 8px var(--c-success);animation:pulse-g 2s infinite}
.dot-running{background:var(--c-warning);box-shadow:0 0 8px var(--c-warning);animation:pulse-a 1.2s infinite}
.dot-failed{background:var(--c-danger);box-shadow:0 0 6px var(--c-danger)}
.dot-idle{background:var(--muted)}
@keyframes pulse-g{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.5;transform:scale(1.3)}}
@keyframes pulse-a{0%,100%{opacity:1}50%{opacity:.4}}
