diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f20278665..e5ea33473 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -148,6 +148,9 @@ jobs: - uses: ./.github/actions/setup-bun + - name: Validate generated brand assets + run: bun run check:icons + - name: Validate translations run: bun run check:i18n @@ -213,6 +216,9 @@ jobs: - name: Typecheck native interaction tests run: bun run check:native-test + - name: Generate native brand assets + run: bun run generate:icons --target desktop + - name: Compile native-test Tauri feature run: cargo check --manifest-path desktop/Cargo.toml --features native-test diff --git a/.gitignore b/.gitignore index 1497de180..07baf89fc 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,17 @@ storybook-static/ /desktop/*.key !/desktop/*.key.pub +# Generated from assets/brand by tools/brand (never hand-edit these outputs) +/.cache/brand/ +/.cache/brand.lock/ +/public/brand/ +/public/favicon.ico +/public/apple-touch-icon.png +/packages/docs/public/brand/ +/packages/docs/public/favicon.ico +/packages/docs/public/apple-touch-icon.png +/desktop/icons/ + # Copied from node_modules at build time public/canvaskit.wasm public/canvaskit-webgpu/ diff --git a/.storybook/main.ts b/.storybook/main.ts index d3bbd3d3a..de11eeb79 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,11 +1,16 @@ import type { StorybookConfig } from '@storybook/vue3-vite' import type { PluginOption } from 'vite' +import { ensureBrandAssets } from '@open-pencil/brand-tools' + function flattenPlugins(plugins: PluginOption[]): PluginOption[] { return plugins.flatMap((plugin) => (Array.isArray(plugin) ? flattenPlugins(plugin) : [plugin])) } +await ensureBrandAssets(['web']) + const config: StorybookConfig = { + staticDirs: ['../public'], stories: ['../src/**/*.stories.@(js|ts)', '../packages/vue/src/**/*.stories.@(js|ts)'], addons: ['@storybook/addon-docs', '@storybook/addon-a11y', '@storybook/addon-themes'], framework: { diff --git a/AGENTS.md b/AGENTS.md index 0c75e5f75..8910fb828 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -158,6 +158,10 @@ PR titles use Conventional Commits because GitHub uses them as merge subjects. T - Component domains use lowercase/kebab-case folders; Vue files stay PascalCase and component composables camelCase. Do not add new PascalCase app folders or root-level base controls; migrate old ones when touched. - Non-component folders/files use lowercase or kebab-case except standard entrypoints. Group multi-file domains in subfolders instead of repeated sibling prefixes (`selection/container.ts`, not `selection-container.ts`). +### Brand assets + +Canonical brand artwork lives in `assets/brand/`: the main mark and an optical micro master. `tools/brand/` derives web/docs/native icons locally with RealFaviconGenerator and Tauri; generated assets are ignored, not committed. Vite/VitePress configs prepare their own targets, and Tauri dev/build hooks prepare native icons. Direct Cargo checks must run `bun run generate:icons --target desktop` first. Keep the app manifest in `vite/pwa.ts`, use `BrandMark` for in-app branding, and never symlink web assets to desktop icons. See `assets/brand/README.md` for commands and output ownership. + ### Repo tools and scripts Private tooling belongs under `tools//{src,tests}`, with kebab-case domains and focused tests. `scripts/` may contain only tiny compatibility entrypoints; put real workflow, release, architecture, package, or visual tooling in `tools/`. diff --git a/CHANGELOG.md b/CHANGELOG.md index ed9dde2ec..54b4b843c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ ### Changed +- Refresh the OpenPencil mark across the editor, documentation, browser tabs, installed web apps, and desktop icons, with small-size and dark-background adaptations. - Explore editable component, typography, and paint comparisons in the demo, with the original examples preserved on a reference page. - Use compact desktop Home search actions with consistent responsive layout and control sizing. - Keep pixel-grid rounding invisible while showing alignment guides only for real geometry, objects, and canvas/layout guides. diff --git a/assets/brand/README.md b/assets/brand/README.md new file mode 100644 index 000000000..155666ca1 --- /dev/null +++ b/assets/brand/README.md @@ -0,0 +1,35 @@ +# OpenPencil brand sources + +- `mark.svg` is the teal pencil-P master: a long pointed stem, contrasting teal blocks, a faint clipped pixel grid, and white editing handles with blue borders (`#005CFF`). The square sits at the top-left; the circle sits on the outer curve. +- `mark-micro.svg` renders at 16px and preserves the main P's geometry and proportions. Its square and circular handles are enlarged for small sizes, with the circle slightly larger than the square. It has no grid. +- Both use the same tight `28 28 228 228` viewBox. Keep the P geometry aligned between masters; optical adjustments belong to the handles, not the letter's proportions. +- Both use real transparent counters and no white outline. Preserve the `data-part` attributes used for derived dark and monochrome artwork. +- Dark artwork has its own brighter teal palette, lighter blue borders, soft-white handle centers, and a subtler grid. Monochrome artwork omits the grid. + +Edit these SVGs, not generated files. Platform backgrounds, padding, and dark colors live in `tools/brand/src/config.ts`. The approved main colors are defined by the SVG artwork. The official app-icon variant puts the light-palette mark on an ivory (`#F5F5EF`) rounded tile that fills the image, with transparency only at the rounded corners. Native desktop assets retain their platform-specific outer margin. Desktop icons, any-purpose PWA icons, and larger in-app branding share this composition. The tile stays ivory in both themes; use `BrandMark` with `variant="app-icon"` for larger placements. The editor header uses a 24px tile. Favicons use the same tile with the optical micro master inside, in both browser themes. Generated `brand/app-icon.svg` and `brand/app-icon-1024.png` are suitable for profile images. Apple Touch keeps an opaque square for platform rounding; maskable artwork stays opaque and inside the central 80%-diameter safe circle. + +## Generation + +```sh +bun run generate:icons # All targets +bun run generate:icons --target web # App/browser/PWA +bun run generate:icons --target docs # Documentation +bun run generate:icons --target desktop # Native PNG/ICO/ICNS +bun run generate:icons --force # Ignore the content cache +bun run check:icons # Fresh generation, contracts, reproducibility, types +bun test tools/brand/tests +``` + +Generation is local using pinned RealFaviconGenerator/Sharp and Tauri versions; no hosted generator or credentials are needed. Generated assets and the cache are ignored by Git. Only the two artwork masters, settings, code, tests, and the normal Playwright visual baseline are tracked. + +Vite ensures web assets before app dev/build. VitePress ensures docs assets before docs dev/build. Storybook prepares the assets for its stories. Tauri's dev/build hooks prepare native icons before compilation. Direct Cargo commands bypass those hooks: run `bun run generate:icons --target desktop` before `cargo check` or `cargo build` on a fresh checkout. CI's native-contract job does this explicitly. No icon generation runs in the shipped application. + +Outputs are owned by `tools/brand/src/config.ts`: `public/brand/`, `packages/docs/public/brand/`, the root ICO/Apple Touch files in each public directory, and `desktop/icons/`. The app's manifest remains in `vite/pwa.ts`; docs intentionally do not receive an installable-app manifest. Web assets never symlink into desktop output. + +Preparation fingerprints the artwork, generator code/settings, lockfile and runtime/tool versions, verifies output hashes, and skips unchanged targets. Missing or corrupted outputs regenerate. A cross-process lock serializes concurrent builds; each file is published atomically and the cache is written last. Destination symlinks are rejected. Native ICNS frame ordering is normalized without re-encoding images. + +## Review + +Use the **Brand/Mark** Storybook stories for main, micro, dark, and monochrome appearances. `tests/e2e/brand/icons.spec.ts` checks the browser assets, app theme selection, and the main mark's visual baseline. Review intentional changes before updating its snapshot. Run at actual 16/24/32 pixel sizes as well as large sizes. + +Do not mechanically replace generic pencil/tool icons or historical screenshots. Social artwork, external profile avatars, and Apple Icon Composer layered icons are separate design/export tasks. diff --git a/assets/brand/mark-micro.svg b/assets/brand/mark-micro.svg new file mode 100644 index 000000000..dee13eeb7 --- /dev/null +++ b/assets/brand/mark-micro.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/brand/mark.svg b/assets/brand/mark.svg new file mode 100644 index 000000000..1a74ebc34 --- /dev/null +++ b/assets/brand/mark.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/bun.lock b/bun.lock index d0c50e58f..ca171cb42 100644 --- a/bun.lock +++ b/bun.lock @@ -98,6 +98,7 @@ "@hono/node-server": "^1.19.17", "@iconify-json/lucide": "^1.2.123", "@modelcontextprotocol/client": "^2.0.0", + "@open-pencil/brand-tools": "workspace:*", "@open-pencil/mcp": "workspace:*", "@oxlint/plugins": "1.57.0", "@playwright/test": "^1.62.1", @@ -105,7 +106,7 @@ "@storybook/addon-docs": "^10.5.8", "@storybook/addon-themes": "^10.5.8", "@storybook/vue3-vite": "^10.5.8", - "@tauri-apps/cli": "^2.11.4", + "@tauri-apps/cli": "2.11.4", "@types/culori": "^4.0.1", "@types/node": "^25.9.5", "@types/opentype.js": "^1.3.10", @@ -230,6 +231,7 @@ "@iconify/vue": "^5.0.1", }, "devDependencies": { + "@open-pencil/brand-tools": "workspace:*", "@shikijs/vitepress-twoslash": "^4.4.3", "@tailwindcss/vite": "^4.3.3", "vitepress": "^2.0.0-alpha.19", @@ -394,6 +396,24 @@ "dedent": "^1.7.2", }, }, + "tools/brand": { + "name": "@open-pencil/brand-tools", + "dependencies": { + "@open-pencil/package-artifacts": "workspace:*", + "@realfavicongenerator/generate-favicon": "0.9.0", + "@realfavicongenerator/image-adapter-node": "0.9.0", + "@tauri-apps/cli": "2.11.4", + "proper-lockfile": "4.1.2", + "sharp": "0.34.5", + "valibot": "^1.4.2", + }, + "devDependencies": { + "@types/bun": "^1.3.14", + "@types/node": "^25.9.5", + "@types/proper-lockfile": "4.1.4", + "typescript": "~5.8.3", + }, + }, "tools/docs": { "name": "@open-pencil/docs-tools", }, @@ -816,7 +836,7 @@ "@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], - "@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], + "@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="], @@ -1022,6 +1042,56 @@ "@iconify/vue": ["@iconify/vue@5.0.1", "", { "dependencies": { "@iconify/types": "^2.0.0" }, "peerDependencies": { "vue": ">=3.0.0" } }, "sha512-aumwwooJlFJ5H5qYWB6ZTAyM0C8hpfcSVLB9/a3qnH1GGvIJ+FEbpEs4s/HfErYe/M5qZeLjwmESR5fFm3lXEw=="], + "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], + + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], + + "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], + + "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], + + "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], + + "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], + + "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], + + "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], + + "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], + + "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], + + "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], + + "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], + + "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], + + "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], + + "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], + + "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], + + "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], + + "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], + + "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], + + "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], + + "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], + + "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], + + "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], + + "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], + + "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], + "@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="], "@inquirer/checkbox": ["@inquirer/checkbox@4.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA=="], @@ -1232,6 +1302,8 @@ "@open-pencil/authoring-reference-tools": ["@open-pencil/authoring-reference-tools@workspace:tools/authoring-reference"], + "@open-pencil/brand-tools": ["@open-pencil/brand-tools@workspace:tools/brand"], + "@open-pencil/cli": ["@open-pencil/cli@workspace:packages/cli"], "@open-pencil/core": ["@open-pencil/core@workspace:packages/core"], @@ -1476,6 +1548,10 @@ "@quansync/fs": ["@quansync/fs@1.0.0", "", { "dependencies": { "quansync": "^1.0.0" } }, "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ=="], + "@realfavicongenerator/generate-favicon": ["@realfavicongenerator/generate-favicon@0.9.0", "", { "dependencies": { "@svgdotjs/svg.js": "^3.2.0" } }, "sha512-Fez/4q+w02OWL3daQ71rDmTRymgbeT457sz/6kQL+lJ9yZf0EWziKIDbSBJ5145JaJuqSkDk7eaoz/migAw3HA=="], + + "@realfavicongenerator/image-adapter-node": ["@realfavicongenerator/image-adapter-node@0.9.0", "", { "dependencies": { "@realfavicongenerator/generate-favicon": "^0.9.0", "@svgdotjs/svg.js": "^3.2.0", "sharp": "^0.34.5", "svgdom": "^0.1.19" } }, "sha512-MAemmKAPMRqf/7QnWmJV2GBjny6QejZhE8z0cQiaDVlZJy39pCocZ/fFqIqH2tDS0GMReaAIP+vSD1FA3j5ufw=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.2.4", "", { "os": "android", "cpu": "arm64" }, "sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA=="], "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Dc5mPD8F5F/FS8i01syd7FTF6yB2fVthH/TRkjwJkzUK6EpoxHtqvZQP5Zwq80/5z19TWYHIg1KOHboCgVx/aQ=="], @@ -1666,6 +1742,8 @@ "@supabase/supabase-js": ["@supabase/supabase-js@2.112.3", "", { "dependencies": { "@supabase/auth-js": "2.112.3", "@supabase/functions-js": "2.112.3", "@supabase/postgrest-js": "2.112.3", "@supabase/realtime-js": "2.112.3", "@supabase/storage-js": "2.112.3" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0" }, "optionalPeers": ["@opentelemetry/api"] }, "sha512-Jv1bxVQmEJNkjvPEhFaKjPzsh+Ozyew6lWGD+SoYcsclDEP1z7yEvKvfUQfzy0DkxRIQnZNxmmWtAzw5XLTQoA=="], + "@svgdotjs/svg.js": ["@svgdotjs/svg.js@3.2.8", "", {}, "sha512-NUdbI/7FDdqGpzKmqr09IQoy9MUcrAC/3bC8gLgXi6OfJuyri450zMLvJekFUhuq3iN5gpdPjoSoStNl9Eijfg=="], + "@swc/helpers": ["@swc/helpers@0.5.23", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw=="], "@tailwindcss/node": ["@tailwindcss/node@4.3.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="], @@ -1818,6 +1896,8 @@ "@types/pako": ["@types/pako@2.0.4", "", {}, "sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw=="], + "@types/proper-lockfile": ["@types/proper-lockfile@4.1.4", "", { "dependencies": { "@types/retry": "*" } }, "sha512-uo2ABllncSqg9F1D4nugVl9v93RmjxF6LJzQLMLDdPaXCUIDPeOJ21Gbqi43xNKzBi/WQ0Q0dICqufzQbMjipQ=="], + "@types/raf": ["@types/raf@3.4.3", "", {}, "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw=="], "@types/rbush": ["@types/rbush@4.0.0", "", {}, "sha512-+N+2H39P8X+Hy1I5mC6awlTX54k3FhiUmvt7HWzGJZvF+syUAAxP/stwppS8JE84YHqFgRMv6fCy31202CMFxQ=="], @@ -2204,6 +2284,8 @@ "broker-factory": ["broker-factory@3.1.15", "", { "dependencies": { "@babel/runtime": "^7.29.7", "fast-unique-numbers": "^9.0.27", "tslib": "^2.8.1", "worker-factory": "^7.0.50" } }, "sha512-ko+aWvgNuP49meGrdjUu7rC+Y+Wai3cCPxP3xWwHsHfehFjOh5ZQM2yC4gEB2UddeZ/YXhm0K1eG/L6fxym2Og=="], + "brotli": ["brotli@1.3.3", "", { "dependencies": { "base64-js": "^1.1.2" } }, "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg=="], + "browser-stdout": ["browser-stdout@1.3.1", "", {}, "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="], "browserslist": ["browserslist@4.28.8", "", { "dependencies": { "baseline-browser-mapping": "^2.11.12", "caniuse-lite": "^1.0.30001809", "electron-to-chromium": "^1.5.402", "node-releases": "^2.0.53", "update-browserslist-db": "^1.3.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA=="], @@ -2284,7 +2366,7 @@ "cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="], - "clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + "clone": ["clone@2.1.2", "", {}, "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="], "cloudflare-redirect-parser": ["cloudflare-redirect-parser@1.0.0", "", {}, "sha512-puEB3wmP47RICu/CboTHd237Up/r3Nagsr622mJxWgvEVfRxNlKceNfpPieMYDe/E1nYJsf6iempsrkitgQZVw=="], @@ -2458,6 +2540,8 @@ "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + "dfa": ["dfa@1.2.0", "", {}, "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q=="], + "diff": ["diff@8.0.4", "", {}, "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw=="], "dns-over-http-resolver": ["dns-over-http-resolver@3.0.16", "", { "dependencies": { "quick-lru": "^7.0.0", "weald": "^1.0.2" } }, "sha512-Qnq8HhNRuMnA61pf1lVPlStCAv1BVrraCx0umPESWgYKf995tUMF5oNhW59PKdnf7E8d5yqwHlEoFywXjsNMCw=="], @@ -2682,6 +2766,8 @@ "font-family-papandreou": ["font-family-papandreou@0.2.0-patch2", "", {}, "sha512-l/YiRdBSH/eWv6OF3sLGkwErL+n0MqCICi9mppTZBOCL5vixWGDqCYvRcuxB2h7RGCTzaTKOHT2caHvCXQPRlw=="], + "fontkit": ["fontkit@2.0.4", "", { "dependencies": { "@swc/helpers": "^0.5.12", "brotli": "^1.3.2", "clone": "^2.1.2", "dfa": "^1.2.0", "fast-deep-equal": "^3.1.3", "restructure": "^3.0.0", "tiny-inflate": "^1.0.3", "unicode-properties": "^1.4.0", "unicode-trie": "^2.0.0" } }, "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g=="], + "fontoxpath": ["fontoxpath@3.34.0", "", { "dependencies": { "prsc": "4.0.0", "xspattern": "^3.1.0" } }, "sha512-7FgBQRohn4WR/2eVdYqZtKBFZkJNaiP4kGdfqS6bAg465og05ixGA2OgfMdxsO1mnX67+64JX/8JKclVqS+bzA=="], "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], @@ -3748,6 +3834,8 @@ "resq": ["resq@1.11.0", "", { "dependencies": { "fast-deep-equal": "^2.0.1" } }, "sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw=="], + "restructure": ["restructure@3.0.2", "", {}, "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw=="], + "ret": ["ret@0.5.0", "", {}, "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw=="], "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], @@ -3792,6 +3880,8 @@ "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + "sax": ["sax@1.6.1", "", {}, "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q=="], + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], "scule": ["scule@1.3.0", "", {}, "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g=="], @@ -3820,6 +3910,8 @@ "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], + "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], @@ -3852,7 +3944,7 @@ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], - "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], "simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="], @@ -3974,6 +4066,8 @@ "svg2pdf.js": ["svg2pdf.js@2.7.0", "", { "dependencies": { "cssesc": "^3.0.0", "font-family-papandreou": "^0.2.0-patch1", "specificity": "^0.4.1", "svgpath": "^2.3.0" }, "peerDependencies": { "jspdf": "^4.0.0 || ^3.0.0 || ^2.0.0" } }, "sha512-nXK4Wx28H0KtOktanm5nsphl1KMEoLNMelAT/776qxPAj9DshwYcqgdpKuBnY1nrcYOriQFHVQLE4tIag+aDJA=="], + "svgdom": ["svgdom@0.1.29", "", { "dependencies": { "fontkit": "^2.0.4", "image-size": "^2.0.2", "sax": "^1.4.1" } }, "sha512-BpwpgRfvntIF3Pdn8Pe5pUvZXxaKz9GVSYfs7g3CfjHdvmVkYYqJjZeLV+2oJCXzkaPITDuVD7ZAUV+BkJedtw=="], + "svgpath": ["svgpath@2.6.0", "", {}, "sha512-OIWR6bKzXvdXYyO4DK/UWa1VA1JeKq8E+0ug2DG98Y/vOmMpfZNj+TIG988HjfYSqtcy/hFOtZq/n/j5GSESNg=="], "swrv": ["swrv@1.2.0", "", { "peerDependencies": { "vue": ">=3.2.26 < 4" } }, "sha512-lH/g4UcNyj+7lzK4eRGT4C68Q4EhQ6JtM9otPRIASfhhzfLWtbZPHcMuhuba7S9YVYuxkMUGImwMyGpfbkH07A=="], @@ -4012,6 +4106,8 @@ "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], + "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], + "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], "tinyexec": ["tinyexec@1.3.0", "", {}, "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ=="], @@ -4132,8 +4228,12 @@ "unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="], + "unicode-properties": ["unicode-properties@1.4.1", "", { "dependencies": { "base64-js": "^1.3.0", "unicode-trie": "^2.0.0" } }, "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg=="], + "unicode-property-aliases-ecmascript": ["unicode-property-aliases-ecmascript@2.2.0", "", {}, "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ=="], + "unicode-trie": ["unicode-trie@2.0.0", "", { "dependencies": { "pako": "^0.2.5", "tiny-inflate": "^1.0.0" } }, "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ=="], + "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], @@ -4456,6 +4556,8 @@ "@grpc/proto-loader/yargs": ["yargs@17.7.3", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g=="], + "@inquirer/core/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + "@inquirer/core/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], "@inquirer/external-editor/iconv-lite": ["iconv-lite@0.7.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ=="], @@ -4484,12 +4586,16 @@ "@multiformats/dns/uint8arrays": ["uint8arrays@6.1.1", "", { "dependencies": { "multiformats": "^14.0.0" } }, "sha512-iz7JN0XCSZYA111lhFG2Ui9EhFvTNekqSRHw3lvMHq+dzwWy1OQftxFQREEh4rffU0oSoXdQHsk2TiHKVm4fsA=="], + "@oxc-parser/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], + "@oxc-resolver/binding-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q=="], "@oxc-resolver/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg=="], "@puppeteer/browsers/yargs": ["yargs@17.7.3", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g=="], + "@rolldown/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], + "@rollup/plugin-terser/serialize-javascript": ["serialize-javascript@7.1.0", "", {}, "sha512-RNEqWOyhhUQYN9V1GfHwu9AR/g+NTciH6Z5u3/no6X3/w+04J2lVDL+svFQVXgXrEGBMG2puMVN3gq2SNGuTGw=="], "@shikijs/vitepress-twoslash/magic-string": ["magic-string@1.2.1", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vCfXkt3lIJha02CjPT1igeysyHVfCsEpIeD20O+X9aJ2hML3/kKx8E9Iv1FB+aMSAlDOEAtpRWzuooQCrYwdUg=="], @@ -4620,6 +4726,8 @@ "create-wdio/yargs": ["yargs@17.7.3", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g=="], + "defaults/clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + "degenerator/ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="], "detective-typescript/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.67.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.67.0", "@typescript-eslint/tsconfig-utils": "8.67.0", "@typescript-eslint/types": "8.67.0", "@typescript-eslint/visitor-keys": "8.67.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.5.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.1.0" } }, "sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw=="], @@ -4638,6 +4746,8 @@ "execa/@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], + "execa/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + "expect-webdriverio/@vitest/snapshot": ["@vitest/snapshot@4.1.11", "", { "dependencies": { "@vitest/pretty-format": "4.1.11", "@vitest/utils": "4.1.11", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog=="], "extract-zip/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], @@ -4650,6 +4760,8 @@ "floating-vue/@floating-ui/dom": ["@floating-ui/dom@1.1.1", "", { "dependencies": { "@floating-ui/core": "^1.1.0" } }, "sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw=="], + "foreground-child/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + "glob/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], "globby/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], @@ -4750,8 +4862,6 @@ "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], - "proper-lockfile/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], - "proxy-agent/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], "raw-body/iconv-lite": ["iconv-lite@0.7.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ=="], @@ -4808,6 +4918,8 @@ "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], + "svgdom/image-size": ["image-size@2.0.4", "", { "bin": { "image-size": "bin/image-size.js" } }, "sha512-QRUkFFsRV/6fuESxb9Vkq+a0LkSrgKXuc2NEqfikiXxxN/G3tjWt5EVUlMaImRBZRZK/jRBEbYvpPYZL8t08Zw=="], + "tempy/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], "tempy/type-fest": ["type-fest@0.16.0", "", {}, "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg=="], @@ -4822,6 +4934,8 @@ "type-is/content-type": ["content-type@2.1.0", "", {}, "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag=="], + "unicode-trie/pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="], + "unplugin-raw/unplugin": ["unplugin@3.3.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "picomatch": "^4.0.4", "webpack-virtual-modules": "^0.6.2" }, "peerDependencies": { "@farmfe/core": "*", "@rspack/core": "*", "bun-types-no-globals": "*", "esbuild": "*", "rolldown": "*", "rollup": "*", "unloader": "*", "vite": "*", "webpack": "*" }, "optionalPeers": ["@farmfe/core", "@rspack/core", "bun-types-no-globals", "esbuild", "rolldown", "rollup", "unloader", "vite", "webpack"] }, "sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg=="], "unplugin-vue/unplugin": ["unplugin@3.3.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "picomatch": "^4.0.4", "webpack-virtual-modules": "^0.6.2" }, "peerDependencies": { "@farmfe/core": "*", "@rspack/core": "*", "bun-types-no-globals": "*", "esbuild": "*", "rolldown": "*", "rollup": "*", "unloader": "*", "vite": "*", "webpack": "*" }, "optionalPeers": ["@farmfe/core", "@rspack/core", "bun-types-no-globals", "esbuild", "rolldown", "rollup", "unloader", "vite", "webpack"] }, "sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg=="], @@ -5082,8 +5196,6 @@ "blamer/execa/npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="], - "blamer/execa/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], - "blamer/execa/strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="], "cheerio/parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], diff --git a/desktop/icons/128x128.png b/desktop/icons/128x128.png deleted file mode 100644 index 082cd22d1..000000000 Binary files a/desktop/icons/128x128.png and /dev/null differ diff --git a/desktop/icons/128x128@2x.png b/desktop/icons/128x128@2x.png deleted file mode 100644 index cbda7b775..000000000 Binary files a/desktop/icons/128x128@2x.png and /dev/null differ diff --git a/desktop/icons/32x32.png b/desktop/icons/32x32.png deleted file mode 100644 index 9c6fe222e..000000000 Binary files a/desktop/icons/32x32.png and /dev/null differ diff --git a/desktop/icons/Square107x107Logo.png b/desktop/icons/Square107x107Logo.png deleted file mode 100644 index afb2770b9..000000000 Binary files a/desktop/icons/Square107x107Logo.png and /dev/null differ diff --git a/desktop/icons/Square142x142Logo.png b/desktop/icons/Square142x142Logo.png deleted file mode 100644 index 12d5b6754..000000000 Binary files a/desktop/icons/Square142x142Logo.png and /dev/null differ diff --git a/desktop/icons/Square150x150Logo.png b/desktop/icons/Square150x150Logo.png deleted file mode 100644 index 14d3f1b3a..000000000 Binary files a/desktop/icons/Square150x150Logo.png and /dev/null differ diff --git a/desktop/icons/Square284x284Logo.png b/desktop/icons/Square284x284Logo.png deleted file mode 100644 index 6c5f40975..000000000 Binary files a/desktop/icons/Square284x284Logo.png and /dev/null differ diff --git a/desktop/icons/Square30x30Logo.png b/desktop/icons/Square30x30Logo.png deleted file mode 100644 index eb7f3df15..000000000 Binary files a/desktop/icons/Square30x30Logo.png and /dev/null differ diff --git a/desktop/icons/Square310x310Logo.png b/desktop/icons/Square310x310Logo.png deleted file mode 100644 index cd6a98ed5..000000000 Binary files a/desktop/icons/Square310x310Logo.png and /dev/null differ diff --git a/desktop/icons/Square44x44Logo.png b/desktop/icons/Square44x44Logo.png deleted file mode 100644 index 19594d6e1..000000000 Binary files a/desktop/icons/Square44x44Logo.png and /dev/null differ diff --git a/desktop/icons/Square71x71Logo.png b/desktop/icons/Square71x71Logo.png deleted file mode 100644 index a54582861..000000000 Binary files a/desktop/icons/Square71x71Logo.png and /dev/null differ diff --git a/desktop/icons/Square89x89Logo.png b/desktop/icons/Square89x89Logo.png deleted file mode 100644 index b6f394995..000000000 Binary files a/desktop/icons/Square89x89Logo.png and /dev/null differ diff --git a/desktop/icons/StoreLogo.png b/desktop/icons/StoreLogo.png deleted file mode 100644 index 0185d7cee..000000000 Binary files a/desktop/icons/StoreLogo.png and /dev/null differ diff --git a/desktop/icons/icon.icns b/desktop/icons/icon.icns deleted file mode 100644 index d96f76285..000000000 Binary files a/desktop/icons/icon.icns and /dev/null differ diff --git a/desktop/icons/icon.ico b/desktop/icons/icon.ico deleted file mode 100644 index 30dffc9c2..000000000 Binary files a/desktop/icons/icon.ico and /dev/null differ diff --git a/desktop/icons/icon.png b/desktop/icons/icon.png deleted file mode 100644 index ca13c58ab..000000000 Binary files a/desktop/icons/icon.png and /dev/null differ diff --git a/desktop/tauri.conf.json b/desktop/tauri.conf.json index 1497a4e28..e6e3a7cdf 100644 --- a/desktop/tauri.conf.json +++ b/desktop/tauri.conf.json @@ -4,9 +4,9 @@ "version": "0.14.0", "identifier": "net.dannote.open-pencil", "build": { - "beforeDevCommand": "bun run generate:tauri-menu && bun run dev", + "beforeDevCommand": "bun run generate:icons --target desktop && bun run generate:tauri-menu && bun run dev", "devUrl": "http://localhost:1420", - "beforeBuildCommand": "bun run generate:tauri-menu && bun run build", + "beforeBuildCommand": "bun run generate:icons --target desktop && bun run generate:tauri-menu && bun run build", "frontendDist": "../dist" }, "app": { diff --git a/index.html b/index.html index 5cb84d49c..ae2559ca9 100644 --- a/index.html +++ b/index.html @@ -3,8 +3,8 @@ - - + + @@ -39,7 +39,7 @@ color: rgb(var(--loader-fg)); background: var(--loader-bg); } - #boot-splash svg { width: 32px; height: 32px; opacity: 0.45; } + #boot-splash img { width: 40px; height: 40px; } #boot-splash .bar { position: absolute; bottom: 50%; @@ -70,9 +70,7 @@
- - - + OpenPencil
diff --git a/package.json b/package.json index b5c111b61..6c5eb17c5 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "packages/mcp", "packages/harness", "packages/docs", + "tools/brand", "tools/docs", "tools/lint", "tools/package-artifacts", @@ -40,7 +41,7 @@ "lint:structure": "oxlint -c oxlint.json commitlint.config.ts vite.config.ts vite/ .storybook/ src/ packages/scene-graph/src/ packages/scene-graph/scripts/ packages/core/src/ packages/vue/src/ packages/cli/src/ packages/mcp/src/ packages/harness/src/ packages/harness/tests/ packages/dom-css/src/ packages/dom-css/tests/ packages/dom-css/scripts/ packages/pen/src/ packages/pen/scripts/ packages/kiwi/src/ packages/kiwi/tests/ packages/kiwi/scripts/ packages/fig/src/ packages/fig/tests/ packages/fig/scripts/ tests/ scripts/ tools/", "format": "oxfmt --write .oxfmtrc.json commitlint.config.ts vite.config.ts vite/ .storybook/ src/ packages/scene-graph/src/ packages/scene-graph/scripts/ packages/core/src/ packages/cli/src/ packages/mcp/src/ packages/harness/src/ packages/harness/tests/ packages/vue/src/ packages/dom-css/src/ packages/dom-css/tests/ packages/dom-css/scripts/ packages/pen/src/ packages/pen/scripts/ packages/kiwi/src/ packages/kiwi/tests/ packages/kiwi/scripts/ packages/fig/src/ packages/fig/tests/ packages/fig/scripts/ tests scripts/ tools/", "format:check": "bun run format && status=$(git status --porcelain -uall) && test -z \"$status\" || (echo \"$status\" && exit 1)", - "check": "bun run build:packages && bun run lint && tsgo --noEmit && bun run check:vue && bun run check:native-test && bun run check:i18n && bun run check:docs && bun run check:changelog && bun run check:packages && bun run check:deps && bun run check:audit && bun run check:secrets && bun run check:monorepo && bun run check:arch && bun run test:type-shapes && bun run test:tools && bun run test:dupes", + "check": "bun run check:icons && bun run build:packages && bun run lint && tsgo --noEmit && bun run check:vue && bun run check:native-test && bun run check:i18n && bun run check:docs && bun run check:changelog && bun run check:packages && bun run check:deps && bun run check:audit && bun run check:secrets && bun run check:monorepo && bun run check:arch && bun run test:type-shapes && bun run test:tools && bun run test:dupes", "check:commits": "commitlint", "check:changelog": "bun tools/release-packages/src/check-changelog.ts", "check:deps": "knip --include unlisted,unresolved,binaries", @@ -76,6 +77,8 @@ "docs:build": "bun --filter @open-pencil/docs build", "docs:build:production": "bun --filter @open-pencil/docs build:production", "docs:preview": "bun --filter @open-pencil/docs preview", + "generate:icons": "bun tools/brand/src/cli.ts generate", + "check:icons": "bun tools/brand/src/cli.ts check && bun --filter @open-pencil/brand-tools check", "generate:tauri-menu": "bun tools/tauri-menu/src/generate.ts" }, "dependencies": { @@ -172,6 +175,7 @@ "@hono/node-server": "^1.19.17", "@iconify-json/lucide": "^1.2.123", "@modelcontextprotocol/client": "^2.0.0", + "@open-pencil/brand-tools": "workspace:*", "@open-pencil/mcp": "workspace:*", "@oxlint/plugins": "1.57.0", "@playwright/test": "^1.62.1", @@ -179,7 +183,7 @@ "@storybook/addon-docs": "^10.5.8", "@storybook/addon-themes": "^10.5.8", "@storybook/vue3-vite": "^10.5.8", - "@tauri-apps/cli": "^2.11.4", + "@tauri-apps/cli": "2.11.4", "@types/culori": "^4.0.1", "@types/node": "^25.9.5", "@types/opentype.js": "^1.3.10", diff --git a/packages/docs/.vitepress/config.ts b/packages/docs/.vitepress/config.ts index 2b364ff24..110c7c6d9 100644 --- a/packages/docs/.vitepress/config.ts +++ b/packages/docs/.vitepress/config.ts @@ -1,6 +1,7 @@ import { dirname, resolve } from 'node:path' import { fileURLToPath } from 'node:url' +import { ensureBrandAssets } from '@open-pencil/brand-tools' import { transformerTwoslash } from '@shikijs/vitepress-twoslash' import { createFileSystemTypesCache } from '@shikijs/vitepress-twoslash/cache-fs' import tailwindcss from '@tailwindcss/vite' @@ -11,6 +12,8 @@ import { docsLocales } from './locales.ts' import { rootThemeConfig } from './root-theme.ts' import { BASE, LOCALE_PREFIXES, applyPageSeo, siteHead, withAlternateSitemapLinks } from './seo.ts' +await ensureBrandAssets(['docs']) + const configDir = dirname(fileURLToPath(import.meta.url)) const docsRoot = dirname(configDir) const packagesRoot = dirname(docsRoot) diff --git a/packages/docs/.vitepress/root-theme.ts b/packages/docs/.vitepress/root-theme.ts index b847dec84..3306546a2 100644 --- a/packages/docs/.vitepress/root-theme.ts +++ b/packages/docs/.vitepress/root-theme.ts @@ -11,6 +11,7 @@ import { import type { DefaultTheme } from 'vitepress' export const rootThemeConfig = (): DefaultTheme.Config => ({ + logo: { light: '/brand/mark.svg', dark: '/brand/mark-dark.svg', alt: 'OpenPencil' }, search: { provider: 'local' }, nav: [ diff --git a/packages/docs/.vitepress/seo.ts b/packages/docs/.vitepress/seo.ts index 19b7001ed..9be287e03 100644 --- a/packages/docs/.vitepress/seo.ts +++ b/packages/docs/.vitepress/seo.ts @@ -19,7 +19,10 @@ export const LOCALES: Record][] = [ - ['link', { rel: 'icon', type: 'image/png', href: '/favicon.png' }], + ['link', { rel: 'icon', href: '/favicon.ico', sizes: 'any' }], + ['link', { rel: 'icon', type: 'image/png', href: '/brand/favicon-96x96.png', sizes: '96x96' }], + ['link', { rel: 'icon', type: 'image/svg+xml', href: '/brand/favicon.svg' }], + ['link', { rel: 'apple-touch-icon', href: '/apple-touch-icon.png' }], ['link', { rel: 'alternate', type: 'text/plain', title: 'llms.txt', href: '/llms.txt' }], ['link', { rel: 'alternate', type: 'text/plain', title: 'llms-full.txt', href: '/llms-full.txt' }], ['meta', { property: 'og:type', content: 'website' }], diff --git a/packages/docs/package.json b/packages/docs/package.json index f9517ddd6..2b53d3e6d 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -15,6 +15,7 @@ "preview": "vitepress preview" }, "devDependencies": { + "@open-pencil/brand-tools": "workspace:*", "@shikijs/vitepress-twoslash": "^4.4.3", "@tailwindcss/vite": "^4.3.3", "vitepress": "^2.0.0-alpha.19", diff --git a/packages/docs/public/favicon.png b/packages/docs/public/favicon.png deleted file mode 120000 index c5a0c50f7..000000000 --- a/packages/docs/public/favicon.png +++ /dev/null @@ -1 +0,0 @@ -../../../public/favicon-32.png \ No newline at end of file diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png deleted file mode 120000 index 86a465e8c..000000000 --- a/public/apple-touch-icon.png +++ /dev/null @@ -1 +0,0 @@ -../desktop/icons/icon.png \ No newline at end of file diff --git a/public/favicon-128.png b/public/favicon-128.png deleted file mode 120000 index c73eef32b..000000000 --- a/public/favicon-128.png +++ /dev/null @@ -1 +0,0 @@ -../desktop/icons/128x128.png \ No newline at end of file diff --git a/public/favicon-32.png b/public/favicon-32.png deleted file mode 120000 index 8b5c29821..000000000 --- a/public/favicon-32.png +++ /dev/null @@ -1 +0,0 @@ -../desktop/icons/32x32.png \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 120000 index 5328d95b4..000000000 --- a/public/favicon.ico +++ /dev/null @@ -1 +0,0 @@ -../desktop/icons/icon.ico \ No newline at end of file diff --git a/public/pwa-192.png b/public/pwa-192.png deleted file mode 100644 index 0f125ee4e..000000000 Binary files a/public/pwa-192.png and /dev/null differ diff --git a/public/pwa-512.png b/public/pwa-512.png deleted file mode 100644 index bea6272ce..000000000 Binary files a/public/pwa-512.png and /dev/null differ diff --git a/public/pwa-maskable-512.png b/public/pwa-maskable-512.png deleted file mode 100644 index 7d15465a5..000000000 Binary files a/public/pwa-maskable-512.png and /dev/null differ diff --git a/src/App.vue b/src/App.vue index 884ccca38..ed2b83d21 100644 --- a/src/App.vue +++ b/src/App.vue @@ -18,8 +18,8 @@ import PublishLibraryDialog from '@/components/libraries/PublishLibraryDialog.vu import LibraryUpdateReviewDialog from '@/components/libraries/review/LibraryUpdateReviewDialog.vue' import RecoveryDialog from '@/components/recovery/RecoveryDialog.vue' import SettingsDialog from '@/components/settings/SettingsDialog.vue' -import AppShell from '@/components/Shell/AppShell.vue' -import AppToast from '@/components/Shell/AppToast.vue' +import AppShell from '@/components/shell/AppShell.vue' +import AppToast from '@/components/shell/AppToast.vue' const store = useEditorStore() const { updates, locale } = useI18n() diff --git a/src/components/LayersPanel.vue b/src/components/LayersPanel.vue index 15dd3b19f..a674a784c 100644 --- a/src/components/LayersPanel.vue +++ b/src/components/LayersPanel.vue @@ -5,7 +5,7 @@ import { computed, ref } from 'vue' import { useI18n } from '@open-pencil/vue' -import AppMenu from '@/components/Shell/AppMenu.vue' +import AppMenu from '@/components/shell/AppMenu.vue' import SegmentedControl from '@/components/ui/select/SegmentedControl.vue' import splitterTheme from '@/theme/splitter' diff --git a/src/components/brand/BrandMark.stories.ts b/src/components/brand/BrandMark.stories.ts new file mode 100644 index 000000000..48c42ba47 --- /dev/null +++ b/src/components/brand/BrandMark.stories.ts @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from '@storybook/vue3-vite' + +import BrandMark from './BrandMark.vue' +import type { BrandMarkProps } from './types' + +const meta = { + title: 'Brand/Mark', + component: BrandMark, + args: { variant: 'mark', appearance: 'light', class: 'size-32' } +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Mark: Story = {} +export const Micro: Story = { args: { variant: 'micro', class: 'size-4' } } +export const Monochrome: Story = { args: { variant: 'mono' } } +export const AppIcon: Story = { args: { variant: 'app-icon' } } +export const AppIconDark: Story = { + args: { variant: 'app-icon', appearance: 'dark' }, + render: (args) => ({ + components: { BrandMark }, + setup: () => ({ args }), + template: '
' + }) +} +export const Dark: Story = { + args: { appearance: 'dark' }, + render: (args) => ({ + components: { BrandMark }, + setup: () => ({ args }), + template: '
' + }) +} diff --git a/src/components/brand/BrandMark.vue b/src/components/brand/BrandMark.vue new file mode 100644 index 000000000..103ca89b3 --- /dev/null +++ b/src/components/brand/BrandMark.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/components/brand/types.ts b/src/components/brand/types.ts new file mode 100644 index 000000000..9be91181a --- /dev/null +++ b/src/components/brand/types.ts @@ -0,0 +1,6 @@ +export interface BrandMarkProps { + variant?: 'mark' | 'micro' | 'mono' | 'app-icon' + appearance?: 'light' | 'dark' + decorative?: boolean + class?: string +} diff --git a/src/components/chat/ReasoningBlock.stories.ts b/src/components/chat/ReasoningBlock.stories.ts index f5cb469e9..c2de46d19 100644 --- a/src/components/chat/ReasoningBlock.stories.ts +++ b/src/components/chat/ReasoningBlock.stories.ts @@ -29,7 +29,7 @@ const meta = { }) } satisfies Meta export default meta -type Story = StoryObj +type Story = StoryObj> export const Collapsed: Story = {} export const Expanded: Story = { args: { display: 'expanded' } } export const WhileThinking: Story = { args: { display: 'while-thinking', streaming: true } } diff --git a/src/components/editor/EditorWorkspace.vue b/src/components/editor/EditorWorkspace.vue index 517119d65..a4014ee4a 100644 --- a/src/components/editor/EditorWorkspace.vue +++ b/src/components/editor/EditorWorkspace.vue @@ -8,7 +8,9 @@ import { useEditorStore } from '@/app/editor/active-store' import { appRuntimeConfig } from '@/app/runtime/config' import { loadEditorLayout, saveEditorLayout } from '@/app/shell/layout-storage' import { appMenuShortcut } from '@/app/shell/menu/shortcut' +import { resolvedAppTheme } from '@/app/shell/theme' import { activeTab } from '@/app/tabs' +import BrandMark from '@/components/brand/BrandMark.vue' import CanvasSplitRoot from '@/components/canvas/CanvasSplitRoot.vue' import CollabPanel from '@/components/CollabPanel/CollabPanel.vue' import EditorCanvas from '@/components/EditorCanvas.vue' @@ -98,7 +100,7 @@ const horizontalSplitterStyles = tv(splitterTheme)({ direction: 'horizontal' }) v-if="!isMobile" class="absolute top-7 left-7 z-10 flex items-center gap-2 rounded-lg border border-border bg-panel px-2 py-1 shadow-sm" > - OpenPencil + {{ store.state.documentName }} diff --git a/src/components/home/document/DocumentEntry.stories.ts b/src/components/home/document/DocumentEntry.stories.ts index 83753fc6d..da7710a80 100644 --- a/src/components/home/document/DocumentEntry.stories.ts +++ b/src/components/home/document/DocumentEntry.stories.ts @@ -15,9 +15,10 @@ const meta = { } satisfies Meta<{ name: string; metadata: string; view: 'grid' | 'list'; disabled?: boolean }> export default meta -export const Default: StoryObj = {} -export const List: StoryObj = { args: { view: 'list' } } -export const LongName: StoryObj = { +type Story = StoryObj +export const Default: Story = {} +export const List: Story = { args: { view: 'list' } } +export const LongName: Story = { args: { name: 'A deliberately long document name that must stay inside the document card' } } -export const Disabled: StoryObj = { args: { disabled: true } } +export const Disabled: Story = { args: { disabled: true } } diff --git a/src/components/preparation/canvas/Overlay.vue b/src/components/preparation/canvas/Overlay.vue index d5a1c25f8..b807675fb 100644 --- a/src/components/preparation/canvas/Overlay.vue +++ b/src/components/preparation/canvas/Overlay.vue @@ -3,6 +3,8 @@ import { ProgressIndicator, ProgressRoot } from 'reka-ui' import { computed } from 'vue' import type { EditorPreparation } from '@/app/editor/preparation/types' +import { resolvedAppTheme } from '@/app/shell/theme' +import BrandMark from '@/components/brand/BrandMark.vue' import { preparationLabel, preparationPercent } from '@/components/preparation/presentation' const { preparation } = defineProps<{ @@ -24,7 +26,7 @@ const progressSteps = computed(() => Math.round(progressValue.value ?? 0)) class="absolute inset-0 z-50 flex items-center justify-center bg-canvas" >
- +

{{ label }}

diff --git a/src/components/Shell/AppMenu.vue b/src/components/shell/AppMenu.vue similarity index 96% rename from src/components/Shell/AppMenu.vue rename to src/components/shell/AppMenu.vue index ece311e46..3f0670a82 100644 --- a/src/components/Shell/AppMenu.vue +++ b/src/components/shell/AppMenu.vue @@ -36,6 +36,8 @@ import { updateMenuChecked } from '@/app/shell/menu/entry' import { appMenuShortcutLabel } from '@/app/shell/menu/shortcut' +import { resolvedAppTheme } from '@/app/shell/theme' +import BrandMark from '@/components/brand/BrandMark.vue' import IconButton from '@/components/ui/button/IconButton.vue' import AppShortcutText from '@/components/ui/menu/AppShortcutText.vue' import { useMenuUI } from '@/components/ui/menu/menu' @@ -61,7 +63,12 @@ const subMenuCls = useMenuUI({ content: 'min-w-44' })