/* Lewk Skywatcher — navy base, forest-green accents */

:root {
  --navy-950: #060d18;
  --navy-900: #0a1626;
  --navy-850: #0d1c30;
  --navy-800: #10233b;
  --navy-700: #1a3354;
  --navy-600: #274668;
  --green-600: #1f7a4a;
  --green-500: #2e9e63;
  --green-400: #3fbf7a;
  --text: #e6eef7;
  --text-muted: #8fa5bd;
  --text-dim: #5d7590;
  --danger: #d9534f;
  --gold: #e0b23f;
  --radius: 12px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  background:
    radial-gradient(1200px 600px at 70% -10%, rgba(46, 158, 99, 0.08), transparent 60%),
    radial-gradient(900px 500px at 10% 110%, rgba(26, 51, 84, 0.55), transparent 60%),
    var(--navy-950);
  color: var(--text);
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

a { color: var(--green-400); text-decoration: none; }
a:hover { text-decoration: underline; }

/* --- Top bar ------------------------------------------------------------ */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.9rem 1.6rem;
  background: rgba(10, 22, 38, 0.85);
  border-bottom: 1px solid var(--navy-700);
  backdrop-filter: blur(6px);
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text);
}
.brand:hover { text-decoration: none; color: var(--green-400); }

.brand-mark {
  width: 22px;
  height: 22px;
  fill: var(--green-500);
}

.topbar-user {
  display: flex;
  align-items: center;
  gap: 0.8rem;
}
.user-name { color: var(--text); font-weight: 600; }
.user-role {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--green-400);
  border: 1px solid var(--green-600);
  border-radius: 999px;
  padding: 0.15rem 0.55rem;
}
a.user-role { text-decoration: none; cursor: pointer; }
a.user-role:hover { background: var(--green-600); color: #fff; }

/* View-switcher pills — admin section (render_admin_nav_pills()), same
   markup as the beacon section's chronicle-themed pills, restyled with
   the navy theme's own variables since style.css and chronicle_css()
   are two separate stylesheets with no shared custom properties. */
.pillwrap { padding-top: 4px; margin-bottom: 20px; }
nav.pills { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: none; -ms-overflow-style: none; }
nav.pills::-webkit-scrollbar { display: none; }
nav.pills a { text-decoration: none; color: var(--text-muted); font-size: 13.5px; font-weight: 600; padding: 6px 14px; border-radius: 999px; border: 1px solid var(--navy-600); white-space: nowrap; background: var(--navy-800); flex: none; }
nav.pills a.active, nav.pills a:hover { color: var(--green-400); border-color: var(--green-500); }

/* --- Layout ------------------------------------------------------------- */

.page {
  flex: 1;
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding: 2.5rem 1.5rem;
}

.footer {
  text-align: center;
  padding: 1.2rem;
  color: var(--text-dim);
  font-size: 0.8rem;
  border-top: 1px solid var(--navy-800);
}

.page-title {
  font-size: 1.9rem;
  font-weight: 700;
  margin-bottom: 0.4rem;
}
.page-sub {
  color: var(--text-muted);
  margin-bottom: 2.2rem;
}
.accent { color: var(--green-400); }

/* --- Buttons ------------------------------------------------------------ */

.btn {
  display: inline-block;
  padding: 0.55rem 1.2rem;
  border-radius: 8px;
  border: 1px solid transparent;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.btn:hover { text-decoration: none; }

.btn-primary {
  background: var(--green-600);
  color: #fff;
}
.btn-primary:hover { background: var(--green-500); }

.btn-ghost {
  background: transparent;
  color: var(--text-muted);
  border-color: var(--navy-600);
}
.btn-ghost:hover { color: var(--text); border-color: var(--green-500); }

/* --- Game grid ----------------------------------------------------------- */

.game-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1.4rem;
}

.game-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding: 2.2rem 1.4rem 1.8rem;
  background: linear-gradient(180deg, var(--navy-800), var(--navy-850));
  border: 1px solid var(--navy-700);
  border-radius: var(--radius);
  text-align: center;
  color: var(--text);
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
}

a.game-tile:hover {
  text-decoration: none;
  transform: translateY(-3px);
  border-color: var(--green-500);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4), 0 0 0 1px var(--green-600);
}

.game-icon {
  width: 76px;
  height: 76px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 18px;
  background: var(--navy-900);
  border: 1px solid var(--navy-600);
}
.game-icon svg {
  width: 44px;
  height: 44px;
  fill: var(--green-400);
}

.game-name {
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.3;
}
.game-tag {
  font-size: 0.78rem;
  color: var(--text-muted);
}

.game-status {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
}
.status-live {
  color: var(--green-400);
  border: 1px solid var(--green-600);
}
.status-soon {
  color: var(--text-dim);
  border: 1px solid var(--navy-600);
}

.game-tile.disabled {
  opacity: 0.45;
  filter: grayscale(0.8);
  cursor: not-allowed;
}
.game-tile.disabled .game-icon svg { fill: var(--text-dim); }

/* Section heading for the non-game rows below the game grid on the home
   page ("More"). Sits between two .game-grid blocks. */
.row-title {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-dim);
  margin: 2.6rem 0 1.1rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--navy-800);
}

/* --- Relationships section ----------------------------------------------
   Rose accent instead of the site's forest green, so the non-game section
   reads as its own thing. Same tile geometry as .game-tile. */

.rel-section { --rose-500: #b3627f; --rose-400: #d4a4b8; --rose-300: #e6c3d1; }

.tile-rose .game-icon svg { fill: var(--rose-400, #d4a4b8); }
a.tile-rose:hover {
  border-color: var(--rose-500, #b3627f);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4), 0 0 0 1px var(--rose-500, #b3627f);
}
.status-open {
  color: var(--rose-400, #d4a4b8);
  border: 1px solid var(--rose-500, #b3627f);
}

.rel-section .page-title { color: var(--rose-300); }

.rel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.4rem;
}

.rel-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 1.7rem 1.5rem 1.5rem;
  background: linear-gradient(180deg, var(--navy-800), var(--navy-850));
  border: 1px solid var(--navy-700);
  border-radius: var(--radius);
  color: var(--text);
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
}
a.rel-tile:hover {
  text-decoration: none;
  transform: translateY(-3px);
  border-color: var(--rose-500);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4), 0 0 0 1px var(--rose-500);
}

.rel-kind {
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--rose-400);
}
.rel-title { font-size: 1.12rem; font-weight: 700; line-height: 1.35; }
.rel-blurb { color: var(--text-muted); font-size: 0.9rem; line-height: 1.55; }
.rel-cta {
  margin-top: 0.35rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--rose-400);
  border: 1px solid var(--rose-500);
  border-radius: 999px;
  padding: 0.2rem 0.8rem;
}

/* --- Login card ----------------------------------------------------------- */

.login-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
}

.login-card {
  width: 100%;
  max-width: 380px;
  background: linear-gradient(180deg, var(--navy-800), var(--navy-850));
  border: 1px solid var(--navy-700);
  border-radius: var(--radius);
  padding: 2.4rem 2.2rem;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.login-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: 1.8rem;
}
.login-brand svg {
  width: 46px;
  height: 46px;
  fill: var(--green-500);
}
.login-brand h1 {
  font-size: 1.25rem;
  letter-spacing: 0.02em;
  text-align: center;
}

.field { margin-bottom: 1.1rem; }
.field label {
  display: block;
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-bottom: 0.35rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.field input {
  width: 100%;
  padding: 0.65rem 0.8rem;
  background: var(--navy-950);
  border: 1px solid var(--navy-600);
  border-radius: 8px;
  color: var(--text);
  font-size: 0.95rem;
}
.field input:focus {
  outline: none;
  border-color: var(--green-500);
  box-shadow: 0 0 0 3px rgba(46, 158, 99, 0.18);
}

.btn-block { width: 100%; text-align: center; }

.form-error {
  background: rgba(217, 83, 79, 0.12);
  border: 1px solid rgba(217, 83, 79, 0.45);
  color: #f2b8b6;
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  font-size: 0.85rem;
  margin-bottom: 1.1rem;
}
.form-notice {
  background: rgba(46, 158, 99, 0.1);
  border: 1px solid var(--green-600);
  color: var(--green-400);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  font-size: 0.85rem;
  margin-bottom: 1.1rem;
}

/* Standing site-wide notice, sized to be read before the login card rather
   than inside it (Curtis 2026-09-08). Gold, not green — this is an advisory,
   not a success state, and gold deliberately never touches the green accent
   here (see beacon_chrome.php on the gold/green adjacency rule). */
.site-banner {
  max-width: 760px;
  margin: 0 auto 2.2rem;
  background: linear-gradient(180deg, rgba(224, 178, 63, 0.15), rgba(224, 178, 63, 0.06));
  border: 1px solid var(--gold);
  border-left-width: 5px;
  border-radius: var(--radius);
  padding: 1.4rem 1.7rem;
  text-align: center;
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.45);
}
.site-banner h2 {
  font-size: 1.3rem;
  line-height: 1.35;
  color: var(--gold);
  margin-bottom: 0.55rem;
}
.site-banner p {
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--text-muted);
}
@media (max-width: 520px) {
  .site-banner { padding: 1.1rem; }
  .site-banner h2 { font-size: 1.05rem; }
}

/* Login page: password / access-code tabs (Curtis 2026-08-08) */
.login-tabs { display: flex; gap: 4px; background: var(--navy-950); border: 1px solid var(--navy-600); border-radius: 8px; padding: 3px; margin-bottom: 1.1rem; }
.login-tab { flex: 1; background: none; border: none; border-radius: 6px; padding: 0.5rem 0.6rem; font-size: 0.85rem; font-weight: 600; color: var(--text-dim); cursor: pointer; }
.login-tab.active { background: var(--navy-700); color: var(--text); }

/* Password field with an eyeball show/hide toggle (set_password.php) */
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 2.4rem; }
.pw-eye { position: absolute; right: 0.55rem; top: 50%; transform: translateY(-50%); background: none; border: none; padding: 4px; cursor: pointer; line-height: 0; }
.pw-eye svg { width: 20px; height: 20px; fill: var(--text-dim); }
.pw-eye:hover svg { fill: var(--text); }

/* --- Section stub --------------------------------------------------------- */

.stub-card {
  background: linear-gradient(180deg, var(--navy-800), var(--navy-850));
  border: 1px solid var(--navy-700);
  border-radius: var(--radius);
  padding: 2rem;
  color: var(--text-muted);
}

/* --- Beacon drill-down grids (servers / alliances / roster) -------------- */

.beacon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 0.9rem;
  margin: 1.2rem 0 2.2rem;
}

.beacon-tile {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 1rem 1.1rem;
  background: linear-gradient(180deg, var(--navy-800), var(--navy-850));
  border: 1px solid var(--navy-600);
  border-radius: 10px;
  color: var(--text);
  transition: border-color 0.15s, transform 0.15s;
}
a.beacon-tile:hover { text-decoration: none; border-color: var(--green-500); transform: translateY(-2px); }

/* "Yours" — the viewer's own server/alliance, once identity context exists. */
.beacon-tile.mine { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold); }

.beacon-tile .beacon-tile-title { font-weight: 700; font-size: 1rem; }
.beacon-tile .beacon-tile-sub { font-size: 0.78rem; color: var(--text-muted); }

/* Unswept / no data yet — visible but not a link. */
.beacon-tile.disabled {
  opacity: 0.4;
  filter: grayscale(0.7);
  cursor: not-allowed;
  border-color: var(--navy-700);
  color: var(--text-dim);
}

/* Disbanded — still a real link (history/roster still viewable), just
   visually deprioritized and always sorted after active ones. */
.beacon-tile.disbanded {
  opacity: 0.55;
  filter: grayscale(0.6);
  border-color: var(--navy-700);
  color: var(--text-dim);
}
a.beacon-tile.disbanded:hover { border-color: var(--text-muted); color: var(--text-muted); }

/* --- Access / context pill row -------------------------------------------- */

.pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.6rem;
}
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  border: 1px solid var(--navy-600);
  color: var(--text-muted);
  font-size: 0.82rem;
  font-weight: 600;
}
a.pill:hover { text-decoration: none; border-color: var(--green-500); color: var(--text); }
.pill.active { border-color: var(--green-500); color: var(--green-400); }
.pill.disabled { opacity: 0.4; cursor: not-allowed; }

/* Context pills (Server / Alliance / Player) — same markup/classes as
   the chronicle chrome's version (app/beacon_chrome.php), themed for
   the site's navy chrome instead, so render_context_pills() works on
   both without a fork. */
.ctx-pills { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.4rem; }
.ctx-pills a, .ctx-pills span {
  text-decoration: none; font-size: 0.82rem; font-weight: 600;
  padding: 0.35rem 0.85rem; border-radius: 999px;
  border: 1px solid var(--navy-600); color: var(--text-muted); background: var(--navy-850);
}
.ctx-pills a:hover { border-color: var(--green-500); color: var(--text); text-decoration: none; }
.ctx-pills .mine { border-color: var(--gold); color: var(--gold); }
.ctx-pills .disabled { opacity: 0.45; }
.you-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-dim); align-self: center; padding-right: 2px; }

.nav-breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 0.85rem; color: var(--text-muted); padding-bottom: 1.1rem; }
.nav-breadcrumb a { text-decoration: none; color: var(--text-muted); }
.nav-breadcrumb a:hover { color: var(--green-400); text-decoration: underline; }
.nav-breadcrumb .current { color: var(--text); font-weight: 700; }
.nav-breadcrumb .sep { color: var(--text-dim); }

.site-search { max-width: 880px; margin: 2.5rem auto 0; padding: 1rem 1.5rem; border-top: 1px solid var(--navy-800); }
.site-search form { display: flex; gap: 0.5rem; max-width: 420px; }
.site-search input {
  flex: 1; padding: 0.55rem 0.8rem; border: 1px solid var(--navy-600); border-radius: 8px;
  background: var(--navy-950); color: var(--text); font-size: 0.9rem;
}
.site-search button {
  padding: 0.55rem 1.1rem; border: 1px solid transparent; border-radius: 8px;
  background: var(--green-600); color: #fff; font-weight: 600; font-size: 0.85rem; cursor: pointer;
}
.site-search button:hover { background: var(--green-500); }

/* --- Interactive smoke background --------------------------------------- */
/* Opt-in per page via page_header($title, ['smoke' => true]) which adds the
   .has-smoke body class, the #smoke canvas, and loads assets/js/smoke-bg.js.
   The canvas is a fixed, full-viewport layer behind everything; real content
   is lifted above it. On these pages the smoke replaces the body's static
   background glow (which stays as the no-WebGL fallback). */
.has-smoke #smoke {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
}
.has-smoke .smoke-vignette {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* darkens the edges so content near the viewport border stays readable */
  background: radial-gradient(120% 90% at 50% 40%, transparent 45%, rgba(6, 13, 24, 0.55) 100%);
}
/* Lift the real page chrome above the canvas + vignette (z-index 0). */
.has-smoke .topbar,
.has-smoke main.page,
.has-smoke .footer {
  position: relative;
  z-index: 1;
}
/* Turn the solid cards into glass so the smoke reads through them, matching
   the approved POC. Kept fairly opaque (~0.72) so text contrast holds. */
.has-smoke .login-card,
.has-smoke .game-tile {
  background: linear-gradient(180deg, rgba(16, 35, 59, 0.72), rgba(13, 28, 48, 0.72));
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
/* The standing notice gets the same glass blur, but keeps its own gold wash —
   so it is listed separately rather than added to the rule above. */
.has-smoke .site-banner {
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
