diff --git a/design/build-shadow-css.ts b/design/build-shadow-css.ts index 68f410d84..c68f86082 100644 --- a/design/build-shadow-css.ts +++ b/design/build-shadow-css.ts @@ -26,7 +26,7 @@ export interface BuildShadowCssOptions { /** * Absolute path to the primary-ramp override stylesheet, appended AFTER * the UnoCSS output so its `:host`/`:root, :host` block wins over Wind's - * own primary declarations (see each package's `primary-ramp.css`). + * own primary declarations (the shared `design/primary-ramp.css`). */ primaryRampPath: string /** diff --git a/design/panel-theme.ts b/design/panel-theme.ts new file mode 100644 index 000000000..79cd81a48 --- /dev/null +++ b/design/panel-theme.ts @@ -0,0 +1,35 @@ +import type { DevframeBranding } from '../packages/hub-ui/src/types' +import { setupDevframeConnection } from 'devframe/client' + +/** Apply startup branding to a built-in devframe's iframe SPA. */ +export function applyPanelBranding(): () => void { + if (window.parent === window) + return () => {} + + const root = document.documentElement + const previous = root.style.getPropertyValue('--devframe-primary') + const priority = root.style.getPropertyPriority('--devframe-primary') + let disposed = false + let applied = false + + void setupDevframeConnection().then(({ connectionMeta }) => { + const configs = connectionMeta.configs as { ui?: { branding?: DevframeBranding } } | undefined + const color = configs?.ui?.branding?.primaryColor + if (disposed || !color || !CSS.supports('color', color)) + return + root.style.setProperty('--devframe-primary', color) + applied = true + }).catch(() => { + // Connection failures leave the SPA's default palette intact. + }) + + return () => { + disposed = true + if (!applied) + return + if (previous) + root.style.setProperty('--devframe-primary', previous, priority) + else + root.style.removeProperty('--devframe-primary') + } +} diff --git a/packages/hub-ui/src/client/primary-ramp.css b/design/primary-ramp.css similarity index 52% rename from packages/hub-ui/src/client/primary-ramp.css rename to design/primary-ramp.css index d8c5cf57c..bf05c5eee 100644 --- a/packages/hub-ui/src/client/primary-ramp.css +++ b/design/primary-ramp.css @@ -1,9 +1,11 @@ /* - * Primary color as a single overridable variable: `--devframe-primary`. - * - * Appended AFTER the UnoCSS output (see `scripts/build-css.ts`) so this block - * wins over Wind3's own `:root, :host` primary declarations, and imported after - * `virtual:uno.css` in the Storybook preview for the same reason. + * Primary color as a single overridable variable: `--devframe-primary`. Shared + * by every devframe surface: appended after each shadow-root build's UnoCSS + * output (the hub-ui dock, the json-render renderer module; see + * `build-shadow-css.ts`), imported last by every built-in devframe panel SPA so + * it inherits a rebranded hub's accent, and imported after `virtual:uno.css` in + * the hub-ui Storybook preview. It always wins over Wind's own `:root, :host` + * primary declarations because it comes last. * * Each stop (`--colors-primary-*`) is derived from `--devframe-primary` via * `color-mix`. When `--devframe-primary` is unset, the intermediate @@ -11,28 +13,31 @@ * references an unset var with no fallback), so each `--colors-primary-` * falls back to the exact devframe default hex; the default look is preserved, * and only an explicit override derives a new ramp. The vars inherit through - * the tree, so setting `--devframe-primary` on the dock host retints - * everything, and setting it on a group's chrome container retints just that - * group (the group-accent mechanism). + * the tree, so setting `--devframe-primary` on a host (the dock host, a viewer + * mount container, or a panel's ``) retints everything below it, and + * setting it on a group's chrome container retints just that group (the + * group-accent mechanism). * - * The dock's shadow root is built on Wind3, which bakes `primary`-based - * utilities (`text-primary`, `bg-primary`, `btn-primary`, `ring-primary-500`, - * …) to literal `rgb()` triplets rather than referencing these variables, so - * `scripts/build-css.ts` rewires those baked colors into CSS relative-color - * syntax reading `--colors-primary-` (see `rewireBakedPrimaryColors` in - * `design/uno.config.ts`) so this block actually retints them, not just the - * handful of rules (the glow gradient below) that reference the variables - * directly. The stops declared here (`DEFAULT`/`600`/`500`/`400`/`300`) must - * match `OVERRIDABLE_PRIMARY_STOPS` there. + * A shadow root built on Wind3 bakes `primary`-based utilities (`text-primary`, + * `bg-primary`, `btn-primary`, `ring-primary-500`, …) to literal `rgb()` + * triplets rather than referencing these variables, so `build-shadow-css.ts` + * rewires those baked colors into CSS relative-color syntax reading + * `--colors-primary-` (see `rewireBakedPrimaryColors` in `uno.config.ts`) + * so this block actually retints them, not just the handful of rules (the dock's + * glow gradient) that reference the variables directly. The stops declared here + * (`DEFAULT`/`600`/`500`/`400`/`300`) must match `OVERRIDABLE_PRIMARY_STOPS` + * there. * - * `:host` is the effective selector inside the dock's shadow root; `:root` is - * for the light-DOM Storybook preview (it matches nothing in the shadow root). + * `:host` is the effective selector inside a shadow root; `:root` is for the + * light-DOM panel SPAs and the Storybook preview (it matches nothing in a + * shadow root). * * `.devframes-accent-scope` re-declares the whole block on a group's chrome * container: because custom properties inherit as computed values, a descendant * that only overrides `--devframe-primary` would keep the `:host`-computed * stops; re-running the derivation here recomputes them from the container's * own `--devframe-primary` (a group's `accentColor`), retinting just that group. + * Inert on surfaces that never apply the class. */ :root, :host, diff --git a/design/uno.config.ts b/design/uno.config.ts index 297cad0a4..5529c656a 100644 --- a/design/uno.config.ts +++ b/design/uno.config.ts @@ -1,6 +1,6 @@ import type { Preset } from 'unocss' import { fileURLToPath } from 'node:url' -import { presetAnthonyDesign } from '@antfu/design/unocss' +import { presetAnthonyDesign, resolvePrimary } from '@antfu/design/unocss' import { defineConfig, presetIcons, @@ -60,7 +60,16 @@ export function createDesignConfig(options: CreateDesignConfigOptions = {}) { * shared border color (matching `border-base`) for unqualified borders. */ preflights: [{ getCSS: () => '*,::before,::after{border-color:#8882}' }], + theme: { + // Stable palette for status marks and preview content that intentionally + // keeps the default accent when the surrounding panel adopts a theme. + colors: { devframe: resolvePrimary('#3a6a45') }, + }, shortcuts: { + /** Fixed semantic colors stay independent of the panel's primary accent. */ + 'color-status-positive': 'color-devframe-600 dark:color-devframe-300', + 'color-preview-accent': 'color-devframe-600 dark:color-devframe-300', + 'bg-preview-accent': 'bg-devframe', /** Fixed navbar height, shared by every surface's top nav. */ 'h-nav': 'h-10', /** Named z-index layers, shared across every surface. */ @@ -131,8 +140,8 @@ export const shadowSurfaceSafelist: string[] = [ ] /** - * The primary-ramp stops a shadow-root surface's `primary-ramp.css` exposes - * as overridable `--colors-primary-` custom properties (derived from + * The primary-ramp stops the shared `design/primary-ramp.css` exposes as + * overridable `--colors-primary-` custom properties (derived from * `--devframe-primary`). Must match that file's declarations exactly. */ const OVERRIDABLE_PRIMARY_STOPS = ['DEFAULT', '600', '500', '400', '300'] as const diff --git a/docs/content/1.guide/18.hub-initiate.md b/docs/content/1.guide/18.hub-initiate.md index bfbd648cf..9fc32d826 100644 --- a/docs/content/1.guide/18.hub-initiate.md +++ b/docs/content/1.guide/18.hub-initiate.md @@ -53,7 +53,7 @@ interface DevframeHubUi { `@devframes/hub-ui`'s `createUi()` is the reference (standalone `viewer` SPA + floating dock); its `setup(ctx)` publishes config to `ctx.staticConfig.ui` (`ConnectionMeta.configs.ui`): - **`viewer`**: set to `false` to disable the standalone viewer. -- **`branding`**: rebrand the UI (logo, name, primary color). `background` accepts any CSS `background` value (color, gradient, image, or `transparent`) or `{ light, dark }` variants. These flat forms apply everywhere. Use `{ standalone, iframe? }` to specialize the framed viewer; an omitted `iframe` value falls back to `standalone`. +- **`branding`**: rebrand the UI (logo, name, primary color). `background` accepts any CSS `background` value (color, gradient, image, or `transparent`) or `{ light, dark }` variants. These flat forms apply everywhere. Use `{ standalone, iframe? }` to specialize the framed viewer; an omitted `iframe` value falls back to `standalone`. Built-in devframe panels read `branding.primaryColor` from the existing connection metadata at startup and map it to CSS primary tokens. Standalone SPAs keep their default accent; status and preview palettes remain independent. Reload panels after changing startup branding. - **`dockPreferences`** tunes the dock rail: `categoryOrder`, floating-dock `maxVisibleItems`, first-run `defaultMode` (`'float'`/`'edge'`) and `defaultPosition`. - **`embeddedVisibility`** sets the floating dock's reveal policy: - `'normal'` (default): shows immediately. diff --git a/examples/hub-deno/src/hub.ts b/examples/hub-deno/src/hub.ts index 0bd51cc01..cb1a3b958 100644 --- a/examples/hub-deno/src/hub.ts +++ b/examples/hub-deno/src/hub.ts @@ -40,7 +40,7 @@ export const hub: HubInstance = globalRef.__hubDenoMinimal ??= initHub({ * Rebrand the reference UI to Deno's own navy in one field, no CSS: * `createUi`'s `branding` option publishes `ConnectionMeta.configs.ui.branding`, * which the dock reads at connect time and feeds into `--devframe-primary` - * (see `@devframes/hub-ui`'s `primary-ramp.css`). + * (see the shared `design/primary-ramp.css`). */ ui: createUi({ branding: { primaryColor: '#70ffaf', productName: 'Devframes on Deno' } }), /** diff --git a/examples/hub-fastify/src/hub.ts b/examples/hub-fastify/src/hub.ts index eb01e5166..4b1ffe6eb 100644 --- a/examples/hub-fastify/src/hub.ts +++ b/examples/hub-fastify/src/hub.ts @@ -40,7 +40,7 @@ export const hub: HubInstance = globalRef.__hubFastifyMinimal ??= initHub({ * Rebrand the reference UI to Fastify's own black in one field, no CSS: * `createUi`'s `branding` option publishes `ConnectionMeta.configs.ui.branding`, * which the dock reads at connect time and feeds into `--devframe-primary` - * (see `@devframes/hub-ui`'s `primary-ramp.css`). + * (see the shared `design/primary-ramp.css`). */ ui: createUi({ branding: { primaryColor: '#2f2f2f', productName: 'Devframes on Fastify' } }), /** diff --git a/examples/hub-hono/src/app.ts b/examples/hub-hono/src/app.ts index 125ac97c5..bf692caa7 100644 --- a/examples/hub-hono/src/app.ts +++ b/examples/hub-hono/src/app.ts @@ -43,7 +43,7 @@ export const hub: HubInstance = globalRef.__hubHonoMinimal ??= initHub({ * Rebrand the reference UI to Hono's own orange in one field, no CSS: * `createUi`'s `branding` option publishes `ConnectionMeta.configs.ui.branding`, * which the dock reads at connect time and feeds into `--devframe-primary` - * (see `@devframes/hub-ui`'s `primary-ramp.css`). + * (see the shared `design/primary-ramp.css`). */ ui: createUi({ branding: { primaryColor: '#e36002', productName: 'Devframes on Hono' } }), /** diff --git a/examples/hub-next/src/client/hub.ts b/examples/hub-next/src/client/hub.ts index e3e8012a0..72b6d789c 100644 --- a/examples/hub-next/src/client/hub.ts +++ b/examples/hub-next/src/client/hub.ts @@ -65,7 +65,7 @@ async function loadHub(): Promise { // `@devframes/next/hub` runs the socket on a side-car (Next routes can't // accept WS upgrades). `createUi`'s `branding` option rebrands the dock via // `ConnectionMeta.configs.ui.branding`, read at connect time and fed into - // `--devframe-primary` (see `@devframes/hub-ui`'s `primary-ramp.css`). + // `--devframe-primary` (see the shared `design/primary-ramp.css`). return createNextDevframeHub({ devframes, ui: (hubUi.createUi as typeof CreateUi)({ branding: { primaryColor: '#3f8ba9', productName: 'Devframes on Next.js' } }), diff --git a/examples/hub-nitro/hub.ts b/examples/hub-nitro/hub.ts index 8e6b04642..bdaa1b7c8 100644 --- a/examples/hub-nitro/hub.ts +++ b/examples/hub-nitro/hub.ts @@ -41,7 +41,7 @@ export const hub: HubInstance = globalRef.__hubNitroMinimal ??= initHub({ * Rebrand the reference UI to Nitro's own pink/red in one field, no CSS: * `createUi`'s `branding` option publishes `ConnectionMeta.configs.ui.branding`, * which the dock reads at connect time and feeds into `--devframe-primary` - * (see `@devframes/hub-ui`'s `primary-ramp.css`). + * (see the shared `design/primary-ramp.css`). */ ui: createUi({ branding: { primaryColor: '#ff2056', productName: 'Devframes on Nitro' } }), /** diff --git a/examples/hub-rsbuild/rsbuild.config.ts b/examples/hub-rsbuild/rsbuild.config.ts index 58281f0a2..b8e2b0eb8 100644 --- a/examples/hub-rsbuild/rsbuild.config.ts +++ b/examples/hub-rsbuild/rsbuild.config.ts @@ -79,7 +79,7 @@ export default defineConfig({ * CSS: `createUi`'s `branding` option publishes * `ConnectionMeta.configs.ui.branding`, which the dock reads at * connect time and feeds into `--devframe-primary` (see - * `@devframes/hub-ui`'s `primary-ramp.css`). + * the shared `design/primary-ramp.css`). */ ui: createUi({ branding: { primaryColor: '#ff5e00', productName: 'Devframes on Rsbuild' } }), /** diff --git a/examples/hub-sveltekit/src/hub.ts b/examples/hub-sveltekit/src/hub.ts index 25ad63475..c698339b6 100644 --- a/examples/hub-sveltekit/src/hub.ts +++ b/examples/hub-sveltekit/src/hub.ts @@ -41,7 +41,7 @@ export const hub: HubInstance = globalRef.__hubSvelteKitMinimal ??= initHub({ * Rebrand the reference UI to Svelte's own orange in one field, no CSS: * `createUi`'s `branding` option publishes `ConnectionMeta.configs.ui.branding`, * which the dock reads at connect time and feeds into `--devframe-primary` - * (see `@devframes/hub-ui`'s `primary-ramp.css`). + * (see the shared `design/primary-ramp.css`). */ ui: createUi({ branding: { primaryColor: '#ff3e00', productName: 'Devframes on SvelteKit' } }), /** diff --git a/examples/hub-vite/vite.config.ts b/examples/hub-vite/vite.config.ts index 0e524826c..c1e29392d 100644 --- a/examples/hub-vite/vite.config.ts +++ b/examples/hub-vite/vite.config.ts @@ -83,7 +83,7 @@ export default defineConfig({ * Rebrand the reference UI to Vite's own purple in one field, no CSS: * `createUi`'s `branding` option publishes `ConnectionMeta.configs.ui.branding`, * which the dock reads at connect time and feeds into `--devframe-primary` - * (see `@devframes/hub-ui`'s `primary-ramp.css`). Passing `ui` overrides + * (see the shared `design/primary-ramp.css`). Passing `ui` overrides * the default `createUi()` the plugin would otherwise use. */ ui: createUi({ branding: { primaryColor: '#646cff', productName: 'Devframes on Vite' } }), diff --git a/packages/hub-ui/.storybook/preview.ts b/packages/hub-ui/.storybook/preview.ts index 20baf8de2..45cacd0f2 100644 --- a/packages/hub-ui/.storybook/preview.ts +++ b/packages/hub-ui/.storybook/preview.ts @@ -6,7 +6,7 @@ import 'virtual:uno.css' import '@antfu/design/styles.css' import '../src/client/style.css' // After uno so the primary-ramp override wins, matching the shadow-root build. -import '../src/client/primary-ramp.css' +import '../../../design/primary-ramp.css' // Drive the shared `@antfu/design` tokens off the toolbar theme toggle: dark mode // is the `.dark` class on ``, and the canvas takes the semantic diff --git a/packages/hub-ui/scripts/build-css.ts b/packages/hub-ui/scripts/build-css.ts index 213ab1d56..6c19d6147 100644 --- a/packages/hub-ui/scripts/build-css.ts +++ b/packages/hub-ui/scripts/build-css.ts @@ -13,7 +13,7 @@ const { sourceCount, css } = await buildShadowCss({ srcDir: SRC_DIR, globs: ['components/**/*.{ts,vue}', 'state/**/*.ts', 'embedded/**/*.ts', 'standalone/**/*.{ts,html}'], config, - primaryRampPath: join(SRC_DIR, 'primary-ramp.css'), + primaryRampPath: fileURLToPath(new URL('../../../design/primary-ramp.css', import.meta.url)), userStylePath: join(SRC_DIR, 'style.css'), varPrefix: '--un-hub-', }) diff --git a/packages/json-render-ui/scripts/build-css.ts b/packages/json-render-ui/scripts/build-css.ts index e940952b7..2f0987cc0 100644 --- a/packages/json-render-ui/scripts/build-css.ts +++ b/packages/json-render-ui/scripts/build-css.ts @@ -16,7 +16,7 @@ const { sourceCount, css } = await buildShadowCss({ srcDir: SRC_DIR, globs: ['components/**/*.ts', 'renderer.ts', 'dock-renderer.ts', 'renderer-module/**/*.ts'], config, - primaryRampPath: join(SRC_DIR, 'renderer-module/primary-ramp.css'), + primaryRampPath: fileURLToPath(new URL('../../../design/primary-ramp.css', import.meta.url)), userStylePath: [ moduleRequire.resolve('@antfu/design/styles/scrollbar.css'), join(SRC_DIR, 'renderer-module/style.css'), diff --git a/packages/json-render-ui/src/renderer-module/primary-ramp.css b/packages/json-render-ui/src/renderer-module/primary-ramp.css deleted file mode 100644 index 0de6de26c..000000000 --- a/packages/json-render-ui/src/renderer-module/primary-ramp.css +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Primary color as a single overridable variable: `--devframe-primary`. - * - * Mirrors `@devframes/hub-ui`'s ramp (see its `src/client/primary-ramp.css` - * for the full derivation notes): each stop (`--colors-primary-*`) is - * derived from `--devframe-primary` via `color-mix`, falling back to the - * devframe default sage green when it is unset. - * - * Appended AFTER the UnoCSS output (see `scripts/build-css.ts`) so this block - * wins over Wind3's own `:root, :host` primary declarations. `:host` is the - * effective selector inside the renderer module's shadow root, whose host is - * the viewer-owned mount container, and `--devframe-primary` (set by a - * viewer's branding on any ancestor) inherits across the shadow boundary onto - * it, so a rebranded hub retints the rendered views too. - * - * The renderer module's shadow root is built on Wind3, which bakes - * `primary`-based utilities to literal `rgb()` triplets rather than - * referencing these variables, so `scripts/build-css.ts` rewires those baked - * colors into CSS relative-color syntax reading `--colors-primary-` - * (see `rewireBakedPrimaryColors` in `design/uno.config.ts`) so this block - * actually retints them. The stops declared here (`DEFAULT`/`600`/`500`/ - * `400`/`300`) must match `OVERRIDABLE_PRIMARY_STOPS` there. - */ -:root, -:host { - --devframe-primary-DEFAULT: var(--devframe-primary); - --devframe-primary-600: color-mix(in oklab, var(--devframe-primary), white 9%); - --devframe-primary-500: color-mix(in oklab, var(--devframe-primary), white 18%); - --devframe-primary-400: color-mix(in oklab, var(--devframe-primary), white 34%); - --devframe-primary-300: color-mix(in oklab, var(--devframe-primary), white 54%); - - --colors-primary-DEFAULT: var(--devframe-primary-DEFAULT, #3a6a45); - --colors-primary-600: var(--devframe-primary-600, #40704b); - --colors-primary-500: var(--devframe-primary-500, #578861); - --colors-primary-400: var(--devframe-primary-400, #75a67e); - --colors-primary-300: var(--devframe-primary-300, #93c69d); -} diff --git a/plugins/a11y/app/main.tsx b/plugins/a11y/app/main.tsx index 4463c0610..3b7069ee5 100644 --- a/plugins/a11y/app/main.tsx +++ b/plugins/a11y/app/main.tsx @@ -1,9 +1,14 @@ +/// + /* @refresh reload */ + import { render } from 'solid-js/web' +import { applyPanelBranding } from '../../../design/panel-theme' import { App } from './app.tsx' import 'virtual:uno.css' import '@antfu/design/styles.css' import './styles.css' +import '../../../design/primary-ramp.css' // Shared design tokens flip on the `.dark` class; mirror the OS preference onto // (the other devframe plugins follow the same approach). @@ -20,3 +25,6 @@ if (!root) throw new Error('#app mount node missing from index.html') render(() => , root) + +const stopPanelTheme = applyPanelBranding() +import.meta.hot?.dispose(stopPanelTheme) diff --git a/plugins/assets/app/main.ts b/plugins/assets/app/main.ts index 63d704e3f..b89b69a7d 100644 --- a/plugins/assets/app/main.ts +++ b/plugins/assets/app/main.ts @@ -1,8 +1,10 @@ import { createApp } from 'vue' +import { applyPanelBranding } from '../../../design/panel-theme' import App from './app/App.vue' import 'virtual:uno.css' import 'floating-vue/dist/style.css' import '@antfu/design/styles.css' +import '../../../design/primary-ramp.css' // Shared design tokens flip on the `.dark` class; mirror the OS preference // onto (the built-in devframe plugins all follow this approach). @@ -15,3 +17,6 @@ applyScheme(mq.matches) mq.addEventListener('change', e => applyScheme(e.matches)) createApp(App).mount('#app') + +const stopPanelTheme = applyPanelBranding() +import.meta.hot?.dispose(stopPanelTheme) diff --git a/plugins/code-server/app/main.ts b/plugins/code-server/app/main.ts index e6b23a3f3..11ef18057 100644 --- a/plugins/code-server/app/main.ts +++ b/plugins/code-server/app/main.ts @@ -1,8 +1,12 @@ +/// + import { createApp } from 'vue' +import { applyPanelBranding } from '../../../design/panel-theme' import App from './App.vue' import 'virtual:uno.css' import '@antfu/design/styles.css' import './style.css' +import '../../../design/primary-ramp.css' // The shared design tokens flip on the `.dark` class; mirror the OS preference // onto (the other devframe plugins follow the same approach). @@ -15,3 +19,6 @@ applyScheme(mq.matches) mq.addEventListener('change', e => applyScheme(e.matches)) createApp(App).mount('#app') + +const stopPanelTheme = applyPanelBranding() +import.meta.hot?.dispose(stopPanelTheme) diff --git a/plugins/data-inspector/app/components/QueryEditor.vue b/plugins/data-inspector/app/components/QueryEditor.vue index e084aa8c5..e7d0c87a0 100644 --- a/plugins/data-inspector/app/components/QueryEditor.vue +++ b/plugins/data-inspector/app/components/QueryEditor.vue @@ -366,7 +366,7 @@ ul.discovery-view-editor-hints-popup { --at-apply: 'bg-#8882 color-active'; } .discovery-view-editor-hint .match { - --at-apply: 'color-primary-700 dark:color-primary-300'; + --at-apply: 'color-active'; font-weight: 600; } .discovery-view-editor-hint::before { diff --git a/plugins/data-inspector/app/main.ts b/plugins/data-inspector/app/main.ts index 6b3cb9934..7ab6eb803 100644 --- a/plugins/data-inspector/app/main.ts +++ b/plugins/data-inspector/app/main.ts @@ -1,4 +1,7 @@ +/// + import { createApp } from 'vue' +import { applyPanelBranding } from '../../../design/panel-theme' import App from './App.vue' import 'virtual:uno.css' // floating-vue's base popper/transition structure, then @antfu/design's themed @@ -8,5 +11,9 @@ import 'floating-vue/dist/style.css' import '@antfu/design/styles/floating-vue.css' import '@antfu/design/styles.css' import './style.css' +import '../../../design/primary-ramp.css' createApp(App).mount('#app') + +const stopPanelTheme = applyPanelBranding() +import.meta.hot?.dispose(stopPanelTheme) diff --git a/plugins/git/app/app/layout.tsx b/plugins/git/app/app/layout.tsx index 39b7b2e1e..56f516fb7 100644 --- a/plugins/git/app/app/layout.tsx +++ b/plugins/git/app/app/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata } from 'next' import type { ReactNode } from 'react' import './globals.css' import '@antfu/design/styles.css' +import '../../../../design/primary-ramp.css' export const metadata: Metadata = { title: 'Git Dashboard', diff --git a/plugins/git/app/components/theme.ts b/plugins/git/app/components/theme.ts index 39f6fa854..9e822cb47 100644 --- a/plugins/git/app/components/theme.ts +++ b/plugins/git/app/components/theme.ts @@ -1,6 +1,7 @@ 'use client' import { useEffect, useState } from 'react' +import { applyPanelBranding } from '../../../../design/panel-theme' export type Theme = 'light' | 'dark' @@ -28,6 +29,8 @@ function systemTheme(): Theme { export function useTheme() { const [theme, setTheme] = useState('dark') + useEffect(() => applyPanelBranding(), []) + useEffect(() => { setTheme(readStored() ?? systemTheme()) }, []) diff --git a/plugins/git/app/components/ui/status-mark.tsx b/plugins/git/app/components/ui/status-mark.tsx index 0bdee2ac0..08db8e726 100644 --- a/plugins/git/app/components/ui/status-mark.tsx +++ b/plugins/git/app/components/ui/status-mark.tsx @@ -20,8 +20,8 @@ const STATUS_COLOR: Record = { 'added': 'text-success', 'deleted': 'text-error', 'modified': 'text-warning', - 'renamed': 'color-active', - 'copied': 'color-active', + 'renamed': 'color-status-positive', + 'copied': 'color-status-positive', 'type-changed': 'text-warning', 'unmerged': 'text-error', 'unknown': 'color-muted', diff --git a/plugins/inspect/app/main.ts b/plugins/inspect/app/main.ts index 1894611c0..9e153dd40 100644 --- a/plugins/inspect/app/main.ts +++ b/plugins/inspect/app/main.ts @@ -1,9 +1,13 @@ +/// + import { createApp } from 'vue' +import { applyPanelBranding } from '../../../design/panel-theme' import App from './App.vue' import 'virtual:uno.css' import 'floating-vue/dist/style.css' import '@antfu/design/styles.css' import './style.css' +import '../../../design/primary-ramp.css' // The shared design tokens flip on the `.dark` class; mirror the OS preference // onto (the other devframe plugins follow the same approach). @@ -16,3 +20,6 @@ applyScheme(mq.matches) mq.addEventListener('change', e => applyScheme(e.matches)) createApp(App).mount('#app') + +const stopPanelTheme = applyPanelBranding() +import.meta.hot?.dispose(stopPanelTheme) diff --git a/plugins/messages/app/main.ts b/plugins/messages/app/main.ts index 1a314e3d0..302cefd62 100644 --- a/plugins/messages/app/main.ts +++ b/plugins/messages/app/main.ts @@ -1,4 +1,8 @@ +/// + +import { applyPanelBranding } from '../../../design/panel-theme' import { mountMessages } from './client/index' +import '../../../design/primary-ramp.css' // The shared design tokens flip on the `.dark` class; mirror the OS preference // onto (the other devframe plugins follow the same approach). The @@ -19,3 +23,6 @@ if (!app) mountMessages(app).catch((error) => { app.textContent = `Failed to connect: ${error instanceof Error ? error.message : String(error)}` }) + +const stopPanelTheme = applyPanelBranding() +import.meta.hot?.dispose(stopPanelTheme) diff --git a/plugins/og/app/app/app.vue b/plugins/og/app/app/app.vue index 0f10f9965..3f2ca6dcf 100644 --- a/plugins/og/app/app/app.vue +++ b/plugins/og/app/app/app.vue @@ -49,7 +49,7 @@ onMounted(() => viewer.inspect())
- + {{ viewer.snapshot.value.url }} diff --git a/plugins/og/app/app/components/previews/TelegramPreview.vue b/plugins/og/app/app/components/previews/TelegramPreview.vue index 107b4ac84..ee6ad7999 100644 --- a/plugins/og/app/app/components/previews/TelegramPreview.vue +++ b/plugins/og/app/app/components/previews/TelegramPreview.vue @@ -11,12 +11,12 @@ const time = new Intl.DateTimeFormat(undefined, { hour: '2-digit', minute: '2-di