/* Specter dashboard — app shell.

   Layout is a thin server rail, a sidebar with the server head and grouped nav,
   and a content area that leads with stat cards. The look is near-black with one
   Specter-blue accent and flat rounded cards: depth comes from a hair of border
   and a slightly lighter surface, not glow. Identity stays specterX (the ghost,
   a faint blue drift), the geometry is calm and roomy. */

:root {
  --bg:        #111113;
  --rail:      #0C0C0E;
  --side:      #161619;
  --surface:   #1C1C21;
  --surface-2: #232329;
  --line:      #26262C;
  --line-2:    #32323A;
  --text:      #EDEEF2;
  --muted:     #9AA0AA;
  --faint:     #6B6F7A;

  /* One accent: Specter blue. Everything interactive derives from it. */
  --a1:        #4AA3FF;
  --a1-hi:     #6FB7FF;
  --a1-rgb:    74, 163, 255;

  --green:     #3BC66B;
  --red:       #E5484D;

  --r:    8px;
  --r-lg: 12px;
}

* { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Geist', system-ui, -apple-system, sans-serif;
  font-size: 14px;
  line-height: 1.55;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}
code, .mono { font-family: 'Geist Mono', ui-monospace, monospace; }

/* faint blue drift, well behind everything and kept subtle */
.wisps { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; opacity: 0.35; }
.wisp {
  position: absolute; bottom: -12vh; width: 2px; height: 2px; border-radius: 50%;
  background: rgba(var(--a1-rgb), 0.55); animation: floatup linear infinite; opacity: 0;
}
.wisp:nth-child(even) { background: rgba(120, 190, 255, 0.5); }
@keyframes floatup {
  0%{transform:translateY(0);opacity:0} 12%{opacity:var(--op,0.3)}
  88%{opacity:var(--op,0.3)} 100%{transform:translateY(-116vh) translateX(var(--drift,20px));opacity:0}
}

/* --- pre-auth (sign-in / loading) ------------------------------------------ */

#gate { position: relative; z-index: 2; height: 100%; overflow-y: auto; }
.pane { animation: rise 0.3s cubic-bezier(0.2,0.8,0.2,1) both; }
.centred { text-align: center; max-width: 460px; margin: 0 auto; padding-top: 15vh; }
@keyframes rise { from{opacity:0;transform:translateY(8px)} to{opacity:1} }

.hero-ghost {
  width: 84px; height: 84px; margin: 0 auto 20px; display: block;
  filter: drop-shadow(0 0 34px rgba(var(--a1-rgb), 0.3));
  animation: bob 6s ease-in-out infinite;
}
@keyframes bob { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-4px)} }

.centred h1 { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; margin: 0 0 6px; }

.discord {
  display: inline-flex; align-items: center; gap: 10px;
  margin: 14px 0 18px; padding: 12px 28px;
  background: #5865F2; color: #fff; text-decoration: none;
  border-radius: var(--r); font-weight: 600; font-size: 15px;
  transition: background 0.15s, transform 0.14s;
}
.discord:hover { background: #6b76f5; transform: translateY(-1px); }
.centred .fine { max-width: 42ch; margin: 10px auto 0; }

/* --- app shell ------------------------------------------------------------- */

.app { position: relative; z-index: 2; display: grid; grid-template-columns: 64px 244px 1fr; height: 100%; }

/* server rail */
.rail {
  background: var(--rail); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  padding: 12px 0; overflow-y: auto;
}
.rail::-webkit-scrollbar { width: 0; }
.rail-btn {
  width: 44px; height: 44px; border-radius: 14px; flex: none;
  background: var(--surface); border: 1px solid var(--line);
  display: grid; place-items: center; cursor: pointer; overflow: hidden;
  font-weight: 700; color: var(--muted); text-decoration: none; position: relative;
  transition: border-radius 0.18s, border-color 0.15s, transform 0.15s, background 0.15s;
}
.rail-btn img { width: 100%; height: 100%; object-fit: cover; }
.rail-btn:hover { border-radius: 16px; transform: translateY(-1px); color: var(--text); }
.rail-btn.active { border-color: var(--a1); border-radius: 16px; }
.rail-btn.active::before {
  content: ""; position: absolute; left: -12px; top: 50%; transform: translateY(-50%);
  width: 4px; height: 24px; border-radius: 0 3px 3px 0; background: var(--a1);
}
.rail-home {
  background: linear-gradient(135deg, rgba(var(--a1-rgb),0.22), transparent);
  margin-bottom: 4px;
}
.rail-home img { width: 27px; height: 27px; object-fit: contain;
  filter: drop-shadow(0 0 6px rgba(var(--a1-rgb),0.45)); }
.rail-sep { width: 26px; height: 1px; background: var(--line); flex: none; }

/* sidebar */
.side {
  background: var(--side); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; overflow: hidden;
}
.side-head {
  padding: 22px 18px 18px; text-align: center; border-bottom: 1px solid var(--line);
}
.side-head .sv-icon {
  width: 64px; height: 64px; border-radius: 18px; margin: 0 auto 12px;
  background: var(--surface-2); border: 1px solid var(--line);
  display: grid; place-items: center; font-weight: 700; font-size: 22px; color: var(--a1);
  overflow: hidden;
}
.side-head .sv-icon img { width: 100%; height: 100%; object-fit: cover; }
.side-head .sv-name { font-weight: 700; font-size: 15.5px; letter-spacing: -0.01em; }
.side-head .sv-sub { color: var(--faint); font-size: 11.5px; margin-top: 3px; }

.side-nav { flex: 1; overflow-y: auto; padding: 12px 10px; }
.nav-group { font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--faint); padding: 14px 10px 6px; }
.nav-group:first-child { padding-top: 2px; }
.nav-item {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 10px; border-radius: var(--r); cursor: pointer;
  color: var(--muted); text-decoration: none; font-size: 13.5px; font-weight: 500;
  transition: background 0.13s, color 0.13s;
}
.nav-item:hover { background: rgba(255,255,255,0.045); color: var(--text); }
.nav-item.active { background: rgba(var(--a1-rgb), 0.14); color: var(--a1); }
/* Icons are PNG masks so they take the item's text colour. */
.nav-item .ico {
  width: 17px; height: 17px; flex: none; background: currentColor;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
}
.nav-item .badge {
  margin-left: auto; font-size: 10px; font-family: 'Geist Mono', monospace;
  background: rgba(var(--a1-rgb),0.18); color: var(--a1);
  padding: 1px 7px; border-radius: 20px;
}

.side-foot {
  padding: 13px 18px; border-top: 1px solid var(--line);
  color: var(--faint); font-size: 12.5px; text-decoration: none;
}
.side-foot:hover { color: var(--red); }

/* content */
.content { overflow-y: auto; padding: 34px 40px 70px; position: relative; }
.content h1 { font-size: 23px; font-weight: 700; letter-spacing: -0.02em; margin: 0 0 5px; }
.content .muted { color: var(--muted); margin: 0 0 26px; font-size: 13.5px; }

/* stat cards */
.cards { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); margin-bottom: 28px; }
.scard {
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); padding: 18px 19px;
  display: flex; flex-direction: column; gap: 11px;
  transition: border-color 0.15s, transform 0.15s;
}
.scard:hover { border-color: var(--line-2); transform: translateY(-1px); }
.scard .top { display: flex; align-items: center; gap: 11px; }
.scard .label { font-size: 13px; color: var(--muted); }
.scard .value { font-size: 27px; font-weight: 700; letter-spacing: -0.02em; }
.scard .value.off { color: var(--faint); }
.scard .sub { font-size: 11.5px; color: var(--faint); }

/* --- settings panels ------------------------------------------------------- */

.panel {
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--surface); margin-bottom: 14px; overflow: hidden; max-width: 660px;
}
.panel > h2 {
  margin: 0; padding: 13px 17px; font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.13em; color: var(--muted);
  border-bottom: 1px solid var(--line);
}
.row {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 12px 17px; border-bottom: 1px solid rgba(255,255,255,0.035);
}
.row:last-child { border-bottom: none; }
.row label { color: var(--text); font-size: 13.5px; }

input[type="text"], input[type="number"], select, textarea {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--line-2); border-radius: var(--r);
  padding: 8px 11px; font-family: inherit; font-size: 13.5px; min-width: 180px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
textarea { width: 100%; min-height: 96px; resize: vertical; font-size: 13px; }
.row.stack { display: block; }
.row.stack label { display: block; margin-bottom: 9px; }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: rgba(var(--a1-rgb), 0.6);
  box-shadow: 0 0 0 3px rgba(var(--a1-rgb), 0.13);
}

.switch { position: relative; width: 44px; height: 25px; flex: none; }
.switch input { opacity: 0; width: 0; height: 0; }
.slider {
  position: absolute; inset: 0; cursor: pointer;
  background: rgba(255,255,255,0.08); border: 1px solid var(--line-2);
  border-radius: 25px; transition: background 0.18s, border-color 0.18s;
}
.slider:before {
  content: ""; position: absolute; width: 17px; height: 17px; left: 3px; top: 3px;
  background: #757A8A; border-radius: 50%;
  transition: transform 0.2s cubic-bezier(0.2,0.8,0.2,1), background 0.18s;
}
.switch input:checked + .slider { background: rgba(var(--a1-rgb), 0.22); border-color: rgba(var(--a1-rgb), 0.5); }
.switch input:checked + .slider:before { transform: translateX(18px); background: var(--a1); }

.savebar { display: flex; align-items: center; gap: 14px; padding: 6px 0; max-width: 660px; }
button.primary {
  background: var(--a1); color: #08131F;
  font-family: inherit; font-weight: 700; font-size: 13.5px;
  border: none; border-radius: var(--r); padding: 10px 24px; cursor: pointer;
  transition: background 0.15s, transform 0.12s, box-shadow 0.15s;
  box-shadow: 0 2px 12px rgba(var(--a1-rgb), 0.28);
}
button.primary:hover { background: var(--a1-hi); transform: translateY(-1px); }
button.primary:disabled { opacity: 0.45; cursor: default; transform: none; box-shadow: none; }
.ok  { color: var(--a1); }
.bad { color: var(--red); }

.fine { color: var(--faint); font-size: 12px; }

/* scrollbars, quiet */
.content::-webkit-scrollbar, .side-nav::-webkit-scrollbar { width: 8px; }
.content::-webkit-scrollbar-thumb, .side-nav::-webkit-scrollbar-thumb {
  background: var(--line-2); border-radius: 8px;
}

@media (max-width: 760px) {
  .app { grid-template-columns: 56px 1fr; }
  .side { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  .wisps { display: none; }
}

/* --- coloured stat badges --------------------------------------------------
   icons8's coloured/glass styles are premium; the free tier is monochrome. So
   the coloured badge LOOK is built here from the per-card accent (--c): a tinted
   tile, a soft gloss, and the monochrome icon filled with that accent. The
   overview reads like Vetox's coloured stat icons, from free assets. */

.scard { position: relative; overflow: hidden; }
.scard .badge-ico {
  position: relative; width: 36px; height: 36px; border-radius: 10px; flex: none;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--c, var(--a1)) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--c, var(--a1)) 34%, transparent);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.16),
              0 2px 10px color-mix(in srgb, var(--c, var(--a1)) 20%, transparent);
}
.scard .badge-ico::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(150deg, rgba(255,255,255,0.26), transparent 55%);
  pointer-events: none;
}
.scard .badge-ico .ico {
  width: 19px; height: 19px; background: var(--c, var(--a1));
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
}
.scard .value.on { color: var(--c, var(--a1)); }

/* --- loading + error states ----------------------------------------------- */

.loading { display: flex; align-items: center; gap: 11px; color: var(--muted); padding: 8px 0; }
.spinner {
  width: 17px; height: 17px; border-radius: 50%;
  border: 2px solid var(--line-2); border-top-color: var(--a1);
  animation: spin 0.7s linear infinite; flex: none;
}
@keyframes spin { to { transform: rotate(360deg); } }

.retry {
  margin-top: 14px; background: var(--surface-2); color: var(--text);
  border: 1px solid var(--line-2); border-radius: var(--r);
  padding: 8px 18px; font-family: inherit; font-size: 13px; cursor: pointer;
}
.retry:hover { border-color: var(--a1); }

/* sidebar skeleton while the first fetch is in flight */
.skeleton { padding: 12px 10px; }
.sk-row { height: 30px; border-radius: var(--r); margin-bottom: 6px;
  background: linear-gradient(90deg, var(--surface) 25%, var(--surface-2) 50%, var(--surface) 75%);
  background-size: 200% 100%; animation: shimmer 1.3s ease-in-out infinite; }
@keyframes shimmer { to { background-position: -200% 0; } }
