/* ═══════════════════════════════════════════════════════════════════════════
   NAV RAIL — the icon-tile navigation, an alternative to the list sidebar.

   Scoped under body.nav-rail so the classic sidebar is untouched when it's off,
   and deliberately theme-agnostic: it styles through the same :root variables
   as everything else, so it looks native in both Classic and Nebula rather than
   being a Nebula-only feature.

   Shape follows the reference: a narrow column of rounded icon tiles, each with
   its label beneath, and a permanently visible arrow tab on the right edge that
   opens the full menu. Tiles are the CATEGORIES that already exist (Live,
   Manage, Community, Account) plus Home — clicking one opens a flyout listing
   that category's real pages, so nothing about the information architecture
   changes, only its presentation.
   ═══════════════════════════════════════════════════════════════════════════ */

#navRail { display: none; }

body.nav-rail .sidebar { display: none; }
body.nav-rail #navRail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 188px;
  flex-shrink: 0;
  padding: 12px 0 14px;
  background: var(--bg-panel);
  border-right: 1px solid var(--border);
  position: relative;
  z-index: 40;
}
html.nebula body.nav-rail #navRail {
  background: rgba(7, 11, 22, 0.82);
  border-right-color: rgba(0, 229, 255, 0.12);
  backdrop-filter: blur(10px);
}

/* Same treatment as the list sidebar's logo (height 104, object-fit contain)
   so the brand reads at one size in both navigation modes — the rail is widened
   to 112px specifically to carry it rather than shrinking the mark. */
/* Same treatment as the list sidebar's logo. Its rendered size is governed by
   the rail's width (contain, wide wordmark), which is why the rail is 152px —
   the mark grows with the column, it isn't scaled down to fit a narrow one. */
/* Byte-identical to the list sidebar's logo rule. The rail is the sidebar's
   width for exactly this reason: with object-fit contain, the mark's rendered
   size is governed by the column, so anything narrower shrinks it no matter
   what height is set. */
#navRail .rail-logo {
  height: 104px; width: 100%; max-width: 200px;
  object-fit: contain; display: block; margin: 0 auto 4px;
  cursor: pointer;
}

/* ── tiles ── */
/* No box by default. A bordered tile inside a bordered panel beside a bordered
   rail is three levels of chrome competing at the same weight, which is what
   made this feel heavy — the icon is enough to aim at, and the frame only needs
   to appear for the thing you're actually on. */
.rail-tile {
  width: 156px; height: 84px;
  border-radius: 14px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-dim);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 5px;
  cursor: pointer;
  transition: color .15s, border-color .15s, background .15s, box-shadow .15s;
  position: relative;
  flex-shrink: 0;
}
/* Icons carry the accent by default rather than inheriting the dim label
   colour — they're the thing you aim at, and at 26px they can hold it. */
.rail-tile svg { width: 34px; height: 34px; stroke: var(--accent); fill: none; stroke-width: 1.7; }
.rail-tile:hover svg, .rail-tile.active svg { filter: drop-shadow(0 0 6px rgba(0,229,255,0.55)); }
.rail-tile span { font-size: 12.5px; font-weight: 700; letter-spacing: .02em; }
.rail-tile:hover { color: var(--bright); background: rgba(255,255,255,0.045); }
/* One selected look, not two. .current marks the section holding the page
   you're on, .active marks the menu you have open — they were drawn
   differently (a underline vs a framed tile) on the theory that they answer
   different questions, but two selection styles in one column just reads as
   noise. Same treatment for both. */
.rail-tile.active,
.rail-tile.current {
  color: var(--accent);
  border-color: rgba(0, 229, 255, 0.45);
  background: rgba(0, 229, 255, 0.08);
}

/* Focus has to be visible now these are reachable by keyboard. */
.rail-tile:focus-visible,
.rail-arrow:focus-visible,
.rail-foot .rf-link:focus-visible,
#navRail .rail-logo:focus-visible,
#railPop .pop-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Accent bar on the selected tile, the way the reference marks the current
   section — drawn on the left edge where the eye tracks the column. */
.rail-tile.active::before {
  content: "";
  position: absolute; left: -16px; top: 20px; bottom: 20px;
  width: 3px; border-radius: 2px;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent);
}
/* A live badge collapses to a dot — there's no room for the word on a tile. */
/* Says LIVE rather than showing an unexplained dot — the list view spells it
   out, and a bare dot next to an icon is guesswork. */
.rail-tile .rail-dot {
  position: absolute; top: 6px; right: 10px;
  font-size: 7.5px; font-weight: 900; letter-spacing: .06em;
  padding: 1px 5px; border-radius: 8px;
  background: var(--red); color: #fff;
  box-shadow: 0 0 8px rgba(255,71,87,0.6);
}

.rail-spacer { flex: 1; }

/* ── rail footer ──
   The list sidebar shows who's signed in and links What's New; without these
   the rail quietly drops information rather than just presenting it
   differently. */
.rail-foot {
  width: 100%;
  padding: 8px 8px 0;
  border-top: 1px solid var(--border);
  text-align: center;
}
html.nebula .rail-foot { border-top-color: rgba(0,229,255,0.12); }
.rail-foot .rf-user {
  display: flex; align-items: center; justify-content: center; gap: 5px;
  font-size: 10.5px; font-weight: 700; color: var(--text);
  margin-bottom: 5px;
}
.rail-foot .rf-user span {
  max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rail-foot .rf-dot {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
  background: var(--green); box-shadow: 0 0 6px rgba(0,255,136,0.6);
}
.rail-foot .rf-link {
  font-size: 9.5px; color: var(--text-dim); cursor: pointer;
  padding: 3px 0; letter-spacing: .03em;
}
.rail-foot .rf-link:hover { color: var(--accent); }

/* ── the arrow tab ──
   Always visible, vertically centred on the rail's right edge, per the brief.
   Half-outside the rail so it reads as a pull rather than a button in a row. */
.rail-arrow {
  position: absolute;
  right: -11px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 46px;
  border-radius: 0 11px 11px 0;
  border: 1px solid var(--border); border-left: none;
  background: var(--bg-card);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; cursor: pointer;
  z-index: 41;
  transition: background .15s, box-shadow .15s;
}
.rail-arrow:hover { background: var(--bg-hover); box-shadow: 0 0 12px rgba(0, 229, 255, 0.2); }
.rail-arrow span { transition: transform .2s; display: block; }
body.rail-open .rail-arrow span { transform: rotate(180deg); }

/* ── the scrim ──
   The panel floats over live content, so paragraph text sits directly behind
   menu labels and the eye keeps trying to read both. Dimming and softly
   blurring everything behind it removes the competition without hiding where
   you are — the page is still visible, just pushed back a layer.

   It starts at the rail's right edge so the nav itself stays lit, and it
   swallows the click that dismisses the menu. */
#railScrim {
  display: none;
  position: fixed;
  inset: 0 0 0 188px;
  z-index: 50;
  background: rgba(4, 6, 15, 0.55);
  backdrop-filter: blur(2.5px);
  animation: railScrimIn .16s ease both;
}
body.rail-open #railScrim { display: block; }
@keyframes railScrimIn { from { opacity: 0; } to { opacity: 1; } }
@media (max-width: 900px) { #railScrim { inset: 0 0 0 164px; } }

/* ── the pop-out ──
   Overlays the page rather than widening the layout: the content underneath
   never reflows, so opening the menu can't shuffle a card you were reading.
   Positioned from JS at the clicked tile's own height, so the panel reads as
   coming OUT of that tile.

   Items are buttons in a row that wraps, not a vertical list — at a glance you
   see the whole category at once instead of scanning a column. */
#railPop {
  display: none;
  position: fixed;
  z-index: 60;
  max-width: min(760px, calc(100vw - 140px));
  padding: 10px 12px 12px;
  border-radius: 14px;
  border: 1px solid var(--border);
  background: var(--bg-panel);
  box-shadow: 0 24px 60px rgba(0,0,0,0.7);
  animation: railPopIn .16s ease both;
}
body.rail-open #railPop { display: block; }
@keyframes railPopIn {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: translateX(0); }
}
html.nebula #railPop {
  /* Opaque, not translucent: a see-through panel over a blurred page is still
     two competing images, which is the strain we're removing. */
  background: #0a1120;
  border-color: rgba(0, 229, 255, 0.22);
  box-shadow: 0 24px 60px rgba(0,0,0,0.75), 0 0 30px rgba(0, 229, 255, 0.10);
}
/* The little nib pointing back at the tile it came from. */
#railPop::before {
  content: "";
  position: absolute; left: -6px; top: var(--nib-top, 26px);
  width: 10px; height: 10px;
  background: inherit;
  border-left: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  transform: rotate(45deg);
}
html.nebula #railPop::before { border-color: rgba(0, 229, 255, 0.22); }

#railPop .pop-head {
  font-family: 'Exo 2', sans-serif;
  font-size: 10.5px; font-weight: 800; letter-spacing: 1.6px; text-transform: uppercase;
  color: var(--text-dim);
  padding: 0 2px 9px;
}
/* Items are the same tile as the one that opened them — click a square, get
   more squares. A row of wide pills next to a column of tiles read as two
   different navigations bolted together. */
/* Same square as the rail tile, and borderless for the same reason: the panel
   is already a frame, so framing every item inside it doubles the weight for
   no extra meaning. */
#railPop .pop-row { display: flex; flex-wrap: wrap; gap: 2px; max-width: 486px; }
/* Groups one pop-out into two halves (your channel's setup, then your account).
   flex-basis 100% is what forces the break in a wrapping row. */
#railPop .pop-sep {
  flex: 0 0 100%;
  display: flex; align-items: center; gap: 10px;
  margin: 12px 2px 2px;
  font-family: 'Exo 2', sans-serif;
  font-size: 10.5px; font-weight: 800; letter-spacing: 1.6px; text-transform: uppercase;
  color: var(--text-dim);
}
#railPop .pop-sep::after { content: ""; flex: 1; height: 1px; background: var(--border); }
#railPop .pop-item {
  position: relative;
  width: 156px; height: 84px;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 5px;
  padding: 6px;
  border-radius: 14px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-dim);
  font-size: 12.5px; font-weight: 700;
  text-align: center; line-height: 1.15;
  cursor: pointer;
  transition: all .14s;
}
#railPop .pop-item:hover { color: var(--bright); background: rgba(255,255,255,0.05); }
#railPop .pop-item.active {
  color: var(--accent);
  border-color: rgba(0,229,255,0.45);
  background: rgba(0,229,255,0.08);
}
#railPop .pop-item .icon { font-size: 26px; line-height: 1; }
/* Image icons match the emoji's optical size on a tile. */
#railPop .pop-item .icon img { width: 28px; height: 28px; border-radius: 7px; display: block; }
/* Status line under a tile's name (Beta on the Games tiles). Tiny and dim so it
   reads as a footnote, not a second label; the fixed tile height absorbs it. */
#railPop .pop-sub {
  font-size: 9.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-dim); opacity: .85; line-height: 1; margin-top: -2px;
}
/* Corner badge rather than a row under the label. In the flow it stretched the
   tile and pushed the icon off centre, so a menu of eleven items rippled
   wherever a plan lock happened to fall. Pinned to the corner, every tile keeps
   the same geometry whether it carries a badge or not. */
#railPop .pop-badge {
  position: absolute; top: 6px; right: 6px;
  font-size: 10px; font-weight: 900; letter-spacing: .05em;
  padding: 2px 7px; border-radius: 8px;
  background: var(--red); color: #fff;
  box-shadow: 0 0 8px rgba(255,71,87,0.55);
}
/* Plan locks keep the sidebar's own palette instead of borrowing LIVE's red.
   Red should mean "happening now"; a locked feature is information, not an
   alarm, and Pro vs Elite has to be tellable apart at a glance. */
#railPop .pop-badge.pro-pill {
  background: rgba(167,139,250,0.22); color: #c4b5fd;
  border: 1px solid rgba(167,139,250,0.5); box-shadow: none;
}
#railPop .pop-badge.elite-pill {
  background: rgba(255,215,0,0.18); color: #ffd700;
  border: 1px solid rgba(255,215,0,0.5); box-shadow: none;
}

/* The hamburger collapses the rail the same way it collapses the classic
   sidebar. It used to do nothing here: the collapse rule targets .sidebar, and
   in rail mode .sidebar is already display:none, so the button quietly folded
   an invisible element while the rail stayed put. The rail is a sibling of
   .sidebar inside .app, so it collapses on the same class. */
body.nav-rail #navRail { transition: width .2s ease, opacity .2s ease; }
body.nav-rail .app.sidebar-collapsed #navRail {
  width: 0; min-width: 0; padding: 0; opacity: 0;
  border-right: none; overflow: hidden; pointer-events: none;
}

/* Rail replaces the sidebar entirely on small screens too. */
@media (max-width: 900px) {
  body.nav-rail #navRail { width: 164px; }
  .rail-tile, #railPop .pop-item { width: 136px; height: 78px; }
  #navRail .rail-logo { height: 84px; }
  #railPop { max-width: calc(100vw - 100px); }
}

/* ── phones ──
   The rail is a desktop affordance and does not survive the trip down. It sits
   in the layout flow, so at 164px it was eating 42% of a 390px phone and
   squeezing every page into the strip left over. Worse, reaching a page costs
   three taps here (category tile, then flyout item, then the page) where the
   list costs two, and the flyout itself is a fixed panel positioned from the
   tile's coordinates, which has nowhere to go on a screen this narrow.

   So below 768px, rail mode falls back to the list drawer the dashboard already
   has. The sidebar is static markup that is only ever hidden, never removed, so
   unhiding it reuses the whole existing mechanism unchanged: the hamburger, the
   dimming overlay, toggleSidebar(), and the close-on-navigate handler. Nothing
   in JS needs to know which nav mode is active.

   Desktop keeps the rail exactly as it is. */
@media (max-width: 768px) {
  body.nav-rail #navRail { display: none; }
  body.nav-rail .sidebar { display: flex; }
  /* Both are position:fixed, so a menu left open before a rotate or resize
     would otherwise stay pinned over the page with no way to dismiss it. */
  body.nav-rail #railScrim,
  body.nav-rail #railPop { display: none !important; }
}

/* ── themes dialog ── */
#themeModal {
  display: none;
  position: fixed; inset: 0; z-index: 9998;
  background: rgba(0,0,0,0.6);
  align-items: center; justify-content: center;
}
#themeModal.open { display: flex; }
#themeModal .tm-box {
  width: min(560px, 92vw);
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 22px;
}
html.nebula #themeModal .tm-box { border-color: rgba(0,229,255,0.2); box-shadow: 0 0 40px rgba(0,229,255,0.08); }
#themeModal h3 { font-family: 'Exo 2', sans-serif; margin: 0 0 4px; color: var(--bright); }
#themeModal .tm-sub { font-size: 12.5px; color: var(--text-dim); margin-bottom: 18px; }
#themeModal .tm-label { font-size: 11px; font-weight: 800; letter-spacing: 1.2px; text-transform: uppercase; color: var(--text-dim); margin: 14px 0 8px; }
#themeModal .tm-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
/* Three looks need a third column; the navigation row stays a pair. */
/* Five looks now: auto-fit so the row reflows instead of needing a new rule
   each time one is added. */
#themeModal .tm-row-3 { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); }
@media (max-width: 560px) { #themeModal .tm-row-3 { grid-template-columns: 1fr; } }
#themeModal .tm-opt {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 12px; cursor: pointer; transition: all .15s;
  background: var(--bg-card);
}
#themeModal .tm-opt:hover { border-color: var(--accent); }
#themeModal .tm-opt.sel { border-color: var(--accent); background: rgba(0,229,255,0.07); box-shadow: 0 0 14px rgba(0,229,255,0.12); }
#themeModal .tm-opt .tm-name { font-weight: 800; color: var(--bright); font-size: 13.5px; margin-bottom: 3px; }
#themeModal .tm-opt .tm-desc { font-size: 11.5px; color: var(--text-dim); line-height: 1.45; }
/* Tiny visual preview so the choice isn't made from words alone. */
#themeModal .tm-swatch { height: 34px; border-radius: 7px; margin-bottom: 9px; border: 1px solid var(--border); }
#themeModal .sw-classic { background: linear-gradient(135deg, #161b22 0%, #0d1117 100%); }
#themeModal .sw-horizon {
  background:
    radial-gradient(circle 30px at 92% 108%, transparent 0 17px, rgba(255,236,210,0.75) 18px, rgba(255,157,77,0.5) 21px, transparent 30px),
    radial-gradient(ellipse 50px 34px at 88% 100%, rgba(255,140,60,0.18), transparent 65%),
    #030308;
}
#themeModal .sw-deepfield {
  background:
    radial-gradient(circle 3px at 26% 34%, rgba(217,160,102,0.65), transparent 70%),
    radial-gradient(circle 2px at 64% 24%, rgba(201,143,168,0.6), transparent 70%),
    radial-gradient(circle 3px at 78% 68%, rgba(111,168,196,0.6), transparent 70%),
    radial-gradient(circle 2px at 40% 74%, rgba(217,192,122,0.55), transparent 70%),
    #04050a;
}
#themeModal .sw-icemoon {
  background:
    repeating-linear-gradient(24deg, transparent 0 14px, rgba(120,165,200,0.5) 14px 15px, transparent 15px 30px),
    radial-gradient(ellipse 40px 24px at 80% 0%, #ffffff, transparent 60%),
    #e8f0f7;
}
#themeModal .sw-mission {
  background:
    repeating-linear-gradient(0deg, rgba(255,167,38,0.16) 0 1px, transparent 1px 3px),
    linear-gradient(rgba(255,167,38,0.22) 1px, transparent 1px) 0 0 / 100% 12px,
    linear-gradient(90deg, rgba(255,167,38,0.22) 1px, transparent 1px) 0 0 / 12px 100%,
    #07060a;
}
#themeModal .sw-orbit {
  background:
    radial-gradient(circle 12px at 76% 74%, rgba(255,176,102,0.55), rgba(140,80,190,0.5) 60%, transparent 66%),
    radial-gradient(circle 5px at 22% 28%, rgba(200,190,235,0.6), transparent 70%),
    radial-gradient(ellipse 40px 60px at 70% 10%, rgba(120,70,200,0.35), transparent 60%),
    #06040f;
}
#themeModal .sw-nebula {
  background:
    radial-gradient(ellipse 60px 30px at 80% -10%, rgba(56,132,255,0.5), transparent 60%),
    radial-gradient(ellipse 50px 30px at 10% 120%, rgba(124,92,255,0.4), transparent 60%),
    #04060f;
}
/* Miniatures of each navigation instead of a coloured bar. A flat swatch said
   nothing about the difference between the two layouts, and read as a stray
   pill floating above the label. */
#themeModal .tm-mini {
  height: 46px; border-radius: 7px; margin-bottom: 9px;
  border: 1px solid var(--border);
  background: var(--bg-input);
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 3px;
  padding: 6px;
}
#themeModal .tm-mini i { display: block; border-radius: 2px; background: var(--text-dim); opacity: .5; }
/* list: a wide column with rows in it */
#themeModal .mini-list::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 34%;
  background: var(--bg-card); border-right: 1px solid var(--border);
}
#themeModal .mini-list i { width: 26%; height: 5px; margin-left: 2px; position: relative; }
/* rail: a narrow column of squares */
#themeModal .mini-rail::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 16%;
  background: var(--bg-card); border-right: 1px solid var(--border);
}
#themeModal .mini-rail i { width: 9px; height: 9px; margin-left: 2px; border-radius: 3px; position: relative; }
#themeModal .tm-opt.sel .tm-mini i { background: var(--accent); opacity: .85; }

/* The current choice is stated, not just tinted — a highlight alone is easy to
   misread as hover, especially with two options side by side. */
#themeModal .tm-opt { position: relative; }
#themeModal .tm-opt.sel::after {
  content: "¹3 Selected";
  position: absolute; top: 8px; right: 8px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .04em;
  padding: 2px 7px; border-radius: 10px;
  background: var(--accent); color: #06121a;
}
#themeModal .tm-close { margin-top: 20px; display: flex; justify-content: flex-end; }
