/* ===========================================================================
   Owner Dashboard - visual layer.
   Dark by default: this is a screen an owner leaves open on a second monitor.
   Colour roles come from the validated data-viz palette (see charts.js header);
   nothing here invents a hue.
   =========================================================================== */
:root {
  color-scheme: dark;
  --plane:        #0d0d0d;
  --surface:      #161719;
  --surface-2:    #1d1e21;
  --ink:          #ffffff;
  --ink-2:        #c3c2b7;
  --ink-muted:    #898781;
  --hairline:     rgba(255, 255, 255, 0.10);
  --hairline-2:   rgba(255, 255, 255, 0.055);

  --s1: #3987e5;   /* categorical 1 - blue   */
  --s2: #d95926;   /* categorical 2 - orange */
  --s3: #199e70;   /* categorical 3 - aqua   */

  --good:     #0ca30c;
  --warning:  #fab219;
  --serious:  #ec835a;
  --critical: #d03b3b;

  --radius: 14px;
  --gap: 16px;
  font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--plane); color: var(--ink);
  font: 15px/1.55 system-ui, -apple-system, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--s1); }
button { font: inherit; color: inherit; }

/* ── top bar ─────────────────────────────────────────────────────────────── */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 12px 24px; background: rgba(13, 13, 13, 0.86);
  backdrop-filter: blur(14px); border-bottom: 1px solid var(--hairline);
}
.brand { display: flex; align-items: baseline; gap: 10px; margin-right: 6px; }
.brand b { font-size: 16px; letter-spacing: -0.01em; }
.brand span { color: var(--ink-muted); font-size: 12.5px; }

.picker { position: relative; }
.picker > button {
  display: flex; align-items: center; gap: 9px;
  background: var(--surface-2); border: 1px solid var(--hairline);
  border-radius: 10px; padding: 7px 12px; cursor: pointer; max-width: 380px;
}
.picker > button:hover { border-color: rgba(255,255,255,.22); }
.picker .caret { color: var(--ink-muted); font-size: 11px; }
.picker-menu {
  position: absolute; top: calc(100% + 6px); left: 0; min-width: 330px; z-index: 60;
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: 12px; padding: 6px; box-shadow: 0 18px 50px rgba(0,0,0,.6);
}
.picker-menu label {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border-radius: 8px; cursor: pointer;
}
.picker-menu label:hover { background: var(--surface-2); }
.picker-menu .sep { height: 1px; background: var(--hairline); margin: 5px 8px; }
.picker-menu .vendor { margin-left: auto; color: var(--ink-muted); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }

.spacer { flex: 1; }
.asof { color: var(--ink-muted); font-size: 12.5px; text-align: right; line-height: 1.35; }
.btn {
  background: var(--surface-2); border: 1px solid var(--hairline);
  border-radius: 10px; padding: 7px 14px; cursor: pointer;
}
.btn:hover { border-color: rgba(255,255,255,.24); }
.btn.primary { background: var(--s1); border-color: transparent; color: #fff; font-weight: 550; }
.btn.primary:hover { filter: brightness(1.08); }
.btn:disabled { opacity: .45; cursor: default; }

/* ── tabs ────────────────────────────────────────────────────────────────── */
.tabs { display: flex; gap: 2px; padding: 0 18px; border-bottom: 1px solid var(--hairline); overflow-x: auto; }
.tabs button {
  background: none; border: 0; border-bottom: 2px solid transparent;
  padding: 11px 14px; cursor: pointer; color: var(--ink-2); white-space: nowrap;
}
.tabs button:hover { color: var(--ink); }
.tabs button[aria-selected='true'] { color: var(--ink); border-bottom-color: var(--s1); font-weight: 550; }

main { padding: 22px 24px 72px; max-width: 1560px; margin: 0 auto; }

/* ── cards & grid ────────────────────────────────────────────────────────── */
.grid { display: grid; gap: var(--gap); grid-template-columns: repeat(12, 1fr); }
.card {
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius); padding: 16px 18px; min-width: 0;
  /* Grid rows stretch to the tallest card, so the contents must be able to
     stretch too - otherwise a short chart leaves a dead panel beside a long
     table. The chart and the scroll area take the slack. */
  display: flex; flex-direction: column;
}
.card > h3 {
  margin: 0 0 2px; font-size: 13px; font-weight: 600; letter-spacing: .01em;
  color: var(--ink-2); display: flex; align-items: center; gap: 8px;
}
.card > .sub { margin: 0 0 12px; font-size: 12px; color: var(--ink-muted); }
.span3 { grid-column: span 3; } .span4 { grid-column: span 4; }
.span5 { grid-column: span 5; } .span6 { grid-column: span 6; }
.span7 { grid-column: span 7; } .span8 { grid-column: span 8; }
.span9 { grid-column: span 9; } .span12 { grid-column: span 12; }
@media (max-width: 1180px) {
  .span3, .span4, .span5 { grid-column: span 6; }
  .span7, .span8, .span9 { grid-column: span 12; }
}
@media (max-width: 760px) { .grid > * { grid-column: span 12 !important; } main { padding: 16px 12px 60px; } }

/* ── stat tile ───────────────────────────────────────────────────────────── */
.tile .label { font-size: 12.5px; color: var(--ink-muted); display: flex; align-items: center; gap: 7px; }
.tile .value {
  font-size: 30px; font-weight: 600; letter-spacing: -0.022em; margin: 6px 0 2px; line-height: 1.1;
}
.tile .value.sm { font-size: 24px; }
.tile .delta { font-size: 12.5px; color: var(--ink-2); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tile .context { font-size: 12px; color: var(--ink-muted); margin-top: 5px; }
.tile .spark { height: 34px; margin-top: 8px; }
.up { color: var(--good); } .down { color: var(--critical); }
.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: none; }
.tile.is-critical { border-color: rgba(208, 59, 59, .55); }
.tile.is-warning  { border-color: rgba(250, 178, 25, .40); }

/* ── narrative ───────────────────────────────────────────────────────────── */
.narrative { background: linear-gradient(180deg, #191b1f 0%, #161719 100%); }
.narrative h2 { margin: 2px 0 10px; font-size: 20px; letter-spacing: -0.015em; }
.narrative p { margin: 0 0 11px; color: var(--ink-2); max-width: 78ch; }
.narrative p:last-child { margin-bottom: 0; white-space: pre-line; }
.narrative .src {
  font-size: 11px; color: var(--ink-muted); text-transform: uppercase; letter-spacing: .07em;
  display: flex; align-items: center; gap: 8px; margin-bottom: 4px;
}

/* ── insight feed ────────────────────────────────────────────────────────── */
.feed { display: flex; flex-direction: column; gap: 10px; }
.finding {
  display: grid; grid-template-columns: 20px 1fr; gap: 12px;
  padding: 13px 14px; border: 1px solid var(--hairline-2); border-radius: 11px;
  background: var(--surface-2);
}
.finding.critical { border-left: 3px solid var(--critical); }
.finding.warning  { border-left: 3px solid var(--warning); }
.finding.watch    { border-left: 3px solid var(--ink-muted); }
.finding.good     { border-left: 3px solid var(--good); }
.finding .icon { font-size: 15px; line-height: 1.3; text-align: center; }
.finding .t { font-weight: 600; margin-bottom: 3px; }
.finding .m { color: var(--ink-2); font-size: 14px; }
.finding .a { margin-top: 7px; font-size: 13px; color: var(--ink-muted); }
.finding .a b { color: var(--ink-2); font-weight: 550; }
.finding .stake { float: right; font-size: 12px; color: var(--ink-muted); margin-left: 12px; white-space: nowrap; }

/* ── tables ──────────────────────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th {
  text-align: left; font-weight: 550; color: var(--ink-muted); font-size: 11.5px;
  text-transform: uppercase; letter-spacing: .055em; padding: 0 10px 8px; white-space: nowrap;
}
td { padding: 9px 10px; border-top: 1px solid var(--hairline-2); vertical-align: top; }
tbody tr:hover { background: rgba(255,255,255,.028); }
.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.name { font-weight: 500; }
.muted { color: var(--ink-muted); }
.pill {
  display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 11.5px;
  border: 1px solid var(--hairline); color: var(--ink-2);
}
.pill.bad { color: #ffb3b3; border-color: rgba(208,59,59,.5); background: rgba(208,59,59,.12); }
.pill.warn { color: #ffdf9e; border-color: rgba(250,178,25,.42); background: rgba(250,178,25,.10); }
.pill.ok { color: #a9e6a9; border-color: rgba(12,163,12,.42); background: rgba(12,163,12,.10); }
.scroll { max-height: 460px; overflow: auto; margin: 0 -6px; padding: 0 6px; flex: 1 1 auto; }

/* ── charts ──────────────────────────────────────────────────────────────── */
.chart { width: 100%; height: 260px; flex: 1 1 auto; min-height: 230px; }
.chart.tall { height: 330px; min-height: 300px; }
.chart.short { height: 190px; min-height: 170px; }
.legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: var(--ink-2); margin-top: 4px; }
.legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; margin-right: 6px; }

/* ── settings ────────────────────────────────────────────────────────────── */
.form { display: grid; gap: 12px; grid-template-columns: repeat(2, 1fr); }
.form .full { grid-column: span 2; }
label.field { display: block; font-size: 12px; color: var(--ink-muted); margin-bottom: 5px; }
input[type=text], input[type=password], select, textarea {
  width: 100%; background: var(--plane); color: var(--ink);
  border: 1px solid var(--hairline); border-radius: 9px; padding: 9px 11px; font: inherit;
}
input:focus, select:focus, textarea:focus { outline: 2px solid rgba(57,135,229,.5); outline-offset: 1px; }
.conn { border: 1px solid var(--hairline); border-radius: 12px; padding: 14px 16px; margin-bottom: 12px; background: var(--surface-2); }
.conn header { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.conn header b { font-size: 15px; }
.conn .orgs { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.log {
  font: 12px/1.6 ui-monospace, 'Cascadia Mono', Consolas, monospace; background: var(--plane);
  border: 1px solid var(--hairline); border-radius: 10px; padding: 10px 12px;
  max-height: 260px; overflow: auto; white-space: pre-wrap; color: var(--ink-2);
}
.banner {
  border: 1px solid rgba(250,178,25,.4); background: rgba(250,178,25,.08);
  border-radius: 11px; padding: 12px 14px; margin-bottom: var(--gap); color: #ffdf9e;
}
.loading { color: var(--ink-muted); padding: 60px 0; text-align: center; }
.hidden { display: none !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   PHONE
   The dashboard has a domain now (dashboard.twinmind.au), which means it is
   read on a phone, standing up, one-handed. Three things were wrong there and
   none of them are visible on a 1680px monitor:

   1. A table wider than the screen was simply CUT. It scrolled - .scroll has
      always had overflow:auto - but nothing on screen said so, so the last
      columns ("oldest", "outstanding") did not exist as far as the reader knew.
      A number the owner cannot see is worse than one that was never computed.
   2. The header spent a fifth of the screen restating what the picker under it
      already said.
   3. Charts kept their desktop tick counts and printed "$0 $100k$200k$300k" as
      one smear (fixed in charts.js -> forWidth).
   ═══════════════════════════════════════════════════════════════════════════ */

/* A scrolled-away edge announces itself: the shadow is pinned to the container,
   the cover is pinned to the CONTENT, so they only coincide - and the shadow
   only disappears - when there is genuinely nothing more to the right. */
.scroll {
  background:
    linear-gradient(to left, var(--surface) 62%, rgba(22, 23, 25, 0)) right center / 26px 100% no-repeat local,
    linear-gradient(to left, rgba(0, 0, 0, .55), rgba(0, 0, 0, 0)) right center / 26px 100% no-repeat scroll;
  overscroll-behavior-x: contain;
}
/* A header that scrolls out of a 460px-tall table leaves numbers with no names. */
.scroll thead th { position: sticky; top: 0; z-index: 2; background: var(--surface); }

.tabs { scrollbar-width: none; scroll-snap-type: x proximity; }
.tabs::-webkit-scrollbar { display: none; }
.tabs button { scroll-snap-align: start; }

@media (max-width: 760px) {
  /* One row of controls, one row of provenance - instead of five wrapped ones. */
  .topbar { gap: 8px; padding: 9px 12px; }
  .brand b { font-size: 15px; }
  .brand span { display: none; }          /* the picker below already says it */
  .spacer { display: none; }
  .picker { margin-left: auto; }
  .topbar .btn { order: 2; }
  .asof { order: 3; flex-basis: 100%; text-align: left; font-size: 11px; line-height: 1.35; }

  /* Swiping a table sideways must not cost you the name of the row you are in. */
  .scroll th:first-child,
  .scroll td:first-child {
    position: sticky; left: 0; z-index: 1;
    background: var(--surface);
    box-shadow: 1px 0 0 var(--hairline-2);
  }
  .scroll thead th:first-child { z-index: 3; }

  /* A thumb is not a mouse pointer. */
  .tabs button { padding: 13px 14px; }
  .btn, .picker > button { min-height: 40px; }
  table { font-size: 13px; }
  th { padding: 0 8px 8px; }
  td { padding: 10px 8px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   VERDICTS, FILTERS AND THE DRILL-DOWN
   Added with the Profit rebuild. Three ideas, all of them about reading:

   1. A number is coloured by whether it moved the way you WANT, and only when
      the movement is big enough to matter. Everything used to be red, so a page
      of costs was a wall of red and nothing on it stood out.
   2. Teal against vermilion, never green against red - green/red is the pair
      that collapses for a red-green deficiency, and this page has one reader.
   3. The currency marker belongs to the column heading, in `.unit`, so the
      cells below it can be bare, right-aligned and tabular.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  --v-good:       #2ec27e;
  --v-minor-good: #3f8f74;
  --v-neutral:    #8b8a84;
  --v-minor-bad:  #cf9440;
  --v-bad:        #e2604a;
}
.v-good       { color: var(--v-good); }
.v-minor-good { color: var(--v-minor-good); }
.v-neutral    { color: var(--v-neutral); }
.v-minor-bad  { color: var(--v-minor-bad); }
.v-bad        { color: var(--v-bad); }

/* The unit, stated once per column so no cell has to carry it. */
th .unit { color: var(--ink-muted); font-weight: 400; letter-spacing: 0; text-transform: none; }

/* A chart that filters says so with the cursor before you click it. */
.chart.is-clickable { cursor: pointer; }

/* ── active filters ─────────────────────────────────────────────────────── */
.filterbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: var(--gap); padding: 9px 12px;
  background: rgba(57, 135, 229, .08); border: 1px solid rgba(57, 135, 229, .3);
  border-radius: 11px;
}
.filterbar-lead { color: var(--ink-2); font-size: 12.5px; }
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--surface-2); border: 1px solid var(--hairline);
  border-radius: 999px; padding: 4px 10px; font-size: 12.5px; cursor: pointer;
}
.chip:hover { border-color: rgba(255,255,255,.3); }
.chip-dim { color: var(--ink-muted); }
.chip-val { color: var(--ink); font-weight: 550; }
.chip-x { color: var(--ink-muted); font-size: 14px; line-height: 1; }
.chip-all { background: none; color: var(--ink-muted); }
.linkish {
  background: none; border: 0; padding: 0; color: var(--s1); cursor: pointer;
  font: inherit; text-align: left; border-bottom: 1px dotted rgba(57,135,229,.45);
}
.linkish:hover { color: #7fb4f0; }
.btn.sm { padding: 4px 10px; font-size: 12.5px; border-radius: 8px; }

/* ── the monthly P&L ────────────────────────────────────────────────────── */
table.pnl th { vertical-align: bottom; }
table.pnl tr.pnl-group th {
  border-bottom: 1px solid var(--hairline-2); padding-bottom: 5px;
  color: var(--ink-2); font-size: 11px;
}
table.pnl tr.pnl-group th + th { border-left: 1px solid var(--hairline-2); }
table.pnl tr.pnl-total td { font-weight: 600; background: rgba(255,255,255,.028); }
table.pnl tr.pnl-total td:first-child { color: var(--ink); }

/* ── the drill-down tree ────────────────────────────────────────────────── */
.tree-wrap { max-height: 620px; }
table.tree td { padding: 7px 10px; }
table.tree .tree-name { padding-left: calc(10px + var(--depth) * 20px); white-space: nowrap; }
.tree-row.lvl-0 > .tree-name .tree-label { font-weight: 600; }
.tree-row.lvl-0 > td { border-top: 1px solid var(--hairline); }
.tree-row.lvl-2 > td, .tree-row.lvl-3 > td { color: var(--ink-2); }
.tree-row:hover > td { background: rgba(255,255,255,.03); }
.twist {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; margin-right: 8px; flex: none;
  background: var(--surface-2); border: 1px solid var(--hairline);
  border-radius: 5px; cursor: pointer; color: var(--ink-2);
  font-size: 13px; line-height: 1; padding: 0;
}
.twist:hover { border-color: rgba(255,255,255,.3); color: var(--ink); }
.twist-leaf { background: none; border-color: transparent; cursor: default; }
.kind-icon { color: var(--ink-muted); margin-right: 7px; font-size: 12px; }
.tree-label { }
.tree-sub { color: var(--ink-muted); font-size: 11.5px; margin-left: 8px; }
.tag {
  display: inline-block; margin-left: 7px; padding: 1px 6px; border-radius: 999px;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
}
.tag-new  { color: #a9e6a9; border: 1px solid rgba(12,163,12,.42); }
.tag-gone { color: var(--ink-muted); border: 1px solid var(--hairline); }
.spark-cell { padding-right: 12px !important; }
.spark-svg { vertical-align: middle; }

/* The proof that the rows below add up to the row above. */
.recon { font-size: 12.5px; margin: 0 0 4px; }
.recon.ok  { color: var(--v-minor-good); }
.recon.bad { color: var(--v-minor-bad); }

@media (max-width: 760px) {
  .filterbar { padding: 8px 10px; }
  table.tree .tree-name { padding-left: calc(8px + var(--depth) * 13px); }
  .tree-sub { display: none; }
  .spark-cell { display: none; }
  table.tree thead th:nth-child(8) { display: none; }
}


/* A card with nothing to report must not be stretched to its neighbour's
   height by the grid. "Nobody has changed their payment habits" filled half a
   screen with black. */
.card[data-quiet] { align-self: start; }

/* A supplier's name is one thing, so it wraps as one thing. Broken over two
   lines under an underline it read as two separate links. */
.linkish.name, td .name { white-space: nowrap; }
@media (max-width: 700px) { .linkish.name, td .name { white-space: normal; } }

/* ── phone: the controls that matter must be thumb-sized ──────────────────
   The "+" that opens a cost is the single most-used control on the Profit
   page — "я нажал плюсик, он сразу показывает, у какого сотрудника выросла".
   At 18px it is a mouse target, not a thumb target: the phone audit counted
   eleven controls under the 40px minimum. Growing only the HIT AREA with a
   transparent pseudo-element satisfies a thumb but not the audit, which
   measures the element - and an audit you have to remember to excuse is an
   audit nobody runs. So the box itself is 40px here. The rows get taller,
   which is what a touch list should be. */
@media (max-width: 700px) {
  .twist { width: 40px; height: 40px; font-size: 19px; border-radius: 9px; margin-right: 6px; }
  .twist-leaf { width: 22px; height: 22px; }
  .btn.sm { padding: 10px 14px; font-size: 13px; }
  .chip { padding: 9px 13px; font-size: 13px; }
  .linkish { display: inline-flex; align-items: center; min-height: 40px; }
}

/* ── the headline tiles were computing a direction and then not showing it ──
   Every tile passes `deltaGood`, and the markup has carried .up/.down since the
   first version — but `.tile .delta` sets a colour and beats a bare `.up` on
   specificity, so all four tiles rendered the same grey. "Profit fell $14,621"
   and "costs fell $40,874" are opposite news and looked identical.
   Four headline movements is exactly where a direction colour belongs; the
   materiality gate exists for the dozens of rows in a table, not for these. */
.tile .delta.up   { color: var(--v-good); }
.tile .delta.down { color: var(--v-bad); }
