diff --git a/.gitignore b/.gitignore index 43c6d4e..663af5b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,15 @@ out/ .test-fixtures/ *.log *.png +# Canonical brand icons are generated from @mind-studio/ui/brand (npm run gen:icons) +# and committed so the favicon/PWA/apple-touch assets ship with the app. +!src/app/apple-icon.png +!public/icon-192.png +!public/icon-512.png +# Tauri desktop icons — regenerated from the same canonical mark +# (npm run gen:tauri-icons) and committed so the bundled app matches the brand. +!src-tauri/icons/*.png +!src-tauri/icons/**/*.png .env .env*.local .DS_Store diff --git a/package-lock.json b/package-lock.json index 18db2a6..80d496f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@inrupt/solid-client-authn-browser": "^4.0.0", "@inrupt/solid-client-authn-node": "^3.1.0", "@mind-studio/core": "^0.7.0", - "@mind-studio/ui": "^0.5.0", + "@mind-studio/ui": "^0.7.0", "@tauri-apps/api": "^2.11.0", "lucide-react": "^0.460.0", "next": "16.2.6", @@ -28,6 +28,7 @@ "@types/react-dom": "^19", "husky": "^9.1.7", "lint-staged": "^17.0.7", + "sharp": "^0.34.5", "tailwindcss": "^4", "tsx": "^4.22.3", "typescript": "^5", @@ -380,6 +381,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -893,8 +895,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "devOptional": true, "license": "MIT", - "optional": true, "engines": { "node": ">=18" } @@ -906,6 +908,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -928,6 +931,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -950,6 +954,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -966,6 +971,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -982,6 +988,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -998,6 +1005,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1014,6 +1022,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1030,6 +1039,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1046,6 +1056,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1062,6 +1073,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1078,6 +1090,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1094,6 +1107,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1110,6 +1124,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1132,6 +1147,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1154,6 +1170,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1176,6 +1193,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1198,6 +1216,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1220,6 +1239,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1242,6 +1262,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1264,6 +1285,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -1286,6 +1308,7 @@ "cpu": [ "wasm32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -1305,6 +1328,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -1324,6 +1348,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -1343,6 +1368,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -1515,9 +1541,9 @@ } }, "node_modules/@mind-studio/ui": { - "version": "0.5.0", - "resolved": "https://npm.pkg.github.com/download/@mind-studio/ui/0.5.0/3fc873067e04a306cb44015874f24eeaf683a6d9", - "integrity": "sha512-nJJN2RuP4KvFDyZYJSRnG68kHt6WXFyxyVYH8jCpK6l0Bj+T0+lj7lNuAUrW0bm2atE04NGkZjMAkmZoxjBxmQ==", + "version": "0.7.0", + "resolved": "https://npm.pkg.github.com/download/@mind-studio/ui/0.7.0/70071acee41c5d7bcc3bed636a6473e35dac9f6a", + "integrity": "sha512-PvkztbjfiFM7W8Zk0/rWYlMn26DiIakuhBQfxphi5les6J6eo9W7zZzLhbGpEp7ytB1+SaKev95ZFOxVhKx6cw==", "license": "MIT", "dependencies": { "@base-ui/react": "^1.5.0", @@ -6405,8 +6431,8 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "devOptional": true, "license": "ISC", - "optional": true, "bin": { "semver": "bin/semver.js" }, @@ -6418,9 +6444,9 @@ "version": "0.34.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", - "optional": true, "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", diff --git a/package.json b/package.json index a323513..dbb45de 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,8 @@ "build": "next build", "start": "next start -p 3100", "typecheck": "tsc --noEmit", + "gen:icons": "node scripts/gen-icons.mjs", + "gen:tauri-icons": "npm run gen:icons && tauri icon src-tauri/icons/app-icon.png", "lint": "biome check .", "lint:fix": "biome check --write .", "format": "biome format --write .", @@ -31,7 +33,7 @@ "@inrupt/solid-client-authn-browser": "^4.0.0", "@inrupt/solid-client-authn-node": "^3.1.0", "@mind-studio/core": "^0.7.0", - "@mind-studio/ui": "^0.5.0", + "@mind-studio/ui": "^0.7.0", "@tauri-apps/api": "^2.11.0", "lucide-react": "^0.460.0", "next": "16.2.6", @@ -47,6 +49,7 @@ "@types/react-dom": "^19", "husky": "^9.1.7", "lint-staged": "^17.0.7", + "sharp": "^0.34.5", "tailwindcss": "^4", "tsx": "^4.22.3", "typescript": "^5", diff --git a/public/icon-192.png b/public/icon-192.png new file mode 100644 index 0000000..6ef4ebe Binary files /dev/null and b/public/icon-192.png differ diff --git a/public/icon-512.png b/public/icon-512.png new file mode 100644 index 0000000..0b247e7 Binary files /dev/null and b/public/icon-512.png differ diff --git a/scripts/gen-icons.mjs b/scripts/gen-icons.mjs new file mode 100644 index 0000000..a2fbd3f --- /dev/null +++ b/scripts/gen-icons.mjs @@ -0,0 +1,105 @@ +/* + * Generates Shell's brand icons from the canonical Mind mark. + * + * Shell is the unified Mind host, so its icons are mark-only (no per-app + * label). The artwork is imported from `@mind-studio/ui/brand` — the design + * system's single source of truth — so these icons can never drift from the + * published logo. Re-run after bumping the package: `npm run gen:icons`. + * + * Web outputs (Next.js file-convention metadata): + * src/app/icon.svg favicon — gradient weave, transparent, square + * src/app/apple-icon.png 180×180 apple-touch — white mark on green, 22% radius + * public/icon-192.png 192×192 maskable — white mark on full-bleed green + * public/icon-512.png 512×512 maskable — white mark on full-bleed green + * + * Tauri desktop master: + * src-tauri/icons/app-icon.png 1024×1024 app-icon master — white mark on a + * full-bleed Mind-Green backplate. NOT the final + * desktop art; it's the source for the Tauri + * icon generator, which rewrites src-tauri/icons/* + * (all PNG sizes + icon.icns + icon.ico). Run: + * `npx tauri icon src-tauri/icons/app-icon.png` + * (also wired as `npm run gen:tauri-icons`). + * + * The maskable icons bleed the green to the edges (the platform mask crops the + * corners) and keep the mark inside the ~80% safe zone. + */ + +import { writeFileSync } from "node:fs"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { MIND_GREEN, MIND_MARK_SVG, monoMarkSvg } from "@mind-studio/ui/brand"; +import sharp from "sharp"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const root = resolve(__dirname, ".."); +const out = (p) => resolve(root, p); + +// Brand green backplate (the solid surface behind the white mono mark). +const GREEN = MIND_GREEN.base; // #16B88A + +/* ---------------------------------------------------------------- favicon.svg */ +// Nest the full-colour mark inside a square canvas, centred with a little +// breathing room (meet → preserves the mark's aspect, no distortion). +const nested = MIND_MARK_SVG.replace( + ' +${nested} + +`; +writeFileSync(out("src/app/icon.svg"), faviconSvg, "utf8"); + +/* ------------------------------------------------------------------ raster ops */ +// Rasterise the monochrome mark to a transparent square of the given size. +async function rasterMark(px, color = "#ffffff") { + return sharp(Buffer.from(monoMarkSvg(color))) + .resize(px, px, { fit: "contain", background: { r: 0, g: 0, b: 0, alpha: 0 } }) + .png() + .toBuffer(); +} + +// Maskable: white mark on a full-bleed green square; mark kept in the safe zone. +async function maskable(size, file) { + const mark = await rasterMark(Math.round(size * 0.66)); + await sharp({ create: { width: size, height: size, channels: 4, background: GREEN } }) + .composite([{ input: mark, gravity: "center" }]) + .png() + .toFile(out(file)); +} + +// Apple touch: white mark on a green backplate with a 22% corner radius. +async function appleIcon(size, file) { + const r = Math.round(size * 0.22); + const backplate = Buffer.from( + ``, + ); + const mark = await rasterMark(Math.round(size * 0.62)); + await sharp(backplate).composite([{ input: mark, gravity: "center" }]).png().toFile(out(file)); +} + +// Tauri desktop master: a 1024×1024 full-bleed Mind-Green square with the white +// mono mark centred in the safe zone — the app-icon style (matches the web +// apple-icon look). The Tauri icon generator squares/rounds this per platform. +async function tauriMaster(size, file) { + const mark = await rasterMark(Math.round(size * 0.62)); + await sharp({ create: { width: size, height: size, channels: 4, background: GREEN } }) + .composite([{ input: mark, gravity: "center" }]) + .png() + .toFile(out(file)); +} + +await Promise.all([ + maskable(192, "public/icon-192.png"), + maskable(512, "public/icon-512.png"), + appleIcon(180, "src/app/apple-icon.png"), + tauriMaster(1024, "src-tauri/icons/app-icon.png"), +]); + +console.log( + "[gen:icons] wrote icon.svg, apple-icon.png, icon-192.png, icon-512.png, src-tauri/icons/app-icon.png", +); +console.log( + "[gen:icons] desktop icons: run `npm run gen:tauri-icons` to rewrite src-tauri/icons/* from the master", +); diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png new file mode 100644 index 0000000..aca0548 Binary files /dev/null and b/src-tauri/icons/128x128.png differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000..89dbb8c Binary files /dev/null and b/src-tauri/icons/128x128@2x.png differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png new file mode 100644 index 0000000..b11ac0c Binary files /dev/null and b/src-tauri/icons/32x32.png differ diff --git a/src-tauri/icons/64x64.png b/src-tauri/icons/64x64.png new file mode 100644 index 0000000..9a03719 Binary files /dev/null and b/src-tauri/icons/64x64.png differ diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000..202a420 Binary files /dev/null and b/src-tauri/icons/Square107x107Logo.png differ diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png new file mode 100644 index 0000000..8537acb Binary files /dev/null and b/src-tauri/icons/Square142x142Logo.png differ diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png new file mode 100644 index 0000000..d737ef6 Binary files /dev/null and b/src-tauri/icons/Square150x150Logo.png differ diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png new file mode 100644 index 0000000..edeba09 Binary files /dev/null and b/src-tauri/icons/Square284x284Logo.png differ diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png new file mode 100644 index 0000000..6ccca69 Binary files /dev/null and b/src-tauri/icons/Square30x30Logo.png differ diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png new file mode 100644 index 0000000..f1b0597 Binary files /dev/null and b/src-tauri/icons/Square310x310Logo.png differ diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png new file mode 100644 index 0000000..40636d5 Binary files /dev/null and b/src-tauri/icons/Square44x44Logo.png differ diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png new file mode 100644 index 0000000..564428b Binary files /dev/null and b/src-tauri/icons/Square71x71Logo.png differ diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png new file mode 100644 index 0000000..4e07bd1 Binary files /dev/null and b/src-tauri/icons/Square89x89Logo.png differ diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png new file mode 100644 index 0000000..d0afda1 Binary files /dev/null and b/src-tauri/icons/StoreLogo.png differ diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..0d2bcdb Binary files /dev/null and b/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..20a55da Binary files /dev/null and b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..63ea1af Binary files /dev/null and b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..4620509 Binary files /dev/null and b/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..30e28ac Binary files /dev/null and b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..84be6dd Binary files /dev/null and b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..54d5676 Binary files /dev/null and b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..1c6fe34 Binary files /dev/null and b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..31e75c2 Binary files /dev/null and b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..30ed40a Binary files /dev/null and b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..f5b82e3 Binary files /dev/null and b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..0cd176a Binary files /dev/null and b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..7559072 Binary files /dev/null and b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..0d714f8 Binary files /dev/null and b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..1915ae2 Binary files /dev/null and b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/app-icon.png b/src-tauri/icons/app-icon.png new file mode 100644 index 0000000..c53ac2a Binary files /dev/null and b/src-tauri/icons/app-icon.png differ diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns index 766dd1d..198424d 100644 Binary files a/src-tauri/icons/icon.icns and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico index ba6521f..d98b177 100644 Binary files a/src-tauri/icons/icon.ico and b/src-tauri/icons/icon.ico differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png new file mode 100644 index 0000000..ed9635d Binary files /dev/null and b/src-tauri/icons/icon.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@1x.png b/src-tauri/icons/ios/AppIcon-20x20@1x.png new file mode 100644 index 0000000..5bc77ef Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-20x20@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@2x-1.png b/src-tauri/icons/ios/AppIcon-20x20@2x-1.png new file mode 100644 index 0000000..a1ecf75 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-20x20@2x-1.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@2x.png b/src-tauri/icons/ios/AppIcon-20x20@2x.png new file mode 100644 index 0000000..a1ecf75 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-20x20@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@3x.png b/src-tauri/icons/ios/AppIcon-20x20@3x.png new file mode 100644 index 0000000..250f61c Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-20x20@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@1x.png b/src-tauri/icons/ios/AppIcon-29x29@1x.png new file mode 100644 index 0000000..0c228ab Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-29x29@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@2x-1.png b/src-tauri/icons/ios/AppIcon-29x29@2x-1.png new file mode 100644 index 0000000..610258a Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-29x29@2x-1.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@2x.png b/src-tauri/icons/ios/AppIcon-29x29@2x.png new file mode 100644 index 0000000..610258a Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-29x29@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@3x.png b/src-tauri/icons/ios/AppIcon-29x29@3x.png new file mode 100644 index 0000000..b9f5962 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-29x29@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@1x.png b/src-tauri/icons/ios/AppIcon-40x40@1x.png new file mode 100644 index 0000000..a1ecf75 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-40x40@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@2x-1.png b/src-tauri/icons/ios/AppIcon-40x40@2x-1.png new file mode 100644 index 0000000..baf4d20 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-40x40@2x-1.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@2x.png b/src-tauri/icons/ios/AppIcon-40x40@2x.png new file mode 100644 index 0000000..baf4d20 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-40x40@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@3x.png b/src-tauri/icons/ios/AppIcon-40x40@3x.png new file mode 100644 index 0000000..fa3db61 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-40x40@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-512@2x.png b/src-tauri/icons/ios/AppIcon-512@2x.png new file mode 100644 index 0000000..83e7ed5 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-512@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-60x60@2x.png b/src-tauri/icons/ios/AppIcon-60x60@2x.png new file mode 100644 index 0000000..fa3db61 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-60x60@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-60x60@3x.png b/src-tauri/icons/ios/AppIcon-60x60@3x.png new file mode 100644 index 0000000..22ca01d Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-60x60@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-76x76@1x.png b/src-tauri/icons/ios/AppIcon-76x76@1x.png new file mode 100644 index 0000000..1a4c947 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-76x76@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-76x76@2x.png b/src-tauri/icons/ios/AppIcon-76x76@2x.png new file mode 100644 index 0000000..b97f359 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-76x76@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png b/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png new file mode 100644 index 0000000..dfc69c4 Binary files /dev/null and b/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png differ diff --git a/src/app/apple-icon.png b/src/app/apple-icon.png new file mode 100644 index 0000000..76f3c17 Binary files /dev/null and b/src/app/apple-icon.png differ diff --git a/src/app/connect/page.tsx b/src/app/connect/page.tsx index e9be222..1454447 100644 --- a/src/app/connect/page.tsx +++ b/src/app/connect/page.tsx @@ -1,3 +1,4 @@ +import { Logo } from "@mind-studio/ui"; import ConnectForm from "@/components/ConnectForm"; import { PrototypeWarning } from "@/components/PrototypeWarning"; @@ -13,8 +14,11 @@ const IS_LOCAL_ISSUER = ISSUER.includes("localhost") || ISSUER.includes("127.0.0 export default function ConnectPage() { return (
-

- Mind Shell — the everything app + {/* The shell is the unified Mind host — its lockup is the shared weave mark + + the "Mind" wordmark (no per-app label), from the design system. */} + +

+ The everything app

Sign in once. Everything lives in your pod. diff --git a/src/app/icon.svg b/src/app/icon.svg index d1c2a79..9ac8266 100644 --- a/src/app/icon.svg +++ b/src/app/icon.svg @@ -1,4 +1,66 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/manifest.ts b/src/app/manifest.ts new file mode 100644 index 0000000..fe7f64a --- /dev/null +++ b/src/app/manifest.ts @@ -0,0 +1,42 @@ +import type { MetadataRoute } from "next"; + +// Web app manifest — lets users add Mind (the shell host) to the homescreen with +// the brand mark and Mind Green chrome. Maskable icons (generated by +// scripts/gen-icons.mjs from the canonical mark) bleed green to the edges so the +// platform mask can crop the corners without clipping the weave. +export default function manifest(): MetadataRoute.Manifest { + return { + name: "Mind — the everything app", + short_name: "Mind", + description: + "A Dock-style shell that wraps your Mind identity and hosts every app on one surface — shipping with Vault, a zero-knowledge password manager.", + start_url: "/", + display: "standalone", + background_color: "#07080b", + theme_color: "#16B88A", + // Both PNGs live in public/ (served at the root) and carry the green to the + // edges; the 512 doubles as the "any" icon (a little safe-zone padding is + // fine there). Separate entries per purpose — Next's manifest type rejects + // the space-separated "any maskable" form the spec allows. + icons: [ + { + src: "/icon-192.png", + sizes: "192x192", + type: "image/png", + purpose: "maskable", + }, + { + src: "/icon-512.png", + sizes: "512x512", + type: "image/png", + purpose: "maskable", + }, + { + src: "/icon-512.png", + sizes: "512x512", + type: "image/png", + purpose: "any", + }, + ], + }; +} diff --git a/src/app/opengraph-image.tsx b/src/app/opengraph-image.tsx new file mode 100644 index 0000000..4bc14ed --- /dev/null +++ b/src/app/opengraph-image.tsx @@ -0,0 +1,75 @@ +import { MIND_MARK_SVG } from "@mind-studio/ui/brand"; +import { ImageResponse } from "next/og"; + +export const alt = "Mind — the everything app"; +export const size = { width: 1200, height: 630 }; +export const contentType = "image/png"; + +// The canonical Mind mark as a data URI, so the share card carries the real +// brand artwork (sourced from the design system, never a vendored copy). +const MARK_DATA_URI = `data:image/svg+xml;base64,${Buffer.from(MIND_MARK_SVG).toString("base64")}`; + +// Social share card. Uses the default font (no remote fetch) so it renders +// deterministically at build time. Mind Green on dark to match the brand +// (green is the single UI accent; cyan/teal only as atmospheric glow). The +// shell is the unified host, so the lockup reads as the bare "Mind" wordmark. +export default function OpengraphImage() { + return new ImageResponse( +
+
+ {/* biome-ignore lint/performance/noImgElement: Satori (next/og) only supports . */} + + Mind +
+
+
+ One surface · every app · your pod +
+
+ One identity.  + Every app. +
+
+ A Dock-style shell that wraps your Mind identity and hosts every app on one surface — + shipping with Vault, a zero-knowledge password manager. +
+
+ mindpods.org +
+
, + { ...size }, + ); +}