/* =========================================================
   Galaxy Panel - Design system
   Deep-space blues with a violet/cyan nebula accent.
   Display face: Space Grotesk / Body: Inter
   ========================================================= */

:root {
  --bg: #070a16;
  --bg-elevated: #0c1128;
  --surface: #10152f;
  --surface-2: #171d40;
  --border: #232c56;
  --border-soft: #1a2142;

  --text: #eef1ff;
  --text-dim: #a2aad6;
  --text-faint: #6b7299;

  --blue: #3d6bfa;
  --blue-bright: #6a8cff;
  --violet: #8b5cf6;
  --cyan: #35d0ff;
  --green: #34d399;
  --amber: #fbbf24;
  --red: #fb5079;

  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 22px;

  --shadow-glow: 0 0 0 1px var(--border-soft), 0 20px 60px -20px rgba(61, 107, 250, 0.35);
  --font-display: 'Space Grotesk', 'Inter', system-ui, sans-serif;
  --font-body: 'Inter', system-ui, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
}

body {
  position: relative;
  z-index: 0;
  background-image:
    radial-gradient(ellipse 900px 500px at 12% -10%, rgba(139, 92, 246, 0.16), transparent 60%),
    radial-gradient(ellipse 800px 600px at 110% 10%, rgba(53, 208, 255, 0.10), transparent 55%),
    radial-gradient(ellipse 1200px 800px at 50% 120%, rgba(61, 107, 250, 0.10), transparent 60%),
    radial-gradient(ellipse 700px 500px at 90% 90%, rgba(251, 80, 121, 0.05), transparent 55%);
  min-height: 100vh;
}

h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  letter-spacing: -0.02em;
  margin: 0;
}
h1 {
  background: linear-gradient(120deg, var(--text) 40%, var(--blue-bright) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

a { color: var(--blue-bright); text-decoration: none; }
a:hover { color: var(--cyan); }
p { color: var(--text-dim); line-height: 1.6; margin: 0 0 1em; }

::selection { background: var(--violet); color: white; }

:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
}

/* ---------- Starfield (signature element) ---------- */
.starfield {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}
.starfield::before, .starfield::after {
  content: "";
  position: absolute;
  inset: -10%;
  background-repeat: repeat;
  background-image:
    radial-gradient(1.5px 1.5px at 20% 30%, #ffffff 100%, transparent),
    radial-gradient(1px 1px at 60% 70%, #ffffff 100%, transparent),
    radial-gradient(1px 1px at 85% 15%, #cdd6ff 100%, transparent),
    radial-gradient(1.5px 1.5px at 40% 85%, #ffffff 100%, transparent),
    radial-gradient(1px 1px at 10% 60%, #cdd6ff 100%, transparent),
    radial-gradient(1px 1px at 75% 45%, #ffffff 100%, transparent);
  background-size: 340px 340px;
  opacity: 0.55;
  animation: star-drift 90s linear infinite;
  will-change: transform;
}
.starfield::after {
  background-size: 500px 500px;
  opacity: 0.3;
  animation-duration: 140s;
  animation-direction: reverse;
}
@keyframes drift {
  from { background-position: 0 0; }
  to { background-position: 300px 200px; }
}
/* Same visual drift, but moves the whole (oversized) layer via transform
   instead of animating background-position. transform runs on the GPU
   compositor thread - no per-frame repaint of the gradients, which is
   what made the background-position version noticeably heavy on
   lower-end hardware. Only safe to use where the oversized layer can't
   trigger a scrollbar (fixed positioning, or an overflow:hidden wrapper) -
   see each usage below. */
@keyframes star-drift {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-300px, -200px, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .starfield::before, .starfield::after { animation: none; }
}

/* =========================================================
   Galaxy theming: app-wide atmosphere
   The landing page already had the starfield/glow identity -
   this brings the same "deep space" feel into the actual
   dashboard/admin interior, which used to be flat solid panels.
   ========================================================= */

/* Custom scrollbar, everywhere - matches the theme instead of
   the browser's default grey bar. */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--blue), var(--violet));
  border-radius: 100px;
  border: 2px solid var(--bg);
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, var(--blue-bright), var(--violet)); background-clip: padding-box; }
* { scrollbar-width: thin; scrollbar-color: var(--violet) transparent; }

/* Soft glowing focus ring on inputs instead of a plain browser outline -
   feels more like "console UI", less like a stock form. */
input:focus-visible, select:focus-visible, textarea:focus-visible,
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--blue-bright);
  box-shadow: 0 0 0 3px rgba(61, 107, 250, 0.25);
}

/* Sidebar: a faint nebula glow behind the nav instead of a flat panel,
   plus a very quiet starfield so it doesn't feel like a plain sidebar
   from any other admin template. */
.sidebar {
  position: relative;
  background:
    radial-gradient(ellipse 260px 200px at 15% 0%, rgba(139, 92, 246, 0.16), transparent 65%),
    radial-gradient(ellipse 220px 260px at 100% 70%, rgba(53, 208, 255, 0.08), transparent 60%),
    var(--bg-elevated);
}
/* The star layer lives in its own wrapper with its own overflow:hidden,
   separate from .sidebar's own overflow-y:auto (used for scrolling long
   nav lists). That's what lets the oversized, transform-animated star
   pattern move on the cheap GPU compositor path without ever
   contributing to .sidebar's own scrollable area (which is what caused
   the phantom scrollbar bug the last time this used transform directly
   on a child of the scrolling element itself). */
.sidebar > .sidebar-stars {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
.sidebar-stars::before {
  content: "";
  position: absolute;
  inset: -20% -20%;
  background-image:
    radial-gradient(1px 1px at 18% 22%, #ffffff 100%, transparent),
    radial-gradient(1px 1px at 68% 55%, #cdd6ff 100%, transparent),
    radial-gradient(1px 1px at 40% 78%, #ffffff 100%, transparent),
    radial-gradient(1px 1px at 85% 30%, #cdd6ff 100%, transparent),
    radial-gradient(1px 1px at 25% 90%, #ffffff 100%, transparent),
    radial-gradient(1px 1px at 55% 12%, #cdd6ff 100%, transparent);
  background-size: 220px 220px;
  opacity: 0.4;
  animation: star-drift 110s linear infinite;
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .sidebar-stars::before { animation: none; }
}
.sidebar > * { position: relative; z-index: 1; }

.brand-mark { position: relative; }
.brand-mark::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--blue-bright), var(--violet) 70%, transparent 100%);
  opacity: 0.45;
  filter: blur(9px);
  z-index: -1;
  animation: brand-pulse 3.5s ease-in-out infinite;
}
@keyframes brand-pulse {
  0%, 100% { opacity: 0.35; transform: scale(0.94); }
  50% { opacity: 0.65; transform: scale(1.08); }
}

/* Cards lift and glow a little on hover instead of sitting completely
   inert - makes the interface feel responsive rather than static. */
.card, .stat-card, .role-chip, .faq-item {
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.card:hover, .stat-card:hover {
  border-color: var(--border);
  box-shadow: 0 16px 40px -22px rgba(61, 107, 250, 0.45);
}

/* A slow-drifting nebula wash behind the main content area, well below
   everything else - subtle on purpose, this is a workspace, not a hero
   section, but it stops the interior pages from feeling flat compared
   to the landing page. */
.main { position: relative; }
.main::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(ellipse 800px 550px at 88% -8%, rgba(53, 208, 255, 0.22), transparent 60%),
    radial-gradient(ellipse 700px 750px at -8% 105%, rgba(139, 92, 246, 0.24), transparent 60%),
    radial-gradient(ellipse 700px 600px at 40% 40%, rgba(61, 107, 250, 0.12), transparent 65%),
    radial-gradient(ellipse 550px 450px at 95% 90%, rgba(251, 80, 121, 0.1), transparent 60%);
  pointer-events: none;
}
.main::after {
  content: "";
  position: fixed;
  inset: -20% -20%;
  z-index: -1;
  background-image:
    radial-gradient(2px 2px at 15% 20%, #ffffff 100%, transparent),
    radial-gradient(1.5px 1.5px at 35% 65%, #cdd6ff 100%, transparent),
    radial-gradient(1.5px 1.5px at 55% 15%, #ffffff 100%, transparent),
    radial-gradient(2px 2px at 75% 80%, #cdd6ff 100%, transparent),
    radial-gradient(1.5px 1.5px at 90% 35%, #ffffff 100%, transparent),
    radial-gradient(1.5px 1.5px at 22% 92%, #cdd6ff 100%, transparent),
    radial-gradient(1.5px 1.5px at 65% 45%, #ffffff 100%, transparent),
    radial-gradient(1.5px 1.5px at 5% 45%, #ffffff 100%, transparent),
    radial-gradient(1.5px 1.5px at 45% 5%, #cdd6ff 100%, transparent),
    radial-gradient(2px 2px at 82% 60%, #ffffff 100%, transparent);
  background-size: 380px 380px;
  opacity: 0.7;
  pointer-events: none;
  animation: star-drift 130s linear infinite;
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  .brand-mark::after { animation: none; }
  .main::after { animation: none; }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.7em 1.3em;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.92rem;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: linear-gradient(135deg, var(--blue), var(--violet));
  color: white;
  box-shadow: 0 8px 24px -8px rgba(61, 107, 250, 0.6);
  position: relative;
  overflow: hidden;
}
.btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,0.35) 50%, transparent 70%);
  transform: translateX(-100%);
  transition: transform 0.6s ease;
}
.btn-primary:hover::after { transform: translateX(100%); }
.btn-primary:hover { box-shadow: 0 10px 30px -6px rgba(139, 92, 246, 0.65); color: white; }
.btn-secondary {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--border);
}
.btn-secondary:hover { border-color: var(--blue-bright); color: var(--text); }
.btn-ghost {
  background: transparent;
  color: var(--text-dim);
  border-color: var(--border);
}
.btn-ghost:hover { color: var(--text); border-color: var(--blue-bright); }
.btn-danger {
  background: rgba(251, 80, 121, 0.12);
  color: var(--red);
  border-color: rgba(251, 80, 121, 0.35);
}
.btn-danger:hover { background: rgba(251, 80, 121, 0.2); color: var(--red); }
.btn-success {
  background: rgba(52, 211, 153, 0.12);
  color: var(--green);
  border-color: rgba(52, 211, 153, 0.38);
}
.btn-success:hover { background: rgba(52, 211, 153, 0.22); border-color: var(--green); color: var(--green); }
.btn-warning {
  background: rgba(251, 146, 60, 0.12);
  color: #fb923c;
  border-color: rgba(251, 146, 60, 0.4);
}
.btn-warning:hover { background: rgba(251, 146, 60, 0.22); border-color: #fb923c; color: #fb923c; }
.btn-sm { padding: 0.45em 0.9em; font-size: 0.8rem; }
.btn-block { width: 100%; }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }

/* ---------- Forms ---------- */
label { display: block; font-size: 0.82rem; color: var(--text-dim); margin-bottom: 0.4em; font-weight: 600; }
input:not([type="checkbox"]):not([type="radio"]), select, textarea {
  width: 100%;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.75em 0.9em;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: 0.94rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
/* Checkboxes/radios are meant to stay their small, native size - the
   rule above is written for text/number/select fields and would
   otherwise stretch a checkbox's actual click target to full width
   with heavy padding, visibly shifting its little glyph away from
   where plain header text (or a label) starts in the same column. */
input[type="checkbox"], input[type="radio"] {
  width: 1.05em;
  height: 1.05em;
  margin: 0;
  padding: 0;
  vertical-align: middle;
  accent-color: var(--blue-bright);
}
input:focus, select:focus, textarea:focus {
  border-color: var(--blue-bright);
  box-shadow: 0 0 0 3px rgba(61, 107, 250, 0.25);
  outline: none;
}
textarea { resize: vertical; min-height: 100px; }
.field { margin-bottom: 1.15em; }
.field-row { display: flex; gap: 1em; align-items: flex-start; }
.field-row .field { flex: 1; }
.hint { font-size: 0.78rem; color: var(--text-faint); margin-top: 0.35em; white-space: normal; overflow-wrap: break-word; }

/* Small "(i)" info icon that shows a custom dark tooltip bubble on
   hover (desktop) or tap (mobile/touch, via the "active" class toggled
   by a tiny inline onclick - :hover alone doesn't fire reliably on
   touch, and native mobile Safari/Chrome can need two taps before a
   plain non-form element's :focus registers). :focus is kept too so
   keyboard/tab navigation still reveals it without a mouse or touch.
   Deliberately a custom bubble rather than the native title="" tooltip
   used before - the native one is unstyled, slow to appear, and (on
   touch devices) doesn't appear at all without a long-press. */
.info-tooltip { position: relative; display: inline-flex; color: var(--text-faint); cursor: help; }
.info-tooltip-text {
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-elevated);
  color: var(--text);
  border: 1px solid var(--border-soft);
  box-shadow: 0 12px 32px -12px rgba(0, 0, 0, 0.6);
  padding: 0.6em 0.85em;
  border-radius: var(--radius-sm);
  font-size: 0.78rem;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  white-space: normal;
  width: max-content;
  max-width: 220px;
  text-align: left;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s ease;
  pointer-events: none;
  z-index: 60;
}
.info-tooltip-text::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--bg-elevated);
}
.info-tooltip:hover .info-tooltip-text,
.info-tooltip:focus .info-tooltip-text,
.info-tooltip.active .info-tooltip-text {
  opacity: 1;
  visibility: visible;
}
/* For a trigger near the top of a scrolling container (e.g. a table
   header row inside .table-wrap) - "above" would get silently clipped
   by the container's own overflow instead of showing, so this flips
   the bubble (and its little pointer arrow) to open downward instead,
   where there's always room since the table's body rows are below it. */
.info-tooltip-below .info-tooltip-text {
  bottom: auto;
  top: calc(100% + 9px);
}
.info-tooltip-below .info-tooltip-text::after {
  top: auto;
  bottom: 100%;
  border-top-color: transparent;
  border-bottom-color: var(--bg-elevated);
}

.alert {
  padding: 0.85em 1.1em;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  margin-bottom: 1.2em;
  border: 1px solid transparent;
  border-left-width: 3px;
}
.alert-error { background: rgba(251, 80, 121, 0.1); border-color: rgba(251, 80, 121, 0.3); border-left-color: var(--red); color: #ffb3c4; }
.alert-success { background: rgba(52, 211, 153, 0.1); border-color: rgba(52, 211, 153, 0.3); border-left-color: var(--green); color: #8ff0cc; }
.alert-info { background: rgba(61, 107, 250, 0.1); border-color: rgba(61, 107, 250, 0.3); border-left-color: var(--blue-bright); color: #b7c6ff; }

/* ---------- Surfaces ---------- */
.card {
  background: linear-gradient(180deg, var(--surface), var(--bg-elevated));
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 1.5em;
  position: relative;
  box-shadow: 0 12px 32px -24px rgba(0, 0, 0, 0.6);
}
.card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  border-radius: var(--radius) var(--radius) 0 0;
  background: linear-gradient(90deg, transparent, var(--blue-bright), var(--violet), transparent);
  opacity: 0.6;
  pointer-events: none;
}
.card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.2em; gap: 1em; flex-wrap: wrap; }
.card-header h2, .card-header h3 { margin: 0; }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.3em 0.7em;
  border-radius: 100px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.badge-blue { background: rgba(61, 107, 250, 0.15); color: var(--blue-bright); box-shadow: 0 0 0 1px rgba(61, 107, 250, 0.2) inset; }
.badge-green { background: rgba(52, 211, 153, 0.15); color: var(--green); box-shadow: 0 0 0 1px rgba(52, 211, 153, 0.2) inset; }
.badge-amber { background: rgba(251, 191, 36, 0.15); color: var(--amber); box-shadow: 0 0 0 1px rgba(251, 191, 36, 0.2) inset; }
.badge-red { background: rgba(251, 80, 121, 0.15); color: var(--red); box-shadow: 0 0 0 1px rgba(251, 80, 121, 0.2) inset; }
.badge-gray { background: rgba(162, 170, 214, 0.15); color: var(--text-dim); }

/* ---------- Customer-facing roles (Owner / Official Staff / OG User /
   any custom ones an admin adds) - color comes from the database now
   (user_roles.color), applied inline per-badge rather than hardcoded
   here per role. This class only supplies the shared shape/spacing;
   background/color/border are set inline using each role's own color. */
.role-badge-dynamic { border-radius: 100px; padding: 0.2em 0.7em; font-weight: 600; font-size: 0.78rem; }

.pill-nav { display: flex; gap: 0.5em; flex-wrap: wrap; margin-bottom: 1.3em; }
.pill-nav a {
  padding: 0.5em 1em;
  border-radius: 100px;
  background: var(--surface-2);
  color: var(--text-dim);
  font-size: 0.84rem;
  font-weight: 600;
  border: 1px solid var(--border);
  transition: box-shadow 0.15s ease;
}
.pill-nav a.active, .pill-nav a:hover {
  background: linear-gradient(135deg, var(--blue), var(--violet));
  color: white;
  border-color: transparent;
  box-shadow: 0 4px 16px -4px rgba(139, 92, 246, 0.6);
}

/* ---------- Tables ---------- */
.table-wrap { overflow-x: auto; }
/* Used on Service Updates (added/removed/price-change tabs) to mark a
   category boundary between two consecutive rows - a plain border on
   the row above/below wouldn't stand out from the table's own normal
   row dividers, so this is a dedicated near-empty spacer row with a
   thicker, brand-colored line instead. */
.category-divider-row td { padding: 0; border-top: 3px solid var(--blue-bright); border-bottom: none; }
table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
th, td { text-align: left; padding: 0.85em 1em; border-bottom: 1px solid var(--border-soft); white-space: nowrap; }
/* Browsers give form controls a small built-in margin by default that
   plain header text doesn't have, even with identical cell padding -
   without this reset, a checkbox/number input sits visibly offset from
   where its column header starts (e.g. the Refill/Cancel columns on
   the service import review table). */
td input[type="number"] { margin: 0; vertical-align: middle; }
th { color: var(--text-faint); font-weight: 600; font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.04em; border-bottom: 1px solid var(--border-soft); }
tbody tr { transition: background 0.15s ease; }
/* No :last-child border removal here on purpose - several tables have a
   hidden <tr> (inline edit forms) after the last visible row, which would
   silently make :last-child target the wrong row and leave an inconsistent
   border behind. Every row keeps its border-bottom instead, uniformly. */
tbody tr:hover { background: rgba(61, 107, 250, 0.09); }
.import-row-clickable { cursor: pointer; }
td.wrap { white-space: normal; }

/* Category title row inside the single, page-wide /services table -
   spans every column so the whole page stays ONE continuous table
   instead of one table per category (see the HTML comment in
   services-content.ejs for why that matters: with table-layout:auto,
   a separate <table> per category computes its column widths from
   only that category's own rows, which left Price/Min/Max sitting at
   different x-positions between a short-named category and a
   long-named one). */
.services-category-row td {
  background: rgba(61, 107, 250, 0.07);
  padding: 0.85em 1em;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
  white-space: normal;
}
/* Every category row after the first gets a divider above it, so
   consecutive categories are visually separated even though they're
   just rows in the same table now, not separate cards. */
.services-category-row:not(:first-child) td { border-top: 1px solid var(--border-soft); }

/* Explicit opt-in for "this column always stays on one line, sized to
   its own content" - already the default for every td/th (see the
   base rule above), but spelled out explicitly on the columns that
   rely on it (ID, Min, Max, Price, etc.) so the intent survives even
   if that base default ever changes, and so a plain (non
   table-layout:fixed) table's columns read the same way perfectpanel-
   hosted panels mark theirs up. */
.nowrap { white-space: nowrap; }

/* Wraps a service/name cell onto a second (or third) line instead of
   cutting it off with an ellipsis - matches how perfectpanel-hosted
   panels (SMMCost, JustAnotherPanel, etc.) show their /services table:
   the name is always fully visible, breaking within its own fixed
   column width rather than being cut off or pushing later columns out
   of place. Sets its own white-space:normal rather than relying on a
   `wrap` class on the parent <td>, since the base "th, td" rule above
   defaults every cell to nowrap. overflow-wrap/word-break
   additionally let a single very long unbroken token (rare, but
   possible) still break instead of overflowing the column. display:block
   makes this start its own line, so a sibling ".hint" (description/
   category) still renders on the line(s) below it, same as before.
   Keeps the `title` attribute for consistency with the rest of the
   panel, even though the name is no longer ever visually cut off. */
.name-wrap {
  display: block;
  white-space: normal;
  overflow-wrap: break-word;
  word-break: break-word;
}

.empty-state {
  text-align: center;
  padding: 3.5em 1.5em;
  color: var(--text-faint);
}
.empty-state::before {
  content: "";
  display: block;
  width: 46px; height: 46px;
  margin: 0 auto 1em;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--blue-bright), var(--violet) 75%);
  opacity: 0.35;
}
.empty-state h3 { color: var(--text-dim); margin-bottom: 0.4em; }

/* ---------- Stat cards ---------- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 1em; margin-bottom: 1.5em; }
.stat-card {
  background: linear-gradient(180deg, var(--surface), var(--bg-elevated));
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 1.3em 1.4em;
  position: relative;
  overflow: hidden;
}
.stat-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--blue-bright);
}
.stat-card::after {
  content: "";
  position: absolute;
  right: -30px; top: -30px;
  width: 100px; height: 100px;
  background: radial-gradient(circle, rgba(139, 92, 246, 0.35), transparent 70%);
}
.stat-card .label { font-size: 0.78rem; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; }
.stat-card .value { font-family: var(--font-display); font-size: 1.9rem; margin-top: 0.25em; }

/* =========================================================
   App shell (sidebar layout for dashboard + admin)
   ========================================================= */
.app-shell { display: flex; min-height: 100vh; }

.sidebar {
  width: 250px;
  flex-shrink: 0;
  background: var(--bg-elevated);
  border-right: 1px solid var(--border-soft);
  padding: 1.4em 1.1em;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.brand { display: flex; align-items: center; gap: 0.6em; padding: 0.4em 0.5em 1.3em; }
.brand-mark {
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
}
.brand-mark img { width: 100%; height: 100%; object-fit: contain; }
.brand-name { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; }

.nav-section { margin-top: 1.2em; }
.nav-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-faint); padding: 0 0.6em; margin-bottom: 0.5em; font-weight: 700; }
.nav-label-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
}
.nav-label-toggle .nav-collapse-arrow {
  font-size: 0.95rem;
  line-height: 1;
  transition: transform 0.15s ease, color 0.15s ease;
  color: var(--text-dim);
  flex-shrink: 0;
}
.nav-label-toggle:hover .nav-collapse-arrow { color: var(--blue-bright); }
.nav-section.collapsed .nav-collapse-arrow { transform: rotate(-90deg); }
.nav-section.collapsed .nav-collapsible-body { display: none; }
.nav-link {
  display: flex; align-items: center; gap: 0.7em;
  padding: 0.65em 0.7em;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  font-size: 0.88rem;
  font-weight: 600;
  margin-bottom: 0.15em;
}
.nav-link .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text-faint); flex-shrink: 0; }
.nav-link .nav-icon { width: 16px; text-align: center; flex-shrink: 0; color: var(--text-faint); font-size: 0.88rem; }
.nav-link:hover { background: var(--surface-2); color: var(--text); }
.nav-link.active { background: linear-gradient(135deg, rgba(61,107,250,0.18), rgba(139,92,246,0.18)); color: var(--text); }
.nav-link.active .dot { background: var(--cyan); box-shadow: 0 0 8px var(--cyan); }
.nav-link.active .nav-icon { color: var(--cyan); text-shadow: 0 0 8px rgba(53, 208, 255, 0.6); }
.nav-link:hover .nav-icon { color: var(--text); }

.sidebar-footer { margin-top: auto; padding-top: 1em; border-top: 1px solid var(--border-soft); }
.balance-chip {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.8em 0.9em;
  margin-bottom: 0.8em;
}
.balance-chip .label { font-size: 0.7rem; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.05em; }
.balance-chip .value { font-family: var(--font-display); font-size: 1.2rem; margin-top: 0.15em; }

/* Balance + Role, shown once at the top of the sidebar instead of
   repeating as separate pill-shaped chips on every single page (which
   wrapped awkwardly under the page title on narrow screens). Reuses the
   sidebar's own card language (see .balance-chip above) instead of the
   free-floating pill shape those chips used elsewhere, since a full pill
   stretched across the sidebar's width looked odd. */
.sidebar-account-box {
  display: flex;
  flex-direction: column;
  gap: 0.5em;
  margin: 1em 0 1.2em;
}
.sidebar-account-box .role-chip {
  border-radius: var(--radius-sm);
  justify-content: space-between;
}

.main {
  flex: 1;
  min-width: 0;
  padding: 1.8em 2.2em 3em;
}
.topbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.6em; gap: 1em; flex-wrap: wrap; }
.topbar h1 {
  font-size: 1.5rem;
  /* Page titles ("Dashboard", "New Order", etc.) use the same font as
     the rest of the panel here, instead of the Space Grotesk display
     font other headings still use - the negative letter-spacing from
     the shared h1/h2/h3/h4 rule was tuned for Space Grotesk's
     proportions, so it's reset to normal rather than carried over onto
     a font it wasn't chosen for. The gradient text treatment stays,
     only the letterforms themselves change. */
  font-family: var(--font-body);
  letter-spacing: normal;
}
.user-menu { display: flex; align-items: center; gap: 0.8em; font-size: 0.86rem; color: var(--text-dim); }
.avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: linear-gradient(135deg, var(--violet), var(--cyan));
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; color: white; font-size: 0.85rem;
}
.role-chip {
  display: flex;
  align-items: center;
  gap: 0.6em;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 0.5em 1em;
}
.role-chip-label {
  font-size: 0.72rem;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
}
.currency-trigger {
  background: none;
  border: none;
  color: var(--text-faint);
  font-size: 0.78rem;
  font-family: var(--font-body);
  cursor: pointer;
  padding: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
}
.currency-trigger:hover { color: var(--text); }
.currency-menu {
  display: none;
  flex-direction: column;
  gap: 0.15em;
  position: fixed;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.35em;
  min-width: 100px;
  box-shadow: 0 12px 28px -8px rgba(0, 0, 0, 0.55);
  z-index: 500;
  /* Caps the list at roughly 4 visible currencies before scrolling,
     so enabling many currencies doesn't turn this into one long list
     towering over the field that opened it. Has no effect when there
     are 4 or fewer - the box is already shorter than this on its own. */
  max-height: 9.4em;
  overflow-y: auto;
}
.currency-menu.open { display: flex; }
.currency-menu-item {
  background: none;
  border: none;
  text-align: left;
  padding: 0.45em 0.7em;
  border-radius: 6px;
  font-size: 0.85rem;
  font-family: var(--font-body);
  color: var(--text-dim);
  cursor: pointer;
}
.currency-menu-item:hover { background: rgba(61, 107, 250, 0.14); color: var(--text); }
.currency-menu-item.active { background: linear-gradient(135deg, var(--blue), var(--violet)); color: white; }

/* ---------- Auth pages ---------- */
.auth-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: 2em;
  overflow: hidden;
}
.auth-wrap::before {
  content: "";
  position: absolute;
  inset: -10%;
  background-repeat: repeat;
  background-image:
    radial-gradient(1.5px 1.5px at 20% 30%, #ffffff 100%, transparent),
    radial-gradient(1px 1px at 60% 70%, #ffffff 100%, transparent),
    radial-gradient(1px 1px at 85% 15%, #cdd6ff 100%, transparent),
    radial-gradient(1.5px 1.5px at 40% 85%, #ffffff 100%, transparent),
    radial-gradient(1px 1px at 10% 60%, #cdd6ff 100%, transparent),
    radial-gradient(1px 1px at 75% 45%, #ffffff 100%, transparent);
  background-size: 340px 340px;
  opacity: 0.45;
  animation: star-drift 90s linear infinite;
  will-change: transform;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .auth-wrap::before { animation: none; }
}
.auth-card {
  width: 100%;
  max-width: 420px;
  background: linear-gradient(180deg, var(--surface), var(--bg-elevated));
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 2.4em 2.2em;
  box-shadow: var(--shadow-glow);
  position: relative;
  z-index: 1;
}
.auth-card::before {
  content: "";
  position: absolute;
  top: 0; left: 10%; right: 10%;
  height: 2px;
  border-radius: 100px;
  background: linear-gradient(90deg, transparent, var(--blue-bright), var(--violet), transparent);
  opacity: 0.7;
}
.auth-card .brand { justify-content: center; padding-bottom: 1.6em; }
.auth-card h1 { font-size: 1.4rem; text-align: center; margin-bottom: 0.3em; }
.auth-card .sub { text-align: center; color: var(--text-faint); font-size: 0.88rem; margin-bottom: 1.6em; }
.auth-foot { text-align: center; margin-top: 1.4em; font-size: 0.86rem; color: var(--text-faint); }

/* =========================================================
   Landing page
   ========================================================= */
.landing-nav {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.4em 4vw;
  position: relative; z-index: 2;
}
.landing-nav .links { display: flex; gap: 1.8em; align-items: center; }
.landing-nav .links a { color: var(--text-dim); font-size: 0.9rem; font-weight: 600; }
.landing-nav .links a:hover { color: var(--text); }

@media (max-width: 640px) {
  .landing-nav { flex-wrap: wrap; row-gap: 0.9em; padding: 1.1em 5vw; }
  .landing-nav .links { flex-wrap: wrap; justify-content: center; gap: 0.7em 1.2em; width: 100%; }
}

.hero {
  position: relative;
  padding: 6vw 4vw 5vw;
  text-align: center;
  overflow: hidden;
}
.hero-eyebrow {
  display: inline-flex; align-items: center; gap: 0.5em;
  background: var(--surface-2); border: 1px solid var(--border);
  padding: 0.4em 1em; border-radius: 100px;
  font-size: 0.78rem; color: var(--text-dim); font-weight: 600;
  margin-bottom: 1.4em; position: relative; z-index: 1;
}
.hero-eyebrow .pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--cyan); box-shadow: 0 0 10px var(--cyan); }
.hero h1 {
  font-size: clamp(2.2rem, 5vw, 4rem);
  max-width: 900px; margin: 0 auto 0.5em;
  position: relative; z-index: 1;
  background: linear-gradient(135deg, #ffffff 30%, var(--blue-bright) 70%, var(--violet) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero p.lead { font-size: 1.1rem; max-width: 620px; margin: 0 auto 2em; position: relative; z-index: 1; }
.hero-cta { display: flex; gap: 1em; justify-content: center; position: relative; z-index: 1; flex-wrap: wrap; }
.hero-stats { display: flex; gap: 3em; justify-content: center; margin-top: 3.5em; position: relative; z-index: 1; flex-wrap: wrap; }
.hero-stats .stat { text-align: center; }
.hero-stats .stat .value { font-family: var(--font-display); font-size: 2rem; }
.hero-stats .stat .label { font-size: 0.78rem; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.05em; }

.section { padding: 4vw 4vw; position: relative; z-index: 1; }
.section-head { text-align: center; max-width: 620px; margin: 0 auto 2.5em; }
.section-head h2 { font-size: clamp(1.6rem, 3vw, 2.3rem); margin-bottom: 0.5em; }

.feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.2em; max-width: 1100px; margin: 0 auto; }
.feature-card {
  background: linear-gradient(180deg, var(--surface), var(--bg-elevated));
  border: 1px solid var(--border-soft); border-radius: var(--radius);
  padding: 1.6em;
}
.feature-card .icon {
  width: 40px; height: 40px; border-radius: 10px;
  background: linear-gradient(135deg, var(--blue), var(--violet));
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 1em; font-size: 1.1rem;
}
.feature-card h3 { font-size: 1.05rem; margin-bottom: 0.4em; }
.feature-card p { font-size: 0.9rem; margin: 0; }

.pricing-table-wrap { max-width: 900px; margin: 0 auto; }

/* ---------- Supported platforms: two counter-scrolling logo rows ---------- */
.platform-marquee {
  display: flex;
  flex-direction: column;
  gap: 1.1em;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, black 8%, black 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, black 8%, black 92%, transparent);
}
.platform-track { overflow: hidden; width: 100%; }
.platform-track-inner {
  display: flex;
  gap: 1em;
  width: max-content;
}
.platform-track-a .platform-track-inner { animation: platform-scroll 75s linear infinite reverse; }
.platform-track-b .platform-track-inner { animation: platform-scroll 75s linear infinite; }
@keyframes platform-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
.platform-badge {
  display: flex;
  align-items: center;
  gap: 0.7em;
  flex-shrink: 0;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  padding: 0.9em 1.5em;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text);
  white-space: nowrap;
}
.platform-badge i { font-size: 1.35rem; color: var(--blue-bright); }
@media (prefers-reduced-motion: reduce) {
  .platform-track-a .platform-track-inner, .platform-track-b .platform-track-inner { animation: none; }
}

.landing-footer {
  border-top: 1px solid var(--border-soft);
  padding: 2.5em 4vw; text-align: center;
  color: var(--text-faint); font-size: 0.85rem;
  position: relative; z-index: 1;
}
.landing-footer-category {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-faint);
  margin-bottom: 0.6em;
}
.landing-footer-links {
  display: flex;
  justify-content: center;
  gap: 1.6em;
  flex-wrap: wrap;
  margin-bottom: 1em;
}
.landing-footer-links a {
  color: var(--text-dim);
  font-size: 0.85rem;
}
.landing-footer-links a:hover { color: var(--text); }

@media (max-width: 860px) {
  .main { padding: 1.4em; padding-top: calc(56px + 1.4em); }
  .field-row { flex-direction: column; align-items: stretch; gap: 0; }
}

/* ---------- Mobile navigation: sidebar becomes a slide-in drawer ---------- */
.mobile-topbar { display: none; }
.mobile-sidebar-backdrop { display: none; }

@media (max-width: 860px) {
  .mobile-topbar {
    display: flex;
    align-items: center;
    gap: 0.8em;
    position: fixed;
    top: 0; left: 0; right: 0;
    height: 56px;
    padding: 0 1em;
    background: var(--bg-elevated);
    border-bottom: 1px solid var(--border-soft);
    z-index: 200;
  }
  .mobile-menu-btn {
    background: none;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    width: 38px; height: 38px;
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
    flex-shrink: 0;
  }
  .mobile-topbar .brand { padding: 0; }

  .sidebar {
    position: fixed;
    top: 0; left: 0;
    height: 100vh;
    z-index: 300;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
    box-shadow: 30px 0 60px -20px rgba(0, 0, 0, 0.6);
  }
  .sidebar.mobile-open { transform: translateX(0); }

  .mobile-sidebar-backdrop.mobile-open {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(5, 8, 20, 0.6);
    z-index: 250;
  }
}

/* ---------- Category drag & drop (admin services) ---------- */
.category-card.draggable-category { cursor: grab; }
.category-card.draggable-category:active { cursor: grabbing; }
.category-card.dragging { opacity: 0.5; border-color: var(--blue-bright); }
.category-card[draggable="true"] .card-header { user-select: none; }

/* ---------- Sidebar notification badges (e.g. Support) ---------- */
.nav-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 100px;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1;
  margin-left: 0.35em;
}
.nav-count-red { background: var(--red); color: white; }
.nav-count-cyan { background: var(--cyan); color: #062430; }

/* ---------- Custom confirm/prompt dialogs (replaces native browser dialogs) ---------- */
.gp-dialog-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(5, 8, 20, 0.65);
  backdrop-filter: blur(4px);
  align-items: center;
  justify-content: center;
  z-index: 2000;
  padding: 1.5em;
}
.gp-dialog-box {
  width: 100%;
  max-width: 380px;
  background: linear-gradient(180deg, var(--surface), var(--bg-elevated));
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 1.6em;
  box-shadow: var(--shadow-glow);
}
.gp-dialog-message {
  color: var(--text);
  font-size: 0.94rem;
  line-height: 1.55;
  margin: 0 0 1.3em;
  white-space: pre-wrap;
  max-height: 50vh;
  overflow-y: auto;
}
.gp-dialog-input { margin-bottom: 1.3em; }
.gp-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.6em;
}

/* ---------- FAQ accordion ---------- */
.faq-item {
  background: linear-gradient(180deg, var(--surface), var(--bg-elevated));
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  margin-bottom: 0.9em;
  overflow: hidden;
}
.faq-question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  width: 100%;
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  padding: 1.1em 1.3em;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  color: var(--text);
}
.faq-question:hover { color: var(--blue-bright); }
.faq-question .faq-icon {
  flex-shrink: 0;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.9rem;
}
.faq-item.open .faq-icon { background: linear-gradient(135deg, var(--blue), var(--violet)); border-color: transparent; color: white; }
.faq-answer {
  display: none;
  padding: 0 1.3em 1.4em;
  color: var(--text-dim);
  font-size: 0.92rem;
  line-height: 1.65;
}
.faq-item.open .faq-answer { display: block; }

.changelog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  width: 100%;
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  padding: 1.1em 1.3em;
  color: var(--text);
}
.changelog-header:hover h2 { color: var(--blue-bright); }
.changelog-icon {
  flex-shrink: 0;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.9rem;
}
.changelog-item.open .changelog-icon { background: linear-gradient(135deg, var(--blue), var(--violet)); border-color: transparent; color: white; }
.changelog-body { display: none; }
.changelog-item.open .changelog-body { display: block; }
.changelog-body li a { color: var(--blue-bright); }
.changelog-body li a:hover { text-decoration: underline; }
.faq-answer h4 { font-family: var(--font-display); font-size: 0.92rem; color: var(--text); margin: 1.1em 0 0.4em; }
.faq-answer h4:first-child { margin-top: 0; }
.faq-answer ul { margin: 0.4em 0 0.9em; padding-left: 1.3em; }
.faq-answer li { margin-bottom: 0.3em; }
.faq-answer strong { color: var(--text); }
.faq-answer code { background: var(--surface-2); padding: 0.15em 0.4em; border-radius: 4px; font-size: 0.88em; }

/* ---------- Custom select dropdowns (see custom-select.js) ----------
   The native <select> is visually hidden (but stays in the DOM,
   focusable, and fully functional for forms/JS) and this themed
   trigger + menu takes over instead - on every screen size, not just
   mobile. Native dropdowns can't be restyled and, worse, their popup
   can render wider than the field itself when an option's text is
   long (exactly what caused the Service dropdown to spill outside its
   card on desktop) - this custom version always wraps long text
   within the field's own width instead. */
.cs-wrapper { position: relative; }
.cs-native-select {
  display: none !important;
}
.cs-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6em;
  width: 100%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.75em 0.9em;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 0.92rem;
  text-align: left;
  white-space: normal;
  cursor: pointer;
}
.cs-trigger:disabled { opacity: 0.5; cursor: not-allowed; }
.cs-trigger::after {
  content: '▾';
  color: var(--text-faint);
  flex-shrink: 0;
}
.cs-trigger.open::after { content: '▴'; }
.cs-menu {
  display: none;
  flex-direction: column;
  gap: 0.15em;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 0.4em;
  max-height: 260px;
  overflow-y: auto;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.35em;
  box-shadow: 0 16px 32px -10px rgba(0, 0, 0, 0.6);
  z-index: 400;
}
/* Applied via JS when there isn't enough room below the field to fit
   the menu before the bottom of the screen - flips it to grow upward
   from the field instead, anchored the same way but on the other side. */
.cs-menu.open-upward {
  top: auto;
  bottom: 100%;
  margin-top: 0;
  margin-bottom: 0.4em;
}
.cs-menu.open { display: flex; }
.cs-menu-item {
  background: none;
  border: none;
  text-align: left;
  white-space: normal;
  padding: 0.6em 0.7em;
  border-radius: 6px;
  font-size: 0.9rem;
  font-family: var(--font-body);
  color: var(--text-dim);
  cursor: pointer;
}
.cs-menu-item:hover { background: rgba(61, 107, 250, 0.14); color: var(--text); }
.cs-menu-item.active { background: linear-gradient(135deg, var(--blue), var(--violet)); color: white; }
.cs-menu-item:disabled { opacity: 0.4; cursor: not-allowed; }
.cs-menu-item-with-icon { display: flex; align-items: center; gap: 0.6em; }
.cs-menu-item-with-icon i { width: 19px; font-size: 1.05em; text-align: center; flex-shrink: 0; color: var(--text-faint); }
.cs-menu-item-with-icon.active i { color: white; }
.cs-trigger-label { display: flex; align-items: center; gap: 0.6em; min-width: 0; }
.cs-trigger-label i { width: 19px; font-size: 1.05em; text-align: center; flex-shrink: 0; color: var(--text-faint); }

/* Shared sizing for platform/category/service icons wherever they show
   up outside the New Order dropdowns above (Services & Prices, admin
   Services, Orders tables) - a bit larger than the surrounding text so
   they read clearly as icons instead of nearly disappearing next to it.
   Color is left to each usage (varies: faint for row icons, brighter
   for section headers), only sizing is shared here. */
.entity-icon { font-size: 1.15em; width: 1.2em; text-align: center; display: inline-block; }
.entity-icon-inline { margin-right: 0.45em; }

/* Star toggle on /services (see services-content.ejs) - a plain
   <button> reset to look like an icon-only control, not a boxed
   button, so it sits inline with the row like the platform icon it
   replaced. Muted/outline by default, filled and amber once favourited
   - matches the filled-vs-outline fa-solid/fa-regular swap the button's
   onclick handler does client-side after a successful toggle. */
.favorite-star {
  background: none;
  border: none;
  padding: 0;
  font-size: 1.05em;
  line-height: 1;
  color: var(--text-faint);
  cursor: pointer;
  transition: color 0.15s ease, transform 0.1s ease;
}
.favorite-star:hover { color: var(--amber); transform: scale(1.1); }
.favorite-star.is-favorite { color: var(--amber); }
.favorite-star:disabled { cursor: default; opacity: 0.6; }

/* ---------- Public info pages (FAQ/Terms/Privacy without login) ---------- */
.public-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  flex-wrap: wrap;
  padding: 1.2em 5vw;
  border-bottom: 1px solid var(--border-soft);
}
.public-main {
  max-width: 900px;
  margin: 0 auto;
  /* clamp() instead of a plain "5vw": with the global box-sizing:border-box
     (see the "*" rule near the top of this file), max-width caps the
     TOTAL box (content + padding) at 900px - but a plain "5vw" keeps
     growing with the *viewport*, not with this already-capped box. Past
     the point where the box hits its 900px ceiling (viewport ~900px,
     where 5vw happens to equal ~45px), the padding kept eating further
     and further into the content area instead of staying put - at
     2200px wide it had already shrunk the actual usable content down to
     680px (verified in the browser), visibly clipping the last column
     of any table wide enough to reach it. 45px is exactly 5vw at that
     900px breakpoint, so this clamps at the same point the box itself
     does - no visible jump, just growth that actually stops instead of
     continuing forever on wide monitors. */
  padding: 2.2em clamp(1.2em, 5vw, 45px) 4em;
}
/* Guest-facing /services specifically wants to be as wide as the
   logged-in view of the same page (main.main next to the 250px fixed
   sidebar, effectively viewport-minus-sidebar with no cap of its own)
   - the standard 900px .public-main cap (sized for readable prose on
   FAQ/Terms/etc., not a data table) was making the same table wrap
   the service name onto noticeably more lines for a logged-out visitor
   than a logged-in one for no real reason.
   This recreates that exact computation - viewport minus the
   sidebar's own 250px, with the same 2.2em left/right padding
   .main itself uses (see ".main { padding: 1.8em 2.2em 3em; }" above)
   - rather than a fixed max-width number, which measured out WIDER
   than the logged-in table at 1400px but narrower again at 1920px:
   a flat number can't track a subtraction that scales with the
   viewport, only a matching calc() can guarantee parity at every
   width, not just one. Only applied above 860px - below that
   breakpoint the sidebar itself goes off-canvas (see ".sidebar" in
   the max-width:860px media query) and .main falls back to its own
   small fixed padding with no sidebar subtraction at all, so
   subtracting a no-longer-present 250px here would leave almost no
   room for content on a phone-sized screen. */
.public-main-wide {
  max-width: calc(100vw - 250px);
  padding-left: 2.2em;
  padding-right: 2.2em;
}
@media (max-width: 860px) {
  .public-main-wide { max-width: 900px; }
}

/* ---------- Responsive form-card widths ----------
   Single narrow "form" cards (New Order, Add Funds, Profile, etc.) used
   to be pinned at a fixed pixel width regardless of screen size - fine
   on a laptop, but stranded in a huge sea of empty space on a wide
   monitor. clamp() lets them grow with the viewport within sane bounds
   instead, so the page actually uses the screen it's given. */
.form-card { max-width: clamp(420px, 42vw, 900px); margin-left: auto; margin-right: auto; }
.form-card-wide { max-width: clamp(480px, 50vw, 1100px); margin-left: auto; margin-right: auto; }
.form-card-widest { max-width: clamp(480px, 55vw, 1200px); margin-left: auto; margin-right: auto; }

/* ---------- Popups (Admin -> Popups, Anzeige: views/partials/popup-modal.ejs) ---------- */
.gp-popup-box {
  position: relative;
  width: 100%;
  max-width: 460px;
  background: linear-gradient(180deg, var(--surface), var(--bg-elevated));
  border: 1px solid var(--border-soft);
  border-top: 3px solid var(--popup-accent, var(--blue));
  border-radius: var(--radius-lg);
  padding: 1.6em;
  box-shadow: var(--shadow-glow);
}
.gp-popup-box[data-type="info"] { --popup-accent: var(--blue-bright); }
.gp-popup-box[data-type="warning"] { --popup-accent: var(--amber); }
.gp-popup-box[data-type="important"] { --popup-accent: var(--red); }
.gp-popup-box[data-type="success"] { --popup-accent: var(--green); }
.gp-popup-title { display: flex; align-items: center; gap: 0.6em; margin: 0 0 0.9em; font-size: 1.15rem; color: var(--text); }
.gp-popup-title i { color: var(--popup-accent); }
.gp-popup-body { color: var(--text-dim); font-size: 0.93rem; line-height: 1.6; word-break: break-word; max-height: 50vh; overflow-y: auto; margin-bottom: 1.4em; padding-right: 1.7em; }
.gp-popup-body a { color: var(--blue-bright); text-decoration: underline; }
.gp-popup-actions { flex-wrap: wrap; }
.gp-popup-queue { margin-right: auto; align-self: center; font-size: 0.78rem; color: var(--text-faint); }
.popup-chip { cursor: pointer; width: 100%; font-family: inherit; text-align: left; color: inherit; }
.popup-chip { padding-right: 1.3em; }
.popup-chip .nav-count { min-width: 15px; height: 15px; padding: 0 4px; font-size: 0.62rem; margin-left: 0; }
.popup-chip-arrow { color: var(--text-faint); font-size: 0.8rem; transition: transform 0.15s ease; display: inline-block; margin-right: 0.15em; }
.popup-chip:hover { border-color: var(--blue-bright); }
.popup-menu {
  display: none;
  position: fixed;
  z-index: 1500;
  flex-direction: column;
  gap: 0.3em;
  max-height: 60vh;
  overflow-y: auto;
  padding: 0.45em;
  background: linear-gradient(180deg, var(--surface), var(--bg-elevated));
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  box-shadow: var(--shadow-glow);
}
.popup-menu.open { display: flex; }
.popup-list-item {
  display: flex; align-items: center; gap: 0.6em;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 0.5em 0.8em; color: var(--text-dim); font-size: 0.82rem; font-family: inherit; text-align: left; cursor: pointer;
}
.popup-list-item:hover { border-color: var(--blue-bright); color: var(--text); }
.popup-list-item .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--blue-bright); }
.popup-list-item[data-type="warning"] .dot { background: var(--amber); }
.popup-list-item[data-type="important"] .dot { background: var(--red); }
.popup-list-item[data-type="success"] .dot { background: var(--green); }

/* ---------- FAQ / Terms / Privacy: Inhaltsverzeichnis, Werkzeugleiste, Frage-Bloecke ---------- */
.faq-toc { margin-bottom: 1em; }
.faq-toolbar { display: flex; gap: 0.6em; align-items: center; flex-wrap: wrap; margin-bottom: 1.3em; }
.faq-toolbar input[type="search"] { flex: 1; min-width: 200px; }
.faq-empty { color: var(--text-dim); margin: 0 0 1em; }
.faq-meta { color: var(--text-faint); font-size: 0.82rem; margin: -0.6em 0 1.4em; }
.faq-qa + .faq-qa { margin-top: 1.2em; }
.faq-item { scroll-margin-top: 1em; }
.faq-answer p:last-child, .faq-answer ul:last-child { margin-bottom: 0; }
.faq-tip { background: rgba(61, 107, 250, 0.1); border: 1px solid rgba(106, 140, 255, 0.3); border-radius: var(--radius-sm); padding: 0.7em 1em; margin: 0.8em 0 0; }
.faq-warn { background: rgba(251, 191, 36, 0.08); border: 1px solid rgba(251, 191, 36, 0.3); border-radius: var(--radius-sm); padding: 0.7em 1em; margin: 0.8em 0 0; }
.faq-qa h4 { margin-top: 0; }
.gp-popup-code {
  display: flex; align-items: center; justify-content: space-between; gap: 1em;
  background: var(--surface-2); border: 1px dashed var(--popup-accent, var(--blue-bright)); border-radius: var(--radius-sm);
  padding: 0.7em 1em; margin-bottom: 1.4em;
}
.gp-popup-code-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-faint); font-weight: 700; margin-bottom: 0.15em; }
.gp-popup-code-value { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 1.15rem; font-weight: 700; color: var(--text); letter-spacing: 0.06em; word-break: break-all; user-select: all; }
.gp-popup-body strong { color: var(--text); }
.gp-popup-body .gp-mark { background: rgba(251, 191, 36, 0.22); color: var(--text); padding: 0.05em 0.35em; border-radius: 5px; }
.gp-popup-body code { background: var(--surface-2); border: 1px solid var(--border); border-radius: 5px; padding: 0.05em 0.4em; font-size: 0.88em; color: var(--text); }
.popup-format-bar { display: flex; flex-wrap: wrap; gap: 0.35em; margin-bottom: 0.5em; }
.popup-format-bar .btn { min-width: 34px; padding: 0.35em 0.7em; }

.gp-popup-body .gp-line { white-space: pre-wrap; }
.gp-popup-body .gp-gap { height: 0.8em; }
.gp-popup-body .gp-h { font-family: var(--font-display); font-size: 1.05rem; font-weight: 700; color: var(--text); margin-top: 0.4em; }
.gp-popup-body .gp-li { display: flex; gap: 0.6em; margin: 0.15em 0; }
.gp-popup-body .gp-li-mark { flex: none; min-width: 1.1em; color: var(--popup-accent, var(--blue-bright)); font-weight: 700; }
.gp-popup-body .gp-li-text { flex: 1; min-width: 0; }
