/*
  Control Center.

  Ported from the v8 prototype rather than reinvented: the token block, the 270px sidebar,
  the 68px sticky topbar and the card set are that design, transcribed. Where it differs,
  the difference is deliberate and commented.

  The visual language is a dark compact sidebar against a bright working canvas, and it
  applies from here inward only. The marketing site keeps its own dark styling and shares
  none of this, which is why this file lives here rather than in the analytics library --
  the library ships components with semantic class names and no CSS at all, so the same
  panels can render in this palette here and in a paper palette on the personal site.
*/

:root {
  --bg: #f4f6f8;
  --panel: #fff;
  --ink: #17202a;
  --muted: #6b7785;
  --line: #dde3e8;
  --nav: #111a24;
  --nav2: #1a2a39;
  --navText: #dbe5ee;
  --accent: #2277d6;
  --accentSoft: #eaf3ff;
  --good: #16845b;
  --goodSoft: #e9f8f1;
  --warn: #b46a00;
  --warnSoft: #fff5df;
  --bad: #c23c3c;
  --badSoft: #fff0f0;
  --violet: #7456c7;
  --violetSoft: #f1edff;
  --radius: 14px;
  --shadow: 0 10px 30px rgba(20, 32, 43, .06);

  /* Added for the charts. The prototype drew everything in --accent and --warn, which is
     fine for one line against another and useless the moment a panel needs six colours
     that stay distinguishable. */
  --series-people: #2277d6;
  --series-bots: #b46a00;
  --series-3: #16845b;
  --series-4: #7456c7;
  --series-5: #c23c3c;
  --series-6: #0f7b8a;
  --rating-good: #16845b;
  --rating-needs: #b46a00;
  --rating-poor: #c23c3c;
  --grid: #e7edf1;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: Inter, "Segoe UI", Arial, sans-serif;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* --- Frame ------------------------------------------------------------------------- */

.app { display: grid; grid-template-columns: 270px 1fr; min-height: 100vh; }

.sidebar {
  position: sticky; top: 0; height: 100vh; overflow: auto;
  background: linear-gradient(180deg, var(--nav), #0d141c 72%);
  color: var(--navText);
  padding: 18px 14px;
  border-right: 1px solid #25303a;
}

.logo { display: flex; gap: 11px; align-items: center; margin-bottom: 16px; color: inherit; text-decoration: none; }
/* The mark carries its own dark ground and rounded corners, so the gradient plate the
   placeholder initials needed would only box it in. */
.logoMark { width: 38px; height: 38px; display: block; flex: none; border-radius: 10px; }
.logoCopy { display: flex; flex-direction: column; line-height: 1.15; }
.logoCopy strong { font-size: 1rem; }
.logoCopy span { font-size: .7rem; color: #8ea3b6; }

.roleCard { background: #15212c; border: 1px solid #2b3946; border-radius: 8px; padding: 10px 11px; margin-bottom: 16px; }
.roleCard label { display: block; font-size: .62rem; text-transform: uppercase; letter-spacing: .1em; color: #7d92a5; margin-bottom: 5px; }
.roleCard select {
  width: 100%; background: #0f1922; border: 1px solid #314454; color: var(--navText);
  border-radius: 8px; padding: 6px 8px; font-size: .78rem; font-family: inherit;
}
.scope { margin-top: 7px; font-size: .72rem; color: #8ea3b6; }

.navGroup { margin-bottom: 14px; }
.navLabel { font-size: .67rem; font-weight: 700; text-transform: uppercase; letter-spacing: .13em; color: #617384; padding: 0 8px; margin-bottom: 6px; }

.navItem {
  display: flex; align-items: center; gap: 9px; width: 100%;
  background: none; border: 0; cursor: pointer;
  color: #aebdca; font-size: .88rem; font-family: inherit; text-align: left;
  padding: 8px 9px; border-radius: 9px; text-decoration: none;
}
.navItem:hover { background: #192735; color: #fff; text-decoration: none; }
.navItem.active { background: #203448; color: #fff; box-shadow: inset 3px 0 0 #4fa0ff; }
.navIcon { width: 19px; display: inline-flex; justify-content: center; flex: none; }
.navItem .count { margin-left: auto; background: #2b3b49; color: #bcd0df; font-size: .66rem; padding: 1px 7px; border-radius: 999px; }

/* The prototype marked unbuilt screens with nothing at all. Saying so plainly is better
   than a nav item that looks live and opens an empty page. */
.navItem.pending { opacity: .55; }
.navItem.pending:after { content: "soon"; margin-left: auto; font-size: .58rem; text-transform: uppercase; letter-spacing: .08em; color: #6b8098; }
.navItem.pending .count { display: none; }

.sideFoot { margin-top: 18px; padding: 0 8px; font-size: .66rem; color: #65798b; line-height: 1.5; }

.main { display: flex; flex-direction: column; min-width: 0; }

.topbar {
  position: sticky; top: 0; z-index: 20; height: 68px;
  display: flex; align-items: center; gap: 14px; padding: 0 26px;
  background: rgba(255, 255, 255, .94); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.search { flex: 1; max-width: 560px; display: flex; align-items: center; gap: 8px; background: #f1f4f7; border: 1px solid var(--line); border-radius: 10px; padding: 7px 11px; color: var(--muted); }
.search input { flex: 1; border: 0; background: none; outline: none; font-family: inherit; font-size: .82rem; color: var(--ink); }
.search kbd { font-size: .62rem; background: #fff; border: 1px solid var(--line); border-radius: 5px; padding: 2px 5px; color: var(--muted); }

.topActions { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.iconBtn { position: relative; width: 34px; height: 34px; border-radius: 10px; border: 1px solid var(--line); background: #fff; cursor: pointer; font-size: .9rem; }
.notifyDot { position: absolute; top: 7px; right: 7px; width: 7px; height: 7px; border-radius: 50%; background: var(--bad); }
.userPill { display: flex; align-items: center; gap: 9px; border: 1px solid var(--line); border-radius: 11px; padding: 5px 11px 5px 5px; background: #fff; }
.avatar { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; background: var(--accentSoft); color: var(--accent); font-size: .7rem; font-weight: 800; }
.userText { display: flex; flex-direction: column; line-height: 1.2; }
.userText strong { font-size: .76rem; }
.userText span { font-size: .66rem; color: var(--muted); }

.content { padding: 26px; max-width: 1680px; margin: auto; width: 100%; }

.mobileMenu { display: none; }

/* --- Page furniture ---------------------------------------------------------------- */

.pageHead { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 22px; }
.pageHead h1 { font-size: 1.8rem; letter-spacing: -.03em; margin: 0 0 4px; }
.pageHead p { font-size: .9rem; color: var(--muted); margin: 0; max-width: 76ch; }
.headActions { margin-left: auto; display: flex; gap: 9px; flex-wrap: wrap; align-items: center; }

.banner { background: var(--accentSoft); border: 1px solid #cfe2fa; color: #1c4f8f; border-radius: 10px; padding: 10px 13px; font-size: .76rem; margin-bottom: 18px; }
.banner.warn { background: var(--warnSoft); border-color: #f0dcb0; color: #7a4a00; }

.grid { display: grid; gap: 16px; }
.g2 { grid-template-columns: repeat(2, 1fr); }
.g3 { grid-template-columns: repeat(3, 1fr); }
.g4 { grid-template-columns: repeat(4, 1fr); }
.stack { margin-top: 16px; }

.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); min-width: 0; }
.card.pad { padding: 17px; }
.cardHead { display: flex; align-items: flex-start; gap: 12px; padding: 15px 17px; border-bottom: 1px solid var(--line); }
.cardHead h3 { font-size: .92rem; margin: 0; }
.cardHead .sub { font-size: .73rem; color: var(--muted); margin-top: 2px; }
.cardHead .mini, .cardHead .status { margin-left: auto; }

.metric { padding: 17px; }
.metricTop { display: flex; align-items: center; gap: 10px; }
.metricLabel { font-size: .76rem; font-weight: 700; color: var(--muted); }
.metricIcon { margin-left: auto; width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; font-size: .9rem; }
.metricIcon.blue { background: var(--accentSoft); color: var(--accent); }
.metricIcon.green { background: var(--goodSoft); color: var(--good); }
.metricIcon.orange { background: var(--warnSoft); color: var(--warn); }
.metricIcon.violet { background: var(--violetSoft); color: var(--violet); }
.metricValue { font-size: 1.9rem; font-weight: 800; letter-spacing: -.04em; margin: 8px 0 3px; }
.metricFoot { font-size: .72rem; color: var(--muted); }

.trendUp { color: var(--good); font-weight: 700; }
.trendDown { color: var(--bad); font-weight: 700; }
.trendFlat { color: var(--muted); font-weight: 700; }

.status { display: inline-flex; align-items: center; gap: 6px; font-size: .68rem; font-weight: 800; padding: 3px 9px; border-radius: 999px; }
.status:before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.status.good { background: var(--goodSoft); color: var(--good); }
.status.warn { background: var(--warnSoft); color: var(--warn); }
.status.bad { background: var(--badSoft); color: var(--bad); }
.status.info { background: var(--accentSoft); color: var(--accent); }
.status.neutral { background: #eef1f4; color: var(--muted); }

.btn { border: 1px solid var(--line); background: #fff; color: var(--ink); border-radius: 9px; padding: 7px 13px; font-size: .81rem; font-weight: 700; font-family: inherit; cursor: pointer; text-decoration: none; display: inline-block; }
.btn:hover { background: #f7f9fb; text-decoration: none; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primary:hover { background: #1b66bb; }
.mini { border: 1px solid var(--line); background: #fff; border-radius: 7px; padding: 4px 9px; font-size: .68rem; font-weight: 700; font-family: inherit; cursor: pointer; color: var(--ink); text-decoration: none; }
.mini:hover { background: #f7f9fb; text-decoration: none; }
.mini.on { background: var(--accent); border-color: var(--accent); color: #fff; }

.tableWrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: .78rem; }
thead th { text-align: left; font-size: .66rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); background: #fafbfc; padding: 9px 14px; border-bottom: 1px solid var(--line); white-space: nowrap; }
tbody td { padding: 11px 14px; border-bottom: 1px solid #eef1f4; vertical-align: top; }
tbody tr:hover { background: #fbfcfd; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
.mono { font-family: Consolas, monospace; font-size: .73rem; }

.detailList { display: grid; }
.detailRow { display: grid; grid-template-columns: 170px 1fr; gap: 12px; padding: 9px 0; border-bottom: 1px solid #eef1f4; font-size: .76rem; }
.detailRow .key { color: var(--muted); }
.detailRow .val { font-weight: 650; }

.empty { padding: 26px 17px; text-align: center; color: var(--muted); font-size: .8rem; }
.empty strong { display: block; color: var(--ink); font-size: .86rem; margin-bottom: 5px; }

/* The search box on the visitor explorer. Not the topbar search, which is a different
   control with a different job. */
.searchBox {
  font-family: inherit; font-size: .82rem; color: var(--ink);
  background: #fff; border: 1px solid var(--line); border-radius: 9px;
  padding: 8px 11px; min-width: 260px;
}
.searchBox:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accentSoft); }

.tabs { display: flex; gap: 6px; flex-wrap: wrap; border-bottom: 1px solid var(--line); margin-bottom: 18px; }
.tab { border: 0; background: none; font-family: inherit; font-size: .75rem; font-weight: 800; color: var(--muted); padding: 9px 12px; cursor: pointer; border-bottom: 2px solid transparent; text-decoration: none; }
.tab:hover { color: var(--ink); text-decoration: none; }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }

/* --- Charts ------------------------------------------------------------------------ */
/* Server-rendered SVG, no charting library: the hosting policy is script-src 'self' with
   no CDN, and a vendored library would still draw nothing with scripting off. */

.chartWrap { padding: 10px 15px 14px; }
.lineChart { width: 100%; height: auto; min-height: 200px; overflow: visible; display: block; }
.chartGrid line { stroke: var(--grid); stroke-width: 1; }
.chartAxis { display: grid; grid-template-columns: auto 1fr; gap: 8px; }
.chartYLabels { display: flex; flex-direction: column; justify-content: space-between; font-size: .62rem; color: var(--muted); padding: 4px 0 22px; text-align: right; }
.chartXLabels { display: flex; justify-content: space-between; font-size: .62rem; color: var(--muted); padding: 4px 0 0; }
.chartLine { fill: none; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.chartLine.people { stroke: var(--series-people); }
.chartLine.bots { stroke: var(--series-bots); }
.chartArea.people { fill: var(--series-people); opacity: .10; stroke: none; }
.chartDot { stroke: #fff; stroke-width: 2; }
.chartDot.people { fill: var(--series-people); }
.chartDot.bots { fill: var(--series-bots); }
.chartMarker { stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 3 4; opacity: .5; }
.chartLegend { display: flex; gap: 18px; flex-wrap: wrap; padding: 0 15px 12px; color: var(--muted); font-size: .68rem; }
.chartLegend span { display: flex; align-items: center; gap: 6px; }
.chartLegend i { width: 18px; height: 3px; border-radius: 9px; display: inline-block; }

.barlist { display: grid; gap: 8px; padding: 15px 17px; }
.barlistRow { display: grid; grid-template-columns: minmax(90px, 34%) 1fr auto; gap: 10px; align-items: center; font-size: .76rem; }
.barlistLabel { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.barlistTrack { background: #eef1f4; height: 12px; border-radius: 999px; overflow: hidden; }
.barlistFill { display: block; height: 100%; background: var(--series-people); border-radius: 999px; }
.barlistValue { font-variant-numeric: tabular-nums; color: var(--muted); }

.heat { display: grid; grid-template-columns: auto repeat(24, 1fr); gap: 2px; padding: 15px 17px; font-size: .6rem; }
.heatCell { aspect-ratio: 1; border-radius: 3px; background: var(--accentSoft); }
.heatLabel { color: var(--muted); padding-right: 6px; align-self: center; white-space: nowrap; }

.sparkline { width: 100%; height: 34px; display: block; }
.sparkline path { fill: none; stroke: var(--series-people); stroke-width: 2; stroke-linejoin: round; }

.vitalRow { display: flex; align-items: baseline; gap: 10px; padding: 11px 0; border-bottom: 1px solid #eef1f4; font-size: .78rem; }
.vitalRow strong { font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.vitalRow .metricName { width: 62px; font-weight: 800; color: var(--muted); font-size: .7rem; letter-spacing: .04em; }
.vitalRow small { color: var(--muted); margin-left: auto; }

/* --- Responsive -------------------------------------------------------------------- */

@media (max-width: 1180px) {
  .g4 { grid-template-columns: repeat(2, 1fr); }
  .g3 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 860px) {
  .app { grid-template-columns: 1fr; }
  .sidebar { position: fixed; z-index: 40; width: 270px; transform: translateX(-100%); transition: transform .2s; }
  .sidebar.open { transform: none; }
  .mobileMenu { display: inline-flex; }
  .grid, .g2, .g3, .g4 { grid-template-columns: 1fr; }
  .content { padding: 16px; }
  .topbar { padding: 0 16px; }
}

/* Somebody printing a report should get the report, not the furniture. */
@media print {
  .sidebar, .topbar, .headActions, .tabs { display: none !important; }
  .app { grid-template-columns: 1fr; }
  .card { break-inside: avoid; box-shadow: none; }
}


/* ===================================================================================
   Utilities the shared panels rely on
   ===================================================================================

   These exist because the content security policy here is style-src 'self' with no
   'unsafe-inline'. A browser under that policy ignores every style attribute outright,
   so a component that positions anything with one renders with no padding, no spacing
   and -- in the case of a bar chart -- no bars. Everything the library's components need
   is therefore a class, and anything genuinely data-driven is an SVG attribute rather
   than a style.
   =================================================================================== */

.panelPad { padding: 15px 17px; }
.panelPad.tight { padding: 8px 17px 16px; }
.panelNote { font-size: .72rem; color: var(--muted); margin: 12px 0 0; line-height: 1.55; }
.panelNote.inline { display: inline; margin: 0; }
.rowSub { font-size: .7rem; color: var(--muted); margin-top: 2px; }
.tightHeading { margin: 0 0 6px; font-size: 1rem; }
.cardLead { margin: 0 0 14px; font-size: .82rem; color: var(--muted); line-height: 1.6; }
.confirmText { font-size: .84rem; margin: 0 0 12px; line-height: 1.6; }
.emptyAction { margin-top: 14px; }
.spacedBelow { margin-bottom: 16px; }

/* A status pill sitting after text needs to not touch it. */
.status.spaced { margin-left: 6px; }

.buttonRow { display: flex; gap: 9px; flex-wrap: wrap; align-items: center; }
.btn.danger { background: var(--bad); border-color: var(--bad); color: #fff; }
.btn.danger:hover { background: #a83232; }
.card.danger { border-color: #f2cccc; }

.toolbar { display: flex; gap: 10px; padding: 14px 17px; flex-wrap: wrap; align-items: center; }
.toolbarCount { margin-left: auto; font-size: .73rem; color: var(--muted); }
.checkLabel { display: flex; gap: 6px; align-items: center; font-size: .78rem; color: var(--muted); }
.checkLabel input { margin: 0; }

/* Legend swatches. Colour by class, since a style attribute would be discarded. */
.chartLegend .swatch { width: 18px; height: 3px; border-radius: 9px; display: inline-block; }
.chartLegend .swatch.people { background: var(--series-people); }
.chartLegend .swatch.bots { background: var(--series-bots); }
.chartLegend .swatch.markers { background: var(--muted); }

/* Bars as SVG. A rect's width is a presentation attribute, so it survives the policy that
   killed the percentage-width version. */
.barlistBar { width: 100%; height: 12px; display: block; }
.barlistTrackRect { fill: #eef1f4; }
.barlistFillRect { fill: var(--series-people); }
