@bongos/core 1.24.49 → 1.24.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -643,6 +643,10 @@ async function loadCosts() {
643
643
 
644
644
  if (!window.Chart) return; // Chart.js failed to load — skip
645
645
 
646
+ // The chart paints with the page's own tokens (task 1005089): a canvas cannot
647
+ // read var(), so the resolved values are read once per draw, in whichever mode
648
+ // the page is in. Spend is ink, value the --info tone; the faces are the pack's.
649
+ const t = chartTokens();
646
650
  const ctx = els.costChart.getContext('2d');
647
651
  if (costChart) costChart.destroy();
648
652
  costChart = new Chart(ctx, {
@@ -654,23 +658,23 @@ async function loadCosts() {
654
658
  label: `${curLabel()} spent`,
655
659
  data: cumCost,
656
660
  fill: true,
657
- borderColor: '#2a2110',
658
- backgroundColor: 'rgba(139, 111, 44, 0.16)',
661
+ borderColor: t.ink,
662
+ backgroundColor: t.inkWash,
659
663
  tension: 0.2,
660
664
  pointRadius: 2.5,
661
- pointBackgroundColor: '#2a2110',
665
+ pointBackgroundColor: t.ink,
662
666
  borderWidth: 1.5,
663
667
  },
664
668
  {
665
669
  label: 'value wrought',
666
670
  data: cumValue,
667
671
  fill: false,
668
- borderColor: '#2f5a3f',
669
- backgroundColor: 'rgba(74, 125, 92, 0.18)',
672
+ borderColor: t.info,
673
+ backgroundColor: t.info,
670
674
  borderDash: [5, 4],
671
675
  tension: 0.2,
672
676
  pointRadius: 2.5,
673
- pointBackgroundColor: '#2f5a3f',
677
+ pointBackgroundColor: t.info,
674
678
  borderWidth: 1.5,
675
679
  },
676
680
  ],
@@ -678,7 +682,7 @@ async function loadCosts() {
678
682
  options: {
679
683
  responsive: true,
680
684
  maintainAspectRatio: false,
681
- font: { family: '"EB Garamond", Georgia, serif' },
685
+ font: { family: t.body },
682
686
  plugins: {
683
687
  legend: {
684
688
  display: true,
@@ -686,14 +690,16 @@ async function loadCosts() {
686
690
  labels: {
687
691
  boxWidth: 22,
688
692
  padding: 18,
689
- font: { family: '"EB Garamond", Georgia, serif', size: 13, style: 'italic' },
690
- color: '#6e5b3a',
693
+ font: { family: t.body, size: 13 },
694
+ color: t.inkSoft,
691
695
  },
692
696
  },
693
697
  tooltip: {
694
- backgroundColor: 'rgba(42, 33, 16, 0.92)',
695
- titleFont: { family: '"Cinzel", Georgia, serif', size: 11, weight: '500' },
696
- bodyFont: { family: '"EB Garamond", Georgia, serif', size: 13 },
698
+ backgroundColor: t.ink,
699
+ titleColor: t.card,
700
+ bodyColor: t.card,
701
+ titleFont: { family: t.body, size: 12, weight: '500' },
702
+ bodyFont: { family: t.body, size: 13 },
697
703
  padding: 10,
698
704
  callbacks: {
699
705
  label: (c) => `${c.dataset.label}: ${c.parsed.y.toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 })} dr.`,
@@ -706,28 +712,28 @@ async function loadCosts() {
706
712
  title: {
707
713
  display: true,
708
714
  text: `${curLabel()} (cumulative)`,
709
- font: { family: '"Cinzel", Georgia, serif', size: 11, weight: '500' },
710
- color: '#735f3d',
715
+ font: { family: t.body, size: 12, weight: '500' },
716
+ color: t.inkSoft,
711
717
  },
712
718
  ticks: {
713
719
  callback: (v) => `${v} dr.`,
714
- font: { family: '"EB Garamond", Georgia, serif', size: 12 },
715
- color: '#6e5b3a',
720
+ font: { family: t.body, size: 12 },
721
+ color: t.inkSoft,
716
722
  },
717
- grid: { color: 'rgba(139, 111, 44, 0.18)', drawBorder: false },
723
+ grid: { color: t.rule, drawBorder: false },
718
724
  },
719
725
  x: {
720
726
  title: {
721
727
  display: true,
722
728
  text: 'date',
723
- font: { family: '"Cinzel", Georgia, serif', size: 11, weight: '500' },
724
- color: '#735f3d',
729
+ font: { family: t.body, size: 12, weight: '500' },
730
+ color: t.inkSoft,
725
731
  },
726
732
  grid: { display: false },
727
733
  ticks: {
728
734
  maxTicksLimit: 10,
729
- font: { family: '"EB Garamond", Georgia, serif', size: 12 },
730
- color: '#6e5b3a',
735
+ font: { family: t.body, size: 12 },
736
+ color: t.inkSoft,
731
737
  },
732
738
  },
733
739
  },
@@ -735,6 +741,23 @@ async function loadCosts() {
735
741
  });
736
742
  }
737
743
 
744
+ // The resolved values of the tokens the cost chart paints with, read from the
745
+ // page (a canvas cannot take var()). An unset token reads '' and Chart.js keeps
746
+ // its own default for it.
747
+ function chartTokens() {
748
+ const cs = window.getComputedStyle(document.body);
749
+ const v = (name) => cs.getPropertyValue(name).trim();
750
+ return {
751
+ ink: v('--ink'),
752
+ inkSoft: v('--ink-soft'),
753
+ inkWash: v('--glass-strong'),
754
+ info: v('--info'),
755
+ rule: v('--rule-soft'),
756
+ card: v('--bg-card'),
757
+ body: v('--font-body') || 'sans-serif',
758
+ };
759
+ }
760
+
738
761
  function toDayKey(d) {
739
762
  // Postgres returns 'YYYY-MM-DD' as a string OR an ISO timestamp depending
740
763
  // on transport — normalise to YYYY-MM-DD so dedupe works across formats.
@@ -1050,7 +1073,7 @@ function stampRefreshTime() {
1050
1073
  // kinds-of-work fingerprint. Fed by /api/bongos/public/analytics/ecosystem.
1051
1074
  // Inline SVG sparklines — no chart library for this tile.
1052
1075
 
1053
- function foundrySparkline(values, color) {
1076
+ function foundrySparkline(values, tone) {
1054
1077
  const W = 320, H = 54, pad = 4;
1055
1078
  const nums = (values || []).map((v) => (Number.isFinite(Number(v)) ? Number(v) : 0));
1056
1079
  if (nums.length === 0) return '';
@@ -1060,9 +1083,12 @@ function foundrySparkline(values, color) {
1060
1083
  const y = (v) => H - pad - ((v - min) / span) * (H - 2 * pad);
1061
1084
  const line = nums.map((v, i) => `${x(i).toFixed(1)},${y(v).toFixed(1)}`).join(' ');
1062
1085
  const area = `${pad},${H - pad} ${line} ${(W - pad)},${H - pad}`;
1063
- return `<svg class="foundry-spark" viewBox="0 0 ${W} ${H}" preserveAspectRatio="none" role="img" aria-label="trend">
1064
- <polyline class="foundry-spark__area" points="${area}" fill="${color}" />
1065
- <polyline class="foundry-spark__line" points="${line}" fill="none" stroke="${color}" />
1086
+ // The colour is the sheet's (.foundry-spark, and --ink for the ink tone): a
1087
+ // token, never a literal handed in from here (task 1005089).
1088
+ const cls = tone === 'ink' ? 'foundry-spark foundry-spark--ink' : 'foundry-spark';
1089
+ return `<svg class="${cls}" viewBox="0 0 ${W} ${H}" preserveAspectRatio="none" role="img" aria-label="trend">
1090
+ <polyline class="foundry-spark__area" points="${area}" />
1091
+ <polyline class="foundry-spark__line" points="${line}" />
1066
1092
  </svg>`;
1067
1093
  }
1068
1094
 
@@ -1095,8 +1121,8 @@ async function loadEcosystem() {
1095
1121
  const shipVals = (data.ship_rate || []).map((r) => Number(r.n));
1096
1122
  const durVals = (data.duration_trend || []).map((r) => Number(r.avg_actual));
1097
1123
  chartsEl.innerHTML =
1098
- `<div class="foundry__chart"><div class="foundry__chart-title">Works shipped / day</div>${foundrySparkline(shipVals, '#2f5a3f') || '<p class="empty">no data</p>'}</div>` +
1099
- `<div class="foundry__chart"><div class="foundry__chart-title">Avg time per work (min)</div>${foundrySparkline(durVals, '#2d6e7e') || '<p class="empty">no data</p>'}</div>`;
1124
+ `<div class="foundry__chart"><div class="foundry__chart-title">Works shipped / day</div>${foundrySparkline(shipVals, 'ink') || '<p class="empty">no data</p>'}</div>` +
1125
+ `<div class="foundry__chart"><div class="foundry__chart-title">Avg time per work (min)</div>${foundrySparkline(durVals, 'info') || '<p class="empty">no data</p>'}</div>`;
1100
1126
 
1101
1127
  const kinds = (data.top_kinds || []).slice(0, 6);
1102
1128
  if (kindsEl) {