diff --git a/frontend/packages/swarm-ui/build.mjs b/frontend/packages/swarm-ui/build.mjs index 4e680219..7c4874cf 100644 --- a/frontend/packages/swarm-ui/build.mjs +++ b/frontend/packages/swarm-ui/build.mjs @@ -5,10 +5,17 @@ // dist/static/main.js served at /static/main.js (ESM bundle, // Preact + wouter-preact) // dist/static/main.js.map source map sibling +// dist/static/main.css every component's own `import +// './Foo.css'` (Shell.css, Panel.css, …), +// folded by esbuild into one companion +// output alongside main.js — no separate +// build step, this falls out of bundling +// main.tsx with `bundle: true` // dist/static/colors.css served at /static/colors.css // dist/static/theme.css served at /static/theme.css -// dist/static/swarm-ui.css served at /static/swarm-ui.css (@import -// resolved from @hive/shared) +// dist/static/swarm-ui.css served at /static/swarm-ui.css — just the +// shared base reset now (@import resolved +// from @hive/shared), NOT component styles // // Not yet wired into any Rust binary's `ServeDir` — swarm-controller // only serves `/health` today (see swarm-controller/README.md); this diff --git a/frontend/packages/swarm-ui/src/css.d.ts b/frontend/packages/swarm-ui/src/css.d.ts new file mode 100644 index 00000000..8597bb2b --- /dev/null +++ b/frontend/packages/swarm-ui/src/css.d.ts @@ -0,0 +1,4 @@ +// Ambient module for `import './Foo.css'` side-effect imports (esbuild +// resolves these directly, see build.mjs; tsc otherwise has no idea what +// a `.css` specifier is and refuses the whole side-effect import). +declare module '*.css'; diff --git a/frontend/packages/swarm-ui/src/index.html b/frontend/packages/swarm-ui/src/index.html index 9ed89442..6766527b 100644 --- a/frontend/packages/swarm-ui/src/index.html +++ b/frontend/packages/swarm-ui/src/index.html @@ -7,6 +7,7 @@ +
diff --git a/frontend/packages/swarm-ui/src/shell/Shell.tsx b/frontend/packages/swarm-ui/src/shell/Shell.tsx index 508d98f1..9a25878e 100644 --- a/frontend/packages/swarm-ui/src/shell/Shell.tsx +++ b/frontend/packages/swarm-ui/src/shell/Shell.tsx @@ -1,10 +1,12 @@ // — page chrome every swarm-ui route mounts inside: a header // bar (swarm branding) plus a nav row linking the app's real routes. -// Preact-native styling (shell/Shell.css, imported globally via -// ../swarm-ui.css) — deliberately not @hive/shared's chrome.css -// page-header pattern, which is the per-hive MPA dashboard's visual -// language. This package is a clean field, not an inheritor of that -// look. +// Preact-native styling — `./Shell.css` imported right here, not +// wired centrally, so the component and its styles travel together +// (esbuild folds every imported `.css` reachable from `main.tsx` into +// one `main.css` companion output, see build.mjs) — deliberately not +// @hive/shared's chrome.css page-header pattern, which is the per-hive +// MPA dashboard's visual language. This package is a clean field, not +// an inheritor of that look. // // Route list lives here, not prop-drilled from App — one small SPA // has exactly one place that needs to know its own nav, and this is @@ -12,6 +14,7 @@ // is next); no speculative entries. import type { ComponentChildren } from 'preact'; import { Link, useRoute } from 'wouter-preact'; +import './Shell.css'; const NAV_ITEMS: { href: string; label: string }[] = [{ href: '/', label: 'overview' }]; diff --git a/frontend/packages/swarm-ui/src/swarm-ui.css b/frontend/packages/swarm-ui/src/swarm-ui.css index c2f26b80..5289a7a2 100644 --- a/frontend/packages/swarm-ui/src/swarm-ui.css +++ b/frontend/packages/swarm-ui/src/swarm-ui.css @@ -1,5 +1,7 @@ +/* Page-level base only — component styles are colocated with their + component (`./Shell.css` imported by shell/Shell.tsx, etc.) and + land in the `main.css` companion esbuild emits alongside `main.js` + (see build.mjs), not here. This file stays just the shared reset + every page needs regardless of which components a route happens to + use. */ @import "@hive/shared/base.css"; -@import "./shell/Shell.css"; -@import "./ui/panel/Panel.css"; -@import "./ui/status-chip/StatusChip.css"; -@import "./ui/table/Table.css"; diff --git a/frontend/packages/swarm-ui/src/ui/panel/Panel.tsx b/frontend/packages/swarm-ui/src/ui/panel/Panel.tsx index 8998a1e8..de8f88db 100644 --- a/frontend/packages/swarm-ui/src/ui/panel/Panel.tsx +++ b/frontend/packages/swarm-ui/src/ui/panel/Panel.tsx @@ -3,6 +3,7 @@ // card-with-actions/footer/whatever kit — those get added the first // time a real page actually needs one, not speculatively ahead of it. import type { ComponentChildren } from 'preact'; +import './Panel.css'; export function Panel({ title, children }: { title?: string; children: ComponentChildren }) { return ( diff --git a/frontend/packages/swarm-ui/src/ui/status-chip/StatusChip.tsx b/frontend/packages/swarm-ui/src/ui/status-chip/StatusChip.tsx index d83ad6b8..354c9459 100644 --- a/frontend/packages/swarm-ui/src/ui/status-chip/StatusChip.tsx +++ b/frontend/packages/swarm-ui/src/ui/status-chip/StatusChip.tsx @@ -4,6 +4,8 @@ // single static "configured" tone and grows real online/stale/offline // states once a status rollup lands server-side — same component, // richer data later, no rebuild. +import './StatusChip.css'; + export type ChipTone = 'neutral' | 'positive' | 'warning' | 'negative'; export function StatusChip({ tone = 'neutral', label }: { tone?: ChipTone; label: string }) { diff --git a/frontend/packages/swarm-ui/src/ui/table/Table.tsx b/frontend/packages/swarm-ui/src/ui/table/Table.tsx index 402953a7..3e852063 100644 --- a/frontend/packages/swarm-ui/src/ui/table/Table.tsx +++ b/frontend/packages/swarm-ui/src/ui/table/Table.tsx @@ -4,6 +4,7 @@ // any particular row shape, so it stays reusable for the swarm-wide // agent roster later without a rewrite. import type { ComponentChildren } from 'preact'; +import './Table.css'; export interface TableColumn { key: string;