/* ─── APP SHELL ─────────────────────────────────────── */

#app {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

/* ─── SIDEBAR ────────────────────────────────────────── */

#sidebar {
  width: var(--sidebar-width);
  min-width: var(--sidebar-width);
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  position: relative;
  transition: width var(--speed) ease, min-width var(--speed) ease;
  overflow: hidden;           /* no scroll wheel */
  z-index: 100;
  flex-shrink: 0;
}

#sidebar.collapsed {
  width: var(--sidebar-collapsed-width);
  min-width: var(--sidebar-collapsed-width);
}

/* Applied for a single frame while the stored collapse state is restored on
   boot, so the rail is simply in the right place rather than sliding there. */
#sidebar.no-anim,
#sidebar.no-anim * {
  transition: none !important;
}

/* When collapsed, drop the horizontal padding and center every row so the
   brand, nav icons and profile avatar share one vertical center line on the
   narrow rail (otherwise their differing widths leave them slightly off-axis). */
#sidebar.collapsed .sidebar-brand,
#sidebar.collapsed .nav-item,
#sidebar.collapsed .sidebar-profile-btn {
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
}
#sidebar.collapsed .sidebar-toggle {
  margin-left: auto;
  margin-right: auto;
}
/* Remove the labels from the flow entirely (not just fade them) so the icon
   isn't pushed off the rail by an invisible-but-still-sized label + gap. */
#sidebar.collapsed .nav-label,
#sidebar.collapsed .brand-name,
#sidebar.collapsed .sidebar-user-name {
  display: none;
}

/* ── Brand / product icon ── */

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 14px 10px;
  overflow: hidden;
  cursor: pointer;
  position: relative;
  flex-shrink: 0;
  transition: background var(--speed);
}

.sidebar-brand:hover { background: var(--hover); }

/* The lettermark is the fallback the logo image never needs — it stays in the
   markup, permanently hidden, so restoring it for one appearance is a one-line
   revert rather than an edit to index.html. */
.brand-monogram {
  display: none;
  flex-shrink: 0;
  width: var(--icon-slot);
  height: var(--icon-slot);
  border-radius: 50%;
  background: var(--gold);
  color: var(--surface);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
  align-items: center;
  justify-content: center;
  letter-spacing: 0.02em;
}

/* The Arsenal logo is the brand mark in EVERY appearance. Themes may restyle it
   — Windows 2000 squares the corners, Jarvis gives it an arc-reactor pulse — but
   none of them may take it away. */
.brand-logo {
  display: block;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  object-fit: contain;
}

.brand-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 16px;
  color: var(--text);
  white-space: nowrap;
  opacity: 1;
  transition: opacity var(--speed) ease;
  flex: 1;
}

#sidebar.collapsed .brand-name { opacity: 0; }

/* Brand dropdown */
.brand-dropdown {
  position: fixed;
  left: var(--sidebar-width);
  top: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0 8px 8px 0;
  box-shadow: 4px 4px 16px rgba(var(--shadow-rgb),0.10);
  min-width: 200px;
  overflow: hidden;
  display: none;
  z-index: 300;
}

#sidebar.collapsed .brand-dropdown { left: var(--sidebar-collapsed-width); }
.brand-dropdown.open { display: block; }

.brand-dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  font-size: 13px;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--speed), color var(--speed);
}

.brand-dropdown-item:hover {
  background: var(--gold-soft);
  color: var(--gold);
}

.brand-dropdown-divider {
  height: 1px;
  background: var(--border-light);
  margin: 4px 0;
}

/* ── Toggle ── */

.sidebar-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 4px;
  margin: 0 14px 8px;
  color: var(--text-muted);
  flex-shrink: 0;
  transition: background var(--speed), color var(--speed);
}

.sidebar-toggle:hover {
  background: var(--gold-soft);
  color: var(--gold);
}

.sidebar-toggle svg {
  transition: transform var(--speed) ease;
}

#sidebar.collapsed .sidebar-toggle svg { transform: rotate(180deg); }

/* ── Nav ── */

.sidebar-nav {
  flex: 1;
  padding: 4px 0;
  /* T-322: this was a bare `overflow: hidden` with the comment "no scroll".
     It did not prevent scrolling -- it CLIPPED. When the Messages item was
     added the rail outgrew its height and the last item (Agency) vanished
     with no scrollbar and no other indication that anything was missing.
     Nobody noticed for days.

     Two changes, and both are needed. The padding on .nav-item below shrinks
     the items so the current set fits, and this is the fallback for when
     shrinking is not enough (a short laptop viewport, or enough future pages
     that they cannot fit at the minimum size). Failing visibly by scrolling
     is the point; silent clipping is the defect. `min-height: 0` is required
     because this is a flex child -- without it the default `min-height: auto`
     lets the nav grow past the rail and overflow-y never engages. */
  overflow-y: auto;
  min-height: 0;

  /* T-322 follow-up: the owner dragged the window from a 27" monitor to a
     14" laptop panel and the rail didn't change at all, because the first
     pass only sized items off the DOM item count, never off the viewport.
     `overflow-y: auto` alone was also the wrong kind of fallback on its
     own: most browsers/OSes auto-hide an `auto` scrollbar until you hover
     it, which is indistinguishable on screen from "nothing is cut off" —
     the exact silent-clipping complaint this ticket exists to kill. These
     rules force the scrollbar to actually render, in both engines, whenever
     there IS something to scroll (Firefox via `scrollbar-width`/
     `scrollbar-color`, Chromium/Edge via the `::-webkit-scrollbar*`
     pseudo-elements below) instead of leaving it to guesswork. Tokens only —
     `--border` is the same colour already used for hairline dividers. */
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

.sidebar-nav::-webkit-scrollbar { width: 8px; }
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }
.sidebar-nav::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 4px;
}
.sidebar-nav::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* sidebar-nav-sizing.js's applyNavFit() adds this class when even the
   floor item padding (6px) can't fit every item in the currently-measured
   height — i.e. shrinking has hit its limit and the rail WILL scroll.
   `scrollbar-gutter: stable` reserves the scrollbar's track space up front
   so the rail doesn't narrow by a few px the instant scrolling engages,
   which would read as another unexplained layout jump on a screen already
   too short. */
.sidebar-nav.nav-overflowing {
  scrollbar-gutter: stable;
}

/* A soft rounded pill rather than a full-bleed row with a left-edge accent
   bar. Inset from the rail's edges, so the active item reads as a selected
   object sitting on the rail instead of a slab cut out of it.

   Hover is a neutral tint, not the accent: with the accent on both, hover
   and active looked identical for the fraction of a second the pointer was
   over the current page. */
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 1px 8px;
  /* T-322, extended: `--nav-item-pad` is the height-aware value —
     applyNavFit() in components/sidebar-nav-sizing.js measures the REAL,
     currently-available pixel height of `.sidebar-nav` (not just how many
     items exist) and picks a padding from that, so dragging the same
     window from a tall monitor to a short laptop panel actually changes
     this number. It's set on `.sidebar-nav` (custom properties inherit) and
     recomputed on a debounced window resize — see watchNavFit().

     The `clamp(...)` expression is the fallback chain for when
     `--nav-item-pad` hasn't been set yet (first paint, before JS runs) or
     can't be (a caller that can't measure layout): the original T-322
     item-count-only formula, itself falling back to a literal 9px if even
     `--nav-item-count` is missing. 9px is the original, pre-T-322 padding
     and stays the ceiling; 6px is the floor, below which the pill stops
     reading as a usable touch target — past that floor the rail scrolls
     (.sidebar-nav above) rather than shrinking further. */
  padding: var(--nav-item-pad, clamp(6px, calc(80px / var(--nav-item-count, 8)), 9px)) 10px;
  border-radius: var(--radius-control);
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--speed), color var(--speed);
  position: relative;
}

/* `display: flex` above beats the user-agent rule the `hidden` attribute
   relies on, so a nav item shipped hidden in the markup would render anyway.
   That is not theoretical: the Dial Tracker entry is hidden by default and
   revealed by initSidebar() only for agents writing MP or IUL, and without
   this line every FEX-only agent sees an outbound page they have no use for.
   Any future conditional nav item depends on this rule too. */
.nav-item[hidden] { display: none; }

.nav-item:hover {
  background: var(--hover);
  color: var(--text);
}

.nav-item.active {
  background: var(--gold-soft);
  color: var(--gold);
  font-weight: 600;
}

/* Collapsed to the icon rail: shrink the inset so the pill centres under the
   52px rail instead of being squeezed against its left edge. */
#sidebar.collapsed .nav-item { margin-left: 6px; margin-right: 6px; }

/* Every sidebar row uses the same 32px icon slot so the brand, nav items and
   profile all share one vertical center line (see collapsed-rail centering
   below). --icon-slot keeps the monogram / avatar / nav icons in lockstep. */
:root { --icon-slot: 32px; }

.nav-icon {
  font-size: 20px;
  flex-shrink: 0;
  width: var(--icon-slot);
  height: var(--icon-slot);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Custom nav icon image (dropped into src/assets/nav-icons/ and swapped in by
   nav-icons.js). Shown as-is; centered in the icon box. */
.nav-icon-img {
  width: var(--icon-slot);
  height: var(--icon-slot);
  object-fit: contain;
  display: block;
  margin: 0 auto;
  transition: filter var(--speed) ease, transform var(--speed) ease;
}

/* Glow on hover + active — drop-shadow tints to the theme accent (cyan under
   Jarvis, gold under Classic, …) since it reads var(--gold). */
.nav-item:hover .nav-icon-img  { filter: drop-shadow(0 0 5px var(--gold)); }
.nav-item.active .nav-icon-img { filter: drop-shadow(0 0 7px var(--gold)); }

.nav-label {
  font-size: 14px;
  font-weight: 500;
  opacity: 1;
  transition: opacity var(--speed) ease;
}

#sidebar.collapsed .nav-label { opacity: 0; }

/* Tooltip when collapsed */
#sidebar.collapsed .nav-item::after {
  content: attr(data-tooltip);
  position: fixed;
  left: calc(var(--sidebar-collapsed-width) + 8px);
  background: var(--text);
  color: var(--surface);
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 4px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 500;
}

#sidebar.collapsed .nav-item:hover::after { opacity: 1; }

/* ── Profile footer button ── */

.sidebar-profile-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-top: 1px solid var(--border-light);
  cursor: pointer;
  overflow: hidden;
  flex-shrink: 0;
  transition: background var(--speed);
  border-left: 3px solid transparent;
}

.sidebar-profile-btn:hover {
  background: var(--gold-soft);
}

.sidebar-profile-btn.active {
  border-left-color: var(--gold);
  background: var(--gold-soft);
}

.avatar-sm {
  flex-shrink: 0;
  width: var(--icon-slot);
  height: var(--icon-slot);
  border-radius: 50%;
  background: var(--wood-soft);
  color: var(--gold);
  font-size: 12px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  letter-spacing: 0.04em;
  user-select: none;
}

.sidebar-user-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  white-space: nowrap;
  opacity: 1;
  transition: opacity var(--speed) ease;
}

#sidebar.collapsed .sidebar-user-name { opacity: 0; }

/* ─── MAIN ───────────────────────────────────────────── */

#main {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}

/* ─── CONTENT ────────────────────────────────────────── */

#content {
  flex: 1;
  background: var(--bg);
  position: relative;
  --divider-pct: 50;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  min-height: 0;
}
/* Two-pane mode: columns sized by the --divider-pct CSS variable that
   split-pane.js updates while the user drags the divider. */
#content[data-panes="2"] {
  grid-template-columns: calc(var(--divider-pct) * 1%) 6px 1fr;
}

.pane {
  overflow-y: auto;
  min-width: 0;
  min-height: 0;
  position: relative;
}

.split-divider {
  background: var(--border-light);
  cursor: col-resize;
  transition: background var(--speed);
  user-select: none;
  position: relative;
}
.split-divider:hover,
.split-divider:active {
  background: var(--gold);
}
.split-close {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  width: 20px;
  height: 20px;
  border: 0;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-muted);
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(var(--shadow-rgb), 0.18);
  transition: all var(--speed);
  opacity: 0.7;
}
.split-close:hover {
  opacity: 1;
  color: var(--red);
  box-shadow: 0 2px 6px rgba(var(--shadow-rgb), 0.28);
}

.page {
  display: none;
  min-height: 100%;
}

.page.active { display: block; }

/* Safety net: a page-specific stylesheet that puts `display: flex/grid/block` on
   its bare `.<name>-page` rule has the SAME specificity as `.page` above but
   loads later, so it silently wins and forces that page visible under every
   other page (its content bleeds through everywhere). This higher-specificity
   rule (0,2,0) re-asserts the hide for any non-active page and outranks those
   single-class overrides, so the bug can't recur. Active pages set their own
   display (block here, or flex in the page's own `.active` rule). */
.page:not(.active) { display: none; }

/* ── Drop overlay (visible during sidebar drag) ────────────────────────── */
.drop-overlay {
  position: absolute;
  inset: 0;
  z-index: 50;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  pointer-events: auto;
  /* Sit *under* #content's grid-template-columns? It's an absolutely-
     positioned child, so it overlays the whole canvas regardless. */
}
.drop-overlay[hidden] { display: none; }

.drop-zone {
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(181, 137, 58, 0.06);
  border: 2px dashed rgba(181, 137, 58, 0.35);
  margin: 8px;
  border-radius: 12px;
  transition: background var(--speed), border-color var(--speed);
}
.drop-zone.is-over {
  background: rgba(181, 137, 58, 0.18);
  border-color: var(--gold);
}
.drop-label {
  font-family: var(--font-display);
  font-size: 22px;
  color: var(--gold-hover);
  font-weight: 600;
  pointer-events: none;
}

/* ── Popout mode — hide sidebar/FAB so only the requested page shows ── */
body.is-popout #sidebar,
body.is-popout #fab {
  display: none !important;
}
body.is-popout #main { width: 100%; }

.page-padded { padding: 32px 28px; }

/* ─── FAB ────────────────────────────────────────────── */

#fab {
  position: fixed;
  bottom: 28px;
  right: 28px;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--gold);
  color: var(--surface);
  font-size: 24px;
  font-weight: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 16px rgba(181,137,58,0.35);
  cursor: pointer;
  z-index: 1000;
  border: none;
  line-height: 1;
  transition: background var(--speed), transform 0.15s, opacity var(--speed);
}

#fab:hover {
  background: var(--gold-hover);
  transform: scale(1.06);
}

#fab.hidden {
  opacity: 0;
  pointer-events: none;
  transform: scale(0.85);
}

/* ── One-time "new look" notice ───────────────────────────────────────────
   Shown once to a user who was on Classic when Arsenal became the default
   (src/js/theme.js migrateLegacyTheme → components/theme-notice.js). Bottom
   -left so it never covers the FAB. Non-modal and self-dismissing: changing
   the default appearance out from under someone earns an explanation, not a
   dialog they have to clear before they can work. */
.theme-notice {
  position: fixed;
  left: 20px;
  bottom: 20px;
  z-index: 1200;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  max-width: 380px;
  padding: 14px 14px 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-pop);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--speed) ease, transform var(--speed) ease;
}

.theme-notice.is-in { opacity: 1; transform: translateY(0); }

.theme-notice-body { min-width: 0; }

.theme-notice-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 3px;
}

.theme-notice-text {
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-muted);
}

.theme-notice-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  flex-shrink: 0;
}

.theme-notice-close {
  border: none;
  background: transparent;
  color: var(--text-dim);
  font-size: 20px;
  line-height: 1;
  padding: 2px 6px;
  border-radius: var(--radius-control);
  cursor: pointer;
  transition: background var(--speed), color var(--speed);
}

.theme-notice-close:hover { background: var(--hover); color: var(--text); }

@media (prefers-reduced-motion: reduce) {
  .theme-notice { transition: none; }
}

@media (max-width: 720px) {
  .theme-notice { left: 12px; right: 12px; max-width: none; }
}

/* ── Page header ──────────────────────────────────────────────────────────
   Title on the left, controls on the right as a row of pills. Shared rather
   than page-local (the Tracker had its own .tracker-header-row) so every
   page redesigned in a later chunk lands on the same rhythm without
   re-deciding it.

   The controls row wraps under the title on narrow widths instead of
   shrinking the pills, because a pill that has shrunk past its label is
   worse than one on the next line. */
.page-header {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.page-heading { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.page-title {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--text);
}

.page-subtitle {
  font-size: 13px;
  color: var(--text-muted);
}

/* One line. These are a single control cluster — a timeframe picker and the
   settings it governs — so wrapping the gear onto its own row underneath reads
   as two unrelated things. flex-shrink: 0 keeps them from being squeezed by a
   long page title instead. */
.page-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  flex-wrap: nowrap;
  flex-shrink: 0;
}

/* Below this the cluster genuinely cannot fit beside the title, so let it take
   its own full-width row and wrap within itself. */
@media (max-width: 720px) {
  .page-header-actions { margin-left: 0; width: 100%; flex-wrap: wrap; }
}
