@booboo-brain/panel 0.5.4 → 0.5.5

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.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import * as react from 'react';
2
2
 
3
3
  type ApiFn = (path: string, init?: RequestInit) => Promise<any>;
4
- declare function Panel({ api }?: {
4
+ declare function Panel({ api, theme }?: {
5
5
  api?: ApiFn;
6
+ theme?: "dark" | "light";
6
7
  }): react.JSX.Element;
7
8
 
8
9
  declare const PANEL_VERSION: string;
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { orgBootSlice, relTime } from "@booboo-brain/spec";
5
5
  // src/panel-css.ts
6
6
  var PANEL_CSS = String.raw`
7
7
  /* GENERATED from design/tokens.json by scripts/gen-tokens.mjs — DO NOT EDIT */
8
- :root {
8
+ .pnl, .pnl-fatal {
9
9
  --bg: #06080e;
10
10
  --bg-lift: #0a0d15;
11
11
  --card: #0f131c;
@@ -59,7 +59,12 @@ var PANEL_CSS = String.raw`
59
59
  the dachshund's collar), a slow aurora breathing behind everything, cards
60
60
  that lift and settle, numbers that count up. Dark by default. */
61
61
 
62
- :root {
62
+ /* Scoped to the panel's own roots, NEVER :root — see scripts/gen-tokens.mjs.
63
+ A custom property on :root is shadowed by any ancestor declaring the same
64
+ name, so a host whose shell declares --bg-1/--line/--gold silently repaints
65
+ the board. Declaring them here means nothing can sit between these names and
66
+ the elements that read them. */
67
+ .pnl, .pnl-fatal {
63
68
  /* THE STAFF BOARD — a master-key rack, not a dashboard.
64
69
  Structure comes from two real artefacts: a master-key hierarchy (passe
65
70
  général → passe partiel → cylinder, which is literally how a hotel is
@@ -118,8 +123,10 @@ var PANEL_CSS = String.raw`
118
123
  }
119
124
 
120
125
  /* DARK — the wine-and-brass board, now one toggle away instead of the default.
121
- Same structure, same shadows-as-depth logic, inverted ground. */
122
- :root[data-theme="dark"] {
126
+ Same structure, same shadows-as-depth logic, inverted ground.
127
+ Scoped to the panel's own root (not :root) for two reasons: the panel must
128
+ not read a HOST's data-theme as its own, and it must not write one either. */
129
+ .pnl[data-theme="dark"], .pnl-fatal[data-theme="dark"] {
123
130
  --bg: var(--wine);
124
131
  --bg-1: var(--plate);
125
132
  --bg-2: var(--wine2);
@@ -146,15 +153,19 @@ var PANEL_CSS = String.raw`
146
153
  --sh-2: 0 2px 4px rgba(0, 0, 0, .5), 0 16px 34px -18px rgba(0, 0, 0, .85);
147
154
  --sh-3: 0 4px 8px rgba(0, 0, 0, .5), 0 22px 48px -18px rgba(0, 0, 0, .9);
148
155
  }
149
- [data-theme="dark"] body { background: var(--wine); }
150
- [data-theme="dark"] .ag { background: linear-gradient(168deg, var(--plate-lift), #180e16); }
151
- [data-theme="dark"] .bar, [data-theme="dark"] .tabs { background: rgba(11, 5, 9, 0.72); }
152
- [data-theme="dark"] .rack .wt { background: #fff; border-color: transparent; }
153
- [data-theme="dark"] .pnl-stars { opacity: .45; }
156
+ /* The [data-theme="dark"] body rule that used to live here is GONE. A mounted
157
+ component has no business repainting its host's <body> — in Dionisos OS it
158
+ turned the cockpit's body white while the cards stayed dark, which is half of
159
+ what "split-brain" looked like. The standalone app paints its own body in
160
+ app/index.html, which is the page that actually owns it. */
161
+ .pnl[data-theme="dark"] .ag { background: linear-gradient(168deg, var(--plate-lift), #180e16); }
162
+ .pnl[data-theme="dark"] .bar, .pnl[data-theme="dark"] .tabs { background: rgba(11, 5, 9, 0.72); }
163
+ .pnl[data-theme="dark"] .rack .wt { background: #fff; border-color: transparent; }
164
+ .pnl[data-theme="dark"] .pnl-stars { opacity: .45; }
154
165
 
155
- * { box-sizing: border-box; }
156
- body { font-family: var(--font); color: var(--ink); background: var(--bg); overflow-x: hidden; }
166
+ .pnl, .pnl-fatal, .pnl *, .pnl-fatal * { box-sizing: border-box; }
157
167
 
168
+ .pnl, .pnl-fatal { font-family: var(--font); color: var(--ink); background: var(--bg); }
158
169
  .pnl { display: flex; flex-direction: column; position: relative; overflow: hidden; }
159
170
 
160
171
  /* the ground — warm wine light pooling from the top-left, exactly as the hero
@@ -1161,17 +1172,18 @@ function readTheme() {
1161
1172
  return "light";
1162
1173
  }
1163
1174
  }
1164
- function useTheme() {
1175
+ function useTheme(pinned) {
1165
1176
  const [theme, setTheme] = useState(readTheme);
1166
1177
  const chosen = useRef(false);
1167
1178
  useEffect(() => {
1168
- document.documentElement.setAttribute("data-theme", theme);
1179
+ if (pinned) return;
1169
1180
  if (!chosen.current) return;
1170
1181
  try {
1171
1182
  localStorage.setItem(THEME_KEY, theme);
1172
1183
  } catch {
1173
1184
  }
1174
- }, [theme]);
1185
+ }, [theme, pinned]);
1186
+ if (pinned) return [pinned, null];
1175
1187
  return [theme, () => {
1176
1188
  chosen.current = true;
1177
1189
  setTheme((t) => t === "dark" ? "light" : "dark");
@@ -2422,7 +2434,7 @@ function GraphScreen({ hasSnapshot }) {
2422
2434
  ] });
2423
2435
  return /* @__PURE__ */ jsx("div", { className: "graph-wrap", children: /* @__PURE__ */ jsx("iframe", { className: "graph-frame", src: "/view/?file=/snapshot.json", title: "Booboo 3D brain" }) });
2424
2436
  }
2425
- function App() {
2437
+ function App({ theme: pinnedTheme }) {
2426
2438
  const api = useApi();
2427
2439
  const [tab, param] = useRoute();
2428
2440
  const [saved, setSaved] = useState(null);
@@ -2553,11 +2565,11 @@ function App() {
2553
2565
  const nodeCount = useCountUp(stats?.nodes ?? 0, 1200);
2554
2566
  const memTotal = useCountUp(totals?.mem ?? 0, 1100);
2555
2567
  const repTotal = useCountUp(totals?.rep ?? 0, 1300);
2556
- const [theme, toggleTheme] = useTheme();
2568
+ const [theme, toggleTheme] = useTheme(pinnedTheme);
2557
2569
  const [showLaw, setShowLaw] = useState(false);
2558
- if (err && !draft) return /* @__PURE__ */ jsx("div", { className: "pnl-fatal", children: err });
2559
- if (!draft) return /* @__PURE__ */ jsx("div", { className: "pnl-fatal calm", children: "waking the organigram\u2026" });
2560
- return /* @__PURE__ */ jsxs("div", { className: "pnl", children: [
2570
+ if (err && !draft) return /* @__PURE__ */ jsx("div", { className: "pnl-fatal", "data-theme": theme, children: err });
2571
+ if (!draft) return /* @__PURE__ */ jsx("div", { className: "pnl-fatal calm", "data-theme": theme, children: "waking the organigram\u2026" });
2572
+ return /* @__PURE__ */ jsxs("div", { className: "pnl", "data-theme": theme, children: [
2561
2573
  /* @__PURE__ */ jsx("div", { className: "pnl-aurora", "aria-hidden": true }),
2562
2574
  /* @__PURE__ */ jsx(Constellation, {}),
2563
2575
  /* @__PURE__ */ jsxs("header", { className: "bar", children: [
@@ -2594,7 +2606,7 @@ function App() {
2594
2606
  children: "\u2696 show the law"
2595
2607
  }
2596
2608
  ),
2597
- /* @__PURE__ */ jsx("button", { className: "btn ghost theme-toggle", title: "light / dark", "aria-label": "toggle light or dark theme", onClick: toggleTheme, children: theme === "dark" ? "\u2600" : "\u263E" }),
2609
+ toggleTheme && /* @__PURE__ */ jsx("button", { className: "btn ghost theme-toggle", title: "light / dark", "aria-label": "toggle light or dark theme", onClick: toggleTheme, children: theme === "dark" ? "\u2600" : "\u263E" }),
2598
2610
  changes.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2599
2611
  /* @__PURE__ */ jsxs("span", { className: "bar-draft", children: [
2600
2612
  changes.length,
@@ -2653,17 +2665,17 @@ function App() {
2653
2665
  ] }, tab + (param ?? ""))
2654
2666
  ] });
2655
2667
  }
2656
- function Panel({ api = defaultApi } = {}) {
2668
+ function Panel({ api = defaultApi, theme } = {}) {
2657
2669
  return /* @__PURE__ */ jsxs(ApiCtx.Provider, { value: api, children: [
2658
2670
  /* @__PURE__ */ jsx("style", { children: PANEL_CSS }),
2659
- /* @__PURE__ */ jsx(App, {})
2671
+ /* @__PURE__ */ jsx(App, { theme })
2660
2672
  ] });
2661
2673
  }
2662
2674
 
2663
2675
  // package.json
2664
2676
  var package_default = {
2665
2677
  name: "@booboo-brain/panel",
2666
- version: "0.5.4",
2678
+ version: "0.5.5",
2667
2679
  description: "Booboo panel \u2014 the organigram. Run your agents like a company: a drag-drop hierarchy your agents boot from, with buckets, reports, rules and the 3D graph, over one org file + snapshot.",
2668
2680
  license: "MIT",
2669
2681
  repository: {