/* Qlik Command Center - styles.
   Ported from mockup.html (the verified visual design). Light + dark via
   prefers-color-scheme. Self-contained, no external assets. */
:root {
  --bg:#f2f4f7; --panel:#ffffff; --panel2:#f7f9fb; --ink:#1c2733;
  --muted:#5c6b7a; --line:#dbe2ea; --acc:#0b6bcb; --acc-ink:#ffffff;
  --bad:#c0392b; --warn:#a9700a; --ok:#1e8449; --chip:#e8edf3;
  --warn-bg:#fdf3e4; --bad-bg:#fdeaea; --ok-bg:#e8f6ee; --sel:#e3eefb;
  --code:#eef1f5;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg:#12161b; --panel:#1b2129; --panel2:#161c23; --ink:#e4eaf0;
    --muted:#8fa0b0; --line:#2b3541; --acc:#5aa2e8; --acc-ink:#0d1218;
    --bad:#e07b6d; --warn:#d8a24a; --ok:#5dbb86; --chip:#252f3a;
    --warn-bg:#33290f; --bad-bg:#3a1d1a; --ok-bg:#14301f; --sel:#20334a;
    --code:#232b35;
  }
}
* { box-sizing:border-box; scrollbar-width:thin;
    scrollbar-color:var(--line) transparent; }
html,body { margin:0; height:100%; }
body { background:var(--bg); color:var(--ink);
       font:15.5px/1.5 "Segoe UI",system-ui,sans-serif; }
a { color:var(--acc); text-decoration:none; cursor:pointer; }
a:hover { text-decoration:underline; }
code { background:var(--code); padding:1px 5px; border-radius:3px;
       font:13.5px/1.4 Consolas,monospace; word-break:break-all; }
button { background:var(--chip); color:var(--ink); border:1px solid var(--line);
  border-radius:6px; padding:5px 13px; font:inherit; font-size:14.5px;
  cursor:pointer; }
button:hover { border-color:var(--acc); }
button.pri { background:var(--acc); color:var(--acc-ink); border-color:var(--acc); }
button.mini { font-size:12.5px; padding:2px 9px; color:var(--muted); }
button.mini:hover { color:var(--ink); }
button:disabled { opacity:.45; cursor:not-allowed; }
input[type=search], input[type=text], select {
  background:var(--panel2); color:var(--ink); border:1px solid var(--line);
  border-radius:6px; padding:6px 11px; font:inherit; }
input:focus, select:focus { outline:2px solid var(--acc); }
::-webkit-scrollbar { width:11px; height:11px; }
::-webkit-scrollbar-thumb { background:var(--line); border-radius:8px;
  border:3px solid transparent; background-clip:padding-box; }
::-webkit-scrollbar-track { background:transparent; }

/* ---- shell ---- */
#shell { height:100%; display:grid;
         grid-template-rows:52px 1fr; grid-template-columns:210px 1fr;
         grid-template-areas:"top top" "rail main"; }
.top { grid-area:top; display:flex; align-items:center; gap:14px;
       padding:0 18px; background:var(--panel);
       border-bottom:1px solid var(--line); }
.top h1 { font-size:17px; margin:0; white-space:nowrap; }
.top .gen { font-size:12px; color:var(--muted); cursor:help; white-space:nowrap; }
.tenant { display:flex; align-items:center; gap:8px; background:var(--chip);
          border-radius:16px; padding:4px 13px; font-size:14px; cursor:help; }
.dot { width:10px; height:10px; border-radius:50%; display:inline-block; }
.dot.red{background:var(--bad);} .dot.amber{background:var(--warn);}
.dot.green{background:var(--ok);} .dot.grey{background:var(--muted);}
.grow { flex:1; }
.rail { grid-area:rail; background:var(--panel);
        border-right:1px solid var(--line); padding:12px 0; overflow-y:auto; }
.rail .grp { font-size:11px; font-weight:700; letter-spacing:.09em;
  color:var(--muted); padding:14px 18px 4px; }
.rail a { display:flex; gap:11px; align-items:center; padding:9px 18px;
          color:var(--ink); font-size:15px; }
.rail a:hover { background:var(--sel); text-decoration:none; }
.rail a.on { background:var(--sel); border-right:3px solid var(--acc);
             font-weight:600; }
.rail .ic { width:20px; text-align:center; }
#main { grid-area:main; overflow-y:auto; padding:20px 26px 60px; }
.page { max-width:1250px; }

/* ---- shared bits ---- */
h2.pt { margin:0 0 4px; font-size:21px; }
.sub { color:var(--muted); margin:0 0 18px; }
.sec { background:var(--panel); border:1px solid var(--line);
       border-radius:10px; padding:15px 18px; margin-bottom:16px; }
.sec h3 { margin:0 0 10px; font-size:13.5px; text-transform:uppercase;
          letter-spacing:.05em; color:var(--muted); }
.badge { display:inline-block; font-size:12px; font-weight:600;
         border-radius:3px; padding:1px 8px; white-space:nowrap; }
.b-high { background:var(--bad); color:var(--acc-ink); }
.b-med  { background:var(--warn); color:var(--acc-ink); }
.b-low  { background:var(--chip); color:var(--muted); }
.b-ok   { background:var(--ok); color:var(--acc-ink); }
.b-ro   { background:var(--ok-bg); color:var(--ok); border:1px solid var(--ok); }
.b-mut  { background:var(--warn-bg); color:var(--warn); border:1px solid var(--warn); }
.b-destr{ background:var(--bad-bg); color:var(--bad); border:1px solid var(--bad); }
.chip { background:var(--chip); border-radius:5px; padding:2px 9px;
        font-size:13px; white-space:nowrap; }
.muted { color:var(--muted); } .small { font-size:13.5px; }
.dt { border-bottom:1px dotted var(--muted); cursor:help; }
.cards { display:grid; grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
         gap:14px; margin-bottom:16px; }
.card { background:var(--panel); border:1px solid var(--line);
        border-radius:10px; padding:14px 16px; }
.card h4 { margin:0 0 2px; font-size:14px; color:var(--muted);
           text-transform:uppercase; letter-spacing:.04em; font-weight:600; }
.card .big { font-size:26px; font-weight:600; margin:2px 0; }
.card .lines { font-size:14px; color:var(--muted); margin-bottom:10px; }
.card .btns { display:flex; gap:8px; flex-wrap:wrap; }

/* Home: KPI carousel card - cycles Tracked keys / Cleanup potential /
   Notifications in one card slot (cc.js startCarousel/carouselShow). Only
   one .car-slide has .on at a time; dots mirror the active slide. The card
   is a flex column so the dots (margin-top:auto) always sit flush with the
   card's bottom edge regardless of how tall the active slide's content is,
   instead of trailing right after it. */
.car-card { position:relative; display:flex; flex-direction:column; }
.car-slides { flex:1 1 auto; }
.car-slide { display:none; }
.car-slide.on { display:block; }
.car-dots { display:flex; gap:6px; justify-content:center; margin-top:auto; padding-top:8px; }
.car-dot { width:7px; height:7px; border-radius:50%; background:var(--line);
           cursor:pointer; display:inline-block; }
.car-dot.on { background:var(--acc); }

/* Home: What's new card - a .cards grid item spanning 3 columns (next to the
   carousel card), so it lines up with the 4-column KPI row above it. Falls
   back to the full row width on narrow viewports where the grid has fewer
   columns to span across. */
.card.wn-card { grid-column: span 3; display:flex; flex-direction:column; }
@media (max-width: 899px) {
  .card.wn-card { grid-column: 1 / -1; }
}
.wn-head { display:flex; align-items:baseline; gap:10px; margin-bottom:8px; }
/* ~2 row heights shorter than before (was 280px) so the card reads visibly
   more compact and sits better balanced against the carousel card next to
   it, which is usually shorter. */
.wn-list { max-height:215px; overflow-y:auto; }
.wn-row { display:flex; align-items:center; gap:9px; padding:6px 0;
          border-bottom:1px solid var(--line); font-size:14px; }
.wn-row:last-child { border-bottom:none; }
.wn-time { color:var(--muted); font-size:13px; min-width:68px; white-space:nowrap; }
/* min-width:0 overrides the flex-item default of min-width:auto, and
   overflow-wrap lets a long unbroken token (a raw app name/id in the title)
   wrap instead of forcing the row wider than the card - without either, the
   row overflowed .wn-list's (auto-x-by-the-overflow-y-auto-quirk) box and
   silently scrolled the trailing " deleted (Sini)" text out of view. */
.wn-title { flex:1; min-width:0; overflow-wrap:anywhere; }
.banner { display:flex; gap:12px; align-items:center; border-radius:10px;
          padding:13px 18px; margin-bottom:16px; font-size:16px; }
.banner.red { background:var(--bad-bg); border:1px solid var(--bad); }
.banner.amber { background:var(--warn-bg); border:1px solid var(--warn); }
.banner.green { background:var(--ok-bg); border:1px solid var(--ok); }
.banner.grey { background:var(--chip); border:1px solid var(--line); }
.tblwrap { overflow-x:auto; }
table.tbl { width:100%; border-collapse:collapse; font-size:14.5px; }
table.tbl.wide { min-width:1200px; }
.tbl th { text-align:left; color:var(--muted); font-size:12.5px;
          text-transform:uppercase; letter-spacing:.04em; white-space:nowrap;
          border-bottom:1px solid var(--line); padding:6px 10px; }
/* thead in a sortable table: double-click a header to sort (Qlik-style). */
.tbl thead th { cursor:pointer; user-select:none; }
.tbl thead th:hover { color:var(--ink); }
.tbl thead th.sorted { color:var(--ink); }
.sort-ind { font-size:10px; opacity:.75; }
.tbl td { border-bottom:1px solid var(--line); padding:7px 10px;
          vertical-align:top; }
.tbl tr.click { cursor:pointer; }
.tbl tr.click:hover td { background:var(--sel); }
.fresh { display:flex; gap:10px; flex-wrap:wrap; }
.fresh .fc { display:flex; align-items:center; gap:9px; background:var(--panel);
  border:1px solid var(--line); border-radius:8px; padding:7px 13px;
  font-size:14px; }
.age-ok { color:var(--ok); } .age-warn{ color:var(--warn); font-weight:600; }
.tabs { display:flex; gap:4px; border-bottom:1px solid var(--line);
        margin-bottom:14px; flex-wrap:wrap; }
.tabs button { border:none; background:none; border-radius:6px 6px 0 0;
               padding:8px 14px; color:var(--muted); }
.tabs button.on { color:var(--acc); font-weight:600;
                  box-shadow:inset 0 -2px 0 var(--acc); }
.helpbox { display:none; background:var(--sel); border:1px solid var(--acc);
           border-radius:10px; padding:12px 16px; margin-bottom:16px;
           font-size:14.5px; }
body.help .helpbox { display:block; }
.kv { display:grid; grid-template-columns:170px 1fr; gap:4px 14px;
      font-size:14.5px; }
.kv .k { color:var(--muted); }
.prompt { background:var(--panel2); border:1px dashed var(--acc);
  border-radius:8px; padding:12px 15px; font-size:14.5px;
  white-space:pre-wrap; margin:10px 0; }
.prompt .ph { color:var(--muted); font-size:12.5px; text-transform:uppercase;
  letter-spacing:.05em; display:block; margin-bottom:6px; }

/* drawer + modal */
#ovl { position:fixed; inset:0; background:rgba(0,0,0,.35); display:none; }
#ovl.on { display:block; }
.drawer { position:fixed; top:0; right:0; bottom:0; width:640px; max-width:94vw;
  background:var(--panel); border-left:1px solid var(--line);
  box-shadow:-6px 0 24px rgba(0,0,0,.18); padding:18px 24px;
  overflow-y:auto; }
.modal { position:fixed; top:4vh; left:50%; transform:translateX(-50%);
  width:860px; max-width:96vw; max-height:92vh; overflow-y:auto;
  background:var(--panel); border:1px solid var(--line); border-radius:12px;
  box-shadow:0 10px 40px rgba(0,0,0,.3); padding:20px 26px; }
.xrow { display:flex; align-items:baseline; gap:12px; margin-bottom:10px; }
.xrow h3 { margin:0; font-size:18px; text-transform:none; letter-spacing:0;
           color:var(--ink); }
.steps { display:flex; gap:6px; margin:6px 0 18px; flex-wrap:wrap; }
.steps .st { font-size:13px; padding:3px 11px; border-radius:14px;
             background:var(--chip); color:var(--muted); }
.steps .st.on { background:var(--acc); color:var(--acc-ink); font-weight:600; }
.steps .st.done { background:var(--ok-bg); color:var(--ok); }
.frm label { display:block; font-weight:600; margin:13px 0 3px; }
.frm .fh { font-size:13.5px; color:var(--muted); margin:2px 0 4px; }
.frm select, .frm input[type=text] { width:100%; max-width:440px; }
/* Action-dialog options: a highlighted box so the inputs the user must set
   stand out from the surrounding explanation. */
.sec.inputs { background:var(--sel); border-color:var(--acc); }
.fld { margin-bottom:14px; }
.fld:last-child { margin-bottom:2px; }
.fld > label:first-child { margin-top:0; }
.req { font-size:11px; font-weight:600; color:var(--acc); text-transform:uppercase;
       letter-spacing:.04em; border:1px solid var(--acc); border-radius:4px;
       padding:0 5px; vertical-align:middle; }
.opt { font-size:11px; font-weight:600; color:var(--muted); text-transform:uppercase;
       letter-spacing:.04em; border:1px solid var(--line); border-radius:4px;
       padding:0 5px; vertical-align:middle; }
/* Standard Qlik space-type colors (DESIGN.md 11) - used consistently wherever
   a space type is shown: managed #c04e46, shared #3b5cb2, personal #cccccc. */
.chip.sp-managed { background:#c04e46; color:#fff; }
.chip.sp-shared { background:#3b5cb2; color:#fff; }
.chip.sp-personal { background:#cccccc; color:#222; }
.needsel { margin:10px 0; }
.tech { margin-top:14px; font-size:13.5px; }
.tech summary { cursor:pointer; color:var(--muted); }
.actgrid { display:grid; grid-template-columns:repeat(auto-fill,minmax(330px,1fr));
           gap:14px; }
.act { background:var(--panel); border:1px solid var(--line); border-radius:10px;
       padding:13px 16px; display:flex; flex-direction:column; gap:7px; cursor:pointer; }
.act:hover { border-color:var(--acc); }
.act:focus-visible { outline:2px solid var(--acc); outline-offset:2px; }
.act .t { font-weight:600; font-size:15.5px; display:flex; gap:9px;
          align-items:center; justify-content:space-between; }
.act .t .ttl { display:inline-flex; align-items:center; gap:5px; }
.act .t .exticon { font-size:13px; color:var(--muted); font-weight:400; }
.act .d { font-size:14px; color:var(--muted); flex:1; }
.frm label.chk, .frm label.rdo { display:flex; align-items:center; gap:8px;
       font-weight:400; margin:5px 0; max-width:440px; cursor:pointer; }
.frm label.chk input, .frm label.rdo input { width:auto; }
/* Radio options carry their explanation inline, so a wrapped option keeps its
   button aligned with the first text line. */
.frm label.rdo { align-items:flex-start; }
.frm label.rdo input { margin-top:4px; }
.cat { margin:22px 0 10px; font-size:14px; font-weight:700;
       text-transform:uppercase; letter-spacing:.05em; color:var(--muted); }
#toast { position:fixed; bottom:26px; left:50%; transform:translateX(-50%);
  background:var(--ink); color:var(--bg); border-radius:8px; padding:9px 20px;
  font-size:14.5px; opacity:0; transition:opacity .25s; pointer-events:none;
  max-width:70vw; text-align:center; }
#toast.on { opacity:1; }
.issue td:first-child { width:74px; }
.rowbtns { display:flex; gap:7px; flex-wrap:wrap; }
pre.script { background:var(--code); border-radius:8px; padding:12px 16px;
  font:13px/1.5 Consolas,monospace; overflow-x:auto; }
.insight { border-left:3px solid var(--acc); padding:2px 0 2px 12px;
           margin:9px 0; font-size:14.5px; }
.insight .why { color:var(--muted); font-size:13.5px; }
.empty { color:var(--muted); }
.spin { display:inline-block; width:20px; height:20px; border:3px solid var(--line);
  border-top-color:var(--acc); border-radius:50%; animation:sp .8s linear infinite;
  vertical-align:middle; }
@keyframes sp { to { transform:rotate(360deg); } }

/* ---- charts (uPlot sparklines + Frappe Gantt timeline) ---- */
/* uPlot draws inline SVG/canvas; these give it a sizing box and theme its text.
   uPlot reads stroke colors from JS (getComputedStyle of --acc etc.), so here
   we only handle layout + the surrounding chrome. */
.trends { display:flex; gap:22px; flex-wrap:wrap; }
.trends .trend { flex:1; min-width:260px; }
.trend-h { font-size:14px; font-weight:600; margin-bottom:4px; }
.trend-cap { margin:4px 0 0; }
.chart { width:100%; min-height:120px; }
.chart-missing { color:var(--muted); font-size:13.5px; margin:6px 0; }
/* uPlot legend is disabled in JS; make sure its axis text follows the theme. */
.u-title, .u-legend { color:var(--muted); }
.uplot, .u-wrap { font-family:"Segoe UI",system-ui,sans-serif; }

/* Setup checklist card (grey banner state on Home). */
.setup-card .chk-list { display:flex; flex-direction:column; gap:6px; }
.chk-row { display:flex; align-items:center; gap:10px; }
.chk-mark { width:18px; text-align:center; font-weight:700; }
.chk-mark.done { color:var(--ok); }
.chk-mark.pending { color:var(--muted); }
.chk-label { flex:1; }
.optional-hint { margin-top:14px; }

/* Frappe Gantt: read-only reload timeline. Override the library's default
   light palette with our theme variables so it works in light AND dark. */
.gantt-wrap { overflow-x:auto; }
.gantt-container {
  --g-bar-color:var(--acc); --g-bar-border:var(--line);
  --g-tick-color-thick:var(--line); --g-tick-color:var(--line);
  --g-border-color:var(--line); --g-row-border-color:var(--line);
  --g-text-muted:var(--muted); --g-text-light:var(--acc-ink);
  --g-text-dark:var(--ink); --g-progress-color:var(--acc);
  --g-header-background:var(--panel); --g-row-color:var(--panel2);
  --g-weekend-highlight-color:var(--panel2); --g-weekend-label-color:var(--muted);
  --g-today-highlight:var(--acc); --g-arrow-color:var(--muted);
  --g-actions-background:var(--chip); --g-popup-actions:var(--line);
  --g-handle-color:var(--acc);
}
.gantt-container .grid-header { fill:var(--panel); }
.gantt-container .upper-text, .gantt-container .lower-text { fill:var(--muted); }
.gantt-legend { display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin:4px 0 8px; font-size:13.5px; color:var(--muted); }
.gantt-legend .lg { display:inline-block; width:18px; height:8px; border-radius:5px; margin-right:5px; vertical-align:1px; }
.gantt-legend .scheduled { background:#2f7dd3; }
.gantt-legend .dependency { background:#159a81; }
.gantt-legend .manual { background:#c98216; }
.gantt-legend .expected { background:transparent; border:1.5px solid #2f7dd3; }
/* Trigger colors for bars (via custom_class on the bar wrapper). Failed actual
   runs override the trigger color below. */
.gantt-container .bar-wrapper.gv-trigger-scheduled .bar { fill:#2f7dd3; }
.gantt-container .bar-wrapper.gv-trigger-dependency .bar { fill:#159a81; }
.gantt-container .bar-wrapper.gv-trigger-manual .bar { fill:#c98216; }
.gantt-container .bar-wrapper.gv-trigger-unknown .bar { fill:var(--muted); }
.gantt-container .bar-wrapper.gv-fail .bar { fill:var(--bad); }
.gantt-container .bar-wrapper.gv-running .bar { stroke:var(--ink); stroke-width:1.5px; }
.gantt-container .bar-wrapper.gv-expected .bar {
  fill-opacity:.28; stroke:currentColor; stroke-width:1.5px;
}
.gantt-container .bar-wrapper.gv-expected.gv-trigger-scheduled { color:#2f7dd3; }
.gantt-container .bar-wrapper.gv-expected.gv-trigger-dependency { color:#159a81; }
.gantt-container .bar-wrapper.gv-expected.gv-trigger-manual { color:#c98216; }
.gantt-container .bar-wrapper.gv-expected.gv-trigger-unknown { color:var(--muted); }
.gantt-container .arrow path,
.gantt-container path[data-from] { stroke:var(--muted); opacity:.75; }
.gantt-container .cc-now-line {
  background:var(--bad) !important; opacity:.9; width:2px !important;
}
.gantt-container .cc-now-label {
  position:absolute; top:30px; transform:translateX(6px);
  color:var(--bad); font-weight:700; font-size:12px; pointer-events:none;
}
/* Bars are resized to real (short) durations, so the app-name label sits to the
   RIGHT of the bar on the panel background - use the normal ink color. */
.gantt-container .bar-label,
.gantt-container .bar-label.big { fill:var(--ink); }
.timeline-vscroll {
  max-height:72vh; overflow-y:auto; overflow-x:hidden;
  border-top:1px solid var(--line); padding-top:8px;
  scrollbar-color:var(--muted) transparent;
}
.timeline-grid { display:grid; grid-template-columns:310px minmax(0, 1fr); align-items:start; }
.timeline-labels {
  position:sticky; left:0; z-index:2; background:var(--panel);
  border-right:1px solid var(--line);
}
.timeline-labels svg { display:block; }
.fallback-gantt {
  overflow-x:auto; overflow-y:hidden; scrollbar-color:var(--muted) transparent;
}
.fallback-gantt svg { min-width:900px; max-width:none; display:block; }
.timeline-labels .fg-label { fill:var(--muted); font-size:12px; }
.fallback-gantt .fg-tick { fill:var(--muted); font-size:11px; text-anchor:middle; }
.fallback-gantt .fg-day { fill:var(--ink); font-size:11px; font-weight:700; text-anchor:middle; }
.fallback-gantt .fg-grid { stroke:var(--line); stroke-width:1; opacity:.75; }
.fallback-gantt .fg-row,
.timeline-labels .fg-row { stroke:var(--line); stroke-width:1; opacity:.45; }
.fallback-gantt .fg-arrow { fill:none; stroke:var(--muted); stroke-width:1.4; opacity:.7; }
.fallback-gantt .fg-expected { fill-opacity:.32; stroke-width:1.5px; }
.fallback-gantt .fg-now { stroke:var(--bad); stroke-width:2; }
.fallback-gantt .fg-now-text { fill:var(--bad); font-size:12px; font-weight:700; }

/* ---- setup screen (no data) ---- */
.setup { max-width:760px; margin:6vh auto 0; }
.setup .card { padding:22px 26px; }
.setup h2 { font-size:24px; margin:0 0 6px; }
.setup ol { padding-left:22px; }
.setup li { margin:8px 0; }
.setup .in { display:flex; gap:8px; margin-top:8px; flex-wrap:wrap; }
.setup input[type=text] { flex:1; min-width:320px; }
