/* Dashboard UI theme (decisions/0149, moved from Modules/Vulani's
   theme.css with the widget, chat and briefing rules left behind) -- same
   dark navy + orange visual language as Modules/eMapp/app/static/
   theme.css (decisions/0044).
*/

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  background: #0d1f35;
  color: #d0e4f4;
}

/* Suite-wide dark scrollbar (decisions/0088) -- the default OS/browser
   scrollbar (light grey) looks out of place against every module's dark
   background; same light-on-transparent style applied identically in
   Portal/eMapp/Documents/Vulani's own theme files. */
* { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.25) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: rgba(255,255,255,.25); border-radius: 6px; }
*::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.4); }

a { color: #f5a623; }

/* ── App header / global nav ── */
#app-header {
  background: linear-gradient(135deg, #0d1f35 0%, #1a3a5c 100%);
  color: white; padding: 10px 18px 8px;
  border-bottom: 2px solid #f5a623;
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 10px;
}
#app-header .brand { display: flex; align-items: center; gap: 12px; }
#app-header .logo {
  width: 36px; height: 36px; border-radius: 50%; background: #f5a623;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 800; color: #0d1f35; flex-shrink: 0;
}
#app-header h1 { font-size: .95rem; font-weight: 700; margin: 0; }
#app-header .back-link { font-size: .75rem; color: #8aaac8; text-decoration: none; }
#app-header .back-link:hover { color: #f5a623; }
#app-header nav { display: flex; gap: 14px; flex-wrap: wrap; }
#app-header nav a { font-size: .8rem; color: #b8d0e8; text-decoration: none; }
#app-header nav a:hover, #app-header nav a.active { color: #f5a623; }
#app-header .session-info { font-size: .75rem; color: #cdd5e0; text-align: right; }

/* decisions/0077: when embedded in Portal this module's own header is
   redundant; standalone access keeps it. */
.vs-embedded #app-header { display: none; }
/* Signed out inside Portal: the loading screen covers the wait for Portal's
   sign-in token; the standalone "Sign in" prompt never shows there. */
.vs-embedded .dash-signin { display: none; }


/* David: a real, hand-bumped version visible on screen at all times, even
   embedded (deliberately outside #app-header so the hide rule above
   doesn't take it down too) -- so a stale tab/iframe is distinguishable
   from a genuinely updated one without opening devtools. Top-right:
   bottom-right collides with the ambient Vulani bubble (decisions/0074). */
#dashboard-version {
  position: fixed; right: 6px; top: 4px; z-index: 900;
  font-family: 'Consolas', 'Courier New', monospace;
  font-size: .62rem; letter-spacing: .06em;
  color: #6b7f94; opacity: .75; pointer-events: none;
}

/* ── Page body ── */
.dash-page { padding: 0 18px 24px; }
.dash-page h1 { font-size: 1.1rem; color: #f5a623; margin: 14px 0 8px; }
.dash-page h3 {
  font-size: .7rem; color: #f5a623; text-transform: uppercase;
  letter-spacing: .1em; margin: 14px 0 6px; opacity: .8;
}

select, input[type="text"] {
  background: #1a3a5c; border: 1px solid #2a5a8a; color: #d0e4f4;
  padding: 4px 8px; border-radius: 3px; font-size: 12px;
}
select:focus, input[type="text"]:focus { outline: none; border-color: #f5a623; }

button {
  padding: 5px 14px; border: 1px solid #3a5a7a; border-radius: 3px;
  cursor: pointer; font-size: 12px; background: #1e3a58; color: #b8d0e8;
  transition: all .15s;
}
button:hover:not(:disabled) { background: #254870; color: white; border-color: #5a7a9a; }
button:disabled { opacity: .4; cursor: default; }

/* ── Dashboard (decisions/0060 item 4, panels since decisions/0149) ── */
.dash-error { color: #ffaaaa; font-size: .8rem; margin: 4px 0; }
.dash-card {
  border: 1px solid #2a5a8a; background: #112235; border-radius: 6px;
  padding: 1rem 1.1rem; margin-bottom: 1rem;
  /* David, live: charts grew fine on a window resize but never shrank back
     down. CSS Grid items default to min-width:auto -- once Chart.js sets a
     canvas's actual pixel width larger, that becomes part of this card's
     intrinsic content size, and the grid track (.dash-grid) refuses
     to shrink the column below it even though the window did shrink. The
     resize listener (dashboard.js) was firing correctly the whole time;
     the grid item just wouldn't give the canvas anywhere smaller to go. */
  min-width: 0;
}
/* decisions/0149 B: the page is a 12-column grid of panels. The server
   packs them (panels.arrange) and gives each card its --span (columns) and
   --rows, every row filling all 12 columns, so plain row flow keeps the
   user's own order with no gaps. */
.dash-grid {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-flow: row; gap: 1rem;
}
.dash-grid > .dash-card {
  margin-bottom: 0;
  grid-column: span var(--span, 12); grid-row: span var(--rows, 1);
}
@media (max-width: 900px) { .dash-grid > .dash-card { grid-column: 1 / -1; grid-row: auto; } }
.dash-panel { display: flex; flex-direction: column; }
.dash-panel-body { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
.dash-card-hero .dash-chart-wrap-hero { flex: 1 1 auto; }
.dash-chart-wrap-hero { min-height: 320px; height: auto; }
.dash-hero-stats {
  display: flex; flex-wrap: wrap; gap: .4rem 1.6rem; margin: 0 0 1rem;
  padding-bottom: .8rem; border-bottom: 1px solid #1f3d5c;
}
.dash-hero-stat .label {
  display: flex; align-items: center; gap: 6px; font-size: .72rem; color: #8aaac8;
}
.dash-hero-stat .value { font-size: 1.15rem; font-weight: 700; color: #e8f0f8; margin-top: 2px; }
.dash-hero-stat .value .sub { font-size: .75rem; font-weight: 600; color: #8aaac8; margin-left: 4px; }
.dash-swatch { width: 10px; height: 10px; border-radius: 2px; flex: 0 0 auto; }
.dash-swatch-dashed { width: 14px; height: 0; border-radius: 0; border-top: 2px dashed; }
.dash-card h3 {
  font-size: .78rem; font-weight: 600; color: #d0e4f4; text-transform: none;
  letter-spacing: normal; opacity: 1; margin: 0 0 .8rem;
}
.dash-chart-wrap { position: relative; height: 260px; }
.dash-empty { color: #8aaac8; font-size: .85rem; font-style: italic; }


.dash-lb-row { margin-bottom: .7rem; }
.dash-lb-row:last-child { margin-bottom: 0; }
.dash-lb-head {
  display: flex; justify-content: space-between; align-items: center;
  font-size: .82rem; color: #d0e4f4; margin-bottom: 4px;
}
.dash-lb-meta { display: flex; gap: 10px; align-items: center; font-weight: 600; font-size: .78rem; }
.dash-lb-badge { font-weight: 700; width: 3em; flex: 0 0 auto; text-align: right; }
.dash-lb-pace { width: 3.8em; flex: 0 0 auto; text-align: right; font-weight: 700; white-space: nowrap; }
.dash-lb-variance { width: 5.2em; flex: 0 0 auto; text-align: right; }
.dash-lb-bar-track {
  position: relative; height: 10px; background: rgba(255,255,255,.1); border-radius: 6px;
}
.dash-lb-bar-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 6px; transition: width .3s; }
.dash-lb-bar-mark { position: absolute; top: -3px; bottom: -3px; width: 2px; background: rgba(255,255,255,.7); }
/* David: "draw a vertical line of where the spend should be" -- the pace
   line (today's pro-rata %, fiscal_day_progress_pct) is the primary
   reference now, so it reads as more prominent than the plain 100%-spent
   mark above: dashed, orange, and taller so it isn't lost among the
   over/under-pace bar colours it's meant to be judged against. */
.dash-lb-pace-mark {
  position: absolute; top: -5px; bottom: -5px; width: 0;
  border-left: 2px dashed #f5a623;
}

/* decisions/0137: "Expected" label sitting above the dashed pace line. */
.dash-lb-axis { position: relative; height: 1.1rem; margin-bottom: 2px; }
.dash-lb-expected-label {
  position: absolute; bottom: 0; transform: translateX(-50%);
  font-size: .7rem; font-weight: 700; color: #f5a623; white-space: nowrap;
}

.dash-lb-toolbar { margin: -6px 0 .5rem; }
.dash-lb-sort { display: flex; gap: 6px; align-items: center; justify-content: flex-end; flex-wrap: wrap; }
.dash-lb-sort-btn, .dash-lb-dir-btn {
  background: #16283c; border: 1px solid #2a5a8a; color: #9fc2de; border-radius: 4px;
  font-size: .72rem; font-weight: 600; padding: 3px 8px; cursor: pointer;
}
.dash-lb-sort-btn.active { background: #1f4a6e; color: #e8f0f8; border-color: #4fd1c5; }
.dash-lb-dir-btn { color: #d0e4f4; }
.dash-lb-dir-btn:hover, .dash-lb-sort-btn:hover { border-color: #4fd1c5; }

/* decisions/0149 F: the dashboard's own department and cycle, beside the
   title -- same look as eMapp's .context-picker (decisions/0115). */
.dash-title-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin: 14px 0 8px;
}
.dash-title-row h1 { margin: 0; }
/* margin-right keeps it clear of the fixed #dashboard-version badge
   (measured 2026-09-28: badge 36px wide, 6px from the edge; without this
   the two touched when embedded). */
.context-picker { display: inline-flex; align-items: center; gap: 8px; margin-right: 44px; }
.context-picker select {
  background: #0f2540; color: #d0e4f4; border: 1px solid #1e3a5f;
  border-radius: 4px; padding: 4px 8px; font-size: 13px; min-width: 90px;
}
.context-picker select#dept-select { min-width: 260px; }
