/* ==========================================================================
   NULLWIRE — shared theme
   Used by every page: colours, background, scanlines, buttons, panels,
   nav bar, modal, form fields and leaderboard tables.
   Game-specific styles live next to each game (e.g. breach/breach.css).
   ========================================================================== */

/* Font, hosted on this site (not Google Fonts), so visitors' IP addresses
   are never sent to Google. Licence: assets/fonts/OFL.txt (SIL OFL 1.1). */
@font-face {
  font-family: 'Share Tech Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/share-tech-mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --bg: #0a0b10;
  --panel: rgba(14, 16, 24, 0.92);
  --yellow: #d0ed57;
  --yellow-dim: rgba(208, 237, 87, 0.35);
  --yellow-faint: rgba(208, 237, 87, 0.07);
  --cyan: #5ef6ff;
  --cyan-dim: rgba(94, 246, 255, 0.4);
  --cyan-faint: rgba(94, 246, 255, 0.09);
  --red: #ff4d5e;
  --red-dim: rgba(255, 77, 94, 0.4);
  --text: #d6dcc0;
  --muted: #646a78;
  --font: 'Share Tech Mono', Consolas, 'Courier New', monospace;
}

* { box-sizing: border-box; }

/* The hidden attribute always wins, even over display: flex/grid rules. */
[hidden] { display: none !important; }

html, body { margin: 0; }

body {
  min-height: 100vh;
  background: radial-gradient(ellipse at 50% -10%, #1a2030 0%, var(--bg) 60%) fixed, var(--bg);
  color: var(--text);
  font-family: var(--font);
  letter-spacing: 0.04em;
  overflow-x: hidden;
}

/* Scanlines + vignette overlay */
body::before,
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 50;
}
body::before {
  background: repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.025) 0 1px, transparent 1px 3px);
  animation: scan-flicker 6s infinite steps(1);
}
body::after {
  background: radial-gradient(ellipse at center, transparent 55%, rgba(0, 0, 0, 0.55) 100%);
}
@keyframes scan-flicker {
  0%, 100% { opacity: 1; }
  47% { opacity: 0.7; }
  48% { opacity: 1; }
}
@keyframes blink { 50% { opacity: 0.4; } }

button, input { font-family: inherit; }
a { color: var(--cyan); }

.page {
  max-width: 1100px;
  margin: 0 auto;
  padding: 24px 16px 48px;
}

/* ---------- Nav bar ---------- */

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 24px;
  max-width: 1100px;
  margin: 0 auto;
  padding: 14px 16px;
  border-bottom: 1px solid var(--yellow-faint);
  min-height: 62px;
}
.brand {
  color: var(--yellow);
  text-decoration: none;
  font-size: 1.1rem;
  letter-spacing: 0.15em;
  text-shadow: 0 0 8px var(--yellow-dim);
}
.brand-mark { color: var(--cyan); margin-right: 6px; }
/* "NULL" yellow + "WIRE" cyan, one word */
.brand-sub { color: var(--cyan); text-shadow: 0 0 8px var(--cyan-dim); }

.nav-links { display: flex; flex-wrap: wrap; gap: 4px 18px; flex: 1; }
.nav-link {
  color: var(--text);
  text-decoration: none;
  text-transform: uppercase;
  font-size: 0.85rem;
  letter-spacing: 0.12em;
  padding: 4px 0;
  border-bottom: 1px solid transparent;
}
a.nav-link:hover { color: var(--yellow); }
.nav-link.current { color: var(--yellow); border-bottom-color: var(--yellow); }
.nav-link.soon { color: var(--muted); cursor: default; }
.nav-link.soon::after { content: ' ·SOON'; font-size: 0.65rem; }

.nav-user { display: flex; align-items: center; gap: 10px; }
.nav-handle { color: var(--cyan); text-shadow: 0 0 6px var(--cyan-dim); text-decoration: none; }
.nav-handle:hover, .nav-handle.current { text-decoration: underline; }

/* ---------- Titles ---------- */

.eyebrow { color: var(--cyan); font-size: 0.8rem; opacity: 0.8; }

.title {
  margin: 4px 0 0;
  font-size: clamp(1.8rem, 6vw, 2.8rem);
  font-weight: normal;
  color: var(--yellow);
  text-shadow: 0 0 8px var(--yellow-dim), 0 0 24px rgba(208, 237, 87, 0.2);
  letter-spacing: 0.12em;
}

/* Glitchy title: needs data-text="same text" on the element */
.glitch-text { position: relative; }
.glitch-text::before,
.glitch-text::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.glitch-text::before { color: var(--cyan); animation: glitch-a 2.4s infinite steps(1); }
.glitch-text::after  { color: var(--red);  animation: glitch-b 2.4s infinite steps(1); }

@keyframes glitch-a {
  0%, 100% { transform: none; clip-path: inset(0 0 100% 0); }
  5%  { transform: translate(-3px, 0); clip-path: inset(10% 0 55% 0); }
  10% { transform: translate(2px, 0);  clip-path: inset(60% 0 10% 0); }
  15% { clip-path: inset(0 0 100% 0); }
}
@keyframes glitch-b {
  0%, 100% { transform: none; clip-path: inset(0 0 100% 0); }
  6%  { transform: translate(3px, 0);  clip-path: inset(50% 0 25% 0); }
  11% { transform: translate(-2px, 0); clip-path: inset(15% 0 70% 0); }
  16% { clip-path: inset(0 0 100% 0); }
}

/* ---------- Buttons & badges ---------- */

.btn {
  background: transparent;
  color: var(--yellow);
  border: 1px solid var(--yellow-dim);
  padding: 8px 14px;
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  text-decoration: none;
  display: inline-block;
  cursor: pointer;
  transition: background 0.15s, box-shadow 0.15s, color 0.15s;
}
.btn:hover, .btn:focus-visible {
  outline: none;
  background: var(--yellow-faint);
  box-shadow: 0 0 10px var(--yellow-dim), inset 0 0 8px var(--yellow-faint);
}
.btn:disabled { opacity: 0.5; cursor: wait; }
.btn.active {
  background: var(--yellow);
  color: var(--bg);
  box-shadow: 0 0 12px var(--yellow-dim);
}
.btn.primary { border-color: var(--cyan-dim); color: var(--cyan); }
.btn.primary:hover, .btn.primary:focus-visible {
  background: var(--cyan-faint);
  box-shadow: 0 0 12px var(--cyan-dim), inset 0 0 8px var(--cyan-faint);
}
.btn.danger { border-color: var(--red-dim); color: var(--red); }
.btn.danger:hover, .btn.danger:focus-visible {
  background: rgba(255, 77, 94, 0.08);
  box-shadow: 0 0 12px var(--red-dim), inset 0 0 8px rgba(255, 77, 94, 0.08);
}
.btn.small { padding: 5px 10px; font-size: 0.75rem; }
.btn.wide { width: 100%; }

.badge {
  display: inline-block;
  padding: 3px 8px;
  font-size: 0.7rem;
  letter-spacing: 0.15em;
  border: 1px solid currentColor;
  color: var(--yellow);
}
.badge.cyan  { color: var(--cyan); text-shadow: 0 0 6px var(--cyan-dim); }
.badge.muted { color: var(--muted); }
.badge.red   { color: var(--red); }

/* ---------- Panels ---------- */

/* Panels have a cut-off top-right corner, like the in-game UI.
   The cut is a real clip (clip-path), so it looks right on ANY background.
   ::before draws the diagonal edge in the panel's own border colour.
   To recolour a panel's border, set --panel-border (not border-color). */
.panel {
  --notch: 14px;
  --panel-border: var(--yellow-dim);
  background: var(--panel);
  border: 1px solid var(--panel-border);
  box-shadow: inset 0 0 30px rgba(208, 237, 87, 0.03);
  position: relative;
  clip-path: polygon(0 0, calc(100% - var(--notch)) 0, 100% var(--notch), 100% 100%, 0 100%);
}
.panel::before {
  content: '';
  position: absolute;
  z-index: 1;
  top: -2px;
  left: calc(100% - var(--notch) + 1px);
  width: calc(var(--notch) * 1.4143);
  height: 2px;
  background: var(--panel-border);
  transform-origin: 0 50%;
  transform: rotate(45deg);
  pointer-events: none;
}

.panel-head {
  margin: 0;
  padding: 8px calc(14px + var(--notch, 14px)) 8px 14px;  /* keep text clear of the cut corner */
  flex-wrap: wrap;
  font-size: 0.95rem;
  font-weight: normal;
  color: var(--bg);
  background: var(--yellow);
  letter-spacing: 0.12em;
  display: flex;
  align-items: center;
  gap: 10px;
}
.panel-head .idx {
  display: inline-grid;
  place-items: center;
  width: 20px; height: 20px;
  border: 1px solid var(--bg);
  font-size: 0.8rem;
}

/* ---------- Tabs ---------- */

.tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.tab {
  background: transparent;
  border: 1px solid var(--yellow-dim);
  color: var(--text);
  padding: 6px 12px;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  cursor: pointer;
}
.tab:hover { color: var(--yellow); }
.tab.active { background: var(--yellow); color: var(--bg); border-color: var(--yellow); }

/* ---------- Modal + forms ---------- */

.modal {
  position: fixed;
  inset: 0;
  z-index: 45;
  display: grid;
  place-items: center;
  padding: 16px;
  /* No backdrop-filter blur: re-blurring the animated page behind the modal
     on every frame made typing lag in Firefox. A darker layer instead. */
  background: rgba(5, 6, 10, 0.86);
}
/* While a modal is open, the page behind it stands still: no scanline
   flicker or glitch animation repainting the whole screen while you type. */
body.modal-open::before { animation: none; }
body.modal-open .glitch-text::before,
body.modal-open .glitch-text::after { animation: none; clip-path: inset(0 0 100% 0); } /* hide the glitch layers */
.modal[hidden] { display: none; }
.modal-card { width: min(400px, 100%); }
.modal-card .tabs { padding: 16px 16px 0; }
.modal-close {
  position: absolute;
  top: 4px; right: 22px;
  background: none;
  border: 0;
  color: var(--bg);
  font-size: 1.1rem;
  cursor: pointer;
  padding: 4px;
}

.auth-form { display: grid; gap: 14px; padding: 16px; }
.field { display: grid; gap: 6px; font-size: 0.8rem; color: var(--yellow); }
.field[hidden] { display: none; }
.field small { color: var(--muted); }
.field input {
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid var(--yellow-dim);
  color: var(--text);
  padding: 10px;
  font-size: 1rem;
}
.field input:focus { outline: none; border-color: var(--cyan); box-shadow: 0 0 8px var(--cyan-dim); }
.form-note { margin: 0; font-size: 0.8rem; line-height: 1.5; color: var(--text); }
.check { display: flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--text); cursor: pointer; }
.check input { accent-color: var(--cyan); }
.captcha:empty { display: none; }
.form-links { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
.link-btn {
  background: none;
  border: 0;
  padding: 0;
  color: var(--cyan);
  font-size: 0.75rem;
  text-decoration: underline;
  cursor: pointer;
}
.form-msg { margin: 0; min-height: 1.2em; font-size: 0.8rem; color: var(--muted); }
.form-msg.error { color: var(--red); }
.form-msg.ok { color: var(--cyan); }

/* ---------- Leaderboard table ---------- */

.lb-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.lb-table th {
  text-align: left;
  font-weight: normal;
  color: var(--muted);
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  padding: 6px 8px;
  border-bottom: 1px solid var(--yellow-faint);
}
.lb-table td { padding: 7px 8px; border-bottom: 1px solid rgba(255, 255, 255, 0.04); }
.lb-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.lb-table .rank { color: var(--yellow); width: 3.5em; }
.lb-table tr.top1 .rank, .lb-table tr.top1 .name { color: var(--yellow); text-shadow: 0 0 8px var(--yellow-dim); }
.lb-table tr.me td { background: var(--cyan-faint); color: var(--cyan); }
.lb-empty { color: var(--muted); padding: 16px 8px; margin: 0; font-size: 0.85rem; }

@media (max-width: 560px) {
  .lb-table .hide-sm { display: none; }
}

/* Phones: logo + login on the first row, then ONE swipeable row of links */
@media (max-width: 640px) {
  .site-nav {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 10px 12px;
    padding: 10px 16px;
    min-height: 0;
  }
  .nav-links {
    grid-column: 1 / -1;
    grid-row: 2;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 20px;
    padding-bottom: 2px;
    scrollbar-width: none;
  }
  .nav-links::-webkit-scrollbar { display: none; }
  .nav-link { white-space: nowrap; }
  .nav-user { justify-self: end; min-width: 0; }
  .nav-handle { max-width: 34vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* "Duels ●2" badge in the nav */
.nav-badge {
  display: inline-block;
  min-width: 1.4em;
  margin-left: 6px;
  padding: 0 5px;
  background: var(--cyan);
  color: var(--bg);
  border-radius: 8px;
  font-size: 0.7rem;
  text-align: center;
  box-shadow: 0 0 8px var(--cyan-dim);
}

/* badges inside a yellow header bar: dark, so they stay readable */
.panel-head .badge { color: var(--bg); border-color: rgba(10, 11, 16, 0.6); text-shadow: none; }

/* ---------- Footer (every page) ---------- */

.site-footer {
  max-width: 1100px;
  margin: 0 auto;
  padding: 20px 16px 32px;
  border-top: 1px solid var(--yellow-faint);
  display: grid;
  gap: 10px;
  color: var(--muted);
  font-size: 0.75rem;
  line-height: 1.6;
}
.footer-links { display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 0; padding: 0; list-style: none; }
.footer-links a { color: #8d93a1; text-decoration: none; letter-spacing: 0.1em; }
.footer-links a:hover, .footer-links a:focus-visible { color: var(--cyan); text-decoration: underline; }
.footer-note { margin: 0; max-width: 75ch; color: #7d8391; }
