/* =========================================================
   EtherealProxies — design system
   Black base, LED/arcade-sign outline accents.
   Edit the colors in :root below to restyle the whole site.
   ========================================================= */

@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;500;600;700&family=Inter:wght@400;500;600;700&family=Space+Mono:wght@400;700&display=swap');

:root{
  /* base surfaces */
  --bg-0:#08080b;
  --bg-1:#0e0f14;
  --bg-2:#14151c;
  --bg-3:#1b1c25;
  --line:#24262f;

  /* text */
  --ink-0:#f2f3f7;
  --ink-1:#b7bac6;
  --ink-2:#767a89;

  /* LED accent set */
  --led-cyan:#37f0ff;
  --led-magenta:#ff3fc0;
  --led-lime:#b6ff3c;
  --led-amber:#ffb020;
  --led-violet:#9d6bff;
  --discord:#5865F2;

  --radius:10px;
  --radius-sm:6px;

  --font-display:'Chakra Petch','Inter',sans-serif;
  --font-body:'Inter',sans-serif;
  --font-mono:'Space Mono',monospace;
}

*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
body{
  margin:0;
  background:var(--bg-0);
  color:var(--ink-0);
  font-family:var(--font-body);
  -webkit-font-smoothing:antialiased;
  line-height:1.5;
  min-height:100vh;
}
body::before{
  content:'';
  position:fixed; inset:0; pointer-events:none; z-index:0;
  background-image:
    linear-gradient(rgba(255,255,255,.018) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.018) 1px, transparent 1px);
  background-size:38px 38px;
  mask-image:radial-gradient(ellipse at 50% 0%, black 0%, transparent 70%);
}

h1,h2,h3,h4{ font-family:var(--font-display); font-weight:600; margin:0; letter-spacing:.2px; }
a{ color:inherit; text-decoration:none; }
p{ margin:0; }
ul{ margin:0; padding:0; list-style:none; }
button{ font-family:inherit; cursor:pointer; }
input,select,textarea{ font-family:inherit; }

.container{ max-width:1180px; margin:0 auto; padding:0 28px; position:relative; z-index:1; }

/* ---------- LED outline ---------- */
.led{ position:relative; background:var(--bg-1); border-radius:var(--radius); border:1px solid var(--line); }
.led::after{
  content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  box-shadow:
    inset 0 0 0 1px var(--glow,var(--led-cyan)),
    0 0 0 1px color-mix(in srgb, var(--glow,var(--led-cyan)) 55%, transparent),
    0 0 18px -2px color-mix(in srgb, var(--glow,var(--led-cyan)) 65%, transparent);
  opacity:.9;
}
.led--cyan{ --glow:var(--led-cyan); }
.led--magenta{ --glow:var(--led-magenta); }
.led--lime{ --glow:var(--led-lime); }
.led--amber{ --glow:var(--led-amber); }
.led--violet{ --glow:var(--led-violet); }

/* ---------- buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:11px 20px;
  font-family:var(--font-display); font-size:14px; font-weight:600;
  border-radius:var(--radius-sm); border:1px solid var(--line);
  background:var(--bg-2); color:var(--ink-0);
  transition:transform .12s ease, box-shadow .12s ease, border-color .12s ease, background .12s ease;
  white-space:nowrap;
}
.btn:hover{ transform:translateY(-1px); }
.btn:active{ transform:translateY(0); }
.btn:focus-visible{ outline:2px solid var(--led-cyan); outline-offset:2px; }

.btn--led{
  border-color:color-mix(in srgb, var(--glow,var(--led-cyan)) 70%, var(--line));
  box-shadow:0 0 0 1px color-mix(in srgb, var(--glow,var(--led-cyan)) 45%, transparent) inset,
             0 0 14px -3px var(--glow,var(--led-cyan));
}
.btn--led:hover{
  box-shadow:0 0 0 1px color-mix(in srgb, var(--glow,var(--led-cyan)) 70%, transparent) inset,
             0 0 22px -2px var(--glow,var(--led-cyan));
}
.btn--cyan{ --glow:var(--led-cyan); }
.btn--magenta{ --glow:var(--led-magenta); }
.btn--lime{ --glow:var(--led-lime); }
.btn--amber{ --glow:var(--led-amber); }
.btn--violet{ --glow:var(--led-violet); }

.btn--ghost{ background:transparent; border-color:var(--line); color:var(--ink-1); }
.btn--ghost:hover{ color:var(--ink-0); border-color:var(--ink-2); }

.btn--discord{
  background:var(--discord); border-color:var(--discord); color:#fff;
  box-shadow:0 0 16px -4px var(--discord);
}
.btn--discord:hover{ box-shadow:0 0 24px -3px var(--discord); }

.btn--sm{ padding:8px 14px; font-size:13px; }
.btn--full{ width:100%; }
.btn[disabled]{ opacity:.45; cursor:not-allowed; transform:none !important; }

.discord-icon{ width:17px; height:17px; flex-shrink:0; fill:currentColor; }

/* ---------- pills / badges ---------- */
.pill{
  display:inline-flex; align-items:center; gap:6px;
  padding:4px 10px; border-radius:999px;
  font-family:var(--font-mono); font-size:11.5px;
  border:1px solid var(--line); color:var(--ink-1);
}
.pill--dot::before{
  content:''; width:6px; height:6px; border-radius:50%;
  background:var(--glow,var(--led-lime));
  box-shadow:0 0 6px 1px var(--glow,var(--led-lime));
}
/* inline-block + nowrap so a two-word label like "Provisioning failed"
   keeps its pill shape. As a plain inline element the text wrapped and the
   rounded border broke across both lines, which reads as a clipped badge. */
.status-badge{
  font-family:var(--font-mono); font-size:11px; padding:4px 9px;
  border-radius:999px; border:1px solid var(--line);
  display:inline-block; white-space:nowrap; line-height:1.5; vertical-align:middle;
}
.status-active,.status-live{ color:var(--led-lime); border-color:color-mix(in srgb,var(--led-lime) 55%,var(--line)); }
.status-paid{ color:var(--led-cyan); border-color:color-mix(in srgb,var(--led-cyan) 55%,var(--line)); }
.status-pending,.status-soon{ color:var(--led-amber); border-color:color-mix(in srgb,var(--led-amber) 55%,var(--line)); }

/* ---------- forms ---------- */
.field{ display:flex; flex-direction:column; gap:6px; min-width:0; }
.field label{ font-size:12.5px; color:var(--ink-2); font-family:var(--font-mono); letter-spacing:.02em; }
.field input,.field select{
  width:100%; box-sizing:border-box;
  background:var(--bg-3); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:11px 13px; color:var(--ink-0); font-size:14px; outline:none;
  transition:border-color .12s ease, box-shadow .12s ease;
}
.field input::placeholder{ color:var(--ink-2); }
.field input:focus,.field select:focus{
  border-color:var(--led-cyan);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--led-cyan) 22%,transparent);
}
.notice{
  font-size:12.5px; font-family:var(--font-mono); color:var(--led-amber);
  padding:10px 12px; border-radius:var(--radius-sm);
  border:1px solid color-mix(in srgb,var(--led-amber) 50%,var(--line));
  background:color-mix(in srgb,var(--led-amber) 8%,transparent);
  line-height:1.6;
}
.notice--hidden{ display:none; }

.text-muted{ color:var(--ink-1); }
.text-dim{ color:var(--ink-2); }
.mono{ font-family:var(--font-mono); }

::selection{ background:color-mix(in srgb,var(--led-cyan) 35%,transparent); }
::-webkit-scrollbar{ width:10px; height:10px; }
::-webkit-scrollbar-track{ background:var(--bg-0); }
::-webkit-scrollbar-thumb{ background:var(--bg-3); border-radius:6px; border:2px solid var(--bg-0); }
::-webkit-scrollbar-thumb:hover{ background:#2a2c38; }

/* ---------- ethereal starfield ----------
   A handful of tiny, dim, slowly-twinkling dots behind the page —
   meant to be almost subliminal, not decorative in an obvious way.
   Markup + generation live in common.js (initStarfield); this is just
   the look. Add <div class="starfield" id="starfield"></div> as the
   first thing inside <body> on any page that should have it. */
.starfield{
  position:fixed; inset:0;
  overflow:hidden;
  z-index:0;
  pointer-events:none;
}
.starfield .star{
  position:absolute;
  border-radius:50%;
  background:#fff;
  animation:bp-twinkle var(--dur, 5s) ease-in-out infinite;
  animation-delay:var(--delay, 0s);
  will-change:opacity;
}
@keyframes bp-twinkle{
  0%, 100%{ opacity:var(--min-op, 0.08); }
  50%{ opacity:var(--max-op, 0.5); }
}

/* ---------- seasonal glyph particles ----------
   Snowflakes, leaves, bats and so on. Same faint twinkle as the dots,
   plus an optional slow drift so falling things actually fall. */
.starfield .star--glyph{
  width:auto; height:auto; background:none; border-radius:0;
  line-height:1; user-select:none;
  text-shadow:0 0 6px currentColor;
}
.starfield .star--drift{
  animation:bp-twinkle var(--dur, 5s) ease-in-out infinite,
            bp-drift var(--drift-dur, 22s) linear infinite;
  animation-delay:var(--delay, 0s), var(--drift-delay, 0s);
}
@keyframes bp-drift{
  0%   { transform:translate(0, -12vh) rotate(0deg); }
  50%  { transform:translate(var(--sway, 16px), 44vh) rotate(180deg); }
  100% { transform:translate(0, 104vh) rotate(360deg); }
}

/* ---------- notification list items ---------- */
/* ---------- code / embed blocks ---------- */
.code-block{
  background:var(--bg-3); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:14px 16px; font-family:var(--font-mono); font-size:12px; color:var(--ink-1);
  white-space:pre-wrap; word-break:break-all; overflow-wrap:break-word;
  overflow-y:auto; overflow-x:hidden; line-height:1.6;
  min-width:0; /* grid/flex children default to min-width:auto, which silently
                  defeats word-break by refusing to shrink below the content's
                  un-wrapped width — this is what was actually causing the overflow */
}

.notif-item{
  display:flex; gap:11px; padding:13px 14px;
  margin:10px 12px;
  border:1px solid var(--accent, var(--line));
  border-radius:var(--radius-sm);
  background:color-mix(in srgb, var(--accent, var(--line)) 6%, transparent);
  box-shadow:0 0 12px -6px var(--accent, transparent);
  transition:background .12s ease, box-shadow .12s ease;
}
.notif-item:hover{
  background:color-mix(in srgb, var(--accent, var(--line)) 12%, transparent);
  box-shadow:0 0 16px -5px var(--accent, transparent);
}
.notif-item--cyan{ --accent:var(--led-cyan); }
.notif-item--magenta{ --accent:var(--led-magenta); }
.notif-item--lime{ --accent:var(--led-lime); }
.notif-item--amber{ --accent:var(--led-amber); }
.notif-item--violet{ --accent:var(--led-violet); }
.notif-item .notif-icon{
  width:30px; height:30px; border-radius:8px; flex-shrink:0;
  background:color-mix(in srgb, var(--accent, var(--led-amber)) 15%, var(--bg-3));
  border:1px solid color-mix(in srgb, var(--accent, var(--led-amber)) 45%, var(--line));
  display:flex; align-items:center; justify-content:center; font-size:13px;
}
.notif-item .notif-body{ flex:1; min-width:0; }
.notif-item .notif-msg{ font-size:13px; color:var(--ink-0); line-height:1.5; }
.notif-item .notif-time{ font-size:10.5px; color:var(--ink-2); font-family:var(--font-mono); margin-top:6px; line-height:1.45; }

/* ---------- shared site nav + footer ---------- */
.nav{
  position:sticky; top:0; z-index:40;
  background:color-mix(in srgb,var(--bg-0) 88%,transparent);
  backdrop-filter:blur(10px); border-bottom:1px solid var(--line);
}
.nav-row{ display:flex; align-items:center; justify-content:space-between; height:72px; }
.brand{ display:flex; align-items:center; gap:10px; font-family:var(--font-display); font-size:19px; font-weight:700; }
.brand-mark{
  width:38px; height:38px; border-radius:10px;
  background:transparent; border:none; box-shadow:none;
  display:flex; align-items:center; justify-content:center; font-size:19px;
  overflow:hidden;
}
.nav-links{ display:flex; align-items:center; gap:32px; font-size:14px; color:var(--ink-1); }
.nav-links a:hover{ color:var(--ink-0); }
.nav-cta{ display:flex; align-items:center; gap:10px; }

footer{ border-top:1px solid var(--line); padding:40px 0; margin-top:40px; }
.foot-row{ display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:16px; }
.foot-links{ display:flex; gap:22px; font-size:13px; color:var(--ink-2); flex-wrap:wrap; }
.foot-links a{ display:inline-flex; align-items:center; gap:7px; }
.foot-links .discord-icon{ width:14px; height:14px; }
.foot-links a:hover{ color:var(--ink-1); }

/* ---------- modal (Top Up + dialogs) ---------- */
.modal-backdrop{
  position:fixed; inset:0; z-index:200;
  background:rgba(4,4,6,.78); backdrop-filter:blur(4px);
  display:flex; align-items:center; justify-content:center; padding:24px;
  opacity:0; pointer-events:none; transition:opacity .18s ease;
  overflow-y:auto; /* page-level scroll for tall modals on short screens */
}
.modal-backdrop.open{ opacity:1; pointer-events:auto; }
.modal{
  width:100%; max-width:520px; max-height:90vh; overflow-y:auto;
  padding:26px; transform:translateY(12px) scale(.98);
  transition:transform .18s ease;
}

/* A modal's glow must NOT live on the ::after layer.

   .led draws its glow with an absolutely positioned ::after at inset:0.
   That is fine on a panel, but a modal SCROLLS — and an absolute child of
   a scrolling element scrolls with the content. The moment the checkout
   was tall enough to scroll (which happens on high-resolution screens at
   display scaling), the glowing border line slid up through the middle of
   the menu, cutting across the product cards.

   Painting the same glow as the element's own box-shadow fixes it: a
   scroll container's shadows are drawn by the box itself and stay pinned
   to its edges however far the content moves. Identical look, no drift. */
.modal.led::after{ display:none; }
.modal.led{
  box-shadow:
    inset 0 0 0 1px var(--glow,var(--led-cyan)),
    0 0 0 1px color-mix(in srgb, var(--glow,var(--led-cyan)) 55%, transparent),
    0 0 18px -2px color-mix(in srgb, var(--glow,var(--led-cyan)) 65%, transparent);
}

/* A slim, on-brand scrollbar for anything that scrolls inside a modal or
   the notification tray, instead of the platform's grey bar. */
.modal, .notif-scroll{ scrollbar-width:thin; scrollbar-color:color-mix(in srgb,var(--led-cyan) 45%,var(--line)) transparent; }
.modal::-webkit-scrollbar, .notif-scroll::-webkit-scrollbar{ width:8px; }
.modal::-webkit-scrollbar-track, .notif-scroll::-webkit-scrollbar-track{ background:transparent; }
.modal::-webkit-scrollbar-thumb, .notif-scroll::-webkit-scrollbar-thumb{
  background:color-mix(in srgb,var(--led-cyan) 40%,var(--line));
  border-radius:8px; border:2px solid transparent; background-clip:padding-box;
}
.modal::-webkit-scrollbar-thumb:hover, .notif-scroll::-webkit-scrollbar-thumb:hover{
  background:color-mix(in srgb,var(--led-cyan) 70%,var(--line)); background-clip:padding-box;
}
/* On a viewport too short to fit the modal, internal scrolling leaves the
   glowing border pinned while content runs past it. Letting the whole
   modal grow and scrolling the backdrop instead keeps the outline wrapped
   around its content at every height. */
@media (max-height:900px){
  .modal-backdrop{ align-items:flex-start; }
  .modal{ max-height:none; overflow-y:visible; margin:auto 0; }
}
.modal-backdrop.open .modal{ transform:translateY(0) scale(1); }
.modal-head{ display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:20px; gap:14px; }
.modal-head h2{ font-size:19px; margin-bottom:5px; }
.modal-head p{ font-size:13px; color:var(--ink-2); }
.modal-close{
  width:32px; height:32px; border-radius:var(--radius-sm);
  background:var(--bg-2); border:1px solid var(--line); color:var(--ink-1);
  display:flex; align-items:center; justify-content:center; font-size:16px; flex-shrink:0;
}
.modal-close:hover{ color:var(--ink-0); border-color:var(--ink-2); }
.modal-label{ font-family:var(--font-mono); font-size:11.5px; color:var(--ink-2); margin-bottom:10px; }

.category-picker{ display:grid; grid-template-columns:repeat(4,1fr); gap:10px; margin-bottom:22px; }
.category-opt{
  padding:18px 12px; border-radius:var(--radius-sm);
  background:var(--bg-2); border:1px solid var(--line);
  text-align:center; color:var(--ink-1); position:relative;
  transition:border-color .12s ease, box-shadow .12s ease, color .12s ease;
}
.category-opt .po-icon{ font-size:22px; margin-bottom:8px; }
.category-opt .po-name{ font-family:var(--font-display); font-size:13.5px; font-weight:600; }
.category-opt .po-price{ font-family:var(--font-mono); font-size:10.5px; color:var(--ink-2); margin-top:6px; }
.category-opt.selected{
  color:var(--ink-0);
  border-color:color-mix(in srgb,var(--glow,var(--led-cyan)) 70%,var(--line));
  box-shadow:0 0 0 1px color-mix(in srgb,var(--glow,var(--led-cyan)) 40%,transparent) inset,
             0 0 16px -4px var(--glow,var(--led-cyan));
}
.category-opt[disabled]{ opacity:.4; cursor:not-allowed; }
.category-opt .po-soon{ position:absolute; top:8px; right:8px; font-family:var(--font-mono); font-size:9px; color:var(--led-amber); }

.product-picker{ display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin-bottom:22px; }
.product-opt{
  padding:13px; border-radius:var(--radius-sm);
  background:var(--bg-2); border:1px solid var(--line);
  text-align:left; color:var(--ink-1); position:relative;
  transition:border-color .12s ease, box-shadow .12s ease, color .12s ease;
}
.product-opt .po-name{ font-family:var(--font-display); font-size:14px; font-weight:600; display:flex; align-items:center; gap:7px; }
.product-opt .po-price{ font-family:var(--font-mono); font-size:11.5px; color:var(--ink-2); margin-top:5px; }
.product-opt.selected{
  color:var(--ink-0);
  border-color:color-mix(in srgb,var(--glow,var(--led-cyan)) 70%,var(--line));
  box-shadow:0 0 0 1px color-mix(in srgb,var(--glow,var(--led-cyan)) 40%,transparent) inset,
             0 0 16px -4px var(--glow,var(--led-cyan));
}
.product-opt[disabled]{ opacity:.4; cursor:not-allowed; }
.product-opt .po-soon{ position:absolute; top:10px; right:10px; font-family:var(--font-mono); font-size:9.5px; color:var(--led-amber); }

.amount-presets{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:16px; }
.preset{
  padding:7px 14px; border-radius:var(--radius-sm);
  background:var(--bg-2); border:1px solid var(--line);
  color:var(--ink-1); font-family:var(--font-mono); font-size:12.5px;
}
.preset:hover{ color:var(--ink-0); border-color:var(--ink-2); }
.preset.selected{ color:var(--ink-0); border-color:var(--range-glow, var(--led-cyan)); box-shadow:0 0 12px -3px var(--range-glow, var(--led-cyan)); }

.slider-head{ display:flex; justify-content:space-between; align-items:baseline; }
.slider-head .amt{ font-family:var(--font-display); font-size:22px; }

input[type=range]{
  -webkit-appearance:none; appearance:none;
  width:100%; height:5px; border-radius:99px; background:var(--bg-3);
  outline:none; margin:10px 0 0;
}
input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none;
  width:17px; height:17px; border-radius:50%;
  background:var(--range-glow, var(--led-cyan)); border:2px solid var(--bg-0);
  box-shadow:0 0 12px var(--range-glow, var(--led-cyan)); cursor:pointer;
  transition:background .15s ease, box-shadow .15s ease;
}
input[type=range]::-moz-range-thumb{
  width:17px; height:17px; border-radius:50%;
  background:var(--range-glow, var(--led-cyan)); border:2px solid var(--bg-0);
  box-shadow:0 0 12px var(--range-glow, var(--led-cyan)); cursor:pointer;
  transition:background .15s ease, box-shadow .15s ease;
}

.order-summary{
  background:var(--bg-3); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:16px; margin:20px 0;
}
.summary-row{ display:flex; justify-content:space-between; font-size:13.5px; color:var(--ink-1); margin-bottom:10px; }
.summary-row:last-child{ margin-bottom:0; }
.summary-row.total{
  padding-top:12px; border-top:1px solid var(--line); margin-top:14px;
  color:var(--ink-0); font-family:var(--font-display); font-size:17px; font-weight:600;
}
.summary-row .discount{ color:var(--led-lime); }

/* ---------- FAQ accordion ---------- */
.faq-item{ margin-bottom:12px; overflow:hidden; }
.faq-q{
  width:100%; text-align:left; background:none; border:none; color:var(--ink-0);
  padding:18px 20px; font-family:var(--font-display); font-size:15.5px; font-weight:600;
  display:flex; justify-content:space-between; align-items:center; gap:16px;
}
.faq-q .chev{ color:var(--ink-2); font-size:13px; transition:transform .2s ease; flex-shrink:0; }
.faq-item.open .faq-q .chev{ transform:rotate(180deg); }
.faq-a{ max-height:0; overflow:hidden; transition:max-height .25s ease; padding:0 20px; color:var(--ink-1); font-size:14px; }
.faq-item.open .faq-a{ padding-bottom:20px; }
.faq-a p+p{ margin-top:12px; }
.faq-cat{ font-family:var(--font-mono); font-size:11.5px; color:var(--ink-2); margin:38px 0 14px; }

/* ---------- toast ---------- */
.toast{
  position:fixed; bottom:26px; left:50%; transform:translateX(-50%) translateY(20px);
  background:var(--bg-2); border:1px solid var(--led-lime); border-radius:var(--radius-sm);
  padding:12px 20px; font-size:13px; font-family:var(--font-mono); color:var(--ink-0);
  box-shadow:0 0 18px -4px var(--led-lime); opacity:0; pointer-events:none;
  transition:opacity .2s ease, transform .2s ease; z-index:300; max-width:90vw; text-align:center;
}
.toast.show{ opacity:1; transform:translateX(-50%) translateY(0); }

@media (max-width:900px){ .nav-links{ display:none; } }
@media (max-width:760px){
  .container{ padding:0 18px; }
  .product-picker{ grid-template-columns:1fr; }
  .category-picker{ grid-template-columns:repeat(2,1fr); }
}
@media (prefers-reduced-motion:reduce){
  *{ transition:none !important; animation:none !important; }
  html{ scroll-behavior:auto; }
}


/* =========================================================
   PRIVACY MODE (stream-safe admin panel)
   One class does the hiding, so anything sensitive only needs
   data-privacy="<group>" on it to join in. Blur rather than
   display:none keeps the layout identical, so nothing jumps
   when you toggle it mid-stream.
   ========================================================= */
[data-privacy].is-hidden{
  filter: blur(9px);
  /* A blurred string is still selectable and still in the DOM — this
     stops it being highlighted, dragged out, or read by a screen
     capture that grabs selection state. */
  user-select: none;
  pointer-events: none;
  transition: filter .14s ease;
}
[data-privacy]{ transition: filter .14s ease; }

/* Smaller text needs less blur to be unreadable, and too much blur on a
   table cell bleeds into its neighbours. */
td[data-privacy].is-hidden,
.privacy-sm[data-privacy].is-hidden{ filter: blur(5px); }

.privacy-eye{
  background: none;
  border: none;
  padding: 0 0 0 7px;
  margin: 0;
  cursor: pointer;
  color: var(--ink-2);
  font-size: 12px;
  line-height: 1;
  opacity: .55;
  transition: opacity .14s ease, color .14s ease;
}
.privacy-eye:hover{ opacity: 1; color: var(--ink-0); }
.privacy-eye.is-off{ opacity: 1; color: var(--led-amber); }

.privacy-eye--inline{
  padding: 6px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 11.5px;
  white-space: nowrap;
  align-self: center;
}

/* When the master switch is on, make it obvious at a glance which state
   you're in — the one thing worse than forgetting to blur is thinking
   you did. */
#btnPrivacyMaster.is-on{
  border-color: var(--led-amber);
  color: var(--led-amber);
  box-shadow: 0 0 10px -2px var(--led-amber);
}


/* =========================================================
   CONFIRM DIALOG
   Replaces the browser's confirm()/prompt() for anything
   consequential. Sits above the Top Up modal's z-index so a
   confirmation raised from inside it is never trapped behind.
   ========================================================= */
.confirm-backdrop{ z-index: 300; }

.confirm-modal{
  max-width: 460px;
  width: 100%;
}
.confirm-modal .modal-head{ margin-bottom: 16px; }
.confirm-modal .modal-head p{ line-height: 1.55; }

/* The specifics of what's about to happen — which user, which order,
   how many IPs. Set apart so it reads as fact rather than prose. */
.confirm-detail{
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.6;
  color: var(--ink-1);
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 11px 13px;
  margin-bottom: 18px;
  white-space: pre-wrap;
  word-break: break-word;
}

.confirm-actions{
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
  flex-wrap: wrap;
}
/* On a phone the buttons go full width and Confirm sits on top, so the
   thumb doesn't land on it by accident while reaching for Cancel. */
@media (max-width: 420px){
  .confirm-actions{ flex-direction: column-reverse; }
  .confirm-actions .btn{ width: 100%; }
}

/* ---------- brand icons ----------
   Gradient SVGs, used as <img> rather than inlined. Every icon file
   defines the same `id="g"` gradient, so inlining a dozen of them into one
   document would make them all resolve to whichever was parsed first. As
   images each file keeps its own id scope. */
.ico{ display:inline-flex; align-items:center; justify-content:center; flex:none; }
/* Sized generously on purpose. These are detailed line icons with a soft
   glow, drawn on a 64px canvas — at 18px the strokes land under one device
   pixel and the glow smears them into grey fuzz. They only read properly
   from about 24px up, so the layout gives them the room rather than the
   artwork being flattened to suit a smaller box. */
.ico img{ width:24px; height:24px; display:block; }
.po-icon .ico img{ width:34px; height:34px; }
h3 .ico img{ width:26px; height:26px; }
.btn .ico img{ width:18px; height:18px; }

/* ---------- number inputs ----------
   Spinner arrows are useless on a field that ranges into the thousands —
   nobody clicks up-arrow four hundred times — and they eat usable width.
   Both the vendor-prefixed button and `appearance` are needed: Chrome
   hides the buttons, Firefox needs the textfield appearance. */
.no-spin{ -moz-appearance:textfield; appearance:textfield; }
.no-spin::-webkit-outer-spin-button,
.no-spin::-webkit-inner-spin-button{ -webkit-appearance:none; appearance:none; margin:0; }

/* Editable top-up amount */
.amt-edit{ display:inline-flex; align-items:baseline; gap:4px; cursor:text; }
.amt-edit input{ width:5ch; background:transparent; border:0; border-bottom:1px dashed color-mix(in srgb,var(--range-glow,var(--led-cyan)) 60%,transparent); color:inherit; font:inherit; text-align:right; padding:0; outline:none; }
.amt-edit input:focus{ border-bottom-style:solid; }
.no-spin::-webkit-outer-spin-button,.no-spin::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
.no-spin{ -moz-appearance:textfield; appearance:textfield; }
/* Notification tray: scroll, left-aligned text */
.notif-scroll{ max-height:360px; overflow-y:auto; text-align:left; }
.notif-item .notif-icon img{ display:block; }

/* Admin customer panel: order history stays compact and scrolls */
.admin-orders-scroll{ max-height:260px; overflow-y:auto; padding-right:6px;
  scrollbar-width:thin; scrollbar-color:color-mix(in srgb,var(--led-cyan) 45%,var(--line)) transparent; }
.admin-orders-scroll::-webkit-scrollbar{ width:6px; }
.admin-orders-scroll::-webkit-scrollbar-thumb{ background:color-mix(in srgb,var(--led-cyan) 45%,var(--line)); border-radius:6px; }

/* Traffic filters: wrap on narrow screens, keep date-time boxes readable */
.tr-controls{ display:flex; flex-wrap:wrap; gap:14px 18px; align-items:flex-end; }
.tr-controls .field{ margin:0; }
.tr-controls input[type="datetime-local"]{ min-width:200px; color-scheme:dark; }

/* Our own rate-limit notice (see common.js showRateLimit) */
#bpRateLimit{ position:fixed; inset:auto 0 24px 0; display:none; justify-content:center; z-index:300; pointer-events:none; }
#bpRateLimit .bp-rl-card{ pointer-events:auto; display:flex; gap:14px; align-items:center; max-width:460px; margin:0 16px;
  padding:14px 18px; border-radius:var(--radius-sm, 10px); background:var(--bg-2); color:var(--ink-1);
  border:1px solid color-mix(in srgb, var(--led-amber) 60%, var(--line));
  box-shadow:0 0 0 1px color-mix(in srgb, var(--led-amber) 25%, transparent), 0 0 22px -4px color-mix(in srgb, var(--led-amber) 55%, transparent), 0 18px 40px -12px rgba(0,0,0,.6); }
#bpRateLimit .bp-rl-icon{ font-size:22px; }
#bpRateLimit .bp-rl-title{ color:var(--ink-0); font-weight:600; font-size:14px; margin-bottom:2px; }
#bpRateLimit .bp-rl-body{ font-size:12.5px; line-height:1.5; }

/* Clickable chart legends (Traffic detail) */
.tr-legend-item{ cursor:pointer; user-select:none; transition:opacity .15s; }
.tr-legend-item:hover{ opacity:.8; }
.tr-legend-item.off{ opacity:.4; text-decoration:line-through; }

/* ---------- promo bar (config.js → promoBar) ---------- */
.promo-bar{
  position:relative; z-index:45; display:flex; align-items:center; justify-content:center;
  min-height:38px; padding:6px 48px; overflow:hidden;
  background:
    linear-gradient(90deg,
      color-mix(in srgb, var(--led-violet) 38%, var(--bg-0)) 0%,
      color-mix(in srgb, var(--led-cyan) 30%, var(--bg-0)) 50%,
      color-mix(in srgb, var(--led-magenta) 34%, var(--bg-0)) 100%);
  border-bottom:1px solid color-mix(in srgb, var(--led-cyan) 45%, transparent);
  box-shadow:0 0 18px -6px color-mix(in srgb, var(--led-cyan) 70%, transparent);
  color:var(--ink-0); font-size:13px; font-weight:500;
  transition:opacity .2s ease, max-height .2s ease, padding .2s ease; max-height:80px;
}
/* slow shimmer so it catches the eye without being tacky */
.promo-bar::before{
  content:''; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(110deg, transparent 30%, rgba(255,255,255,.10) 50%, transparent 70%);
  transform:translateX(-100%); animation:promoShine 6s ease-in-out infinite;
}
@keyframes promoShine{ 0%,60%{ transform:translateX(-100%); } 100%{ transform:translateX(100%); } }
@media (prefers-reduced-motion: reduce){ .promo-bar::before{ animation:none; display:none; } }
.promo-bar.closing{ opacity:0; max-height:0; padding-top:0; padding-bottom:0; }
.promo-inner{ position:relative; display:flex; align-items:center; justify-content:center; gap:10px; flex-wrap:wrap; text-align:center; }
.promo-spark{ color:var(--led-cyan); text-shadow:0 0 8px var(--led-cyan); }
.promo-text{ color:var(--ink-0); text-decoration:none; font-weight:600; }
a.promo-text:hover{ text-decoration:underline; }
.promo-code{
  position:relative; cursor:pointer; font:inherit; font-size:12px; color:var(--ink-1);
  padding:3px 10px; border-radius:999px;
  background:color-mix(in srgb, var(--bg-0) 55%, transparent);
  border:1px dashed color-mix(in srgb, var(--led-cyan) 70%, transparent);
  transition:border-color .15s, box-shadow .15s;
}
.promo-code b{ color:var(--ink-0); font-family:var(--font-mono); letter-spacing:.04em; }
.promo-code:hover{ border-style:solid; box-shadow:0 0 12px -3px var(--led-cyan); }
.promo-copied{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center; border-radius:999px;
  background:var(--led-lime); color:#0d1400; font-weight:700; opacity:0; transition:opacity .15s;
}
.promo-code.copied .promo-copied{ opacity:1; }
.promo-note{ color:var(--ink-1); font-size:12px; opacity:.9; }
.promo-close{
  position:absolute; right:12px; top:50%; transform:translateY(-50%);
  width:28px; height:28px; border-radius:50%; border:0; cursor:pointer;
  background:transparent; color:var(--ink-1); font-size:13px; line-height:1;
}
.promo-close:hover{ background:color-mix(in srgb, var(--ink-0) 12%, transparent); color:var(--ink-0); }
@media (max-width:600px){
  .promo-bar{ padding:6px 38px 6px 12px; font-size:12px; min-height:34px; }
  .promo-inner{ gap:4px 8px; }
  .promo-spark{ display:none; }
  .promo-code{ padding:2px 8px; font-size:11px; }
  .promo-note{ font-size:11px; }
}

/* promo colour styles (owner picks one in Site & promo) */
.promo-bar.promo--cyan{ background:linear-gradient(90deg, color-mix(in srgb,var(--led-cyan) 40%,var(--bg-0)), color-mix(in srgb,var(--led-cyan) 22%,var(--bg-0))); }
.promo-bar.promo--violet{ background:linear-gradient(90deg, color-mix(in srgb,var(--led-violet) 45%,var(--bg-0)), color-mix(in srgb,var(--led-violet) 24%,var(--bg-0))); border-bottom-color:color-mix(in srgb,var(--led-violet) 55%,transparent); box-shadow:0 0 18px -6px var(--led-violet); }
.promo-bar.promo--amber{ background:linear-gradient(90deg, color-mix(in srgb,var(--led-amber) 45%,var(--bg-0)), color-mix(in srgb,var(--led-amber) 24%,var(--bg-0))); border-bottom-color:color-mix(in srgb,var(--led-amber) 55%,transparent); box-shadow:0 0 18px -6px var(--led-amber); }
.promo-bar.promo--lime{ background:linear-gradient(90deg, color-mix(in srgb,var(--led-lime) 34%,var(--bg-0)), color-mix(in srgb,var(--led-lime) 18%,var(--bg-0))); border-bottom-color:color-mix(in srgb,var(--led-lime) 50%,transparent); box-shadow:0 0 18px -6px var(--led-lime); }
.promo-bar.promo--magenta{ background:linear-gradient(90deg, color-mix(in srgb,var(--led-magenta) 42%,var(--bg-0)), color-mix(in srgb,var(--led-magenta) 22%,var(--bg-0))); border-bottom-color:color-mix(in srgb,var(--led-magenta) 55%,transparent); box-shadow:0 0 18px -6px var(--led-magenta); }
.promo-bar.promo-preview{ border-radius:10px; border:1px solid var(--line); }

/* ---------- ISP set manager ---------- */
.status-cancel{ color:var(--led-magenta); border-color:color-mix(in srgb,var(--led-magenta) 55%,var(--line)); }
.isp-summary{ display:grid; grid-template-columns:repeat(4,1fr); gap:14px; margin-bottom:16px; }
.isp-toolbar{ display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:14px; }
.isp-select{ background:var(--bg-3); border:1px solid var(--line); border-radius:8px; color:var(--ink-1); padding:7px 10px; font-family:var(--font-mono); font-size:12px; }
.isp-card{ margin-bottom:16px; padding:20px 22px; }
.isp-card.is-ended{ opacity:.6; }
.isp-card-main{ display:grid; grid-template-columns:auto 1fr auto; gap:20px; align-items:center; }
.isp-ring-wrap{ position:relative; width:104px; height:104px; flex:none; }
.isp-ring{ overflow:visible; display:block; }
.isp-ring-label{ position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; line-height:1.1; }
.isp-ring-label b{ font-family:var(--font-mono); font-size:24px; color:var(--ink-0); }
.isp-ring-label small{ font-size:8.5px; color:var(--ink-2); text-transform:uppercase; letter-spacing:.05em; margin-top:2px; }
.isp-card-title{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:15px; margin-bottom:8px; }
.isp-meta{ display:flex; gap:22px; flex-wrap:wrap; font-family:var(--font-mono); font-size:13px; color:var(--ink-0); }
.isp-meta i{ display:block; font-style:normal; font-family:var(--font-body, inherit); font-size:10px; color:var(--ink-2); text-transform:uppercase; letter-spacing:.06em; margin-bottom:2px; }
.isp-note{ margin-top:9px; font-size:12.5px; color:var(--ink-1); }
.isp-actions{ display:flex; gap:6px; flex-wrap:wrap; justify-content:flex-end; max-width:300px; }
.isp-lines-wrap{ margin-top:14px; }
.isp-lines{ width:100%; background:var(--bg-3); border:1px solid var(--line); border-radius:8px; color:var(--ink-1); padding:10px 12px; font-size:12px; resize:vertical; }
.isp-empty{ text-align:center; padding:52px 24px; }
.isp-empty h2{ font-size:19px; margin:12px 0 10px; }
.isp-empty p{ max-width:50ch; margin:0 auto 22px; font-size:14px; }
.isp-empty-ico{ width:56px; height:56px; margin:0 auto; border-radius:14px; display:flex; align-items:center; justify-content:center; background:var(--bg-3); border:1px solid var(--line); box-shadow:0 0 22px -6px var(--led-cyan); }
.isp-empty-ico img{ width:26px; height:26px; }
@media (max-width:900px){
  .isp-summary{ grid-template-columns:repeat(2,1fr); }
  .isp-card-main{ grid-template-columns:auto 1fr; }
  .isp-actions{ grid-column:1 / -1; justify-content:flex-start; max-width:none; }
}

/* Admin → users: ISP and bandwidth in their own columns, evenly spaced */
.admin-users-table th, .admin-users-table td{ padding-left:18px; padding-right:18px; }
.admin-users-table th:nth-child(3), .admin-users-table td:nth-child(3){ min-width:120px; }
.admin-users-table th:nth-child(4), .admin-users-table td:nth-child(4){ min-width:130px; }
.admin-users-table td.admin-isp-cell, .admin-users-table td.admin-bandwidth-cell{ white-space:nowrap; }

/* ---------- notification centre ---------- */
.nt-menu{ position:absolute; top:calc(100% + 12px); right:-8px; width:370px; max-width:calc(100vw - 24px); z-index:80; cursor:default; text-align:left;
  background:var(--bg-2); border:1px solid color-mix(in srgb,var(--led-cyan) 45%,var(--line)); border-radius:14px;
  box-shadow:0 0 0 1px color-mix(in srgb,var(--led-cyan) 15%,transparent), 0 0 28px -8px var(--led-cyan), 0 22px 44px -14px rgba(0,0,0,.7); overflow:hidden; }
.nt-head{ display:flex; justify-content:space-between; align-items:center; gap:10px; padding:14px 16px 10px; }
.nt-title{ font-family:var(--font-display, inherit); font-size:15px; font-weight:700; color:var(--ink-0); display:flex; align-items:center; gap:8px; }
.nt-count{ font-family:var(--font-mono); font-size:11px; color:#021417; background:var(--led-cyan); border-radius:999px; padding:1px 7px; box-shadow:0 0 10px -2px var(--led-cyan); }
.nt-count:empty{ display:none; }
.nt-head-actions{ display:flex; align-items:center; gap:4px; }
.nt-link{ background:none; border:1px solid var(--line); border-radius:6px; color:var(--ink-1); font-size:11px; padding:3px 8px; cursor:pointer; font-family:inherit; }
.nt-link:hover{ border-color:var(--led-cyan); color:var(--ink-0); }
.nt-x{ background:none; border:none; color:var(--ink-2); font-size:14px; cursor:pointer; padding:2px 6px; }
.nt-x:hover{ color:var(--ink-0); }
.nt-filters{ display:flex; gap:6px; padding:0 16px 12px; border-bottom:1px solid var(--line); }
.nt-chip{ background:var(--bg-3); border:1px solid var(--line); border-radius:999px; color:var(--ink-2); font-size:11.5px; padding:4px 11px; cursor:pointer; font-family:inherit; }
.nt-chip.active{ color:#021417; background:var(--led-cyan); border-color:var(--led-cyan); box-shadow:0 0 12px -4px var(--led-cyan); }
.nt-list{ max-height:420px; overflow-y:auto; }
.nt-item{ display:flex; gap:12px; padding:12px 16px; border-bottom:1px solid var(--line); position:relative; --nt:var(--led-cyan); }
.nt-item:last-child{ border-bottom:none; }
.nt-item:hover{ background:var(--bg-3); }
.nt-item.is-unread{ background:color-mix(in srgb,var(--nt) 7%,transparent); }
.nt-item.is-unread::before{ content:''; position:absolute; left:0; top:10px; bottom:10px; width:3px; border-radius:0 3px 3px 0; background:var(--nt); box-shadow:0 0 8px var(--nt); }
.nt-success{ --nt:var(--led-lime); } .nt-warning{ --nt:var(--led-amber); } .nt-error{ --nt:var(--led-magenta); }
.nt-info{ --nt:var(--led-cyan); } .nt-announce{ --nt:var(--led-violet); }
.nt-ico{ flex:none; width:30px; height:30px; border-radius:9px; display:flex; align-items:center; justify-content:center; font-size:13px; font-weight:700;
  color:var(--nt); background:color-mix(in srgb,var(--nt) 12%,var(--bg-3)); border:1px solid color-mix(in srgb,var(--nt) 45%,var(--line)); }
.nt-body{ flex:1; min-width:0; }
.nt-row{ display:flex; justify-content:space-between; gap:10px; align-items:baseline; }
.nt-row b{ font-size:13px; color:var(--ink-0); }
.nt-time{ font-family:var(--font-mono); font-size:10.5px; color:var(--ink-2); white-space:nowrap; }
.nt-msg{ font-size:12.5px; color:var(--ink-1); line-height:1.5; margin-top:3px; white-space:pre-line; overflow-wrap:anywhere; }
.nt-empty{ padding:34px 16px; text-align:center; font-size:13px; color:var(--ink-2); }

/* ---------- activity log: capped height, scrolls ---------- */
.activity-scroll{ max-height:520px; overflow-y:auto; }

/* Placeholder until the real username loads (no more flash of someone else's name) */
.skeleton-text{ display:inline-block; min-width:72px; height:12px; border-radius:6px; vertical-align:middle;
  background:linear-gradient(90deg,var(--bg-3) 0%,color-mix(in srgb,var(--line) 70%,var(--bg-3)) 50%,var(--bg-3) 100%);
  background-size:200% 100%; animation:skel 1.2s linear infinite; }
@keyframes skel{ from{ background-position:200% 0; } to{ background-position:-200% 0; } }

.nt-ico img{ display:block; width:16px; height:16px; }
