/* ============================================================================
   Shared visual system of the PaperCut MF reports.
   Validated categorical palette (CVD-safe) — see dataviz/references/palette.md
   ========================================================================== */

/* Three layers, and this order IS the mechanism.
 *
 *   product  what lies underneath: this file, the same in every installation.
 *   brand    the organization's tokens, served at /runtime/brand.css.
 *   report   a report's own theme, baked into its package.
 *
 * Without layers, who wins would depend on the order in which the <link>s
 * appear in the <head> —and pc.js injects one of them at run time, so that
 * order is not guaranteed—. The failure would be silent and of the worst
 * kind: the theme someone chose for THEIR report would vanish the next time
 * the administrator touches the company's brand, with no error and no
 * explanation.
 *
 * Declaring the names up here fixes the precedence once and for all: from
 * this line on it does not matter in which order the sheets arrive.
 *
 * The content is not indented inside @layer on purpose: pushing 250 lines two
 * spaces to the right makes any future diff unreadable, and CSS does not care. */
@layer product, brand, report;

@layer product {

:root {
  color-scheme: light;
  --page:#f9f9f7; --surface-1:#fcfcfb; --surface-2:#f2f1ed; --surface-3:#eceae4;
  --text-primary:#0b0b0b; --text-secondary:#52514e; --muted:#898781;
  --grid:#e1e0d9; --axis:#c3c2b7; --border:rgba(11,11,11,.10); --border-strong:rgba(11,11,11,.18);
  --s1:#2a78d6; --s2:#eb6834; --s3:#1baf7a; --s4:#eda100;
  --s5:#e87ba4; --s6:#008300; --s7:#4a3aa7; --s8:#e34948;
  --good:#0ca30c; --warning:#fab219; --serious:#ec835a; --critical:#d03b3b;
  --good-ink:#006300;
  --seq-100:#cde2fb; --seq-200:#9ec5f4; --seq-300:#6da7ec; --seq-400:#3987e5;
  --seq-500:#256abf; --seq-600:#184f95; --seq-700:#0d366b;
  --shadow:0 1px 2px rgba(11,11,11,.05), 0 8px 24px -16px rgba(11,11,11,.28);
  --radius:10px;
  /* The derived radii. They are worked out from --radius so the organization
     has ONE knob and not five: whoever says «less rounded» does not want to
     fine-tune the radius of the legend swatches.
     The pill is capped with min() instead of being a fixed 999px, and that is
     the trick that makes «not rounded» really mean not rounded: with
     --radius:0, 0×100 is 0 and the pill comes out square; with the usual
     value, min() stays at 999px and nothing changes. */
  --radius-ctl:calc(var(--radius) * .7);
  --radius-min:calc(var(--radius) * .3);
  --radius-pill:min(999px, calc(var(--radius) * 100));
  --font:system-ui,-apple-system,"Segoe UI",sans-serif;
  /* The monospace font has its own token because places that look nothing
     alike ask for it —the installation ID, the content of a file in the
     PaperCut plan, a cell of figures— and until now the stack was copied
     into each of them. */
  --font-mono:ui-monospace,SFMono-Regular,Menlo,monospace;
}
/* A single theme since 17-10-2026. There used to be two dark blocks here —the
   system one and the data-theme="dark" one—; whoever wants another look asks
   the studio for it. pc.js always sets data-theme="light", and that also
   switches off the dark blocks baked into reports already published. */

*,*::before,*::after { box-sizing:border-box; }
html,body { margin:0; padding:0; }
body {
  font-family:var(--font); background:var(--page); color:var(--text-primary);
  font-size:14px; line-height:1.5; -webkit-font-smoothing:antialiased;
}
a { color:var(--s1); }
h1,h2,h3,h4 { margin:0; font-weight:600; letter-spacing:-.011em; }

/* ------------------------------------------------------------------ header */
.pc-head {
  position:sticky; top:0; z-index:40; background:var(--surface-1);
  border-bottom:1px solid var(--border); backdrop-filter:saturate(1.4) blur(6px);
}
.pc-head-in { max-width:1560px; margin:0 auto; padding:10px 22px; display:flex; align-items:center; gap:18px; flex-wrap:wrap; }
.pc-brand { display:flex; align-items:center; gap:10px; min-width:0; }
.pc-logo {
  width:30px; height:30px; border-radius:calc(var(--radius) * .8); flex:none; display:grid; place-items:center;
  background:linear-gradient(140deg,var(--s1),var(--s7)); color:#fff; font-weight:700; font-size:13px;
}
.pc-title { font-size:15px; font-weight:650; white-space:nowrap; }
.pc-sub { font-size:12px; color:var(--muted); white-space:nowrap; }
.pc-nav { display:flex; gap:4px; margin-left:auto; flex-wrap:wrap; }
.pc-nav a {
  font-size:12.5px; padding:6px 11px; border-radius:var(--radius-ctl); text-decoration:none;
  color:var(--text-secondary); white-space:nowrap; border:1px solid transparent;
}
.pc-nav a:hover { background:var(--surface-2); color:var(--text-primary); }
.pc-nav a[aria-current="page"] { background:var(--surface-3); color:var(--text-primary); border-color:var(--border); font-weight:600; }

/* ---------------------------------------------------------------- controls */
.pc-ctl { display:flex; align-items:center; gap:6px; }
.btn, select, input[type="search"], input[type="date"], input[type="text"] {
  font:inherit; font-size:12.5px; color:var(--text-primary); background:var(--surface-1);
  border:1px solid var(--border-strong); border-radius:var(--radius-ctl); padding:6px 9px; min-height:31px;
}
select { padding-right:24px; cursor:pointer; }
/* The date was too tall and broke the filter row: it measured 34.8 px against
   the 31 of the rest —the period segmented control, the drop-downs, the
   buttons—. It is not the padding: Chrome puts an editor and a calendar icon
   in its own shadow DOM, and the content of those two weighs more than the
   «min-height», which is a minimum and not a cap. The height is fixed, which
   with «box-sizing: border-box» is the outer one, and so the four controls
   measure the same. */
input[type="date"] { height:31px; }
.btn { cursor:pointer; display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
.btn:hover { background:var(--surface-2); }
.btn.on { background:var(--s1); border-color:var(--s1); color:#fff; }
.btn.ghost { border-color:transparent; background:transparent; color:var(--text-secondary); }
.btn.ghost:hover { background:var(--surface-2); color:var(--text-primary); }
.btn.sm { min-height:26px; padding:3px 8px; font-size:11.5px; }
input:focus-visible, select:focus-visible, .btn:focus-visible, [tabindex]:focus-visible {
  outline:2px solid var(--s1); outline-offset:1px;
}

/* Segmented control */
.seg { display:inline-flex; border:1px solid var(--border-strong); border-radius:var(--radius-ctl); overflow:hidden; }
.seg button {
  font:inherit; font-size:12px; padding:5px 11px; background:var(--surface-1); color:var(--text-secondary);
  border:0; border-right:1px solid var(--border); cursor:pointer; min-height:29px;
}
.seg button:last-child { border-right:0; }
.seg button[aria-pressed="true"] { background:var(--surface-3); color:var(--text-primary); font-weight:600; }

/* -------------------------------------------------------------- filter bar */
.pc-filters {
  position:sticky; top:51px; z-index:30; background:var(--page);
  border-bottom:1px solid var(--border);
}
/* Inside the panel's iframe there is no header above —PC.header() returns an
   empty div, see trap no. 2 in AGENTS— so those 51px do not exist: the bar
   hung down over the content and covered whatever came first underneath.
   What comes first is usually the notice of PC.datasetNote(), which is
   precisely the one that explains why the report shows zeros. */
:where(.pc-embed) .pc-filters { top:0; }
/* The panel's «Studio» button floats over the bottom right corner of the
   frame; without this room it covered the last label of a chart (05-11-2026). */
:where(.pc-embed) body { padding-bottom:72px; }
.pc-filters-in {
  max-width:1560px; margin:0 auto; padding:10px 22px;
  display:flex; gap:10px; align-items:flex-end; flex-wrap:wrap;
}
/* On a phone the bar folds into a «Filters (n) · period» button and only the
   active filters' chips stay in sight: unfolded and sticky, it covered half to
   two thirds of the report at 390 px (fourth QA run, N-D). */
.pc-filters-toggle { display:none; }
.pc-filters-toggle span { color:var(--muted); font-weight:400; }
.pc-filters-toggle .pc-caret { transition:transform .15s; }
.pc-filters.open .pc-filters-toggle .pc-caret { transform:rotate(180deg); }
@media (max-width:600px){
  .pc-filters-in { padding:8px 16px; gap:8px; }
  .pc-filters-toggle { display:inline-flex; }
  .pc-filters:not(.open) .pc-filters-in > .fld { display:none; }
  .pc-filters.open { max-height:70vh; overflow:auto; }
  /* Opened on its own, the header wraps to three rows on a phone: it scrolls
     away, and the bar sticks to the top. */
  .pc-head { position:static; }
  .pc-filters { top:0; }
}
.fld { display:flex; flex-direction:column; gap:3px; }
.fld > label { font-size:10.5px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); font-weight:600; }
.pc-win { padding:8px 0 0; }
.pc-win .note { display:block; }
.pc-win code { font-size:11px; opacity:.85; }
.chips { display:flex; gap:6px; flex-wrap:wrap; align-items:center; margin-left:auto; }
.chip {
  display:inline-flex; align-items:center; gap:6px; font-size:11.5px; padding:3px 6px 3px 9px;
  border:1px solid var(--border-strong); border-radius:var(--radius-pill); background:var(--surface-2); color:var(--text-secondary);
}
.chip b { color:var(--text-primary); font-weight:600; }
.chip button { border:0; background:transparent; color:var(--muted); cursor:pointer; font-size:14px; line-height:1; padding:0 2px; }
.chip button:hover { color:var(--critical); }

/* --------------------------------------------------------------- container */
main { max-width:1560px; margin:0 auto; padding:20px 22px 64px; }
.grid { display:grid; gap:14px; }
.g2 { grid-template-columns:repeat(2,minmax(0,1fr)); }
.g3 { grid-template-columns:repeat(3,minmax(0,1fr)); }
.g4 { grid-template-columns:repeat(4,minmax(0,1fr)); }
.g-2-1 { grid-template-columns:2fr 1fr; }
.g-1-2 { grid-template-columns:1fr 2fr; }
@media (max-width:1180px){ .g3,.g4,.g-2-1,.g-1-2 { grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:760px){ .grid { grid-template-columns:1fr !important; } }

.card {
  background:var(--surface-1); border:1px solid var(--border); border-radius:var(--radius);
  padding:16px 18px; box-shadow:var(--shadow); min-width:0;
}
.card.flush { padding:0; overflow:hidden; }
.card-h { display:flex; align-items:baseline; gap:10px; margin-bottom:2px; flex-wrap:wrap; }
.card-h h3 { font-size:13.5px; }
.card-h .tools { margin-left:auto; display:flex; gap:4px; align-items:center; }
.card-sub { font-size:11.5px; color:var(--muted); margin-bottom:12px; }
.section-title { font-size:12px; text-transform:uppercase; letter-spacing:.07em; color:var(--muted); font-weight:700; margin:24px 0 10px; }
.section-title:first-child { margin-top:4px; }

/* ------------------------------------------------------------- stat tiles */
.tile { display:flex; flex-direction:column; gap:3px; }
.tile .lbl { font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); font-weight:600; }
.tile .val { font-size:27px; font-weight:640; letter-spacing:-.02em; line-height:1.15; }
.tile .val .u { font-size:14px; font-weight:500; color:var(--text-secondary); margin-left:2px; letter-spacing:0; }
.tile .foot { font-size:11.5px; color:var(--text-secondary); display:flex; align-items:center; gap:5px; }
.delta { display:inline-flex; align-items:center; gap:3px; font-weight:600; font-size:11.5px; }
.delta.up { color:var(--good-ink); } .delta.down { color:var(--critical); } .delta.flat { color:var(--muted); }
.hero { font-size:40px; font-weight:660; letter-spacing:-.025em; line-height:1.05; }

/* ------------------------------------------------------------------ charts */
.chart { width:100%; height:280px; position:relative; }
/* A chart that paints no data says so (pc.js, markEmpty). */
.pc-empty { position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  color:var(--muted); font-size:13px; pointer-events:none; z-index:1; }
.pc-empty > span { background:var(--surface-1); padding:2px 10px; border-radius:var(--radius-pill); }
.chart.sm { height:212px; }
.chart.lg { height:360px; }
.chart.xl { height:440px; }
.legend { display:flex; gap:14px; flex-wrap:wrap; font-size:11.5px; color:var(--text-secondary); margin-top:8px; }
.legend .k { display:inline-flex; align-items:center; gap:6px; cursor:default; }
.legend .sw { width:11px; height:11px; border-radius:var(--radius-min); flex:none; }
.scale-legend { display:flex; align-items:center; gap:8px; font-size:11px; color:var(--muted); margin-top:8px; }
.scale-legend .ramp { height:9px; width:130px; border-radius:var(--radius-min); border:1px solid var(--border); }

/* ------------------------------------------------------------------ tables */
.tbl-wrap { overflow-x:auto; }
table.tbl { width:100%; border-collapse:collapse; font-size:12.5px; font-variant-numeric:tabular-nums; }
table.tbl th, table.tbl td { padding:7px 10px; text-align:left; border-bottom:1px solid var(--grid); white-space:nowrap; }
table.tbl th {
  position:sticky; top:0; background:var(--surface-1); z-index:2; font-weight:600; color:var(--text-secondary);
  font-size:11px; text-transform:uppercase; letter-spacing:.05em; user-select:none;
}
table.tbl th.s { cursor:pointer; } table.tbl th.s:hover { color:var(--text-primary); }
table.tbl th .ar { color:var(--s1); font-size:9px; margin-left:3px; }
table.tbl td.n, table.tbl th.n { text-align:right; }
table.tbl tbody tr:hover { background:var(--surface-2); }
table.tbl tbody tr.clickable { cursor:pointer; }
table.tbl tbody tr.sel { background:var(--surface-3); }
table.tbl td.wrap { white-space:normal; max-width:340px; }
table.tbl .dim { color:var(--muted); }
.tbl-foot { display:flex; align-items:center; gap:10px; padding:9px 14px; border-top:1px solid var(--border); font-size:12px; color:var(--text-secondary); flex-wrap:wrap; }
.tbl-foot .sp { margin-left:auto; display:flex; gap:5px; align-items:center; }

/* proportional bar inside cells */
.mini { display:flex; align-items:center; gap:7px; }
.mini .bar { height:6px; border-radius:var(--radius-min); background:var(--s1); min-width:2px; }
.mini .track { flex:1; height:6px; border-radius:var(--radius-min); background:var(--surface-3); overflow:hidden; min-width:44px; }

/* ------------------------------------------------------------ miscellaneous */
.badge {
  display:inline-flex; align-items:center; gap:4px; font-size:11px; font-weight:600; padding:2px 7px;
  border-radius:var(--radius-pill); border:1px solid var(--border-strong); background:var(--surface-2); color:var(--text-secondary);
  white-space:nowrap;
}
.badge.good { color:var(--good-ink); border-color:color-mix(in srgb,var(--good) 40%,transparent); background:color-mix(in srgb,var(--good) 10%,transparent); }
.badge.warn { color:var(--text-primary); border-color:color-mix(in srgb,var(--warning) 55%,transparent); background:color-mix(in srgb,var(--warning) 16%,transparent); }
.badge.crit { color:var(--critical); border-color:color-mix(in srgb,var(--critical) 40%,transparent); background:color-mix(in srgb,var(--critical) 10%,transparent); }
.badge.info { color:var(--s1); border-color:color-mix(in srgb,var(--s1) 35%,transparent); background:color-mix(in srgb,var(--s1) 10%,transparent); }

.crumbs { display:flex; align-items:center; gap:5px; flex-wrap:wrap; font-size:12.5px; }
.crumbs button { border:0; background:transparent; color:var(--s1); cursor:pointer; font:inherit; padding:2px 4px; border-radius:calc(var(--radius) * .5); }
.crumbs button:hover { background:var(--surface-2); text-decoration:underline; }
.crumbs .sep { color:var(--muted); }
.crumbs .cur { color:var(--text-primary); font-weight:600; padding:2px 4px; }

.kv { display:grid; grid-template-columns:auto 1fr; gap:5px 14px; font-size:12.5px; align-items:baseline; }
.kv dt { color:var(--muted); white-space:nowrap; }
.kv dd { margin:0; color:var(--text-primary); word-break:break-word; }

.empty { padding:34px 18px; text-align:center; color:var(--muted); font-size:13px; }
.note {
  font-size:12px; color:var(--text-secondary); background:var(--surface-2);
  border:1px solid var(--border); border-left:3px solid var(--s1); border-radius:var(--radius-ctl); padding:10px 13px;
}
.note.warn { border-left-color:var(--warning); }
.note.good { border-left-color:var(--good); }
.split { display:grid; grid-template-columns:308px 1fr; gap:14px; align-items:start; }
@media (max-width:980px){ .split { grid-template-columns:1fr; } }

.list { display:flex; flex-direction:column; max-height:min(72vh,700px); overflow-y:auto; }
.list-item {
  display:flex; align-items:center; gap:9px; padding:8px 12px; border:0; border-bottom:1px solid var(--grid);
  background:transparent; cursor:pointer; text-align:left; font:inherit; color:inherit; width:100%;
}
.list-item:hover { background:var(--surface-2); }
.list-item[aria-current="true"] { background:var(--surface-3); box-shadow:inset 3px 0 0 var(--s1); }
.list-item .nm { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:12.5px; }
.list-item .qt { font-size:11.5px; color:var(--muted); font-variant-numeric:tabular-nums; }
.list-item .track { width:52px; }

.drawer-bg { position:fixed; inset:0; background:rgba(11,11,11,.42); z-index:60; }
.drawer {
  position:fixed; top:0; right:0; bottom:0; width:min(560px,94vw); background:var(--surface-1);
  border-left:1px solid var(--border); z-index:61; overflow-y:auto; padding:20px 22px 40px;
  box-shadow:-16px 0 40px -24px rgba(0,0,0,.5);
}
.drawer h3 { font-size:15px; margin-bottom:2px; }
.hidden { display:none !important; }
.sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
.pc-foot { max-width:1560px; margin:0 auto; padding:0 22px 40px; font-size:11.5px; color:var(--muted); }

/* ------------------------------------------------------- embedded mode
   Inside the ecoAI Reports panel the report goes in an iframe and the container
   already brings its own header: here it is enough to identify the report,
   without a sticky bar competing with the container's. */
.pc-head-embed { position:static; background:transparent; border-bottom:0; backdrop-filter:none; }
.pc-head-embed .pc-head-in { padding:14px 22px 0; }

} /* @layer product */
