:root {
  --bg: #0f1419;
  --panel: #1a212b;
  --panel-2: #222c38;
  --border: #2c3744;
  --text: #e6edf3;
  --subtle: #8b97a5;
  --accent: #3fb950;
  --accent-2: #58a6ff;
  --warn: #d29922;
  --danger: #f85149;
  --green-tint: rgba(63,185,80,.06);
  --amber-tint: rgba(210,153,34,.06);
  --red-tint: rgba(248,81,73,.05);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  display: flex;
  min-height: 100vh;
}

/* Sidebar */
.sidebar {
  width: 230px;
  flex-shrink: 0;
  background: var(--panel);
  border-right: 1px solid var(--border);
  padding: 20px 16px;
  position: sticky; top: 0; height: 100vh;
  /* Column, so the account block below can be pushed to the bottom with margin-top:auto
     instead of being absolutely positioned and overlapping the nav on a short window. */
  display: flex; flex-direction: column;
}
.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 0 4px;
}
.logo-mark { flex-shrink: 0; border-radius: 7px; }
.logo-word {
  font-size: 22px; font-weight: 700; letter-spacing: -.01em;
  background: linear-gradient(120deg, #58a6ff, #3fb950);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.sidebar-divider {
  height: 1px; background: var(--border); margin: 18px 0 8px;
}
.nav-section {
  font-size: 10px; text-transform: uppercase; letter-spacing: .1em;
  color: var(--subtle); margin: 22px 8px 8px; font-weight: 600;
}
.nav-link {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-radius: 8px;
  color: var(--text); text-decoration: none; font-size: 14px;
  transition: background .12s;
}
.nav-link:hover { background: var(--panel-2); }
.nav-link.active {
  background: rgba(88,166,255,.15); color: var(--accent-2); font-weight: 600;
}
.nav-link.disabled { color: var(--subtle); pointer-events: none; opacity: .45; }
.nav-icon { width: 18px; height: 18px; flex-shrink: 0; opacity: .6; }
.nav-link.active .nav-icon { opacity: 1; }

/* Content */
.content {
  flex: 1; padding: 28px 36px 120px; max-width: 1100px;
}
.page-head h1 { margin: 0 0 4px; font-size: 26px; }
.subtle { color: var(--subtle); font-size: 13px; }

input[type="text"], input[type="number"] {
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text); border-radius: 8px; padding: 8px 10px; font-size: 14px;
}
input[type="text"]:focus, input[type="number"]:focus {
  outline: none; border-color: var(--accent-2);
}

/* Progress (inline in build bar) */
.progress-inline {
  display: flex; align-items: center; gap: 8px; flex-shrink: 0;
}
.progress-track {
  width: 60px; height: 5px; background: var(--panel-2); border-radius: 3px;
  overflow: hidden;
}
.progress-fill {
  height: 100%; border-radius: 3px; transition: width .4s ease, background .4s ease;
  background: var(--accent-2);
}
.progress-fill.complete { background: var(--accent); }
.progress-label { font-size: 12px; white-space: nowrap; color: var(--subtle); }
.progress-label strong { color: var(--text); }
.build-divider {
  width: 1px; height: 24px; background: var(--border); flex-shrink: 0;
}

/* Source sections */
.source-section { margin-top: 24px; }
.source-section:first-of-type { margin-top: 16px; }
.section-header { margin-bottom: 10px; padding-left: 4px; }
.source-section { border-top: 1px solid var(--border); padding-top: 20px; }
.section-header h2 {
  margin: 0 0 2px; font-size: 15px; font-weight: 700;
  letter-spacing: .01em;
}
.section-header .subtle { margin: 0; }

/* Source cards */
.sources { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 12px; }
.src-card {
  background: var(--panel); border: 1px solid var(--border);
  border-left: 3px solid var(--border); border-radius: 10px;
  padding: 16px 18px;
  transition: transform .15s ease, box-shadow .15s ease, background .2s ease;
}
.src-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(0,0,0,.3);
}
/* Category left-border colors */
.src-card.cat-quant { border-left-color: var(--accent-2); }
.src-card.cat-reclist { border-left-color: var(--warn); }
.src-card.cat-portfolio { border-left-color: var(--accent); }
/* Status tinting */
.src-card.status-fresh { background: var(--green-tint); }
.src-card.status-stale { background: var(--amber-tint); }
.src-card.status-missing { background: var(--red-tint); }

.src-head { display: flex; justify-content: space-between; align-items: center; }
.src-name { font-weight: 600; font-size: 15px; }

.src-status { margin: 10px 0; font-size: 13px; display: flex; gap: 6px; align-items: center; }
.src-status .ok { color: var(--accent); font-size: 10px; }
.src-status .missing { color: var(--danger); font-size: 10px; }
.status-chip {
  display: inline-block; font-size: 11px; padding: 2px 8px; border-radius: 6px;
  font-weight: 500;
}
.status-chip.fresh { background: rgba(63,185,80,.15); color: var(--accent); }
.status-chip.stale { background: rgba(210,153,34,.15); color: var(--warn); }

.src-actions { display: flex; align-items: center; gap: 10px; }
.upload-msg { max-width: 220px; word-break: break-word; }

/* Info tooltip */
.info-trigger {
  position: relative; cursor: pointer; font-size: 11px; color: var(--subtle);
  user-select: none; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1.5px solid var(--subtle); font-style: normal;
  transition: color .15s, border-color .15s;
}
.info-trigger:hover, .info-trigger:focus {
  color: var(--accent-2); border-color: var(--accent-2);
}
.info-popup {
  display: none; position: absolute; top: 28px; right: -8px; z-index: 10;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 14px; width: 260px; font-size: 12px; color: var(--text);
  box-shadow: 0 8px 24px rgba(0,0,0,.5);
}
.info-trigger:hover .info-popup,
.info-trigger:focus .info-popup { display: block; }
.info-title { font-weight: 700; margin-bottom: 6px; font-size: 13px; }
.info-row { margin-bottom: 4px; }
.info-cols {
  margin: 4px 0 6px 16px; padding: 0; list-style: disc;
}
.info-cols li { margin-bottom: 2px; color: var(--subtle); }

.msg-warn { color: var(--warn); }

.btn {
  background: var(--panel-2); border: 1px solid var(--border); color: var(--text);
  padding: 8px 16px; border-radius: 8px; font-size: 13px; cursor: pointer;
  transition: border-color .15s, background .15s;
}
.btn:hover { border-color: var(--accent-2); background: rgba(88,166,255,.08); }
.btn.primary {
  background: var(--accent-2); color: #06121f; border-color: var(--accent-2);
  font-weight: 600; padding: 10px 24px; font-size: 14px;
}
.btn.primary:hover { filter: brightness(1.1); }
.btn.primary:disabled { opacity: .5; cursor: default; filter: none; }

/* Build bar — sticky bottom */
.build-bar {
  position: fixed; bottom: 0; left: 220px; right: 0;
  padding: 14px 36px; max-width: calc(1100px + 72px);
  background: var(--panel); border-top: 1px solid rgba(88,166,255,.25);
  box-shadow: 0 -6px 28px rgba(0,0,0,.5);
  z-index: 5;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.build-bar h2 { margin: 0; font-size: 15px; white-space: nowrap; }
.build-bar input[type="text"] { flex: 1; min-width: 160px; }
.build-bar .btn.primary { flex-shrink: 0; }
#build-msg { font-size: 13px; }
.last-df { font-size: 12px; }
.build-meta {
  display: flex; align-items: center; gap: 14px; flex: 1; flex-wrap: wrap;
}

.msg-ok { color: var(--accent); }
.msg-err { color: var(--danger); }

/* ── Analysis table ───────────────────────────────────────────── */
.filter-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 18px 0 14px;
}
.filter-bar input[type="text"] { width: 200px; }
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.seg-btn {
  background: var(--panel); border: none; color: var(--subtle);
  padding: 7px 12px; font-size: 13px; cursor: pointer; border-right: 1px solid var(--border);
}
.seg-btn:last-child { border-right: none; }
.seg-btn:hover { background: var(--panel-2); color: var(--text); }
.seg-btn.active { background: var(--accent-2); color: #06121f; font-weight: 600; }
.toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--subtle); cursor: pointer; }
.toggle input { accent-color: var(--accent-2); }
.filter-count { margin-left: auto; }

.table-wrap {
  border: 1px solid var(--border); border-radius: 10px; overflow: auto;
  max-height: calc(100vh - 160px);
}
.analysis-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.analysis-table thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--panel-2); color: var(--subtle);
  text-align: center; padding: 10px 12px; font-weight: 600;
  white-space: nowrap; border-bottom: 1px solid var(--border);
  font-size: 12px;
}
.analysis-table th.col-ticker, .analysis-table td.col-ticker { text-align: left; }
.analysis-table th.sortable { cursor: pointer; user-select: none; }
.analysis-table th.sortable:hover { color: var(--text); }
.analysis-table th.sort-asc::after { content: " ▲"; font-size: 9px; }
.analysis-table th.sort-desc::after { content: " ▼"; font-size: 9px; }

.analysis-table tbody td {
  padding: 8px 12px; text-align: center; border-bottom: 1px solid rgba(44,55,68,.5);
  white-space: nowrap;
}
.analysis-table tbody tr:hover { background: rgba(88,166,255,.06); }
.col-ticker { font-size: 14px; }
.col-light .pass { color: var(--accent); font-weight: 700; }
.col-light .fail { color: var(--danger); font-weight: 700; }
.col-light .nodata { color: #44515f; font-size: 11px; }

/* Legend */
.legend { display: flex; gap: 18px; margin: 0 0 10px 2px; }
.legend span span { font-weight: 700; margin-right: 3px; }
.legend .pass { color: var(--accent); }
.legend .fail { color: var(--danger); }
.legend .nodata { color: #6b7785; }

/* Header row with day picker */
.head-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.day-picker-wrap { display: flex; align-items: center; gap: 8px; }
.day-picker-wrap label { white-space: nowrap; }
input[type="date"] {
  background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text); border-radius: 8px; padding: 7px 10px; font-size: 13px;
  color-scheme: dark;
}
input[type="date"]:focus { outline: none; border-color: var(--accent-2); }

.stars { letter-spacing: 1px; color: var(--warn); font-size: 14px; }
.star-empty { color: #3a4654; }
.stars-3 { color: var(--accent); }

.dot.rec { color: var(--warn); }
.dot.port { color: var(--accent); }
.muted { color: #4a5663; }
.col-sector { text-align: left; }

/* Filter bar (simplified) */
.filter-bar .legend { margin: 0; }
.btn-sm { padding: 5px 10px; font-size: 12px; }

/* Header chevron + active filter indicator */
.header-chevron { font-size: 9px; color: #4a5663; margin-left: 2px; }
th:hover .header-chevron { color: var(--subtle); }
.filter-active .header-chevron { color: var(--accent-2); }
.filter-active { color: var(--accent-2) !important; }
.filter-active::before {
  content: ""; display: inline-block; width: 5px; height: 5px;
  border-radius: 50%; background: var(--accent-2); margin-right: 4px;
  vertical-align: middle;
}

/* Column filter popover */
.col-popover {
  z-index: 50; background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px 12px; min-width: 160px;
  box-shadow: 0 8px 28px rgba(0,0,0,.5);
}
/* Sort buttons inside popover */
.pop-sort { display: flex; flex-direction: column; gap: 2px; }
.pop-sort-btn {
  display: block; width: 100%; text-align: left; background: none; border: none;
  color: var(--text); padding: 6px 8px; font-size: 13px; cursor: pointer;
  border-radius: 5px;
}
.pop-sort-btn:hover { background: var(--panel-2); }
.pop-sort-btn.active { background: rgba(88,166,255,.15); color: var(--accent-2); font-weight: 500; }
.pop-divider { height: 1px; background: var(--border); margin: 6px 0; }

.pop-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--subtle); margin-bottom: 8px;
}
.pop-seg { display: flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
.pop-seg-btn {
  flex: 1; background: none; border: none; border-right: 1px solid var(--border);
  color: var(--subtle); padding: 6px 8px; font-size: 12px; cursor: pointer;
  white-space: nowrap;
}
.pop-seg-btn:last-child { border-right: none; }
.pop-seg-btn:hover { background: var(--panel-2); color: var(--text); }
.pop-seg-btn.active { background: var(--accent-2); color: #06121f; font-weight: 600; }

.pop-list-btn {
  display: block; width: 100%; text-align: left; background: none; border: none;
  color: var(--text); padding: 6px 8px; font-size: 13px; cursor: pointer;
  border-radius: 5px;
}
.pop-list-btn:hover { background: var(--panel-2); }
.pop-list-btn.active { background: rgba(88,166,255,.15); color: var(--accent-2); font-weight: 500; }

.pop-checks { max-height: 200px; overflow-y: auto; }
.pop-check {
  display: block; font-size: 12px; padding: 3px 0; cursor: pointer;
  color: var(--text);
}
.pop-check input { accent-color: var(--accent-2); margin-right: 6px; }

.pop-range { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.pop-input {
  width: 70px; background: var(--panel-2); border: 1px solid var(--border);
  color: var(--text); border-radius: 6px; padding: 5px 7px; font-size: 12px;
}
.pop-input:focus { outline: none; border-color: var(--accent-2); }
.pop-apply {
  display: block; width: 100%; background: var(--accent-2); color: #06121f;
  border: none; border-radius: 6px; padding: 6px; font-size: 12px;
  font-weight: 600; cursor: pointer;
}
.pop-apply:hover { filter: brightness(1.1); }

/* Diversity bar */
.diversity-bar {
  position: relative; width: 60px; height: 14px;
  background: var(--panel-2); border-radius: 4px; overflow: hidden;
  display: inline-block;
}
.diversity-fill {
  height: 100%; border-radius: 4px;
  background: linear-gradient(90deg, rgba(210,153,34,.4), rgba(63,185,80,.6));
}
.diversity-val {
  position: absolute; top: 0; left: 0; right: 0;
  text-align: center; font-size: 10px; line-height: 14px; color: var(--text);
}

/* Sector performance */
.perf-pos { color: var(--accent); }
.perf-neg { color: var(--danger); }

/* Rec stars */
.rec-stars-3 { color: var(--accent); }
.rec-stars-2 { color: var(--warn); }

/* Sector stars */
.sect-stars-2 { color: var(--accent); }
.sect-stars-1 { color: var(--warn); }

/* Group header row */
.group-row th {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  padding: 6px 12px; border-bottom: 1px solid var(--border);
  font-weight: 600; background: var(--panel) !important;
}
.gh {
  color: var(--accent-2);
  background: rgba(88,166,255,.08) !important;
  border-left: 2px solid rgba(88,166,255,.3) !important;
}

/* Vertical group separators — runs through header row 2 and all data rows */
.analysis-table td.group-start,
.analysis-table th.group-start {
  border-left: 2px solid rgba(88,166,255,.2);
}

/* Alternating subtle group background tint on data rows */
.analysis-table td.group-start ~ td { /* no-op placeholder */ }

/* Build modal */
.build-modal {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.55); backdrop-filter: blur(4px);
  transition: opacity .4s;
}
.build-modal.bm-fade { opacity: 0; pointer-events: none; }
.bm-panel {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 14px; padding: 28px 32px; min-width: 360px;
  box-shadow: 0 12px 40px rgba(0,0,0,.5);
}
.bm-panel h3 { margin: 0 0 18px; font-size: 17px; }
.bm-steps { display: flex; flex-direction: column; gap: 12px; }
.bm-step { display: flex; align-items: center; gap: 10px; font-size: 14px; }
.bm-icon {
  width: 22px; height: 22px; display: inline-flex; align-items: center;
  justify-content: center; border-radius: 50%; font-size: 13px; font-weight: 700;
  flex-shrink: 0;
}
.bm-pending { color: #4a5663; border: 1.5px solid #4a5663; }
.bm-running {
  color: var(--accent-2); border: 1.5px solid var(--accent-2);
  animation: bm-spin 1s linear infinite;
}
.bm-done { color: var(--accent); border: 1.5px solid var(--accent); }
.bm-error { color: var(--danger); border: 1.5px solid var(--danger); }
@keyframes bm-spin { to { transform: rotate(360deg); } }
.bm-label { font-weight: 500; }
.bm-detail { margin-left: auto; font-size: 12px; }
.bm-footer { margin-top: 18px; text-align: center; font-size: 14px; font-weight: 500; }

/* Signed-in account, pinned to the bottom of the sidebar. The only place the session is
   visible in the UI, and the only way out of it: there is no account settings page. */
.sidebar-user {
  margin-top: auto; padding-top: 14px; border-top: 1px solid var(--border);
  font-size: 11.5px; color: var(--subtle); line-height: 1.5;
}
.sidebar-user .who {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sidebar-user a { color: var(--subtle); text-decoration: none; }
.sidebar-user a:hover { color: var(--danger); }

/* ── Marca animada ─────────────────────────────────────────────────────────────
   Inveria's mark, at two sizes: small beside the sidebar wordmark, large as the sign-in
   page's one illustration. Fun Radar's radar sweeps because the app scans; this one draws
   because the app's whole output is a line through crossed sources — the candles rise, the
   line traces itself over them, and the leading dot lands on the last close.

   Lives in style.css rather than in a template because two pages use it. The viewBox is
   190x190 to match Fun Radar's, so the two marks are interchangeable in a layout. */
.chart-mark { display: block; flex-shrink: 0; overflow: visible; }
.chart-mark--sm { width: 30px; height: 30px; }
.chart-mark--lg { width: 104px; height: 104px; margin: 0 auto 14px; }

.chart-grid line {
  stroke: var(--accent-2);
  stroke-opacity: .16;
  stroke-width: 2;
}

/* transform-box: fill-box so each candle scales from its own bottom edge; without it the
   origin resolves against the whole SVG and they slide instead of growing. */
.chart-candles rect {
  fill: var(--accent-2);
  fill-opacity: .28;
  transform-box: fill-box;
  transform-origin: bottom;
  animation: candle-rise 4.5s ease-in-out infinite;
}
.chart-candles rect:nth-child(2) { animation-delay: .35s; }
.chart-candles rect:nth-child(3) { animation-delay: .7s;  fill: var(--accent); }
.chart-candles rect:nth-child(4) { animation-delay: 1.05s; }
.chart-candles rect:nth-child(5) { animation-delay: 1.4s; fill: var(--accent); }

.chart-area { fill: url(#chartFade); opacity: 0; animation: area-fade 9s ease-in-out infinite; }

/* The line draws itself by unrolling its own dash. 470 is a little over the path's length
   (~455) — a value SHORTER than the path leaves a permanent gap at the end, which reads as
   a rendering bug, so it is deliberately generous. */
.chart-line {
  fill: none;
  stroke: url(#chartStroke);
  stroke-width: 7;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 470;
  animation: line-draw 9s ease-in-out infinite;
}

.chart-dot {
  fill: #fff;
  /* Same reason as the candles: dot-land scales, and without fill-box the origin resolves
     against the viewBox instead of the circle — the dot slides sideways off the end of the
     line as it scales, which is exactly what it looked like. */
  transform-box: fill-box;
  transform-origin: center;
  animation: dot-land 9s ease-in-out infinite;
}
.chart-halo {
  fill: none;
  stroke: var(--accent);
  stroke-width: 3;
  animation: halo-out 9s ease-in-out infinite;
}

@keyframes candle-rise {
  0%, 100% { transform: scaleY(.55); }
  50%      { transform: scaleY(1); }
}
/* One 9s cycle: the line draws over the first third, stands finished for most of the rest,
   then fades and starts again. The long hold is the point — an endlessly redrawing line is
   a distraction on a page whose only task is to press one button.
   Drawing begins at 0% rather than after a pause, so there is no stretch of the loop where
   the mark is just three bars and no line, which is what the first version did. */
@keyframes line-draw {
  0%        { stroke-dashoffset: 470; opacity: 1; }
  30%, 90%  { stroke-dashoffset: 0;   opacity: 1; }
  97%, 100% { stroke-dashoffset: 0;   opacity: 0; }
}
@keyframes area-fade {
  0%        { opacity: 0; }
  32%, 90%  { opacity: .9; }
  97%, 100% { opacity: 0; }
}
@keyframes dot-land {
  0%, 26%   { opacity: 0; transform: scale(.2); }
  33%       { opacity: 1; transform: scale(1.5); }
  40%, 90%  { opacity: 1; transform: scale(1); }
  97%, 100% { opacity: 0; transform: scale(1); }
}
@keyframes halo-out {
  0%, 28%   { opacity: 0;  r: 6; }
  35%       { opacity: .7; r: 10; }
  52%, 100% { opacity: 0;  r: 20; }
}

/* At 30px the gridlines and candles turn to mush and the thin strokes vanish against the
   sidebar. The small variant drops them, keeps the line and the dot, and pushes both
   harder — it is meant to be noticed at a glance. */
.chart-mark--sm .chart-grid,
.chart-mark--sm .chart-candles,
.chart-mark--sm .chart-halo { display: none; }
.chart-mark--sm .chart-line { stroke-width: 13; }
.chart-mark--sm .chart-dot { r: 15; }

/* Someone who asked the OS for less motion gets the finished state, not a frozen
   half-drawn line: dash offset 0, dot and area visible, candles at full height. */
@media (prefers-reduced-motion: reduce) {
  .chart-line, .chart-dot, .chart-halo, .chart-area, .chart-candles rect { animation: none; }
  .chart-line { stroke-dashoffset: 0; }
  .chart-area { opacity: .9; }
  .chart-dot { opacity: 1; }
}
