/* v10: native entry effects touch data marks only; static chart geometry is unchanged. */
/* =====================================================================
   PQB CHART FOUNDATION — palette + chart chrome
   hyperline-dark.jpg supplies colour and filled-chart intent only. Its
   skewed marketing render supplies no geometry, type or spacing.

   Two rules this file exists to enforce:
     1. CHARTS ARE THE ONLY COLOUR. Every hex below is inside a chart.
        Nothing else in the product may consume these tokens.
     2. CHARTS ARE NEVER TENANT-THEMED. There is no --accent*, --brand-*,
        --hbg, --sbg or --ring anywhere in this file, by construction.
        The Instrument Boundary smoke assertion stays green.

   Theme: every mark references a custom property, so a light/dark flip
   repaints with ZERO redraw — no destroy(), no re-render, no reflow.
   This is the single biggest reason the kit is SVG and not canvas.
   ===================================================================== */

/* ---------- LIGHT (chart surface = --card #FFFFFF) ----------
   Scoped to the chart parts, never to :root — so no product surface can
   reach these values by accident. The labelled list and the tooltip carry
   the same block because they live OUTSIDE the SVG host by design. */
.pqbk, .pqbk-list, .pqbk-tip, .pqbk-empty{
  /* Literal anchors from the user's reference histograms. Slots name
     categories, not urgency: expiry is orange; red is reserved for an
     actual loss or breach. Labels, positions and shapes retain identity
     when two hues become similar under a colour-vision simulation. */
  --k-blue:#266DF0;--k-cyan:#14AED6;--k-green:#54D490;
  --k-orange:#FD9040;--k-amber:#F5B90D;--k-deep-green:#0FC27B;
  --k-violet:#8170FD;--k-deepblue:#306198;
  --k-loss:var(--c-bad,#B4232F);
  --k1:var(--k-blue);--k2:var(--k-orange);--k3:var(--k-green);
  --k4:var(--k-cyan);--k5:#111114;--k6:var(--k-amber);
  --k7:var(--k-violet);--k8:var(--k-deepblue);--k9:var(--k-loss);--k10:var(--k-deep-green);
  --k-comparison:var(--k-ink2);

  /* Ordered funnel colours are separate from the single-hue heat ramp.
     The two middle stops interpolate the measured violet/cyan anchors. */
  --funnel1:var(--k-violet);
  --funnel2:color-mix(in srgb,var(--k-violet) 66.666667%,var(--k-cyan));
  --funnel3:color-mix(in srgb,var(--k-violet) 33.333333%,var(--k-cyan));
  --funnel4:var(--k-cyan);

  /* Eight heat stops derive from the named blue, white and chart ink.
     Named blue stays independent of a particular chart's slot-1 role. */
  --s100:color-mix(in srgb,var(--k-blue) 10%,#FFFFFF);
  --s200:color-mix(in srgb,var(--k-blue) 25%,#FFFFFF);
  --s300:color-mix(in srgb,var(--k-blue) 40%,#FFFFFF);
  --s400:color-mix(in srgb,var(--k-blue) 60%,#FFFFFF);
  --s500:color-mix(in srgb,var(--k-blue) 80%,#FFFFFF);
  --s600:var(--k-blue);
  --s700:color-mix(in srgb,var(--k-blue) 85%,var(--k-ink1));
  --s800:color-mix(in srgb,var(--k-blue) 70%,var(--k-ink1));

  /* General divergence uses blue/orange, never the reserved loss red. */
  --dneg3:var(--s700);--dneg2:var(--k-blue);--dneg1:var(--s300);
  --dmid:#E4E4E2;
  --dpos1:color-mix(in srgb,var(--k-orange) 40%,#FFFFFF);
  --dpos2:var(--k-orange);--dpos3:color-mix(in srgb,var(--k-orange) 70%,var(--k-ink1));

  /* chart chrome — greyscale, from the app's own text tokens */
  --k-surface:#FFFFFF;
  --k-ink1:#111114;         /* values, emphasised labels */
  --k-ink2:#6E6E76;         /* axis ticks, secondary labels */
  --k-ink3:#9A9AA2;         /* the quietest label that still reads */
  --k-grid:rgba(17,17,20,.10);
  --k-axis:rgba(17,17,20,.22);
  --k-hair:rgba(17,17,20,.35);   /* crosshair */
  --k-band:rgba(17,17,20,.05);   /* hover band */
  --k-fillA:.08;                 /* dr2: quiet blue area under the line at x2950, y750 */
  --k-area-top:.18;--k-area-bottom:0;
  --k-mark-r:0;             /* v11.1: the last curve in the chart layer, zeroed. Straight edges everywhere. */
  --k-mono:var(--font-mono),ui-monospace,'SF Mono',Menlo,monospace;
  /* 2026-09-21: chart LABELS are text and take the text face. Only tabular figures
     keep --k-mono. Measured off attio-ref.png: Hyperline sets every axis, legend and
     tooltip label sentence-case in its text face — the mono caps were ours, not its. */
  --k-label:var(--font-sans),system-ui,sans-serif;
}

/* ---------- DARK (one shared raised surface) ----------
   Latest JPEG histogram anchors: violet dominates; blue and deep blue
   are secondary. Colour/intent only, never geometry from the skewed image. */
body.dark .pqbk, body.dark .pqbk-list, body.dark .pqbk-tip, body.dark .pqbk-empty,
.pqbk.dark{
  --k-blue:#2F94E4;--k-cyan:#14AED6;--k-green:#54D490;
  --k-orange:#FD9040;--k-amber:#F5B90D;--k-deep-green:#0FC27B;
  --k-violet:#8170FD;--k-deepblue:#306198;
  --k-loss:var(--c-bad,#E85C68);
  --k1:var(--k-blue);--k2:var(--k-orange);--k3:var(--k-green);
  --k4:var(--k-cyan);--k5:#F0F0F2;--k6:var(--k-amber);
  --k7:var(--k-violet);--k8:var(--k-deepblue);--k9:var(--k-loss);--k10:var(--k-deep-green);
  /* Funnel stages and neutral dashed comparisons inherit their light-theme
     roles. Violet/cyan remain visible on the shared raised surface. */

  /* Derived heat stops, not eight separately measured JPEG colours. */
  --s100:color-mix(in srgb,var(--k-blue) 25%,var(--k-surface));
  --s200:color-mix(in srgb,var(--k-blue) 50%,var(--k-surface));
  --s300:var(--k-blue);
  --s400:color-mix(in srgb,var(--k-blue) 90%,#FFFFFF);
  --s500:color-mix(in srgb,var(--k-blue) 80%,#FFFFFF);
  --s600:color-mix(in srgb,var(--k-blue) 70%,#FFFFFF);
  --s700:color-mix(in srgb,var(--k-blue) 60%,#FFFFFF);
  --s800:color-mix(in srgb,var(--k-blue) 50%,#FFFFFF);

  --dneg3:var(--s800);--dneg2:var(--k-blue);--dneg1:var(--s200);
  --dmid:#3A3A3E;
  --dpos1:color-mix(in srgb,var(--k-orange) 50%,var(--k-surface));
  --dpos2:var(--k-orange);--dpos3:color-mix(in srgb,var(--k-orange) 50%,#FFFFFF);

  --k-surface:var(--surface-raised,#191919);
  --k-ink1:#F0F0F2;
  --k-ink2:#9A9AA2;
  --k-ink3:#999999;
  --k-grid:rgba(240,240,242,.12);
  --k-axis:rgba(240,240,242,.24);
  --k-hair:rgba(240,240,242,.40);
  --k-band:rgba(240,240,242,.06);
  --k-fillA:.08;   /* dr1: the line remains dominant over its dark plot ground */
  --k-area-top:.30;--k-area-bottom:0;
}
/* One meaning per hue in both themes: Sales violet, quoted value blue,
   stages amber → orange; comparison remains neutral, dashed and named.
   These use the reference anchors above, never tenant accent colours. */
#an-quoted,#an-quoted .pqbk-tip,#an-quoted-card .pqbk-list{--k1:var(--k-blue)}
#an-sales-c,#an-sales-c .pqbk-tip,#an-sales-lg,#an-sales-tc{--k1:var(--k-violet)}
/* WS10 (Oscar, 2026-09-25): the owner Overview reads Paid sales GREEN (the deep variant, for contrast on white) and
   Quoting over time YELLOW; the rep dashboard charts above keep their hues. */
#ov-sales-c,#ov-sales-c .pqbk-tip,#ov-sales-lg{--k1:var(--k-deep-green)}
#ov-quoted-c,#ov-quoted-c .pqbk-tip,#ov-quoted-lg{--k1:var(--k-amber)}

/* ===================== chart chrome ===================== */

.pqbk{position:relative}
.pqbk svg{display:block;width:100%;overflow:visible;
  font-family:var(--k-label);font-variant-numeric:tabular-nums;
  -webkit-font-feature-settings:"tnum" 1;font-feature-settings:"tnum" 1}

/* dr1/dr2: muted dashed value rules at y703/818, solid baseline at y1280
   in the DPR-2 reference. Labels use the app's 12px Inter at its 14px base. */
.pqbk .kg{stroke:var(--k-grid);stroke-width:1;stroke-dasharray:4 6;shape-rendering:crispEdges}
.pqbk .kg0{stroke:var(--k-axis);stroke-dasharray:none} /* the zero / base rule */
.pqbk .kax{stroke:var(--k-axis);stroke-width:1;shape-rendering:crispEdges}

.pqbk text{fill:var(--k-ink2);font-size:12px;letter-spacing:0;font-family:var(--k-label)}
.pqbk .kt-v{fill:var(--k-ink1);font-size:12px;font-weight:500}   /* a value */
.pqbk .kt-q{fill:var(--k-ink3)}                                   /* quietest */
.pqbk .kt-cat{fill:var(--k-ink2);font-size:12px}
/* An SVG presentation attribute LOSES to any stylesheet rule, so a label that
   must sit on a filled mark takes a CLASS, never setAttribute('fill', ...).
   Getting this wrong is silent: the label renders muted grey on a saturated
   fill and nobody sees a console error. */
.pqbk text.kt-surf{fill:var(--k-surface)}
.pqbk text.kt-ink{fill:var(--k-ink1)}

/* In-cell values retain at least 4.5:1 contrast throughout both ramps.
   Light changes ink at s600; the dark blue anchor at s300 already needs
   surface ink. CSS keeps that choice correct across a theme toggle. */
.pqbk text.on-s0,.pqbk text.on-s1,.pqbk text.on-s2,
.pqbk text.on-s3,.pqbk text.on-s4{fill:var(--k-ink1)}
.pqbk text.on-s5,.pqbk text.on-s6,.pqbk text.on-s7{fill:var(--k-surface)}
body.dark .pqbk text.on-s2,body.dark .pqbk text.on-s3,body.dark .pqbk text.on-s4,
.pqbk.dark text.on-s2,.pqbk.dark text.on-s3,.pqbk.dark text.on-s4{fill:var(--k-surface)}

/* marks */
.pqbk .kline{fill:none;stroke-width:2;stroke-linejoin:round;stroke-linecap:butt}
.pqbk .kline.k-em{stroke-width:2.5}
.pqbk .karea{stroke:none}
.pqbk .karea.fillc{opacity:var(--k-fillA)} /* Preserve the existing spark fill. */
.pqbk .karea-start{stop-color:currentColor;stop-opacity:var(--k-area-top)}
.pqbk .karea-end{stop-color:currentColor;stop-opacity:var(--k-area-bottom)}
.pqbk .kbar{shape-rendering:auto}
.pqbk .kdot{stroke:var(--k-surface);stroke-width:2}   /* the 2px surface ring */
.pqbk .kend{stroke:var(--k-surface);stroke-width:2.5} /* emphasised endpoint */

/* the series colours, applied by class so the theme flip is free */
.pqbk .c1{color:var(--k1)} .pqbk .c2{color:var(--k2)} .pqbk .c3{color:var(--k3)}
.pqbk .c4{color:var(--k4)} .pqbk .c5{color:var(--k5)}
.pqbk .c6{color:var(--k6)} .pqbk .c7{color:var(--k7)} .pqbk .c8{color:var(--k8)}
.pqbk .c9{color:var(--k9)} .pqbk .c10{color:var(--k10)}
.pqbk .c1,.pqbk .c2,.pqbk .c3,.pqbk .c4,.pqbk .c5,
.pqbk .c6,.pqbk .c7,.pqbk .c8,.pqbk .c9,.pqbk .c10{stroke:currentColor}
.pqbk .fillc{fill:currentColor;stroke:none}
.pqbk .strokec{fill:none;stroke:currentColor}

/* A comparison retains its dashed shape as well as its named legend. */
.pqbk .kprev{stroke:var(--k-comparison);stroke-width:1.5;stroke-dasharray:4 4;fill:none}
.pqbk .kprev-end{stroke:var(--k-comparison);stroke-width:1.5;fill:var(--k-surface)}
.pqbk .kend-link{stroke-width:1;opacity:.55;fill:none}
.pqbk .kend-link.comparison{stroke:var(--k-comparison);stroke-dasharray:4 4}

/* The Sales silhouette follows the user's single connected step polygon.
   Generic time-series paths above retain their smooth gradient treatment. */
.pqbk .kstep-area{stroke:none;opacity:1;shape-rendering:crispEdges}
.pqbk .kstep-line{fill:none;stroke-width:2;stroke-linejoin:miter;stroke-linecap:butt;shape-rendering:crispEdges}
.pqbk .kstep-prev{stroke-linejoin:miter;stroke-linecap:butt;shape-rendering:crispEdges}
.pqbk .kstep-prev-halo{fill:none;stroke:var(--k-surface);stroke-width:5;stroke-dasharray:4 4;stroke-linejoin:miter;stroke-linecap:butt;shape-rendering:crispEdges}
.pqbk .kcolumn{shape-rendering:crispEdges}
.pqbk .kcolumn-comparison{fill:none;stroke:var(--k-comparison);stroke-width:1.5;stroke-dasharray:4 4;stroke-linejoin:miter}
.pqbk-columns-list li{min-width:0;max-width:100%;align-items:flex-start}
.pqbk-columns-list b{min-width:0;overflow-wrap:anywhere}
.pqbk-columns-list .comparison i{background:none;border:1.5px dashed currentColor;box-sizing:border-box}

/* labelled list — the ONLY legend in the product. Never chart-drawn. */
.pqbk-list{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-wrap:wrap;
  gap:4px 16px;font-family:var(--k-label);font-size:12px;letter-spacing:0;
  font-variant-numeric:tabular-nums;color:var(--k-ink2)}
.pqbk-list li{display:flex;align-items:center;gap:7px;min-height:18px}
.pqbk-list i{width:10px;height:10px;flex:0 0 10px;border-radius:50%;background:currentColor}
.pqbk-list li.l1{color:var(--k1)} .pqbk-list li.l2{color:var(--k2)}
.pqbk-list li.l3{color:var(--k3)} .pqbk-list li.l4{color:var(--k4)}
.pqbk-list li.l5{color:var(--k5)} .pqbk-list li.l6{color:var(--k6)}
.pqbk-list li.l7{color:var(--k7)} .pqbk-list li.l8{color:var(--k8)}
.pqbk-list li.l9{color:var(--k9)} .pqbk-list li.l10{color:var(--k10)}
.pqbk-list li.comparison{color:var(--k-comparison)}
.pqbk-list li.stat{color:var(--k-ink3)}
.pqbk-list li.stat b{color:var(--k-ink2)}
.pqbk-list b{color:var(--k-ink2);font-weight:500}
.pqbk-list span{color:var(--k-ink1);font-weight:500;margin-left:auto}
/* a swatch alone never carries identity: the label sits beside it, always */

/* tooltip */
.pqbk-tip{position:absolute;pointer-events:none;z-index:6;opacity:0;
  transform:translate(-50%,-100%);transition:opacity .09s linear;
  background:var(--k-surface);border:1px solid var(--k-grid);border-radius:0;
  padding:8px 12px;font-family:var(--k-label);font-size:12px;letter-spacing:0;line-height:1.45;
  font-variant-numeric:tabular-nums;color:var(--k-ink1);white-space:nowrap;
  box-shadow:0 2px 10px rgba(0,0,0,.14)}
.pqbk-tip.on{opacity:1}
.pqbk-tip em{font-style:normal;color:var(--k-ink2)}
.pqbk-tip .sw{display:inline-block;width:8px;height:8px;margin-right:6px;
  vertical-align:baseline;background:currentColor}

/* empty state — a designed answer, not a blank box */
.pqbk-empty{display:flex;flex-direction:column;justify-content:center;
  min-height:0;padding:0;color:var(--k-ink2);
  font-family:var(--k-label);font-size:12px;letter-spacing:0;line-height:1.5}
.pqbk-empty b{display:block;color:var(--k-ink1);font-weight:500;
  font-size:12px;letter-spacing:0;text-transform:none;margin-bottom:0}
.pqbk-empty b+div:not(:empty){margin-top:8px}
.pqbk-empty .rule{height:1px;background:var(--k-grid);margin:12px 0 0}

/* the caption that states the finding in words — always present */
.pqbk-sum{margin:12px 0 0;color:var(--k-ink2);font-family:var(--k-label);font-size:12px;letter-spacing:0;line-height:1.5}

@media (prefers-reduced-motion:reduce){
  .pqbk *{animation:none!important;transition:none!important}
  .pqbk-tip{transition:none}
  .pqbk [data-chart-entry]{clip-path:none!important}
}
@media print{.pqbk [data-chart-entry]{clip-path:none!important}}

/* Dense scatter keeps the original coordinates. The plot labels are measured;
   the complete text roster and keyboard focus expose even coincident quotes. */
.pqbk-scatter .kpoint:focus-visible{outline:2px solid var(--k-ink1);outline-offset:2px}
.pqbk-scatter .pqbk-tip{max-width:calc(100% - 8px);white-space:normal;overflow-wrap:anywhere;box-sizing:border-box}
.pqbk-points{margin-top:12px;font-family:var(--k-label);font-size:12px;line-height:1.5;color:var(--k-ink2)}
.pqbk-points>summary{width:fit-content;max-width:100%;cursor:pointer;color:var(--k-ink2)}
.pqbk-points>summary:hover{color:var(--k-ink1)}
.pqbk-points>summary:focus-visible{outline:2px solid var(--k-ink1);outline-offset:2px}
.pqbk-points>ol{display:grid;gap:8px;margin:12px 0 0;padding:0;list-style:none}
.pqbk-points li{display:grid;gap:4px;overflow-wrap:anywhere}
.pqbk-points li>b{font-weight:500;color:var(--k-ink1)}

/* An empty legend has no content and must not retain its list margin. */
.pqbk-list:empty{display:none}
