From 93675d78eac5888ac25525bd59ca91b694ff9f79 Mon Sep 17 00:00:00 2001 From: Amit Date: Fri, 6 Nov 2026 15:32:54 +0530 Subject: [PATCH 1/6] Add Leather Desk skeuomorph theme using materials and stylesheet. Demonstrates physical chrome tokens and a scoped grain stylesheet via the new theme-provider contract. Co-authored-by: Cursor --- plugins/theme-skeuomorph/manifest.json | 21 +++ plugins/theme-skeuomorph/src/index.ts | 192 +++++++++++++++++++++++++ public/catalog.json | 14 ++ public/theme-skeuomorph.bundle.json | 24 ++++ 4 files changed, 251 insertions(+) create mode 100644 plugins/theme-skeuomorph/manifest.json create mode 100644 plugins/theme-skeuomorph/src/index.ts create mode 100644 public/theme-skeuomorph.bundle.json diff --git a/plugins/theme-skeuomorph/manifest.json b/plugins/theme-skeuomorph/manifest.json new file mode 100644 index 0000000..6c2b604 --- /dev/null +++ b/plugins/theme-skeuomorph/manifest.json @@ -0,0 +1,21 @@ +{ + "id": "readergo.theme.skeuomorph", + "name": "Leather Desk", + "version": "1.0.0", + "description": "Skeuomorphic leather-and-brass workspace chrome with physical materials and a scoped theme stylesheet.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } +} diff --git a/plugins/theme-skeuomorph/src/index.ts b/plugins/theme-skeuomorph/src/index.ts new file mode 100644 index 0000000..44701e1 --- /dev/null +++ b/plugins/theme-skeuomorph/src/index.ts @@ -0,0 +1,192 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Plugin, PluginContext } from '@readergo/plugin-sdk'; + +/** + * Leather Desk - demonstrates ThemeMaterials + first-class stylesheet. + * Host applies radius/shadow/blur tokens and injects scoped CSS under [data-theme]. + */ + +const FRAUNCES = { + id: 'fraunces-display', + name: 'Fraunces', + family: "'Fraunces', 'Georgia', serif", + category: 'display' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap', + targets: ['display', 'editor'] as const, +}; + +const SOURCE_SANS = { + id: 'source-sans-3', + name: 'Source Sans 3', + family: "'Source Sans 3', system-ui, sans-serif", + category: 'sans' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap', + targets: ['body', 'all'] as const, +}; + +const LEATHER_STYLESHEET = ` + /* Desk blotter grain on the workspace root */ + background-image: + radial-gradient(ellipse at 20% 10%, rgb(120 70 40 / 0.18), transparent 45%), + radial-gradient(ellipse at 80% 90%, rgb(40 20 10 / 0.25), transparent 50%), + repeating-linear-gradient( + 115deg, + rgb(255 255 255 / 0.015) 0 1px, + transparent 1px 3px + ); + + .bg-card, + .bg-card\\/40, + .bg-card\\/50, + .bg-card\\/60, + .bg-card\\/70, + .bg-card\\/75, + .bg-card\\/80, + .bg-card\\/85, + .bg-popover, + .bg-popover\\/95 { + background-image: + linear-gradient(180deg, rgb(255 255 255 / 0.07), transparent 40%), + linear-gradient(0deg, rgb(0 0 0 / 0.12), transparent 35%); + box-shadow: var(--inset-highlight), var(--shadow-md); + border-color: hsl(var(--border)); + } + + button, + [role="button"], + .bg-primary { + box-shadow: + var(--inset-highlight), + 0 1px 0 rgb(255 220 160 / 0.25), + var(--shadow-sm); + } + + button:active, + [role="button"]:active { + box-shadow: var(--inset-shadow); + transform: translateY(1px); + } + + input, + textarea, + select, + [data-slot="input"] { + box-shadow: var(--inset-shadow); + background-image: linear-gradient(180deg, rgb(0 0 0 / 0.08), transparent 50%); + } + + /* Soft brass edge on focused actuators */ + button:focus-visible, + [role="button"]:focus-visible, + a:focus-visible, + input:focus-visible, + textarea:focus-visible { + outline: 2px solid hsl(var(--ring)); + outline-offset: 2px; + } +`; + +const LEATHER_DESK_THEME = { + id: 'leather-desk', + name: 'Leather Desk', + type: 'dark' as const, + author: 'ReaderGo Materials', + description: + 'Skeuomorphic walnut-and-brass desk: physical radius, embossed elevation, zero frosted blur, and a scoped leather grain stylesheet.', + colors: { + background: '25 28% 12%', + foreground: '36 40% 88%', + card: '25 24% 16%', + cardForeground: '36 40% 88%', + border: '30 22% 28%', + primary: '36 55% 48%', + primaryForeground: '25 40% 10%', + secondary: '25 18% 20%', + secondaryForeground: '36 30% 82%', + muted: '25 16% 18%', + mutedForeground: '30 14% 58%', + accent: '36 55% 48%', + accentForeground: '25 40% 10%', + destructive: '6 70% 48%', + destructiveForeground: '0 0% 100%', + success: '142 40% 42%', + successForeground: '0 0% 100%', + warning: '38 80% 48%', + warningForeground: '25 40% 10%', + info: '200 40% 48%', + infoForeground: '0 0% 100%', + input: '25 22% 14%', + ring: '36 55% 52%', + heading1: '36 60% 72%', + heading2: '34 45% 66%', + heading3: '32 35% 60%', + }, + fonts: { + display: FRAUNCES, + body: SOURCE_SANS, + editor: FRAUNCES, + mono: SOURCE_SANS, + }, + materials: { + radius: '0.65rem', + radiusSm: '0.4rem', + radiusMd: '0.5rem', + radiusLg: '0.65rem', + radiusXl: '0.85rem', + radius2xl: '1rem', + shadowSm: '0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)', + shadowMd: + '0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)', + shadowLg: + '0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)', + shadowXl: '0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)', + surfaceBlur: '0px', + borderWidth: '1px', + insetHighlight: 'inset 0 1px 0 rgb(255 230 180 / 0.22)', + insetShadow: 'inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)', + }, + stylesheet: LEATHER_STYLESHEET, + stylesheetScoped: true, +}; + +export const SkeuomorphThemePlugin: Plugin = { + manifest: { + id: 'readergo.theme.skeuomorph', + name: 'Leather Desk', + version: '1.0.0', + description: + 'Skeuomorphic leather-and-brass workspace chrome with physical materials and a scoped theme stylesheet.', + category: 'feature', + provides: ['theme-provider', 'font-provider'], + permissions: [], + }, + + async activate(context: PluginContext) { + context.log.info('Leather Desk skeuomorph theme activating (materials + stylesheet)...'); + + await context.registerCapability('theme-provider', { + getThemes: () => [LEATHER_DESK_THEME], + }); + + await context.registerCapability('font-provider', { + getFonts: () => [FRAUNCES, SOURCE_SANS], + }); + + await context.registerCommand({ + id: 'readergo.theme.skeuomorph.enable', + title: 'Theme: Enable Leather Desk', + handler: async () => { + await context.executeCommand('readergo.theme.setTheme', { + themeId: LEATHER_DESK_THEME.id, + }); + return { activeTheme: LEATHER_DESK_THEME.id }; + }, + }); + }, + + deactivate(context: PluginContext) { + context.log.info('Leather Desk skeuomorph theme deactivated.'); + }, +}; + +export default SkeuomorphThemePlugin; diff --git a/public/catalog.json b/public/catalog.json index c36bb6b..88673d6 100644 --- a/public/catalog.json +++ b/public/catalog.json @@ -223,6 +223,20 @@ "bundleHash": "a732e76137d8ce79", "hash": "a732e76137d8ce79" }, + { + "id": "readergo.theme.skeuomorph", + "name": "Leather Desk", + "description": "Skeuomorphic leather-and-brass workspace chrome with physical materials and a scoped theme stylesheet.", + "category": "feature", + "version": "1.0.0", + "provides": [ + "theme-provider", + "font-provider" + ], + "bundleUrl": "theme-skeuomorph.bundle.json", + "bundleHash": "1ee551182074e14d", + "hash": "1ee551182074e14d" + }, { "id": "readergo.features.link-clipper", "name": "Link Clipper", diff --git a/public/theme-skeuomorph.bundle.json b/public/theme-skeuomorph.bundle.json new file mode 100644 index 0000000..aa6afd6 --- /dev/null +++ b/public/theme-skeuomorph.bundle.json @@ -0,0 +1,24 @@ +{ + "manifest": { + "id": "readergo.theme.skeuomorph", + "name": "Leather Desk", + "version": "1.0.0", + "description": "Skeuomorphic leather-and-brass workspace chrome with physical materials and a scoped theme stylesheet.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } + }, + "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-skeuomorph/src/index.ts\nvar FRAUNCES = {\n id: \"fraunces-display\",\n name: \"Fraunces\",\n family: \"'Fraunces', 'Georgia', serif\",\n category: \"display\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-3\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar LEATHER_STYLESHEET = `\n /* Desk blotter grain on the workspace root */\n background-image:\n radial-gradient(ellipse at 20% 10%, rgb(120 70 40 / 0.18), transparent 45%),\n radial-gradient(ellipse at 80% 90%, rgb(40 20 10 / 0.25), transparent 50%),\n repeating-linear-gradient(\n 115deg,\n rgb(255 255 255 / 0.015) 0 1px,\n transparent 1px 3px\n );\n\n .bg-card,\n .bg-card\\\\/40,\n .bg-card\\\\/50,\n .bg-card\\\\/60,\n .bg-card\\\\/70,\n .bg-card\\\\/75,\n .bg-card\\\\/80,\n .bg-card\\\\/85,\n .bg-popover,\n .bg-popover\\\\/95 {\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.07), transparent 40%),\n linear-gradient(0deg, rgb(0 0 0 / 0.12), transparent 35%);\n box-shadow: var(--inset-highlight), var(--shadow-md);\n border-color: hsl(var(--border));\n }\n\n button,\n [role=\"button\"],\n .bg-primary {\n box-shadow:\n var(--inset-highlight),\n 0 1px 0 rgb(255 220 160 / 0.25),\n var(--shadow-sm);\n }\n\n button:active,\n [role=\"button\"]:active {\n box-shadow: var(--inset-shadow);\n transform: translateY(1px);\n }\n\n input,\n textarea,\n select,\n [data-slot=\"input\"] {\n box-shadow: var(--inset-shadow);\n background-image: linear-gradient(180deg, rgb(0 0 0 / 0.08), transparent 50%);\n }\n\n /* Soft brass edge on focused actuators */\n button:focus-visible,\n [role=\"button\"]:focus-visible,\n a:focus-visible,\n input:focus-visible,\n textarea:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n }\n`;\nvar LEATHER_DESK_THEME = {\n id: \"leather-desk\",\n name: \"Leather Desk\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Skeuomorphic walnut-and-brass desk: physical radius, embossed elevation, zero frosted blur, and a scoped leather grain stylesheet.\",\n colors: {\n background: \"25 28% 12%\",\n foreground: \"36 40% 88%\",\n card: \"25 24% 16%\",\n cardForeground: \"36 40% 88%\",\n border: \"30 22% 28%\",\n primary: \"36 55% 48%\",\n primaryForeground: \"25 40% 10%\",\n secondary: \"25 18% 20%\",\n secondaryForeground: \"36 30% 82%\",\n muted: \"25 16% 18%\",\n mutedForeground: \"30 14% 58%\",\n accent: \"36 55% 48%\",\n accentForeground: \"25 40% 10%\",\n destructive: \"6 70% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"142 40% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 48%\",\n warningForeground: \"25 40% 10%\",\n info: \"200 40% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"25 22% 14%\",\n ring: \"36 55% 52%\",\n heading1: \"36 60% 72%\",\n heading2: \"34 45% 66%\",\n heading3: \"32 35% 60%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: SOURCE_SANS\n },\n materials: {\n radius: \"0.65rem\",\n radiusSm: \"0.4rem\",\n radiusMd: \"0.5rem\",\n radiusLg: \"0.65rem\",\n radiusXl: \"0.85rem\",\n radius2xl: \"1rem\",\n shadowSm: \"0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)\",\n shadowMd: \"0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)\",\n shadowXl: \"0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)\",\n surfaceBlur: \"0px\",\n borderWidth: \"1px\",\n insetHighlight: \"inset 0 1px 0 rgb(255 230 180 / 0.22)\",\n insetShadow: \"inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)\"\n },\n stylesheet: LEATHER_STYLESHEET,\n stylesheetScoped: true\n};\nvar SkeuomorphThemePlugin = {\n manifest: {\n id: \"readergo.theme.skeuomorph\",\n name: \"Leather Desk\",\n version: \"1.0.0\",\n description: \"Skeuomorphic leather-and-brass workspace chrome with physical materials and a scoped theme stylesheet.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(\"Leather Desk skeuomorph theme activating (materials + stylesheet)...\");\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => [LEATHER_DESK_THEME]\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => [FRAUNCES, SOURCE_SANS]\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enable\",\n title: \"Theme: Enable Leather Desk\",\n handler: async () => {\n await context.executeCommand(\"readergo.theme.setTheme\", {\n themeId: LEATHER_DESK_THEME.id\n });\n return { activeTheme: LEATHER_DESK_THEME.id };\n }\n });\n },\n deactivate(context) {\n context.log.info(\"Leather Desk skeuomorph theme deactivated.\");\n }\n};\nvar index_default = SkeuomorphThemePlugin;\n\n\n return { SkeuomorphThemePlugin: SkeuomorphThemePlugin, default: index_default };\n}\n" +} \ No newline at end of file From 20a045d16a7c10891b81c36ffb35e831159c208a Mon Sep 17 00:00:00 2001 From: Amit Date: Fri, 6 Nov 2026 15:43:09 +0530 Subject: [PATCH 2/6] Expand Skeuomorph Suite with Steel, Journal, and Walnut atmospheres. Deepens shared physical chrome and ships four materials+stylesheet themes with cycle commands. Co-authored-by: Cursor --- plugins/theme-skeuomorph/manifest.json | 6 +- plugins/theme-skeuomorph/src/chrome.ts | 141 +++++++++++ plugins/theme-skeuomorph/src/index.ts | 225 ++++++------------ plugins/theme-skeuomorph/src/themes.ts | 308 +++++++++++++++++++++++++ public/catalog.json | 28 +-- public/theme-skeuomorph.bundle.json | 8 +- 6 files changed, 537 insertions(+), 179 deletions(-) create mode 100644 plugins/theme-skeuomorph/src/chrome.ts create mode 100644 plugins/theme-skeuomorph/src/themes.ts diff --git a/plugins/theme-skeuomorph/manifest.json b/plugins/theme-skeuomorph/manifest.json index 6c2b604..3d9bd9c 100644 --- a/plugins/theme-skeuomorph/manifest.json +++ b/plugins/theme-skeuomorph/manifest.json @@ -1,8 +1,8 @@ { "id": "readergo.theme.skeuomorph", - "name": "Leather Desk", - "version": "1.0.0", - "description": "Skeuomorphic leather-and-brass workspace chrome with physical materials and a scoped theme stylesheet.", + "name": "Skeuomorph Suite", + "version": "1.1.0", + "description": "Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.", "category": "feature", "provides": [ "theme-provider", diff --git a/plugins/theme-skeuomorph/src/chrome.ts b/plugins/theme-skeuomorph/src/chrome.ts new file mode 100644 index 0000000..3f7ab14 --- /dev/null +++ b/plugins/theme-skeuomorph/src/chrome.ts @@ -0,0 +1,141 @@ +/** + * Shared physical-chrome CSS fragments. + * Host wraps each theme stylesheet under [data-theme=""]. + */ + +/** Embossed panels, recessed fields, raised actuators - works with ThemeMaterials vars. */ +export const SHARED_CHROME = ` + /* Recessed trays (side rails, inspector, activity bar) */ + aside, + [data-sidebar], + nav[aria-label], + .border-r.bg-background\\/95, + .border-r.bg-background\\/70, + .border-r.bg-background\\/85, + .border-l { + box-shadow: var(--inset-shadow); + } + + /* Embossed cards / popovers */ + .bg-card, + .bg-card\\/40, + .bg-card\\/50, + .bg-card\\/60, + .bg-card\\/70, + .bg-card\\/75, + .bg-card\\/80, + .bg-card\\/85, + .bg-popover, + .bg-popover\\/95 { + background-image: + linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 42%), + linear-gradient(0deg, rgb(0 0 0 / 0.14), transparent 38%); + box-shadow: var(--inset-highlight), var(--shadow-md); + border-color: hsl(var(--border)); + } + + /* Raised actuators */ + button, + [role="button"], + .bg-primary { + box-shadow: var(--inset-highlight), var(--shadow-sm); + } + + button:active, + [role="button"]:active { + box-shadow: var(--inset-shadow); + transform: translateY(1px); + } + + /* Recessed fields */ + input, + textarea, + select, + [data-slot="input"] { + box-shadow: var(--inset-shadow); + background-image: linear-gradient(180deg, rgb(0 0 0 / 0.1), transparent 55%); + } + + /* Hairline metal/leather edge on focus */ + button:focus-visible, + [role="button"]:focus-visible, + a:focus-visible, + input:focus-visible, + textarea:focus-visible { + outline: 2px solid hsl(var(--ring)); + outline-offset: 2px; + } + + /* Kill glass - materials already zero blur; keep surfaces opaque */ + .backdrop-blur-sm, + .backdrop-blur, + .backdrop-blur-md, + .backdrop-blur-lg, + .backdrop-blur-xl, + .backdrop-blur-2xl, + .backdrop-blur-3xl { + -webkit-backdrop-filter: none !important; + backdrop-filter: none !important; + } +`; + +export const LEATHER_GRAIN = ` + background-image: + radial-gradient(ellipse at 18% 8%, rgb(140 80 45 / 0.22), transparent 42%), + radial-gradient(ellipse at 82% 92%, rgb(30 14 8 / 0.35), transparent 48%), + repeating-linear-gradient( + 118deg, + rgb(255 230 180 / 0.025) 0 1px, + transparent 1px 4px + ), + repeating-linear-gradient( + 28deg, + rgb(0 0 0 / 0.04) 0 2px, + transparent 2px 5px + ); +`; + +export const STEEL_BRUSH = ` + background-image: + linear-gradient(180deg, rgb(255 255 255 / 0.06), transparent 35%), + repeating-linear-gradient( + 90deg, + rgb(255 255 255 / 0.035) 0 1px, + transparent 1px 3px + ), + repeating-linear-gradient( + 0deg, + rgb(0 0 0 / 0.04) 0 1px, + transparent 1px 2px + ); +`; + +export const JOURNAL_FIBER = ` + background-image: + radial-gradient(ellipse at 50% 0%, rgb(255 255 255 / 0.55), transparent 55%), + repeating-linear-gradient( + 0deg, + rgb(40 30 20 / 0.03) 0 1px, + transparent 1px 3px + ), + repeating-linear-gradient( + 90deg, + rgb(40 30 20 / 0.02) 0 1px, + transparent 1px 4px + ); +`; + +export const WALNUT_GRAIN = ` + background-image: + radial-gradient(ellipse at 30% 20%, rgb(160 100 50 / 0.15), transparent 50%), + repeating-linear-gradient( + 95deg, + rgb(255 210 150 / 0.03) 0 2px, + transparent 2px 7px + ), + repeating-linear-gradient( + 5deg, + rgb(0 0 0 / 0.06) 0 1px, + transparent 1px 6px + ); +`; diff --git a/plugins/theme-skeuomorph/src/index.ts b/plugins/theme-skeuomorph/src/index.ts index 44701e1..d14b7a3 100644 --- a/plugins/theme-skeuomorph/src/index.ts +++ b/plugins/theme-skeuomorph/src/index.ts @@ -1,192 +1,101 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Plugin, PluginContext } from '@readergo/plugin-sdk'; +import { + BOUND_JOURNAL_THEME, + BRUSHED_STEEL_THEME, + LEATHER_DESK_THEME, + SKEUO_FONTS, + SKEUO_THEME_IDS, + SKEUO_THEMES, + WALNUT_LIBRARY_THEME, +} from './themes'; /** - * Leather Desk - demonstrates ThemeMaterials + first-class stylesheet. - * Host applies radius/shadow/blur tokens and injects scoped CSS under [data-theme]. + * Skeuomorph Suite - physical chrome themes using ThemeMaterials + stylesheet. */ -const FRAUNCES = { - id: 'fraunces-display', - name: 'Fraunces', - family: "'Fraunces', 'Georgia', serif", - category: 'display' as const, - cssUrl: 'https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap', - targets: ['display', 'editor'] as const, -}; - -const SOURCE_SANS = { - id: 'source-sans-3', - name: 'Source Sans 3', - family: "'Source Sans 3', system-ui, sans-serif", - category: 'sans' as const, - cssUrl: 'https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap', - targets: ['body', 'all'] as const, -}; - -const LEATHER_STYLESHEET = ` - /* Desk blotter grain on the workspace root */ - background-image: - radial-gradient(ellipse at 20% 10%, rgb(120 70 40 / 0.18), transparent 45%), - radial-gradient(ellipse at 80% 90%, rgb(40 20 10 / 0.25), transparent 50%), - repeating-linear-gradient( - 115deg, - rgb(255 255 255 / 0.015) 0 1px, - transparent 1px 3px - ); - - .bg-card, - .bg-card\\/40, - .bg-card\\/50, - .bg-card\\/60, - .bg-card\\/70, - .bg-card\\/75, - .bg-card\\/80, - .bg-card\\/85, - .bg-popover, - .bg-popover\\/95 { - background-image: - linear-gradient(180deg, rgb(255 255 255 / 0.07), transparent 40%), - linear-gradient(0deg, rgb(0 0 0 / 0.12), transparent 35%); - box-shadow: var(--inset-highlight), var(--shadow-md); - border-color: hsl(var(--border)); - } - - button, - [role="button"], - .bg-primary { - box-shadow: - var(--inset-highlight), - 0 1px 0 rgb(255 220 160 / 0.25), - var(--shadow-sm); - } - - button:active, - [role="button"]:active { - box-shadow: var(--inset-shadow); - transform: translateY(1px); - } - - input, - textarea, - select, - [data-slot="input"] { - box-shadow: var(--inset-shadow); - background-image: linear-gradient(180deg, rgb(0 0 0 / 0.08), transparent 50%); - } - - /* Soft brass edge on focused actuators */ - button:focus-visible, - [role="button"]:focus-visible, - a:focus-visible, - input:focus-visible, - textarea:focus-visible { - outline: 2px solid hsl(var(--ring)); - outline-offset: 2px; - } -`; - -const LEATHER_DESK_THEME = { - id: 'leather-desk', - name: 'Leather Desk', - type: 'dark' as const, - author: 'ReaderGo Materials', - description: - 'Skeuomorphic walnut-and-brass desk: physical radius, embossed elevation, zero frosted blur, and a scoped leather grain stylesheet.', - colors: { - background: '25 28% 12%', - foreground: '36 40% 88%', - card: '25 24% 16%', - cardForeground: '36 40% 88%', - border: '30 22% 28%', - primary: '36 55% 48%', - primaryForeground: '25 40% 10%', - secondary: '25 18% 20%', - secondaryForeground: '36 30% 82%', - muted: '25 16% 18%', - mutedForeground: '30 14% 58%', - accent: '36 55% 48%', - accentForeground: '25 40% 10%', - destructive: '6 70% 48%', - destructiveForeground: '0 0% 100%', - success: '142 40% 42%', - successForeground: '0 0% 100%', - warning: '38 80% 48%', - warningForeground: '25 40% 10%', - info: '200 40% 48%', - infoForeground: '0 0% 100%', - input: '25 22% 14%', - ring: '36 55% 52%', - heading1: '36 60% 72%', - heading2: '34 45% 66%', - heading3: '32 35% 60%', - }, - fonts: { - display: FRAUNCES, - body: SOURCE_SANS, - editor: FRAUNCES, - mono: SOURCE_SANS, - }, - materials: { - radius: '0.65rem', - radiusSm: '0.4rem', - radiusMd: '0.5rem', - radiusLg: '0.65rem', - radiusXl: '0.85rem', - radius2xl: '1rem', - shadowSm: '0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)', - shadowMd: - '0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)', - shadowLg: - '0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)', - shadowXl: '0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)', - surfaceBlur: '0px', - borderWidth: '1px', - insetHighlight: 'inset 0 1px 0 rgb(255 230 180 / 0.22)', - insetShadow: 'inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)', - }, - stylesheet: LEATHER_STYLESHEET, - stylesheetScoped: true, -}; - export const SkeuomorphThemePlugin: Plugin = { manifest: { id: 'readergo.theme.skeuomorph', - name: 'Leather Desk', - version: '1.0.0', + name: 'Skeuomorph Suite', + version: '1.1.0', description: - 'Skeuomorphic leather-and-brass workspace chrome with physical materials and a scoped theme stylesheet.', + 'Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.', category: 'feature', provides: ['theme-provider', 'font-provider'], permissions: [], }, async activate(context: PluginContext) { - context.log.info('Leather Desk skeuomorph theme activating (materials + stylesheet)...'); + context.log.info('Skeuomorph Suite activating (4 physical atmospheres)...'); await context.registerCapability('theme-provider', { - getThemes: () => [LEATHER_DESK_THEME], + getThemes: () => SKEUO_THEMES, }); await context.registerCapability('font-provider', { - getFonts: () => [FRAUNCES, SOURCE_SANS], + getFonts: () => SKEUO_FONTS, }); + const enable = async (themeId: string) => { + await context.executeCommand('readergo.theme.setTheme', { themeId }); + return { activeTheme: themeId }; + }; + await context.registerCommand({ - id: 'readergo.theme.skeuomorph.enable', - title: 'Theme: Enable Leather Desk', + id: 'readergo.theme.skeuomorph.enableLeather', + title: 'Theme: Leather Desk', + handler: async () => enable(LEATHER_DESK_THEME.id), + }); + + await context.registerCommand({ + id: 'readergo.theme.skeuomorph.enableSteel', + title: 'Theme: Brushed Steel', + handler: async () => enable(BRUSHED_STEEL_THEME.id), + }); + + await context.registerCommand({ + id: 'readergo.theme.skeuomorph.enableJournal', + title: 'Theme: Bound Journal', + handler: async () => enable(BOUND_JOURNAL_THEME.id), + }); + + await context.registerCommand({ + id: 'readergo.theme.skeuomorph.enableWalnut', + title: 'Theme: Walnut Library', + handler: async () => enable(WALNUT_LIBRARY_THEME.id), + }); + + await context.registerCommand({ + id: 'readergo.theme.skeuomorph.cycle', + title: 'Theme: Cycle Skeuomorph Atmosphere', handler: async () => { - await context.executeCommand('readergo.theme.setTheme', { - themeId: LEATHER_DESK_THEME.id, - }); - return { activeTheme: LEATHER_DESK_THEME.id }; + const active = (await context.executeCommand('readergo.theme.getActiveTheme')) as any; + const currentId = active?.id || LEATHER_DESK_THEME.id; + const idx = SKEUO_THEME_IDS.indexOf(currentId); + const next = SKEUO_THEME_IDS[idx >= 0 ? (idx + 1) % SKEUO_THEME_IDS.length : 0]; + return enable(next); }, }); + + await context.registerCommand({ + id: 'readergo.theme.skeuomorph.getModes', + title: 'Theme: List Skeuomorph Atmospheres', + handler: async () => + SKEUO_THEMES.map((t) => ({ + id: t.id, + name: t.name, + type: t.type, + description: t.description, + })), + }); }, deactivate(context: PluginContext) { - context.log.info('Leather Desk skeuomorph theme deactivated.'); + context.log.info('Skeuomorph Suite deactivated.'); }, }; export default SkeuomorphThemePlugin; +export * from './themes'; +export * from './chrome'; diff --git a/plugins/theme-skeuomorph/src/themes.ts b/plugins/theme-skeuomorph/src/themes.ts new file mode 100644 index 0000000..26619d9 --- /dev/null +++ b/plugins/theme-skeuomorph/src/themes.ts @@ -0,0 +1,308 @@ +import { + JOURNAL_FIBER, + LEATHER_GRAIN, + SHARED_CHROME, + STEEL_BRUSH, + WALNUT_GRAIN, +} from './chrome'; + +export const FRAUNCES = { + id: 'fraunces-display', + name: 'Fraunces', + family: "'Fraunces', 'Georgia', serif", + category: 'display' as const, + cssUrl: + 'https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap', + targets: ['display', 'editor'] as const, +}; + +export const SOURCE_SANS = { + id: 'source-sans-3', + name: 'Source Sans 3', + family: "'Source Sans 3', system-ui, sans-serif", + category: 'sans' as const, + cssUrl: + 'https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap', + targets: ['body', 'all'] as const, +}; + +export const IBM_PLEX_MONO = { + id: 'ibm-plex-mono-steel', + name: 'IBM Plex Mono', + family: "'IBM Plex Mono', ui-monospace, monospace", + category: 'mono' as const, + cssUrl: + 'https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap', + targets: ['mono'] as const, +}; + +export const LITERATA = { + id: 'literata-journal', + name: 'Literata', + family: "'Literata', 'Georgia', serif", + category: 'serif' as const, + cssUrl: + 'https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap', + targets: ['display', 'editor'] as const, +}; + +export const SKEUO_FONTS = [FRAUNCES, SOURCE_SANS, IBM_PLEX_MONO, LITERATA]; + +const PHYSICAL_MATERIALS_BASE = { + surfaceBlur: '0px', + borderWidth: '1px', +}; + +export const LEATHER_DESK_THEME = { + id: 'leather-desk', + name: 'Leather Desk', + type: 'dark' as const, + author: 'ReaderGo Materials', + description: + 'Walnut blotter and brass actuators - embossed cards, recessed trays, leather grain.', + colors: { + background: '25 28% 12%', + foreground: '36 40% 88%', + card: '25 24% 16%', + cardForeground: '36 40% 88%', + border: '30 22% 28%', + primary: '36 55% 48%', + primaryForeground: '25 40% 10%', + secondary: '25 18% 20%', + secondaryForeground: '36 30% 82%', + muted: '25 16% 18%', + mutedForeground: '30 14% 58%', + accent: '36 55% 48%', + accentForeground: '25 40% 10%', + destructive: '6 70% 48%', + destructiveForeground: '0 0% 100%', + success: '142 40% 42%', + successForeground: '0 0% 100%', + warning: '38 80% 48%', + warningForeground: '25 40% 10%', + info: '200 40% 48%', + infoForeground: '0 0% 100%', + input: '25 22% 14%', + ring: '36 55% 52%', + heading1: '36 60% 72%', + heading2: '34 45% 66%', + heading3: '32 35% 60%', + }, + fonts: { + display: FRAUNCES, + body: SOURCE_SANS, + editor: FRAUNCES, + mono: SOURCE_SANS, + }, + materials: { + ...PHYSICAL_MATERIALS_BASE, + radius: '0.65rem', + radiusSm: '0.4rem', + radiusMd: '0.5rem', + radiusLg: '0.65rem', + radiusXl: '0.85rem', + radius2xl: '1rem', + shadowSm: '0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)', + shadowMd: + '0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)', + shadowLg: + '0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)', + shadowXl: '0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)', + insetHighlight: 'inset 0 1px 0 rgb(255 230 180 / 0.22)', + insetShadow: 'inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)', + }, + stylesheet: `${LEATHER_GRAIN}\n${SHARED_CHROME}`, + stylesheetScoped: true, +}; + +export const BRUSHED_STEEL_THEME = { + id: 'brushed-steel', + name: 'Brushed Steel', + type: 'dark' as const, + author: 'ReaderGo Materials', + description: + 'Cold instrument panel - machined aluminum grain, tight radii, cyan status LEDs.', + colors: { + background: '210 12% 14%', + foreground: '210 20% 92%', + card: '210 10% 18%', + cardForeground: '210 20% 92%', + border: '210 8% 32%', + primary: '198 72% 48%', + primaryForeground: '210 30% 8%', + secondary: '210 10% 22%', + secondaryForeground: '210 15% 85%', + muted: '210 8% 20%', + mutedForeground: '210 8% 58%', + accent: '198 72% 48%', + accentForeground: '210 30% 8%', + destructive: '0 65% 50%', + destructiveForeground: '0 0% 100%', + success: '152 45% 42%', + successForeground: '0 0% 100%', + warning: '38 85% 50%', + warningForeground: '210 30% 8%', + info: '198 72% 52%', + infoForeground: '210 30% 8%', + input: '210 12% 16%', + ring: '198 72% 52%', + heading1: '198 70% 72%', + heading2: '200 45% 68%', + heading3: '205 30% 64%', + }, + fonts: { + display: SOURCE_SANS, + body: SOURCE_SANS, + editor: SOURCE_SANS, + mono: IBM_PLEX_MONO, + }, + materials: { + ...PHYSICAL_MATERIALS_BASE, + radius: '0.35rem', + radiusSm: '0.2rem', + radiusMd: '0.28rem', + radiusLg: '0.35rem', + radiusXl: '0.45rem', + radius2xl: '0.55rem', + shadowSm: '0 1px 0 rgb(255 255 255 / 0.14), 0 1px 2px rgb(0 0 0 / 0.5)', + shadowMd: + '0 1px 0 rgb(255 255 255 / 0.1), 0 3px 8px rgb(0 0 0 / 0.45), inset 0 -1px 0 rgb(0 0 0 / 0.25)', + shadowLg: '0 10px 24px rgb(0 0 0 / 0.5), 0 1px 0 rgb(255 255 255 / 0.08)', + shadowXl: '0 18px 36px rgb(0 0 0 / 0.55)', + insetHighlight: 'inset 0 1px 0 rgb(255 255 255 / 0.28)', + insetShadow: 'inset 0 2px 5px rgb(0 0 0 / 0.55), inset 0 1px 0 rgb(0 0 0 / 0.3)', + }, + stylesheet: `${STEEL_BRUSH}\n${SHARED_CHROME}`, + stylesheetScoped: true, +}; + +export const BOUND_JOURNAL_THEME = { + id: 'bound-journal', + name: 'Bound Journal', + type: 'light' as const, + author: 'ReaderGo Materials', + description: + 'Cloth-bound notebook - inked linen fiber, soft pressed pages, midnight ink accents.', + colors: { + background: '40 18% 93%', + foreground: '220 25% 16%', + card: '40 22% 97%', + cardForeground: '220 25% 16%', + border: '35 12% 78%', + primary: '222 35% 28%', + primaryForeground: '40 30% 96%', + secondary: '38 14% 88%', + secondaryForeground: '220 20% 22%', + muted: '38 12% 90%', + mutedForeground: '220 10% 42%', + accent: '160 28% 32%', + accentForeground: '40 30% 96%', + destructive: '4 65% 42%', + destructiveForeground: '0 0% 100%', + success: '152 35% 32%', + successForeground: '0 0% 100%', + warning: '32 70% 38%', + warningForeground: '0 0% 100%', + info: '210 40% 38%', + infoForeground: '0 0% 100%', + input: '40 20% 95%', + ring: '222 35% 32%', + heading1: '222 40% 22%', + heading2: '220 28% 28%', + heading3: '218 20% 34%', + }, + fonts: { + display: LITERATA, + body: SOURCE_SANS, + editor: LITERATA, + mono: IBM_PLEX_MONO, + }, + materials: { + ...PHYSICAL_MATERIALS_BASE, + radius: '0.55rem', + radiusSm: '0.35rem', + radiusMd: '0.45rem', + radiusLg: '0.55rem', + radiusXl: '0.7rem', + radius2xl: '0.85rem', + shadowSm: '0 1px 0 rgb(255 255 255 / 0.85), 0 1px 2px rgb(40 30 20 / 0.12)', + shadowMd: + '0 1px 0 rgb(255 255 255 / 0.9), 0 4px 12px rgb(40 30 20 / 0.12), 0 1px 3px rgb(40 30 20 / 0.08)', + shadowLg: '0 12px 28px rgb(40 30 20 / 0.14), 0 2px 6px rgb(40 30 20 / 0.08)', + shadowXl: '0 20px 40px rgb(40 30 20 / 0.16)', + insetHighlight: 'inset 0 1px 0 rgb(255 255 255 / 0.95)', + insetShadow: 'inset 0 2px 4px rgb(40 30 20 / 0.12), inset 0 1px 0 rgb(40 30 20 / 0.06)', + }, + stylesheet: `${JOURNAL_FIBER}\n${SHARED_CHROME}`, + stylesheetScoped: true, +}; + +export const WALNUT_LIBRARY_THEME = { + id: 'walnut-library', + name: 'Walnut Library', + type: 'dark' as const, + author: 'ReaderGo Materials', + description: + 'Deep library shelves - warm wood grain, amber lamps, wide embossed panels.', + colors: { + background: '28 32% 10%', + foreground: '38 35% 86%', + card: '28 28% 14%', + cardForeground: '38 35% 86%', + border: '32 24% 24%', + primary: '32 70% 46%', + primaryForeground: '28 40% 8%', + secondary: '28 22% 18%', + secondaryForeground: '38 28% 80%', + muted: '28 20% 15%', + mutedForeground: '32 16% 52%', + accent: '150 35% 40%', + accentForeground: '28 40% 8%', + destructive: '8 68% 46%', + destructiveForeground: '0 0% 100%', + success: '150 35% 40%', + successForeground: '0 0% 100%', + warning: '36 78% 48%', + warningForeground: '28 40% 8%', + info: '200 35% 48%', + infoForeground: '0 0% 100%', + input: '28 26% 12%', + ring: '32 70% 50%', + heading1: '38 55% 70%', + heading2: '34 42% 64%', + heading3: '30 32% 58%', + }, + fonts: { + display: FRAUNCES, + body: SOURCE_SANS, + editor: FRAUNCES, + mono: IBM_PLEX_MONO, + }, + materials: { + ...PHYSICAL_MATERIALS_BASE, + radius: '0.75rem', + radiusSm: '0.45rem', + radiusMd: '0.55rem', + radiusLg: '0.75rem', + radiusXl: '1rem', + radius2xl: '1.15rem', + shadowSm: '0 1px 0 rgb(255 200 120 / 0.1), 0 1px 3px rgb(0 0 0 / 0.5)', + shadowMd: + '0 1px 0 rgb(255 200 120 / 0.08), 0 6px 14px rgb(0 0 0 / 0.45), 0 2px 4px rgb(0 0 0 / 0.35)', + shadowLg: '0 14px 32px rgb(0 0 0 / 0.55), 0 4px 10px rgb(0 0 0 / 0.4)', + shadowXl: '0 24px 48px rgb(0 0 0 / 0.6)', + insetHighlight: 'inset 0 1px 0 rgb(255 210 140 / 0.18)', + insetShadow: 'inset 0 3px 6px rgb(0 0 0 / 0.5), inset 0 1px 0 rgb(0 0 0 / 0.3)', + }, + stylesheet: `${WALNUT_GRAIN}\n${SHARED_CHROME}`, + stylesheetScoped: true, +}; + +export const SKEUO_THEMES = [ + LEATHER_DESK_THEME, + BRUSHED_STEEL_THEME, + BOUND_JOURNAL_THEME, + WALNUT_LIBRARY_THEME, +]; + +export const SKEUO_THEME_IDS = SKEUO_THEMES.map((t) => t.id); diff --git a/public/catalog.json b/public/catalog.json index 88673d6..016eaa7 100644 --- a/public/catalog.json +++ b/public/catalog.json @@ -223,20 +223,6 @@ "bundleHash": "a732e76137d8ce79", "hash": "a732e76137d8ce79" }, - { - "id": "readergo.theme.skeuomorph", - "name": "Leather Desk", - "description": "Skeuomorphic leather-and-brass workspace chrome with physical materials and a scoped theme stylesheet.", - "category": "feature", - "version": "1.0.0", - "provides": [ - "theme-provider", - "font-provider" - ], - "bundleUrl": "theme-skeuomorph.bundle.json", - "bundleHash": "1ee551182074e14d", - "hash": "1ee551182074e14d" - }, { "id": "readergo.features.link-clipper", "name": "Link Clipper", @@ -469,6 +455,20 @@ "bundleHash": "1080ee463e3c7560", "hash": "1080ee463e3c7560" }, + { + "id": "readergo.theme.skeuomorph", + "name": "Skeuomorph Suite", + "description": "Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.", + "category": "feature", + "version": "1.1.0", + "provides": [ + "theme-provider", + "font-provider" + ], + "bundleUrl": "theme-skeuomorph.bundle.json", + "bundleHash": "59e024f4f14d4ee7", + "hash": "59e024f4f14d4ee7" + }, { "id": "readergo.theme.solarized", "name": "Solarized Light", diff --git a/public/theme-skeuomorph.bundle.json b/public/theme-skeuomorph.bundle.json index aa6afd6..10cfa9a 100644 --- a/public/theme-skeuomorph.bundle.json +++ b/public/theme-skeuomorph.bundle.json @@ -1,9 +1,9 @@ { "manifest": { "id": "readergo.theme.skeuomorph", - "name": "Leather Desk", - "version": "1.0.0", - "description": "Skeuomorphic leather-and-brass workspace chrome with physical materials and a scoped theme stylesheet.", + "name": "Skeuomorph Suite", + "version": "1.1.0", + "description": "Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.", "category": "feature", "provides": [ "theme-provider", @@ -20,5 +20,5 @@ "ui": "./src/index.ts" } }, - "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-skeuomorph/src/index.ts\nvar FRAUNCES = {\n id: \"fraunces-display\",\n name: \"Fraunces\",\n family: \"'Fraunces', 'Georgia', serif\",\n category: \"display\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-3\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar LEATHER_STYLESHEET = `\n /* Desk blotter grain on the workspace root */\n background-image:\n radial-gradient(ellipse at 20% 10%, rgb(120 70 40 / 0.18), transparent 45%),\n radial-gradient(ellipse at 80% 90%, rgb(40 20 10 / 0.25), transparent 50%),\n repeating-linear-gradient(\n 115deg,\n rgb(255 255 255 / 0.015) 0 1px,\n transparent 1px 3px\n );\n\n .bg-card,\n .bg-card\\\\/40,\n .bg-card\\\\/50,\n .bg-card\\\\/60,\n .bg-card\\\\/70,\n .bg-card\\\\/75,\n .bg-card\\\\/80,\n .bg-card\\\\/85,\n .bg-popover,\n .bg-popover\\\\/95 {\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.07), transparent 40%),\n linear-gradient(0deg, rgb(0 0 0 / 0.12), transparent 35%);\n box-shadow: var(--inset-highlight), var(--shadow-md);\n border-color: hsl(var(--border));\n }\n\n button,\n [role=\"button\"],\n .bg-primary {\n box-shadow:\n var(--inset-highlight),\n 0 1px 0 rgb(255 220 160 / 0.25),\n var(--shadow-sm);\n }\n\n button:active,\n [role=\"button\"]:active {\n box-shadow: var(--inset-shadow);\n transform: translateY(1px);\n }\n\n input,\n textarea,\n select,\n [data-slot=\"input\"] {\n box-shadow: var(--inset-shadow);\n background-image: linear-gradient(180deg, rgb(0 0 0 / 0.08), transparent 50%);\n }\n\n /* Soft brass edge on focused actuators */\n button:focus-visible,\n [role=\"button\"]:focus-visible,\n a:focus-visible,\n input:focus-visible,\n textarea:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n }\n`;\nvar LEATHER_DESK_THEME = {\n id: \"leather-desk\",\n name: \"Leather Desk\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Skeuomorphic walnut-and-brass desk: physical radius, embossed elevation, zero frosted blur, and a scoped leather grain stylesheet.\",\n colors: {\n background: \"25 28% 12%\",\n foreground: \"36 40% 88%\",\n card: \"25 24% 16%\",\n cardForeground: \"36 40% 88%\",\n border: \"30 22% 28%\",\n primary: \"36 55% 48%\",\n primaryForeground: \"25 40% 10%\",\n secondary: \"25 18% 20%\",\n secondaryForeground: \"36 30% 82%\",\n muted: \"25 16% 18%\",\n mutedForeground: \"30 14% 58%\",\n accent: \"36 55% 48%\",\n accentForeground: \"25 40% 10%\",\n destructive: \"6 70% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"142 40% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 48%\",\n warningForeground: \"25 40% 10%\",\n info: \"200 40% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"25 22% 14%\",\n ring: \"36 55% 52%\",\n heading1: \"36 60% 72%\",\n heading2: \"34 45% 66%\",\n heading3: \"32 35% 60%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: SOURCE_SANS\n },\n materials: {\n radius: \"0.65rem\",\n radiusSm: \"0.4rem\",\n radiusMd: \"0.5rem\",\n radiusLg: \"0.65rem\",\n radiusXl: \"0.85rem\",\n radius2xl: \"1rem\",\n shadowSm: \"0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)\",\n shadowMd: \"0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)\",\n shadowXl: \"0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)\",\n surfaceBlur: \"0px\",\n borderWidth: \"1px\",\n insetHighlight: \"inset 0 1px 0 rgb(255 230 180 / 0.22)\",\n insetShadow: \"inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)\"\n },\n stylesheet: LEATHER_STYLESHEET,\n stylesheetScoped: true\n};\nvar SkeuomorphThemePlugin = {\n manifest: {\n id: \"readergo.theme.skeuomorph\",\n name: \"Leather Desk\",\n version: \"1.0.0\",\n description: \"Skeuomorphic leather-and-brass workspace chrome with physical materials and a scoped theme stylesheet.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(\"Leather Desk skeuomorph theme activating (materials + stylesheet)...\");\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => [LEATHER_DESK_THEME]\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => [FRAUNCES, SOURCE_SANS]\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enable\",\n title: \"Theme: Enable Leather Desk\",\n handler: async () => {\n await context.executeCommand(\"readergo.theme.setTheme\", {\n themeId: LEATHER_DESK_THEME.id\n });\n return { activeTheme: LEATHER_DESK_THEME.id };\n }\n });\n },\n deactivate(context) {\n context.log.info(\"Leather Desk skeuomorph theme deactivated.\");\n }\n};\nvar index_default = SkeuomorphThemePlugin;\n\n\n return { SkeuomorphThemePlugin: SkeuomorphThemePlugin, default: index_default };\n}\n" + "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-skeuomorph/src/chrome.ts\nvar SHARED_CHROME = `\n /* Recessed trays (side rails, inspector, activity bar) */\n aside,\n [data-sidebar],\n nav[aria-label],\n .border-r.bg-background\\\\/95,\n .border-r.bg-background\\\\/70,\n .border-r.bg-background\\\\/85,\n .border-l {\n box-shadow: var(--inset-shadow);\n }\n\n /* Embossed cards / popovers */\n .bg-card,\n .bg-card\\\\/40,\n .bg-card\\\\/50,\n .bg-card\\\\/60,\n .bg-card\\\\/70,\n .bg-card\\\\/75,\n .bg-card\\\\/80,\n .bg-card\\\\/85,\n .bg-popover,\n .bg-popover\\\\/95 {\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 42%),\n linear-gradient(0deg, rgb(0 0 0 / 0.14), transparent 38%);\n box-shadow: var(--inset-highlight), var(--shadow-md);\n border-color: hsl(var(--border));\n }\n\n /* Raised actuators */\n button,\n [role=\"button\"],\n .bg-primary {\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n }\n\n button:active,\n [role=\"button\"]:active {\n box-shadow: var(--inset-shadow);\n transform: translateY(1px);\n }\n\n /* Recessed fields */\n input,\n textarea,\n select,\n [data-slot=\"input\"] {\n box-shadow: var(--inset-shadow);\n background-image: linear-gradient(180deg, rgb(0 0 0 / 0.1), transparent 55%);\n }\n\n /* Hairline metal/leather edge on focus */\n button:focus-visible,\n [role=\"button\"]:focus-visible,\n a:focus-visible,\n input:focus-visible,\n textarea:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n }\n\n /* Kill glass - materials already zero blur; keep surfaces opaque */\n .backdrop-blur-sm,\n .backdrop-blur,\n .backdrop-blur-md,\n .backdrop-blur-lg,\n .backdrop-blur-xl,\n .backdrop-blur-2xl,\n .backdrop-blur-3xl {\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n`;\nvar LEATHER_GRAIN = `\n background-image:\n radial-gradient(ellipse at 18% 8%, rgb(140 80 45 / 0.22), transparent 42%),\n radial-gradient(ellipse at 82% 92%, rgb(30 14 8 / 0.35), transparent 48%),\n repeating-linear-gradient(\n 118deg,\n rgb(255 230 180 / 0.025) 0 1px,\n transparent 1px 4px\n ),\n repeating-linear-gradient(\n 28deg,\n rgb(0 0 0 / 0.04) 0 2px,\n transparent 2px 5px\n );\n`;\nvar STEEL_BRUSH = `\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.06), transparent 35%),\n repeating-linear-gradient(\n 90deg,\n rgb(255 255 255 / 0.035) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 0deg,\n rgb(0 0 0 / 0.04) 0 1px,\n transparent 1px 2px\n );\n`;\nvar JOURNAL_FIBER = `\n background-image:\n radial-gradient(ellipse at 50% 0%, rgb(255 255 255 / 0.55), transparent 55%),\n repeating-linear-gradient(\n 0deg,\n rgb(40 30 20 / 0.03) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 90deg,\n rgb(40 30 20 / 0.02) 0 1px,\n transparent 1px 4px\n );\n`;\nvar WALNUT_GRAIN = `\n background-image:\n radial-gradient(ellipse at 30% 20%, rgb(160 100 50 / 0.15), transparent 50%),\n repeating-linear-gradient(\n 95deg,\n rgb(255 210 150 / 0.03) 0 2px,\n transparent 2px 7px\n ),\n repeating-linear-gradient(\n 5deg,\n rgb(0 0 0 / 0.06) 0 1px,\n transparent 1px 6px\n );\n`;\n\n// plugins/theme-skeuomorph/src/themes.ts\nvar FRAUNCES = {\n id: \"fraunces-display\",\n name: \"Fraunces\",\n family: \"'Fraunces', 'Georgia', serif\",\n category: \"display\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-3\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar IBM_PLEX_MONO = {\n id: \"ibm-plex-mono-steel\",\n name: \"IBM Plex Mono\",\n family: \"'IBM Plex Mono', ui-monospace, monospace\",\n category: \"mono\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap\",\n targets: [\"mono\"]\n};\nvar LITERATA = {\n id: \"literata-journal\",\n name: \"Literata\",\n family: \"'Literata', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SKEUO_FONTS = [FRAUNCES, SOURCE_SANS, IBM_PLEX_MONO, LITERATA];\nvar PHYSICAL_MATERIALS_BASE = {\n surfaceBlur: \"0px\",\n borderWidth: \"1px\"\n};\nvar LEATHER_DESK_THEME = {\n id: \"leather-desk\",\n name: \"Leather Desk\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Walnut blotter and brass actuators - embossed cards, recessed trays, leather grain.\",\n colors: {\n background: \"25 28% 12%\",\n foreground: \"36 40% 88%\",\n card: \"25 24% 16%\",\n cardForeground: \"36 40% 88%\",\n border: \"30 22% 28%\",\n primary: \"36 55% 48%\",\n primaryForeground: \"25 40% 10%\",\n secondary: \"25 18% 20%\",\n secondaryForeground: \"36 30% 82%\",\n muted: \"25 16% 18%\",\n mutedForeground: \"30 14% 58%\",\n accent: \"36 55% 48%\",\n accentForeground: \"25 40% 10%\",\n destructive: \"6 70% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"142 40% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 48%\",\n warningForeground: \"25 40% 10%\",\n info: \"200 40% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"25 22% 14%\",\n ring: \"36 55% 52%\",\n heading1: \"36 60% 72%\",\n heading2: \"34 45% 66%\",\n heading3: \"32 35% 60%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: SOURCE_SANS\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.65rem\",\n radiusSm: \"0.4rem\",\n radiusMd: \"0.5rem\",\n radiusLg: \"0.65rem\",\n radiusXl: \"0.85rem\",\n radius2xl: \"1rem\",\n shadowSm: \"0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)\",\n shadowMd: \"0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)\",\n shadowXl: \"0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 230 180 / 0.22)\",\n insetShadow: \"inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)\"\n },\n stylesheet: `${LEATHER_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BRUSHED_STEEL_THEME = {\n id: \"brushed-steel\",\n name: \"Brushed Steel\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Cold instrument panel - machined aluminum grain, tight radii, cyan status LEDs.\",\n colors: {\n background: \"210 12% 14%\",\n foreground: \"210 20% 92%\",\n card: \"210 10% 18%\",\n cardForeground: \"210 20% 92%\",\n border: \"210 8% 32%\",\n primary: \"198 72% 48%\",\n primaryForeground: \"210 30% 8%\",\n secondary: \"210 10% 22%\",\n secondaryForeground: \"210 15% 85%\",\n muted: \"210 8% 20%\",\n mutedForeground: \"210 8% 58%\",\n accent: \"198 72% 48%\",\n accentForeground: \"210 30% 8%\",\n destructive: \"0 65% 50%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 45% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 85% 50%\",\n warningForeground: \"210 30% 8%\",\n info: \"198 72% 52%\",\n infoForeground: \"210 30% 8%\",\n input: \"210 12% 16%\",\n ring: \"198 72% 52%\",\n heading1: \"198 70% 72%\",\n heading2: \"200 45% 68%\",\n heading3: \"205 30% 64%\"\n },\n fonts: {\n display: SOURCE_SANS,\n body: SOURCE_SANS,\n editor: SOURCE_SANS,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.35rem\",\n radiusSm: \"0.2rem\",\n radiusMd: \"0.28rem\",\n radiusLg: \"0.35rem\",\n radiusXl: \"0.45rem\",\n radius2xl: \"0.55rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.14), 0 1px 2px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.1), 0 3px 8px rgb(0 0 0 / 0.45), inset 0 -1px 0 rgb(0 0 0 / 0.25)\",\n shadowLg: \"0 10px 24px rgb(0 0 0 / 0.5), 0 1px 0 rgb(255 255 255 / 0.08)\",\n shadowXl: \"0 18px 36px rgb(0 0 0 / 0.55)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.28)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.55), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${STEEL_BRUSH}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BOUND_JOURNAL_THEME = {\n id: \"bound-journal\",\n name: \"Bound Journal\",\n type: \"light\",\n author: \"ReaderGo Materials\",\n description: \"Cloth-bound notebook - inked linen fiber, soft pressed pages, midnight ink accents.\",\n colors: {\n background: \"40 18% 93%\",\n foreground: \"220 25% 16%\",\n card: \"40 22% 97%\",\n cardForeground: \"220 25% 16%\",\n border: \"35 12% 78%\",\n primary: \"222 35% 28%\",\n primaryForeground: \"40 30% 96%\",\n secondary: \"38 14% 88%\",\n secondaryForeground: \"220 20% 22%\",\n muted: \"38 12% 90%\",\n mutedForeground: \"220 10% 42%\",\n accent: \"160 28% 32%\",\n accentForeground: \"40 30% 96%\",\n destructive: \"4 65% 42%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 35% 32%\",\n successForeground: \"0 0% 100%\",\n warning: \"32 70% 38%\",\n warningForeground: \"0 0% 100%\",\n info: \"210 40% 38%\",\n infoForeground: \"0 0% 100%\",\n input: \"40 20% 95%\",\n ring: \"222 35% 32%\",\n heading1: \"222 40% 22%\",\n heading2: \"220 28% 28%\",\n heading3: \"218 20% 34%\"\n },\n fonts: {\n display: LITERATA,\n body: SOURCE_SANS,\n editor: LITERATA,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.55rem\",\n radiusSm: \"0.35rem\",\n radiusMd: \"0.45rem\",\n radiusLg: \"0.55rem\",\n radiusXl: \"0.7rem\",\n radius2xl: \"0.85rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.85), 0 1px 2px rgb(40 30 20 / 0.12)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.9), 0 4px 12px rgb(40 30 20 / 0.12), 0 1px 3px rgb(40 30 20 / 0.08)\",\n shadowLg: \"0 12px 28px rgb(40 30 20 / 0.14), 0 2px 6px rgb(40 30 20 / 0.08)\",\n shadowXl: \"0 20px 40px rgb(40 30 20 / 0.16)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.95)\",\n insetShadow: \"inset 0 2px 4px rgb(40 30 20 / 0.12), inset 0 1px 0 rgb(40 30 20 / 0.06)\"\n },\n stylesheet: `${JOURNAL_FIBER}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar WALNUT_LIBRARY_THEME = {\n id: \"walnut-library\",\n name: \"Walnut Library\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Deep library shelves - warm wood grain, amber lamps, wide embossed panels.\",\n colors: {\n background: \"28 32% 10%\",\n foreground: \"38 35% 86%\",\n card: \"28 28% 14%\",\n cardForeground: \"38 35% 86%\",\n border: \"32 24% 24%\",\n primary: \"32 70% 46%\",\n primaryForeground: \"28 40% 8%\",\n secondary: \"28 22% 18%\",\n secondaryForeground: \"38 28% 80%\",\n muted: \"28 20% 15%\",\n mutedForeground: \"32 16% 52%\",\n accent: \"150 35% 40%\",\n accentForeground: \"28 40% 8%\",\n destructive: \"8 68% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"150 35% 40%\",\n successForeground: \"0 0% 100%\",\n warning: \"36 78% 48%\",\n warningForeground: \"28 40% 8%\",\n info: \"200 35% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"28 26% 12%\",\n ring: \"32 70% 50%\",\n heading1: \"38 55% 70%\",\n heading2: \"34 42% 64%\",\n heading3: \"30 32% 58%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.75rem\",\n radiusSm: \"0.45rem\",\n radiusMd: \"0.55rem\",\n radiusLg: \"0.75rem\",\n radiusXl: \"1rem\",\n radius2xl: \"1.15rem\",\n shadowSm: \"0 1px 0 rgb(255 200 120 / 0.1), 0 1px 3px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 200 120 / 0.08), 0 6px 14px rgb(0 0 0 / 0.45), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 14px 32px rgb(0 0 0 / 0.55), 0 4px 10px rgb(0 0 0 / 0.4)\",\n shadowXl: \"0 24px 48px rgb(0 0 0 / 0.6)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 210 140 / 0.18)\",\n insetShadow: \"inset 0 3px 6px rgb(0 0 0 / 0.5), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${WALNUT_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar SKEUO_THEMES = [\n LEATHER_DESK_THEME,\n BRUSHED_STEEL_THEME,\n BOUND_JOURNAL_THEME,\n WALNUT_LIBRARY_THEME\n];\nvar SKEUO_THEME_IDS = SKEUO_THEMES.map((t) => t.id);\n\n// plugins/theme-skeuomorph/src/index.ts\nvar SkeuomorphThemePlugin = {\n manifest: {\n id: \"readergo.theme.skeuomorph\",\n name: \"Skeuomorph Suite\",\n version: \"1.1.0\",\n description: \"Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(\"Skeuomorph Suite activating (4 physical atmospheres)...\");\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => SKEUO_THEMES\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => SKEUO_FONTS\n });\n const enable = async (themeId) => {\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId });\n return { activeTheme: themeId };\n };\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableLeather\",\n title: \"Theme: Leather Desk\",\n handler: async () => enable(LEATHER_DESK_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableSteel\",\n title: \"Theme: Brushed Steel\",\n handler: async () => enable(BRUSHED_STEEL_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableJournal\",\n title: \"Theme: Bound Journal\",\n handler: async () => enable(BOUND_JOURNAL_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableWalnut\",\n title: \"Theme: Walnut Library\",\n handler: async () => enable(WALNUT_LIBRARY_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.cycle\",\n title: \"Theme: Cycle Skeuomorph Atmosphere\",\n handler: async () => {\n const active = await context.executeCommand(\"readergo.theme.getActiveTheme\");\n const currentId = active?.id || LEATHER_DESK_THEME.id;\n const idx = SKEUO_THEME_IDS.indexOf(currentId);\n const next = SKEUO_THEME_IDS[idx >= 0 ? (idx + 1) % SKEUO_THEME_IDS.length : 0];\n return enable(next);\n }\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.getModes\",\n title: \"Theme: List Skeuomorph Atmospheres\",\n handler: async () => SKEUO_THEMES.map((t) => ({\n id: t.id,\n name: t.name,\n type: t.type,\n description: t.description\n }))\n });\n },\n deactivate(context) {\n context.log.info(\"Skeuomorph Suite deactivated.\");\n }\n};\nvar index_default = SkeuomorphThemePlugin;\n\n\n return { BOUND_JOURNAL_THEME: BOUND_JOURNAL_THEME, BRUSHED_STEEL_THEME: BRUSHED_STEEL_THEME, FRAUNCES: FRAUNCES, IBM_PLEX_MONO: IBM_PLEX_MONO, JOURNAL_FIBER: JOURNAL_FIBER, LEATHER_DESK_THEME: LEATHER_DESK_THEME, LEATHER_GRAIN: LEATHER_GRAIN, LITERATA: LITERATA, SHARED_CHROME: SHARED_CHROME, SKEUO_FONTS: SKEUO_FONTS, SKEUO_THEMES: SKEUO_THEMES, SKEUO_THEME_IDS: SKEUO_THEME_IDS, SOURCE_SANS: SOURCE_SANS, STEEL_BRUSH: STEEL_BRUSH, SkeuomorphThemePlugin: SkeuomorphThemePlugin, WALNUT_GRAIN: WALNUT_GRAIN, WALNUT_LIBRARY_THEME: WALNUT_LIBRARY_THEME, default: index_default };\n}\n" } \ No newline at end of file From 234fa2c566c2819de8d09d21473b4ba2b7492d60 Mon Sep 17 00:00:00 2001 From: Amit Date: Fri, 6 Nov 2026 15:46:25 +0530 Subject: [PATCH 3/6] Refine Skeuomorph activity-bar chrome into a physical tool rail. Recessed channel, raised icon wells, latched active state, and inlaid indicator using the new host chrome hooks. Co-authored-by: Cursor --- plugins/theme-skeuomorph/manifest.json | 2 +- plugins/theme-skeuomorph/src/chrome.ts | 130 ++++++++++++++++++++++--- plugins/theme-skeuomorph/src/index.ts | 2 +- public/catalog.json | 6 +- public/theme-skeuomorph.bundle.json | 4 +- 5 files changed, 126 insertions(+), 18 deletions(-) diff --git a/plugins/theme-skeuomorph/manifest.json b/plugins/theme-skeuomorph/manifest.json index 3d9bd9c..ff52577 100644 --- a/plugins/theme-skeuomorph/manifest.json +++ b/plugins/theme-skeuomorph/manifest.json @@ -1,7 +1,7 @@ { "id": "readergo.theme.skeuomorph", "name": "Skeuomorph Suite", - "version": "1.1.0", + "version": "1.1.1", "description": "Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.", "category": "feature", "provides": [ diff --git a/plugins/theme-skeuomorph/src/chrome.ts b/plugins/theme-skeuomorph/src/chrome.ts index 3f7ab14..aecbf65 100644 --- a/plugins/theme-skeuomorph/src/chrome.ts +++ b/plugins/theme-skeuomorph/src/chrome.ts @@ -3,16 +3,124 @@ * Host wraps each theme stylesheet under [data-theme=""]. */ +/** Narrow tool rail - recessed channel with raised icon wells. */ +export const ACTIVITY_BAR_CHROME = ` + /* Outer rail: darker recessed channel with a hard metal/leather edge */ + [data-rg-chrome="activity-bar"] { + background-color: hsl(var(--background)); + background-image: + linear-gradient(90deg, rgb(0 0 0 / 0.28), transparent 55%), + linear-gradient(180deg, rgb(255 255 255 / 0.04), transparent 30%); + border-right-color: hsl(var(--border)); + border-right-width: 1px; + box-shadow: + inset -1px 0 0 rgb(255 255 255 / 0.06), + inset 2px 0 6px rgb(0 0 0 / 0.35), + 2px 0 10px rgb(0 0 0 / 0.25); + -webkit-backdrop-filter: none !important; + backdrop-filter: none !important; + } + + [data-rg-chrome="activity-panel"] { + background-color: hsl(var(--card)); + background-image: + linear-gradient(180deg, rgb(255 255 255 / 0.05), transparent 28%), + linear-gradient(90deg, rgb(0 0 0 / 0.12), transparent 40%); + box-shadow: var(--inset-shadow), 4px 0 18px rgb(0 0 0 / 0.2); + -webkit-backdrop-filter: none !important; + backdrop-filter: none !important; + } + + [data-rg-chrome="activity-bottom"] { + border-top-color: hsl(var(--border)); + box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.06); + } + + /* Brand plate at the top of the rail */ + [data-rg-chrome="activity-brand"] { + margin: 0.35rem 0.35rem 0.15rem; + width: calc(3rem - 0.7rem) !important; + height: 2.75rem !important; + border-radius: var(--radius-md); + border: 1px solid hsl(var(--border)); + background-image: + linear-gradient(180deg, rgb(255 255 255 / 0.1), transparent 55%), + linear-gradient(0deg, rgb(0 0 0 / 0.2), transparent 40%); + box-shadow: var(--inset-highlight), var(--shadow-sm); + } + + [data-rg-chrome="activity-brand"]:hover { + background-color: hsl(var(--muted)); + } + + /* Icon wells - physical buttons sitting in the channel */ + [data-rg-chrome="activity-item"], + [data-rg-chrome="activity-collapse"] { + margin: 0.15rem 0.35rem; + width: calc(3rem - 0.7rem) !important; + height: calc(3rem - 0.55rem) !important; + border-radius: var(--radius-md); + border: 1px solid transparent; + background-image: linear-gradient(180deg, rgb(255 255 255 / 0.03), transparent 60%); + } + + [data-rg-chrome="activity-item"]:hover, + [data-rg-chrome="activity-collapse"]:hover { + border-color: hsl(var(--border)); + background-color: hsl(var(--muted)); + background-image: + linear-gradient(180deg, rgb(255 255 255 / 0.1), transparent 50%), + linear-gradient(0deg, rgb(0 0 0 / 0.15), transparent 40%); + box-shadow: var(--inset-highlight), var(--shadow-sm); + color: hsl(var(--foreground)); + } + + /* Active tool - pressed / latched into the rail */ + [data-rg-chrome="activity-item"][data-rg-active="true"] { + border-color: hsl(var(--primary) / 0.45); + background-color: hsl(var(--primary) / 0.16); + background-image: + linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 45%), + linear-gradient(0deg, rgb(0 0 0 / 0.28), transparent 50%); + box-shadow: + var(--inset-shadow), + 0 0 0 1px hsl(var(--primary) / 0.2), + inset 0 0 10px hsl(var(--primary) / 0.12); + color: hsl(var(--primary)); + } + + [data-rg-chrome="activity-item"][data-rg-active="true"]:hover { + background-color: hsl(var(--primary) / 0.2); + } + + /* Inlaid active indicator - brass/LED strip instead of a flat bar */ + [data-rg-chrome="activity-indicator"] { + left: 0.1rem !important; + width: 3px !important; + border-radius: 999px; + box-shadow: + 0 0 6px hsl(var(--primary) / 0.55), + inset 0 1px 0 rgb(255 255 255 / 0.35); + } + + [data-rg-chrome="activity-item"][data-rg-active="true"] [data-rg-chrome="activity-indicator"] { + opacity: 1 !important; + background: linear-gradient( + 180deg, + hsl(var(--primary)), + hsl(var(--primary) / 0.65) + ) !important; + } +`; + /** Embossed panels, recessed fields, raised actuators - works with ThemeMaterials vars. */ export const SHARED_CHROME = ` - /* Recessed trays (side rails, inspector, activity bar) */ + ${ACTIVITY_BAR_CHROME} + + /* Recessed trays (inspector / misc side rails) */ aside, [data-sidebar], - nav[aria-label], - .border-r.bg-background\\/95, - .border-r.bg-background\\/70, - .border-r.bg-background\\/85, - .border-l { + nav[aria-label] { box-shadow: var(--inset-shadow); } @@ -34,15 +142,15 @@ export const SHARED_CHROME = ` border-color: hsl(var(--border)); } - /* Raised actuators */ - button, - [role="button"], + /* Raised actuators - skip activity-bar items (styled above) */ + button:not([data-rg-chrome^="activity"]), + [role="button"]:not([data-rg-chrome^="activity"]), .bg-primary { box-shadow: var(--inset-highlight), var(--shadow-sm); } - button:active, - [role="button"]:active { + button:not([data-rg-chrome^="activity"]):active, + [role="button"]:not([data-rg-chrome^="activity"]):active { box-shadow: var(--inset-shadow); transform: translateY(1px); } diff --git a/plugins/theme-skeuomorph/src/index.ts b/plugins/theme-skeuomorph/src/index.ts index d14b7a3..944908f 100644 --- a/plugins/theme-skeuomorph/src/index.ts +++ b/plugins/theme-skeuomorph/src/index.ts @@ -18,7 +18,7 @@ export const SkeuomorphThemePlugin: Plugin = { manifest: { id: 'readergo.theme.skeuomorph', name: 'Skeuomorph Suite', - version: '1.1.0', + version: '1.1.1', description: 'Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.', category: 'feature', diff --git a/public/catalog.json b/public/catalog.json index 016eaa7..ef77141 100644 --- a/public/catalog.json +++ b/public/catalog.json @@ -460,14 +460,14 @@ "name": "Skeuomorph Suite", "description": "Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.", "category": "feature", - "version": "1.1.0", + "version": "1.1.1", "provides": [ "theme-provider", "font-provider" ], "bundleUrl": "theme-skeuomorph.bundle.json", - "bundleHash": "59e024f4f14d4ee7", - "hash": "59e024f4f14d4ee7" + "bundleHash": "999b1a905606f812", + "hash": "999b1a905606f812" }, { "id": "readergo.theme.solarized", diff --git a/public/theme-skeuomorph.bundle.json b/public/theme-skeuomorph.bundle.json index 10cfa9a..bf27ed4 100644 --- a/public/theme-skeuomorph.bundle.json +++ b/public/theme-skeuomorph.bundle.json @@ -2,7 +2,7 @@ "manifest": { "id": "readergo.theme.skeuomorph", "name": "Skeuomorph Suite", - "version": "1.1.0", + "version": "1.1.1", "description": "Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.", "category": "feature", "provides": [ @@ -20,5 +20,5 @@ "ui": "./src/index.ts" } }, - "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-skeuomorph/src/chrome.ts\nvar SHARED_CHROME = `\n /* Recessed trays (side rails, inspector, activity bar) */\n aside,\n [data-sidebar],\n nav[aria-label],\n .border-r.bg-background\\\\/95,\n .border-r.bg-background\\\\/70,\n .border-r.bg-background\\\\/85,\n .border-l {\n box-shadow: var(--inset-shadow);\n }\n\n /* Embossed cards / popovers */\n .bg-card,\n .bg-card\\\\/40,\n .bg-card\\\\/50,\n .bg-card\\\\/60,\n .bg-card\\\\/70,\n .bg-card\\\\/75,\n .bg-card\\\\/80,\n .bg-card\\\\/85,\n .bg-popover,\n .bg-popover\\\\/95 {\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 42%),\n linear-gradient(0deg, rgb(0 0 0 / 0.14), transparent 38%);\n box-shadow: var(--inset-highlight), var(--shadow-md);\n border-color: hsl(var(--border));\n }\n\n /* Raised actuators */\n button,\n [role=\"button\"],\n .bg-primary {\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n }\n\n button:active,\n [role=\"button\"]:active {\n box-shadow: var(--inset-shadow);\n transform: translateY(1px);\n }\n\n /* Recessed fields */\n input,\n textarea,\n select,\n [data-slot=\"input\"] {\n box-shadow: var(--inset-shadow);\n background-image: linear-gradient(180deg, rgb(0 0 0 / 0.1), transparent 55%);\n }\n\n /* Hairline metal/leather edge on focus */\n button:focus-visible,\n [role=\"button\"]:focus-visible,\n a:focus-visible,\n input:focus-visible,\n textarea:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n }\n\n /* Kill glass - materials already zero blur; keep surfaces opaque */\n .backdrop-blur-sm,\n .backdrop-blur,\n .backdrop-blur-md,\n .backdrop-blur-lg,\n .backdrop-blur-xl,\n .backdrop-blur-2xl,\n .backdrop-blur-3xl {\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n`;\nvar LEATHER_GRAIN = `\n background-image:\n radial-gradient(ellipse at 18% 8%, rgb(140 80 45 / 0.22), transparent 42%),\n radial-gradient(ellipse at 82% 92%, rgb(30 14 8 / 0.35), transparent 48%),\n repeating-linear-gradient(\n 118deg,\n rgb(255 230 180 / 0.025) 0 1px,\n transparent 1px 4px\n ),\n repeating-linear-gradient(\n 28deg,\n rgb(0 0 0 / 0.04) 0 2px,\n transparent 2px 5px\n );\n`;\nvar STEEL_BRUSH = `\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.06), transparent 35%),\n repeating-linear-gradient(\n 90deg,\n rgb(255 255 255 / 0.035) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 0deg,\n rgb(0 0 0 / 0.04) 0 1px,\n transparent 1px 2px\n );\n`;\nvar JOURNAL_FIBER = `\n background-image:\n radial-gradient(ellipse at 50% 0%, rgb(255 255 255 / 0.55), transparent 55%),\n repeating-linear-gradient(\n 0deg,\n rgb(40 30 20 / 0.03) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 90deg,\n rgb(40 30 20 / 0.02) 0 1px,\n transparent 1px 4px\n );\n`;\nvar WALNUT_GRAIN = `\n background-image:\n radial-gradient(ellipse at 30% 20%, rgb(160 100 50 / 0.15), transparent 50%),\n repeating-linear-gradient(\n 95deg,\n rgb(255 210 150 / 0.03) 0 2px,\n transparent 2px 7px\n ),\n repeating-linear-gradient(\n 5deg,\n rgb(0 0 0 / 0.06) 0 1px,\n transparent 1px 6px\n );\n`;\n\n// plugins/theme-skeuomorph/src/themes.ts\nvar FRAUNCES = {\n id: \"fraunces-display\",\n name: \"Fraunces\",\n family: \"'Fraunces', 'Georgia', serif\",\n category: \"display\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-3\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar IBM_PLEX_MONO = {\n id: \"ibm-plex-mono-steel\",\n name: \"IBM Plex Mono\",\n family: \"'IBM Plex Mono', ui-monospace, monospace\",\n category: \"mono\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap\",\n targets: [\"mono\"]\n};\nvar LITERATA = {\n id: \"literata-journal\",\n name: \"Literata\",\n family: \"'Literata', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SKEUO_FONTS = [FRAUNCES, SOURCE_SANS, IBM_PLEX_MONO, LITERATA];\nvar PHYSICAL_MATERIALS_BASE = {\n surfaceBlur: \"0px\",\n borderWidth: \"1px\"\n};\nvar LEATHER_DESK_THEME = {\n id: \"leather-desk\",\n name: \"Leather Desk\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Walnut blotter and brass actuators - embossed cards, recessed trays, leather grain.\",\n colors: {\n background: \"25 28% 12%\",\n foreground: \"36 40% 88%\",\n card: \"25 24% 16%\",\n cardForeground: \"36 40% 88%\",\n border: \"30 22% 28%\",\n primary: \"36 55% 48%\",\n primaryForeground: \"25 40% 10%\",\n secondary: \"25 18% 20%\",\n secondaryForeground: \"36 30% 82%\",\n muted: \"25 16% 18%\",\n mutedForeground: \"30 14% 58%\",\n accent: \"36 55% 48%\",\n accentForeground: \"25 40% 10%\",\n destructive: \"6 70% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"142 40% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 48%\",\n warningForeground: \"25 40% 10%\",\n info: \"200 40% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"25 22% 14%\",\n ring: \"36 55% 52%\",\n heading1: \"36 60% 72%\",\n heading2: \"34 45% 66%\",\n heading3: \"32 35% 60%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: SOURCE_SANS\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.65rem\",\n radiusSm: \"0.4rem\",\n radiusMd: \"0.5rem\",\n radiusLg: \"0.65rem\",\n radiusXl: \"0.85rem\",\n radius2xl: \"1rem\",\n shadowSm: \"0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)\",\n shadowMd: \"0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)\",\n shadowXl: \"0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 230 180 / 0.22)\",\n insetShadow: \"inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)\"\n },\n stylesheet: `${LEATHER_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BRUSHED_STEEL_THEME = {\n id: \"brushed-steel\",\n name: \"Brushed Steel\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Cold instrument panel - machined aluminum grain, tight radii, cyan status LEDs.\",\n colors: {\n background: \"210 12% 14%\",\n foreground: \"210 20% 92%\",\n card: \"210 10% 18%\",\n cardForeground: \"210 20% 92%\",\n border: \"210 8% 32%\",\n primary: \"198 72% 48%\",\n primaryForeground: \"210 30% 8%\",\n secondary: \"210 10% 22%\",\n secondaryForeground: \"210 15% 85%\",\n muted: \"210 8% 20%\",\n mutedForeground: \"210 8% 58%\",\n accent: \"198 72% 48%\",\n accentForeground: \"210 30% 8%\",\n destructive: \"0 65% 50%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 45% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 85% 50%\",\n warningForeground: \"210 30% 8%\",\n info: \"198 72% 52%\",\n infoForeground: \"210 30% 8%\",\n input: \"210 12% 16%\",\n ring: \"198 72% 52%\",\n heading1: \"198 70% 72%\",\n heading2: \"200 45% 68%\",\n heading3: \"205 30% 64%\"\n },\n fonts: {\n display: SOURCE_SANS,\n body: SOURCE_SANS,\n editor: SOURCE_SANS,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.35rem\",\n radiusSm: \"0.2rem\",\n radiusMd: \"0.28rem\",\n radiusLg: \"0.35rem\",\n radiusXl: \"0.45rem\",\n radius2xl: \"0.55rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.14), 0 1px 2px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.1), 0 3px 8px rgb(0 0 0 / 0.45), inset 0 -1px 0 rgb(0 0 0 / 0.25)\",\n shadowLg: \"0 10px 24px rgb(0 0 0 / 0.5), 0 1px 0 rgb(255 255 255 / 0.08)\",\n shadowXl: \"0 18px 36px rgb(0 0 0 / 0.55)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.28)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.55), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${STEEL_BRUSH}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BOUND_JOURNAL_THEME = {\n id: \"bound-journal\",\n name: \"Bound Journal\",\n type: \"light\",\n author: \"ReaderGo Materials\",\n description: \"Cloth-bound notebook - inked linen fiber, soft pressed pages, midnight ink accents.\",\n colors: {\n background: \"40 18% 93%\",\n foreground: \"220 25% 16%\",\n card: \"40 22% 97%\",\n cardForeground: \"220 25% 16%\",\n border: \"35 12% 78%\",\n primary: \"222 35% 28%\",\n primaryForeground: \"40 30% 96%\",\n secondary: \"38 14% 88%\",\n secondaryForeground: \"220 20% 22%\",\n muted: \"38 12% 90%\",\n mutedForeground: \"220 10% 42%\",\n accent: \"160 28% 32%\",\n accentForeground: \"40 30% 96%\",\n destructive: \"4 65% 42%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 35% 32%\",\n successForeground: \"0 0% 100%\",\n warning: \"32 70% 38%\",\n warningForeground: \"0 0% 100%\",\n info: \"210 40% 38%\",\n infoForeground: \"0 0% 100%\",\n input: \"40 20% 95%\",\n ring: \"222 35% 32%\",\n heading1: \"222 40% 22%\",\n heading2: \"220 28% 28%\",\n heading3: \"218 20% 34%\"\n },\n fonts: {\n display: LITERATA,\n body: SOURCE_SANS,\n editor: LITERATA,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.55rem\",\n radiusSm: \"0.35rem\",\n radiusMd: \"0.45rem\",\n radiusLg: \"0.55rem\",\n radiusXl: \"0.7rem\",\n radius2xl: \"0.85rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.85), 0 1px 2px rgb(40 30 20 / 0.12)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.9), 0 4px 12px rgb(40 30 20 / 0.12), 0 1px 3px rgb(40 30 20 / 0.08)\",\n shadowLg: \"0 12px 28px rgb(40 30 20 / 0.14), 0 2px 6px rgb(40 30 20 / 0.08)\",\n shadowXl: \"0 20px 40px rgb(40 30 20 / 0.16)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.95)\",\n insetShadow: \"inset 0 2px 4px rgb(40 30 20 / 0.12), inset 0 1px 0 rgb(40 30 20 / 0.06)\"\n },\n stylesheet: `${JOURNAL_FIBER}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar WALNUT_LIBRARY_THEME = {\n id: \"walnut-library\",\n name: \"Walnut Library\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Deep library shelves - warm wood grain, amber lamps, wide embossed panels.\",\n colors: {\n background: \"28 32% 10%\",\n foreground: \"38 35% 86%\",\n card: \"28 28% 14%\",\n cardForeground: \"38 35% 86%\",\n border: \"32 24% 24%\",\n primary: \"32 70% 46%\",\n primaryForeground: \"28 40% 8%\",\n secondary: \"28 22% 18%\",\n secondaryForeground: \"38 28% 80%\",\n muted: \"28 20% 15%\",\n mutedForeground: \"32 16% 52%\",\n accent: \"150 35% 40%\",\n accentForeground: \"28 40% 8%\",\n destructive: \"8 68% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"150 35% 40%\",\n successForeground: \"0 0% 100%\",\n warning: \"36 78% 48%\",\n warningForeground: \"28 40% 8%\",\n info: \"200 35% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"28 26% 12%\",\n ring: \"32 70% 50%\",\n heading1: \"38 55% 70%\",\n heading2: \"34 42% 64%\",\n heading3: \"30 32% 58%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.75rem\",\n radiusSm: \"0.45rem\",\n radiusMd: \"0.55rem\",\n radiusLg: \"0.75rem\",\n radiusXl: \"1rem\",\n radius2xl: \"1.15rem\",\n shadowSm: \"0 1px 0 rgb(255 200 120 / 0.1), 0 1px 3px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 200 120 / 0.08), 0 6px 14px rgb(0 0 0 / 0.45), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 14px 32px rgb(0 0 0 / 0.55), 0 4px 10px rgb(0 0 0 / 0.4)\",\n shadowXl: \"0 24px 48px rgb(0 0 0 / 0.6)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 210 140 / 0.18)\",\n insetShadow: \"inset 0 3px 6px rgb(0 0 0 / 0.5), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${WALNUT_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar SKEUO_THEMES = [\n LEATHER_DESK_THEME,\n BRUSHED_STEEL_THEME,\n BOUND_JOURNAL_THEME,\n WALNUT_LIBRARY_THEME\n];\nvar SKEUO_THEME_IDS = SKEUO_THEMES.map((t) => t.id);\n\n// plugins/theme-skeuomorph/src/index.ts\nvar SkeuomorphThemePlugin = {\n manifest: {\n id: \"readergo.theme.skeuomorph\",\n name: \"Skeuomorph Suite\",\n version: \"1.1.0\",\n description: \"Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(\"Skeuomorph Suite activating (4 physical atmospheres)...\");\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => SKEUO_THEMES\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => SKEUO_FONTS\n });\n const enable = async (themeId) => {\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId });\n return { activeTheme: themeId };\n };\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableLeather\",\n title: \"Theme: Leather Desk\",\n handler: async () => enable(LEATHER_DESK_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableSteel\",\n title: \"Theme: Brushed Steel\",\n handler: async () => enable(BRUSHED_STEEL_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableJournal\",\n title: \"Theme: Bound Journal\",\n handler: async () => enable(BOUND_JOURNAL_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableWalnut\",\n title: \"Theme: Walnut Library\",\n handler: async () => enable(WALNUT_LIBRARY_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.cycle\",\n title: \"Theme: Cycle Skeuomorph Atmosphere\",\n handler: async () => {\n const active = await context.executeCommand(\"readergo.theme.getActiveTheme\");\n const currentId = active?.id || LEATHER_DESK_THEME.id;\n const idx = SKEUO_THEME_IDS.indexOf(currentId);\n const next = SKEUO_THEME_IDS[idx >= 0 ? (idx + 1) % SKEUO_THEME_IDS.length : 0];\n return enable(next);\n }\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.getModes\",\n title: \"Theme: List Skeuomorph Atmospheres\",\n handler: async () => SKEUO_THEMES.map((t) => ({\n id: t.id,\n name: t.name,\n type: t.type,\n description: t.description\n }))\n });\n },\n deactivate(context) {\n context.log.info(\"Skeuomorph Suite deactivated.\");\n }\n};\nvar index_default = SkeuomorphThemePlugin;\n\n\n return { BOUND_JOURNAL_THEME: BOUND_JOURNAL_THEME, BRUSHED_STEEL_THEME: BRUSHED_STEEL_THEME, FRAUNCES: FRAUNCES, IBM_PLEX_MONO: IBM_PLEX_MONO, JOURNAL_FIBER: JOURNAL_FIBER, LEATHER_DESK_THEME: LEATHER_DESK_THEME, LEATHER_GRAIN: LEATHER_GRAIN, LITERATA: LITERATA, SHARED_CHROME: SHARED_CHROME, SKEUO_FONTS: SKEUO_FONTS, SKEUO_THEMES: SKEUO_THEMES, SKEUO_THEME_IDS: SKEUO_THEME_IDS, SOURCE_SANS: SOURCE_SANS, STEEL_BRUSH: STEEL_BRUSH, SkeuomorphThemePlugin: SkeuomorphThemePlugin, WALNUT_GRAIN: WALNUT_GRAIN, WALNUT_LIBRARY_THEME: WALNUT_LIBRARY_THEME, default: index_default };\n}\n" + "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-skeuomorph/src/chrome.ts\nvar ACTIVITY_BAR_CHROME = `\n /* Outer rail: darker recessed channel with a hard metal/leather edge */\n [data-rg-chrome=\"activity-bar\"] {\n background-color: hsl(var(--background));\n background-image:\n linear-gradient(90deg, rgb(0 0 0 / 0.28), transparent 55%),\n linear-gradient(180deg, rgb(255 255 255 / 0.04), transparent 30%);\n border-right-color: hsl(var(--border));\n border-right-width: 1px;\n box-shadow:\n inset -1px 0 0 rgb(255 255 255 / 0.06),\n inset 2px 0 6px rgb(0 0 0 / 0.35),\n 2px 0 10px rgb(0 0 0 / 0.25);\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n\n [data-rg-chrome=\"activity-panel\"] {\n background-color: hsl(var(--card));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.05), transparent 28%),\n linear-gradient(90deg, rgb(0 0 0 / 0.12), transparent 40%);\n box-shadow: var(--inset-shadow), 4px 0 18px rgb(0 0 0 / 0.2);\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n\n [data-rg-chrome=\"activity-bottom\"] {\n border-top-color: hsl(var(--border));\n box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.06);\n }\n\n /* Brand plate at the top of the rail */\n [data-rg-chrome=\"activity-brand\"] {\n margin: 0.35rem 0.35rem 0.15rem;\n width: calc(3rem - 0.7rem) !important;\n height: 2.75rem !important;\n border-radius: var(--radius-md);\n border: 1px solid hsl(var(--border));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.1), transparent 55%),\n linear-gradient(0deg, rgb(0 0 0 / 0.2), transparent 40%);\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n }\n\n [data-rg-chrome=\"activity-brand\"]:hover {\n background-color: hsl(var(--muted));\n }\n\n /* Icon wells - physical buttons sitting in the channel */\n [data-rg-chrome=\"activity-item\"],\n [data-rg-chrome=\"activity-collapse\"] {\n margin: 0.15rem 0.35rem;\n width: calc(3rem - 0.7rem) !important;\n height: calc(3rem - 0.55rem) !important;\n border-radius: var(--radius-md);\n border: 1px solid transparent;\n background-image: linear-gradient(180deg, rgb(255 255 255 / 0.03), transparent 60%);\n }\n\n [data-rg-chrome=\"activity-item\"]:hover,\n [data-rg-chrome=\"activity-collapse\"]:hover {\n border-color: hsl(var(--border));\n background-color: hsl(var(--muted));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.1), transparent 50%),\n linear-gradient(0deg, rgb(0 0 0 / 0.15), transparent 40%);\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n color: hsl(var(--foreground));\n }\n\n /* Active tool - pressed / latched into the rail */\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"] {\n border-color: hsl(var(--primary) / 0.45);\n background-color: hsl(var(--primary) / 0.16);\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 45%),\n linear-gradient(0deg, rgb(0 0 0 / 0.28), transparent 50%);\n box-shadow:\n var(--inset-shadow),\n 0 0 0 1px hsl(var(--primary) / 0.2),\n inset 0 0 10px hsl(var(--primary) / 0.12);\n color: hsl(var(--primary));\n }\n\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"]:hover {\n background-color: hsl(var(--primary) / 0.2);\n }\n\n /* Inlaid active indicator - brass/LED strip instead of a flat bar */\n [data-rg-chrome=\"activity-indicator\"] {\n left: 0.1rem !important;\n width: 3px !important;\n border-radius: 999px;\n box-shadow:\n 0 0 6px hsl(var(--primary) / 0.55),\n inset 0 1px 0 rgb(255 255 255 / 0.35);\n }\n\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"] [data-rg-chrome=\"activity-indicator\"] {\n opacity: 1 !important;\n background: linear-gradient(\n 180deg,\n hsl(var(--primary)),\n hsl(var(--primary) / 0.65)\n ) !important;\n }\n`;\nvar SHARED_CHROME = `\n ${ACTIVITY_BAR_CHROME}\n\n /* Recessed trays (inspector / misc side rails) */\n aside,\n [data-sidebar],\n nav[aria-label] {\n box-shadow: var(--inset-shadow);\n }\n\n /* Embossed cards / popovers */\n .bg-card,\n .bg-card\\\\/40,\n .bg-card\\\\/50,\n .bg-card\\\\/60,\n .bg-card\\\\/70,\n .bg-card\\\\/75,\n .bg-card\\\\/80,\n .bg-card\\\\/85,\n .bg-popover,\n .bg-popover\\\\/95 {\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 42%),\n linear-gradient(0deg, rgb(0 0 0 / 0.14), transparent 38%);\n box-shadow: var(--inset-highlight), var(--shadow-md);\n border-color: hsl(var(--border));\n }\n\n /* Raised actuators - skip activity-bar items (styled above) */\n button:not([data-rg-chrome^=\"activity\"]),\n [role=\"button\"]:not([data-rg-chrome^=\"activity\"]),\n .bg-primary {\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n }\n\n button:not([data-rg-chrome^=\"activity\"]):active,\n [role=\"button\"]:not([data-rg-chrome^=\"activity\"]):active {\n box-shadow: var(--inset-shadow);\n transform: translateY(1px);\n }\n\n /* Recessed fields */\n input,\n textarea,\n select,\n [data-slot=\"input\"] {\n box-shadow: var(--inset-shadow);\n background-image: linear-gradient(180deg, rgb(0 0 0 / 0.1), transparent 55%);\n }\n\n /* Hairline metal/leather edge on focus */\n button:focus-visible,\n [role=\"button\"]:focus-visible,\n a:focus-visible,\n input:focus-visible,\n textarea:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n }\n\n /* Kill glass - materials already zero blur; keep surfaces opaque */\n .backdrop-blur-sm,\n .backdrop-blur,\n .backdrop-blur-md,\n .backdrop-blur-lg,\n .backdrop-blur-xl,\n .backdrop-blur-2xl,\n .backdrop-blur-3xl {\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n`;\nvar LEATHER_GRAIN = `\n background-image:\n radial-gradient(ellipse at 18% 8%, rgb(140 80 45 / 0.22), transparent 42%),\n radial-gradient(ellipse at 82% 92%, rgb(30 14 8 / 0.35), transparent 48%),\n repeating-linear-gradient(\n 118deg,\n rgb(255 230 180 / 0.025) 0 1px,\n transparent 1px 4px\n ),\n repeating-linear-gradient(\n 28deg,\n rgb(0 0 0 / 0.04) 0 2px,\n transparent 2px 5px\n );\n`;\nvar STEEL_BRUSH = `\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.06), transparent 35%),\n repeating-linear-gradient(\n 90deg,\n rgb(255 255 255 / 0.035) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 0deg,\n rgb(0 0 0 / 0.04) 0 1px,\n transparent 1px 2px\n );\n`;\nvar JOURNAL_FIBER = `\n background-image:\n radial-gradient(ellipse at 50% 0%, rgb(255 255 255 / 0.55), transparent 55%),\n repeating-linear-gradient(\n 0deg,\n rgb(40 30 20 / 0.03) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 90deg,\n rgb(40 30 20 / 0.02) 0 1px,\n transparent 1px 4px\n );\n`;\nvar WALNUT_GRAIN = `\n background-image:\n radial-gradient(ellipse at 30% 20%, rgb(160 100 50 / 0.15), transparent 50%),\n repeating-linear-gradient(\n 95deg,\n rgb(255 210 150 / 0.03) 0 2px,\n transparent 2px 7px\n ),\n repeating-linear-gradient(\n 5deg,\n rgb(0 0 0 / 0.06) 0 1px,\n transparent 1px 6px\n );\n`;\n\n// plugins/theme-skeuomorph/src/themes.ts\nvar FRAUNCES = {\n id: \"fraunces-display\",\n name: \"Fraunces\",\n family: \"'Fraunces', 'Georgia', serif\",\n category: \"display\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-3\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar IBM_PLEX_MONO = {\n id: \"ibm-plex-mono-steel\",\n name: \"IBM Plex Mono\",\n family: \"'IBM Plex Mono', ui-monospace, monospace\",\n category: \"mono\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap\",\n targets: [\"mono\"]\n};\nvar LITERATA = {\n id: \"literata-journal\",\n name: \"Literata\",\n family: \"'Literata', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SKEUO_FONTS = [FRAUNCES, SOURCE_SANS, IBM_PLEX_MONO, LITERATA];\nvar PHYSICAL_MATERIALS_BASE = {\n surfaceBlur: \"0px\",\n borderWidth: \"1px\"\n};\nvar LEATHER_DESK_THEME = {\n id: \"leather-desk\",\n name: \"Leather Desk\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Walnut blotter and brass actuators - embossed cards, recessed trays, leather grain.\",\n colors: {\n background: \"25 28% 12%\",\n foreground: \"36 40% 88%\",\n card: \"25 24% 16%\",\n cardForeground: \"36 40% 88%\",\n border: \"30 22% 28%\",\n primary: \"36 55% 48%\",\n primaryForeground: \"25 40% 10%\",\n secondary: \"25 18% 20%\",\n secondaryForeground: \"36 30% 82%\",\n muted: \"25 16% 18%\",\n mutedForeground: \"30 14% 58%\",\n accent: \"36 55% 48%\",\n accentForeground: \"25 40% 10%\",\n destructive: \"6 70% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"142 40% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 48%\",\n warningForeground: \"25 40% 10%\",\n info: \"200 40% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"25 22% 14%\",\n ring: \"36 55% 52%\",\n heading1: \"36 60% 72%\",\n heading2: \"34 45% 66%\",\n heading3: \"32 35% 60%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: SOURCE_SANS\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.65rem\",\n radiusSm: \"0.4rem\",\n radiusMd: \"0.5rem\",\n radiusLg: \"0.65rem\",\n radiusXl: \"0.85rem\",\n radius2xl: \"1rem\",\n shadowSm: \"0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)\",\n shadowMd: \"0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)\",\n shadowXl: \"0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 230 180 / 0.22)\",\n insetShadow: \"inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)\"\n },\n stylesheet: `${LEATHER_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BRUSHED_STEEL_THEME = {\n id: \"brushed-steel\",\n name: \"Brushed Steel\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Cold instrument panel - machined aluminum grain, tight radii, cyan status LEDs.\",\n colors: {\n background: \"210 12% 14%\",\n foreground: \"210 20% 92%\",\n card: \"210 10% 18%\",\n cardForeground: \"210 20% 92%\",\n border: \"210 8% 32%\",\n primary: \"198 72% 48%\",\n primaryForeground: \"210 30% 8%\",\n secondary: \"210 10% 22%\",\n secondaryForeground: \"210 15% 85%\",\n muted: \"210 8% 20%\",\n mutedForeground: \"210 8% 58%\",\n accent: \"198 72% 48%\",\n accentForeground: \"210 30% 8%\",\n destructive: \"0 65% 50%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 45% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 85% 50%\",\n warningForeground: \"210 30% 8%\",\n info: \"198 72% 52%\",\n infoForeground: \"210 30% 8%\",\n input: \"210 12% 16%\",\n ring: \"198 72% 52%\",\n heading1: \"198 70% 72%\",\n heading2: \"200 45% 68%\",\n heading3: \"205 30% 64%\"\n },\n fonts: {\n display: SOURCE_SANS,\n body: SOURCE_SANS,\n editor: SOURCE_SANS,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.35rem\",\n radiusSm: \"0.2rem\",\n radiusMd: \"0.28rem\",\n radiusLg: \"0.35rem\",\n radiusXl: \"0.45rem\",\n radius2xl: \"0.55rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.14), 0 1px 2px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.1), 0 3px 8px rgb(0 0 0 / 0.45), inset 0 -1px 0 rgb(0 0 0 / 0.25)\",\n shadowLg: \"0 10px 24px rgb(0 0 0 / 0.5), 0 1px 0 rgb(255 255 255 / 0.08)\",\n shadowXl: \"0 18px 36px rgb(0 0 0 / 0.55)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.28)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.55), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${STEEL_BRUSH}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BOUND_JOURNAL_THEME = {\n id: \"bound-journal\",\n name: \"Bound Journal\",\n type: \"light\",\n author: \"ReaderGo Materials\",\n description: \"Cloth-bound notebook - inked linen fiber, soft pressed pages, midnight ink accents.\",\n colors: {\n background: \"40 18% 93%\",\n foreground: \"220 25% 16%\",\n card: \"40 22% 97%\",\n cardForeground: \"220 25% 16%\",\n border: \"35 12% 78%\",\n primary: \"222 35% 28%\",\n primaryForeground: \"40 30% 96%\",\n secondary: \"38 14% 88%\",\n secondaryForeground: \"220 20% 22%\",\n muted: \"38 12% 90%\",\n mutedForeground: \"220 10% 42%\",\n accent: \"160 28% 32%\",\n accentForeground: \"40 30% 96%\",\n destructive: \"4 65% 42%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 35% 32%\",\n successForeground: \"0 0% 100%\",\n warning: \"32 70% 38%\",\n warningForeground: \"0 0% 100%\",\n info: \"210 40% 38%\",\n infoForeground: \"0 0% 100%\",\n input: \"40 20% 95%\",\n ring: \"222 35% 32%\",\n heading1: \"222 40% 22%\",\n heading2: \"220 28% 28%\",\n heading3: \"218 20% 34%\"\n },\n fonts: {\n display: LITERATA,\n body: SOURCE_SANS,\n editor: LITERATA,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.55rem\",\n radiusSm: \"0.35rem\",\n radiusMd: \"0.45rem\",\n radiusLg: \"0.55rem\",\n radiusXl: \"0.7rem\",\n radius2xl: \"0.85rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.85), 0 1px 2px rgb(40 30 20 / 0.12)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.9), 0 4px 12px rgb(40 30 20 / 0.12), 0 1px 3px rgb(40 30 20 / 0.08)\",\n shadowLg: \"0 12px 28px rgb(40 30 20 / 0.14), 0 2px 6px rgb(40 30 20 / 0.08)\",\n shadowXl: \"0 20px 40px rgb(40 30 20 / 0.16)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.95)\",\n insetShadow: \"inset 0 2px 4px rgb(40 30 20 / 0.12), inset 0 1px 0 rgb(40 30 20 / 0.06)\"\n },\n stylesheet: `${JOURNAL_FIBER}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar WALNUT_LIBRARY_THEME = {\n id: \"walnut-library\",\n name: \"Walnut Library\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Deep library shelves - warm wood grain, amber lamps, wide embossed panels.\",\n colors: {\n background: \"28 32% 10%\",\n foreground: \"38 35% 86%\",\n card: \"28 28% 14%\",\n cardForeground: \"38 35% 86%\",\n border: \"32 24% 24%\",\n primary: \"32 70% 46%\",\n primaryForeground: \"28 40% 8%\",\n secondary: \"28 22% 18%\",\n secondaryForeground: \"38 28% 80%\",\n muted: \"28 20% 15%\",\n mutedForeground: \"32 16% 52%\",\n accent: \"150 35% 40%\",\n accentForeground: \"28 40% 8%\",\n destructive: \"8 68% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"150 35% 40%\",\n successForeground: \"0 0% 100%\",\n warning: \"36 78% 48%\",\n warningForeground: \"28 40% 8%\",\n info: \"200 35% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"28 26% 12%\",\n ring: \"32 70% 50%\",\n heading1: \"38 55% 70%\",\n heading2: \"34 42% 64%\",\n heading3: \"30 32% 58%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.75rem\",\n radiusSm: \"0.45rem\",\n radiusMd: \"0.55rem\",\n radiusLg: \"0.75rem\",\n radiusXl: \"1rem\",\n radius2xl: \"1.15rem\",\n shadowSm: \"0 1px 0 rgb(255 200 120 / 0.1), 0 1px 3px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 200 120 / 0.08), 0 6px 14px rgb(0 0 0 / 0.45), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 14px 32px rgb(0 0 0 / 0.55), 0 4px 10px rgb(0 0 0 / 0.4)\",\n shadowXl: \"0 24px 48px rgb(0 0 0 / 0.6)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 210 140 / 0.18)\",\n insetShadow: \"inset 0 3px 6px rgb(0 0 0 / 0.5), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${WALNUT_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar SKEUO_THEMES = [\n LEATHER_DESK_THEME,\n BRUSHED_STEEL_THEME,\n BOUND_JOURNAL_THEME,\n WALNUT_LIBRARY_THEME\n];\nvar SKEUO_THEME_IDS = SKEUO_THEMES.map((t) => t.id);\n\n// plugins/theme-skeuomorph/src/index.ts\nvar SkeuomorphThemePlugin = {\n manifest: {\n id: \"readergo.theme.skeuomorph\",\n name: \"Skeuomorph Suite\",\n version: \"1.1.1\",\n description: \"Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(\"Skeuomorph Suite activating (4 physical atmospheres)...\");\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => SKEUO_THEMES\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => SKEUO_FONTS\n });\n const enable = async (themeId) => {\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId });\n return { activeTheme: themeId };\n };\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableLeather\",\n title: \"Theme: Leather Desk\",\n handler: async () => enable(LEATHER_DESK_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableSteel\",\n title: \"Theme: Brushed Steel\",\n handler: async () => enable(BRUSHED_STEEL_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableJournal\",\n title: \"Theme: Bound Journal\",\n handler: async () => enable(BOUND_JOURNAL_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableWalnut\",\n title: \"Theme: Walnut Library\",\n handler: async () => enable(WALNUT_LIBRARY_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.cycle\",\n title: \"Theme: Cycle Skeuomorph Atmosphere\",\n handler: async () => {\n const active = await context.executeCommand(\"readergo.theme.getActiveTheme\");\n const currentId = active?.id || LEATHER_DESK_THEME.id;\n const idx = SKEUO_THEME_IDS.indexOf(currentId);\n const next = SKEUO_THEME_IDS[idx >= 0 ? (idx + 1) % SKEUO_THEME_IDS.length : 0];\n return enable(next);\n }\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.getModes\",\n title: \"Theme: List Skeuomorph Atmospheres\",\n handler: async () => SKEUO_THEMES.map((t) => ({\n id: t.id,\n name: t.name,\n type: t.type,\n description: t.description\n }))\n });\n },\n deactivate(context) {\n context.log.info(\"Skeuomorph Suite deactivated.\");\n }\n};\nvar index_default = SkeuomorphThemePlugin;\n\n\n return { ACTIVITY_BAR_CHROME: ACTIVITY_BAR_CHROME, BOUND_JOURNAL_THEME: BOUND_JOURNAL_THEME, BRUSHED_STEEL_THEME: BRUSHED_STEEL_THEME, FRAUNCES: FRAUNCES, IBM_PLEX_MONO: IBM_PLEX_MONO, JOURNAL_FIBER: JOURNAL_FIBER, LEATHER_DESK_THEME: LEATHER_DESK_THEME, LEATHER_GRAIN: LEATHER_GRAIN, LITERATA: LITERATA, SHARED_CHROME: SHARED_CHROME, SKEUO_FONTS: SKEUO_FONTS, SKEUO_THEMES: SKEUO_THEMES, SKEUO_THEME_IDS: SKEUO_THEME_IDS, SOURCE_SANS: SOURCE_SANS, STEEL_BRUSH: STEEL_BRUSH, SkeuomorphThemePlugin: SkeuomorphThemePlugin, WALNUT_GRAIN: WALNUT_GRAIN, WALNUT_LIBRARY_THEME: WALNUT_LIBRARY_THEME, default: index_default };\n}\n" } \ No newline at end of file From 2ce6392cf2c47a9842244ab8c76a7e61707c48bd Mon Sep 17 00:00:00 2001 From: Amit Date: Fri, 6 Nov 2026 16:43:57 +0530 Subject: [PATCH 4/6] Expand Skeuomorph Suite to eight physical atmospheres. Adds Soft Porcelain, Cinnabar Lacquer, Denim Bench, and Brass Console with matching grain stylesheets. Co-authored-by: Cursor --- plugins/theme-skeuomorph/manifest.json | 4 +- plugins/theme-skeuomorph/src/chrome.ts | 45 +++++ plugins/theme-skeuomorph/src/index.ts | 49 +++-- plugins/theme-skeuomorph/src/themes.ts | 252 +++++++++++++++++++++++++ public/catalog.json | 8 +- public/theme-skeuomorph.bundle.json | 6 +- 6 files changed, 330 insertions(+), 34 deletions(-) diff --git a/plugins/theme-skeuomorph/manifest.json b/plugins/theme-skeuomorph/manifest.json index ff52577..d8bba8c 100644 --- a/plugins/theme-skeuomorph/manifest.json +++ b/plugins/theme-skeuomorph/manifest.json @@ -1,8 +1,8 @@ { "id": "readergo.theme.skeuomorph", "name": "Skeuomorph Suite", - "version": "1.1.1", - "description": "Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.", + "version": "1.2.0", + "description": "Eight physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, and Brass Console.", "category": "feature", "provides": [ "theme-provider", diff --git a/plugins/theme-skeuomorph/src/chrome.ts b/plugins/theme-skeuomorph/src/chrome.ts index aecbf65..5dcf4db 100644 --- a/plugins/theme-skeuomorph/src/chrome.ts +++ b/plugins/theme-skeuomorph/src/chrome.ts @@ -247,3 +247,48 @@ export const WALNUT_GRAIN = ` transparent 1px 6px ); `; + +export const PORCELAIN_GLOSS = ` + background-image: + radial-gradient(ellipse at 20% 0%, rgb(255 255 255 / 0.9), transparent 45%), + radial-gradient(ellipse at 80% 100%, rgb(180 200 220 / 0.18), transparent 50%), + linear-gradient(180deg, rgb(255 255 255 / 0.35), transparent 40%); +`; + +export const LACQUER_SHEEN = ` + background-image: + radial-gradient(ellipse at 15% 10%, rgb(180 40 40 / 0.22), transparent 40%), + radial-gradient(ellipse at 85% 90%, rgb(0 0 0 / 0.45), transparent 45%), + linear-gradient(135deg, rgb(255 200 160 / 0.05), transparent 40%), + repeating-linear-gradient( + 120deg, + rgb(255 255 255 / 0.02) 0 1px, + transparent 1px 5px + ); +`; + +export const DENIM_TWILL = ` + background-image: + repeating-linear-gradient( + 45deg, + rgb(255 255 255 / 0.03) 0 1px, + transparent 1px 4px + ), + repeating-linear-gradient( + -45deg, + rgb(0 0 0 / 0.05) 0 1px, + transparent 1px 4px + ), + radial-gradient(ellipse at 50% 0%, rgb(100 140 200 / 0.12), transparent 55%); +`; + +export const BRASS_PATINA = ` + background-image: + radial-gradient(ellipse at 25% 15%, rgb(220 170 80 / 0.14), transparent 45%), + radial-gradient(ellipse at 75% 85%, rgb(40 25 10 / 0.35), transparent 50%), + repeating-linear-gradient( + 92deg, + rgb(255 210 120 / 0.04) 0 1px, + transparent 1px 3px + ); +`; diff --git a/plugins/theme-skeuomorph/src/index.ts b/plugins/theme-skeuomorph/src/index.ts index 944908f..02c0227 100644 --- a/plugins/theme-skeuomorph/src/index.ts +++ b/plugins/theme-skeuomorph/src/index.ts @@ -2,11 +2,15 @@ import { Plugin, PluginContext } from '@readergo/plugin-sdk'; import { BOUND_JOURNAL_THEME, + BRASS_CONSOLE_THEME, BRUSHED_STEEL_THEME, + CINNABAR_LACQUER_THEME, + DENIM_BENCH_THEME, LEATHER_DESK_THEME, SKEUO_FONTS, SKEUO_THEME_IDS, SKEUO_THEMES, + SOFT_PORCELAIN_THEME, WALNUT_LIBRARY_THEME, } from './themes'; @@ -18,16 +22,16 @@ export const SkeuomorphThemePlugin: Plugin = { manifest: { id: 'readergo.theme.skeuomorph', name: 'Skeuomorph Suite', - version: '1.1.1', + version: '1.2.0', description: - 'Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.', + 'Eight physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, and Brass Console.', category: 'feature', provides: ['theme-provider', 'font-provider'], permissions: [], }, async activate(context: PluginContext) { - context.log.info('Skeuomorph Suite activating (4 physical atmospheres)...'); + context.log.info(`Skeuomorph Suite activating (${SKEUO_THEMES.length} physical atmospheres)...`); await context.registerCapability('theme-provider', { getThemes: () => SKEUO_THEMES, @@ -42,29 +46,24 @@ export const SkeuomorphThemePlugin: Plugin = { return { activeTheme: themeId }; }; - await context.registerCommand({ - id: 'readergo.theme.skeuomorph.enableLeather', - title: 'Theme: Leather Desk', - handler: async () => enable(LEATHER_DESK_THEME.id), - }); - - await context.registerCommand({ - id: 'readergo.theme.skeuomorph.enableSteel', - title: 'Theme: Brushed Steel', - handler: async () => enable(BRUSHED_STEEL_THEME.id), - }); + const commands: Array<{ id: string; title: string; themeId: string }> = [ + { id: 'readergo.theme.skeuomorph.enableLeather', title: 'Theme: Leather Desk', themeId: LEATHER_DESK_THEME.id }, + { id: 'readergo.theme.skeuomorph.enableSteel', title: 'Theme: Brushed Steel', themeId: BRUSHED_STEEL_THEME.id }, + { id: 'readergo.theme.skeuomorph.enableJournal', title: 'Theme: Bound Journal', themeId: BOUND_JOURNAL_THEME.id }, + { id: 'readergo.theme.skeuomorph.enableWalnut', title: 'Theme: Walnut Library', themeId: WALNUT_LIBRARY_THEME.id }, + { id: 'readergo.theme.skeuomorph.enablePorcelain', title: 'Theme: Soft Porcelain', themeId: SOFT_PORCELAIN_THEME.id }, + { id: 'readergo.theme.skeuomorph.enableLacquer', title: 'Theme: Cinnabar Lacquer', themeId: CINNABAR_LACQUER_THEME.id }, + { id: 'readergo.theme.skeuomorph.enableDenim', title: 'Theme: Denim Bench', themeId: DENIM_BENCH_THEME.id }, + { id: 'readergo.theme.skeuomorph.enableBrass', title: 'Theme: Brass Console', themeId: BRASS_CONSOLE_THEME.id }, + ]; - await context.registerCommand({ - id: 'readergo.theme.skeuomorph.enableJournal', - title: 'Theme: Bound Journal', - handler: async () => enable(BOUND_JOURNAL_THEME.id), - }); - - await context.registerCommand({ - id: 'readergo.theme.skeuomorph.enableWalnut', - title: 'Theme: Walnut Library', - handler: async () => enable(WALNUT_LIBRARY_THEME.id), - }); + for (const cmd of commands) { + await context.registerCommand({ + id: cmd.id, + title: cmd.title, + handler: async () => enable(cmd.themeId), + }); + } await context.registerCommand({ id: 'readergo.theme.skeuomorph.cycle', diff --git a/plugins/theme-skeuomorph/src/themes.ts b/plugins/theme-skeuomorph/src/themes.ts index 26619d9..74cca6b 100644 --- a/plugins/theme-skeuomorph/src/themes.ts +++ b/plugins/theme-skeuomorph/src/themes.ts @@ -1,6 +1,10 @@ import { + BRASS_PATINA, + DENIM_TWILL, JOURNAL_FIBER, + LACQUER_SHEEN, LEATHER_GRAIN, + PORCELAIN_GLOSS, SHARED_CHROME, STEEL_BRUSH, WALNUT_GRAIN, @@ -298,11 +302,259 @@ export const WALNUT_LIBRARY_THEME = { stylesheetScoped: true, }; +export const SOFT_PORCELAIN_THEME = { + id: 'soft-porcelain', + name: 'Soft Porcelain', + type: 'light' as const, + author: 'ReaderGo Materials', + description: + 'Glazed ceramic workspace - soft gloss plates, cool slate ink, pillowy radius.', + colors: { + background: '210 25% 96%', + foreground: '220 28% 18%', + card: '0 0% 100%', + cardForeground: '220 28% 18%', + border: '210 16% 84%', + primary: '205 55% 42%', + primaryForeground: '0 0% 100%', + secondary: '210 18% 92%', + secondaryForeground: '220 22% 24%', + muted: '210 16% 93%', + mutedForeground: '215 12% 46%', + accent: '340 45% 48%', + accentForeground: '0 0% 100%', + destructive: '4 70% 46%', + destructiveForeground: '0 0% 100%', + success: '152 40% 36%', + successForeground: '0 0% 100%', + warning: '32 75% 42%', + warningForeground: '0 0% 100%', + info: '205 55% 44%', + infoForeground: '0 0% 100%', + input: '210 20% 97%', + ring: '205 55% 44%', + heading1: '220 35% 22%', + heading2: '215 28% 28%', + heading3: '210 22% 34%', + }, + fonts: { + display: SOURCE_SANS, + body: SOURCE_SANS, + editor: SOURCE_SANS, + mono: IBM_PLEX_MONO, + }, + materials: { + ...PHYSICAL_MATERIALS_BASE, + radius: '0.9rem', + radiusSm: '0.5rem', + radiusMd: '0.7rem', + radiusLg: '0.9rem', + radiusXl: '1.1rem', + radius2xl: '1.35rem', + shadowSm: '0 1px 0 rgb(255 255 255 / 0.95), 0 1px 3px rgb(40 60 90 / 0.08)', + shadowMd: + '0 1px 0 rgb(255 255 255), 0 6px 16px rgb(40 60 90 / 0.1), 0 2px 4px rgb(40 60 90 / 0.06)', + shadowLg: '0 14px 32px rgb(40 60 90 / 0.12)', + shadowXl: '0 22px 44px rgb(40 60 90 / 0.14)', + insetHighlight: 'inset 0 1px 0 rgb(255 255 255)', + insetShadow: 'inset 0 2px 4px rgb(40 60 90 / 0.08)', + }, + stylesheet: `${PORCELAIN_GLOSS}\n${SHARED_CHROME}`, + stylesheetScoped: true, +}; + +export const CINNABAR_LACQUER_THEME = { + id: 'cinnabar-lacquer', + name: 'Cinnabar Lacquer', + type: 'dark' as const, + author: 'ReaderGo Materials', + description: + 'Deep lacquer trays with cinnabar accents - glossy sheen, tight metal radius, gold edge light.', + colors: { + background: '0 35% 8%', + foreground: '30 30% 90%', + card: '0 28% 12%', + cardForeground: '30 30% 90%', + border: '8 30% 22%', + primary: '6 72% 46%', + primaryForeground: '30 40% 96%', + secondary: '0 20% 16%', + secondaryForeground: '30 25% 82%', + muted: '0 18% 14%', + mutedForeground: '20 12% 55%', + accent: '38 70% 48%', + accentForeground: '0 40% 8%', + destructive: '0 75% 48%', + destructiveForeground: '0 0% 100%', + success: '145 35% 40%', + successForeground: '0 0% 100%', + warning: '38 80% 48%', + warningForeground: '0 40% 8%', + info: '200 40% 48%', + infoForeground: '0 0% 100%', + input: '0 24% 10%', + ring: '6 72% 50%', + heading1: '38 65% 68%', + heading2: '20 50% 64%', + heading3: '8 40% 60%', + }, + fonts: { + display: FRAUNCES, + body: SOURCE_SANS, + editor: FRAUNCES, + mono: IBM_PLEX_MONO, + }, + materials: { + ...PHYSICAL_MATERIALS_BASE, + radius: '0.4rem', + radiusSm: '0.25rem', + radiusMd: '0.35rem', + radiusLg: '0.4rem', + radiusXl: '0.55rem', + radius2xl: '0.7rem', + shadowSm: '0 1px 0 rgb(255 180 120 / 0.12), 0 1px 3px rgb(0 0 0 / 0.55)', + shadowMd: + '0 1px 0 rgb(255 180 120 / 0.1), 0 5px 14px rgb(0 0 0 / 0.5), 0 2px 4px rgb(80 0 0 / 0.25)', + shadowLg: '0 14px 30px rgb(0 0 0 / 0.55)', + shadowXl: '0 22px 44px rgb(0 0 0 / 0.6)', + insetHighlight: 'inset 0 1px 0 rgb(255 200 160 / 0.2)', + insetShadow: 'inset 0 2px 5px rgb(0 0 0 / 0.55)', + }, + stylesheet: `${LACQUER_SHEEN}\n${SHARED_CHROME}`, + stylesheetScoped: true, +}; + +export const DENIM_BENCH_THEME = { + id: 'denim-bench', + name: 'Denim Bench', + type: 'dark' as const, + author: 'ReaderGo Materials', + description: + 'Indigo workbench with twill texture - copper rivets, stitched borders, utility chrome.', + colors: { + background: '218 28% 14%', + foreground: '210 25% 92%', + card: '218 24% 18%', + cardForeground: '210 25% 92%', + border: '214 20% 30%', + primary: '28 65% 52%', + primaryForeground: '218 40% 10%', + secondary: '218 20% 22%', + secondaryForeground: '210 20% 85%', + muted: '218 18% 20%', + mutedForeground: '214 14% 58%', + accent: '28 65% 52%', + accentForeground: '218 40% 10%', + destructive: '4 70% 50%', + destructiveForeground: '0 0% 100%', + success: '152 40% 42%', + successForeground: '0 0% 100%', + warning: '38 80% 50%', + warningForeground: '218 40% 10%', + info: '200 55% 52%', + infoForeground: '218 40% 10%', + input: '218 22% 16%', + ring: '28 65% 54%', + heading1: '28 70% 68%', + heading2: '210 40% 78%', + heading3: '214 30% 70%', + }, + fonts: { + display: SOURCE_SANS, + body: SOURCE_SANS, + editor: SOURCE_SANS, + mono: IBM_PLEX_MONO, + }, + materials: { + ...PHYSICAL_MATERIALS_BASE, + radius: '0.5rem', + radiusSm: '0.3rem', + radiusMd: '0.4rem', + radiusLg: '0.5rem', + radiusXl: '0.65rem', + radius2xl: '0.8rem', + shadowSm: '0 1px 0 rgb(255 255 255 / 0.08), 0 1px 3px rgb(0 0 0 / 0.45)', + shadowMd: + '0 1px 0 rgb(255 200 140 / 0.08), 0 5px 12px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 20 60 / 0.3)', + shadowLg: '0 12px 28px rgb(0 0 0 / 0.5)', + shadowXl: '0 20px 40px rgb(0 0 0 / 0.55)', + insetHighlight: 'inset 0 1px 0 rgb(255 255 255 / 0.14)', + insetShadow: 'inset 0 2px 5px rgb(0 0 0 / 0.5)', + }, + stylesheet: `${DENIM_TWILL}\n${SHARED_CHROME}`, + stylesheetScoped: true, +}; + +export const BRASS_CONSOLE_THEME = { + id: 'brass-console', + name: 'Brass Console', + type: 'dark' as const, + author: 'ReaderGo Materials', + description: + 'Warm instrument console - oxidized brass bezels, olive panels, engraved mono telemetry.', + colors: { + background: '40 18% 11%', + foreground: '42 35% 86%', + card: '40 16% 15%', + cardForeground: '42 35% 86%', + border: '38 22% 26%', + primary: '42 62% 48%', + primaryForeground: '40 40% 8%', + secondary: '80 12% 18%', + secondaryForeground: '42 28% 80%', + muted: '40 12% 16%', + mutedForeground: '40 12% 54%', + accent: '80 30% 40%', + accentForeground: '42 40% 92%', + destructive: '8 68% 46%', + destructiveForeground: '0 0% 100%', + success: '80 35% 40%', + successForeground: '0 0% 100%', + warning: '38 75% 48%', + warningForeground: '40 40% 8%', + info: '195 35% 48%', + infoForeground: '0 0% 100%', + input: '40 14% 13%', + ring: '42 62% 50%', + heading1: '42 60% 68%', + heading2: '80 25% 62%', + heading3: '40 30% 58%', + }, + fonts: { + display: FRAUNCES, + body: SOURCE_SANS, + editor: IBM_PLEX_MONO, + mono: IBM_PLEX_MONO, + }, + materials: { + ...PHYSICAL_MATERIALS_BASE, + radius: '0.45rem', + radiusSm: '0.25rem', + radiusMd: '0.35rem', + radiusLg: '0.45rem', + radiusXl: '0.6rem', + radius2xl: '0.75rem', + shadowSm: '0 1px 0 rgb(255 210 120 / 0.14), 0 1px 3px rgb(0 0 0 / 0.5)', + shadowMd: + '0 1px 0 rgb(255 210 120 / 0.12), 0 5px 12px rgb(0 0 0 / 0.45), inset 0 -1px 0 rgb(0 0 0 / 0.3)', + shadowLg: '0 12px 28px rgb(0 0 0 / 0.55)', + shadowXl: '0 20px 40px rgb(0 0 0 / 0.6)', + insetHighlight: 'inset 0 1px 0 rgb(255 220 140 / 0.22)', + insetShadow: 'inset 0 2px 5px rgb(0 0 0 / 0.55)', + }, + stylesheet: `${BRASS_PATINA}\n${SHARED_CHROME}`, + stylesheetScoped: true, +}; + export const SKEUO_THEMES = [ LEATHER_DESK_THEME, BRUSHED_STEEL_THEME, BOUND_JOURNAL_THEME, WALNUT_LIBRARY_THEME, + SOFT_PORCELAIN_THEME, + CINNABAR_LACQUER_THEME, + DENIM_BENCH_THEME, + BRASS_CONSOLE_THEME, ]; export const SKEUO_THEME_IDS = SKEUO_THEMES.map((t) => t.id); diff --git a/public/catalog.json b/public/catalog.json index ef77141..5655cc3 100644 --- a/public/catalog.json +++ b/public/catalog.json @@ -458,16 +458,16 @@ { "id": "readergo.theme.skeuomorph", "name": "Skeuomorph Suite", - "description": "Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.", + "description": "Eight physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, and Brass Console.", "category": "feature", - "version": "1.1.1", + "version": "1.2.0", "provides": [ "theme-provider", "font-provider" ], "bundleUrl": "theme-skeuomorph.bundle.json", - "bundleHash": "999b1a905606f812", - "hash": "999b1a905606f812" + "bundleHash": "2927617fc4d3b6de", + "hash": "2927617fc4d3b6de" }, { "id": "readergo.theme.solarized", diff --git a/public/theme-skeuomorph.bundle.json b/public/theme-skeuomorph.bundle.json index bf27ed4..7618b0b 100644 --- a/public/theme-skeuomorph.bundle.json +++ b/public/theme-skeuomorph.bundle.json @@ -2,8 +2,8 @@ "manifest": { "id": "readergo.theme.skeuomorph", "name": "Skeuomorph Suite", - "version": "1.1.1", - "description": "Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.", + "version": "1.2.0", + "description": "Eight physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, and Brass Console.", "category": "feature", "provides": [ "theme-provider", @@ -20,5 +20,5 @@ "ui": "./src/index.ts" } }, - "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-skeuomorph/src/chrome.ts\nvar ACTIVITY_BAR_CHROME = `\n /* Outer rail: darker recessed channel with a hard metal/leather edge */\n [data-rg-chrome=\"activity-bar\"] {\n background-color: hsl(var(--background));\n background-image:\n linear-gradient(90deg, rgb(0 0 0 / 0.28), transparent 55%),\n linear-gradient(180deg, rgb(255 255 255 / 0.04), transparent 30%);\n border-right-color: hsl(var(--border));\n border-right-width: 1px;\n box-shadow:\n inset -1px 0 0 rgb(255 255 255 / 0.06),\n inset 2px 0 6px rgb(0 0 0 / 0.35),\n 2px 0 10px rgb(0 0 0 / 0.25);\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n\n [data-rg-chrome=\"activity-panel\"] {\n background-color: hsl(var(--card));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.05), transparent 28%),\n linear-gradient(90deg, rgb(0 0 0 / 0.12), transparent 40%);\n box-shadow: var(--inset-shadow), 4px 0 18px rgb(0 0 0 / 0.2);\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n\n [data-rg-chrome=\"activity-bottom\"] {\n border-top-color: hsl(var(--border));\n box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.06);\n }\n\n /* Brand plate at the top of the rail */\n [data-rg-chrome=\"activity-brand\"] {\n margin: 0.35rem 0.35rem 0.15rem;\n width: calc(3rem - 0.7rem) !important;\n height: 2.75rem !important;\n border-radius: var(--radius-md);\n border: 1px solid hsl(var(--border));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.1), transparent 55%),\n linear-gradient(0deg, rgb(0 0 0 / 0.2), transparent 40%);\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n }\n\n [data-rg-chrome=\"activity-brand\"]:hover {\n background-color: hsl(var(--muted));\n }\n\n /* Icon wells - physical buttons sitting in the channel */\n [data-rg-chrome=\"activity-item\"],\n [data-rg-chrome=\"activity-collapse\"] {\n margin: 0.15rem 0.35rem;\n width: calc(3rem - 0.7rem) !important;\n height: calc(3rem - 0.55rem) !important;\n border-radius: var(--radius-md);\n border: 1px solid transparent;\n background-image: linear-gradient(180deg, rgb(255 255 255 / 0.03), transparent 60%);\n }\n\n [data-rg-chrome=\"activity-item\"]:hover,\n [data-rg-chrome=\"activity-collapse\"]:hover {\n border-color: hsl(var(--border));\n background-color: hsl(var(--muted));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.1), transparent 50%),\n linear-gradient(0deg, rgb(0 0 0 / 0.15), transparent 40%);\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n color: hsl(var(--foreground));\n }\n\n /* Active tool - pressed / latched into the rail */\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"] {\n border-color: hsl(var(--primary) / 0.45);\n background-color: hsl(var(--primary) / 0.16);\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 45%),\n linear-gradient(0deg, rgb(0 0 0 / 0.28), transparent 50%);\n box-shadow:\n var(--inset-shadow),\n 0 0 0 1px hsl(var(--primary) / 0.2),\n inset 0 0 10px hsl(var(--primary) / 0.12);\n color: hsl(var(--primary));\n }\n\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"]:hover {\n background-color: hsl(var(--primary) / 0.2);\n }\n\n /* Inlaid active indicator - brass/LED strip instead of a flat bar */\n [data-rg-chrome=\"activity-indicator\"] {\n left: 0.1rem !important;\n width: 3px !important;\n border-radius: 999px;\n box-shadow:\n 0 0 6px hsl(var(--primary) / 0.55),\n inset 0 1px 0 rgb(255 255 255 / 0.35);\n }\n\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"] [data-rg-chrome=\"activity-indicator\"] {\n opacity: 1 !important;\n background: linear-gradient(\n 180deg,\n hsl(var(--primary)),\n hsl(var(--primary) / 0.65)\n ) !important;\n }\n`;\nvar SHARED_CHROME = `\n ${ACTIVITY_BAR_CHROME}\n\n /* Recessed trays (inspector / misc side rails) */\n aside,\n [data-sidebar],\n nav[aria-label] {\n box-shadow: var(--inset-shadow);\n }\n\n /* Embossed cards / popovers */\n .bg-card,\n .bg-card\\\\/40,\n .bg-card\\\\/50,\n .bg-card\\\\/60,\n .bg-card\\\\/70,\n .bg-card\\\\/75,\n .bg-card\\\\/80,\n .bg-card\\\\/85,\n .bg-popover,\n .bg-popover\\\\/95 {\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 42%),\n linear-gradient(0deg, rgb(0 0 0 / 0.14), transparent 38%);\n box-shadow: var(--inset-highlight), var(--shadow-md);\n border-color: hsl(var(--border));\n }\n\n /* Raised actuators - skip activity-bar items (styled above) */\n button:not([data-rg-chrome^=\"activity\"]),\n [role=\"button\"]:not([data-rg-chrome^=\"activity\"]),\n .bg-primary {\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n }\n\n button:not([data-rg-chrome^=\"activity\"]):active,\n [role=\"button\"]:not([data-rg-chrome^=\"activity\"]):active {\n box-shadow: var(--inset-shadow);\n transform: translateY(1px);\n }\n\n /* Recessed fields */\n input,\n textarea,\n select,\n [data-slot=\"input\"] {\n box-shadow: var(--inset-shadow);\n background-image: linear-gradient(180deg, rgb(0 0 0 / 0.1), transparent 55%);\n }\n\n /* Hairline metal/leather edge on focus */\n button:focus-visible,\n [role=\"button\"]:focus-visible,\n a:focus-visible,\n input:focus-visible,\n textarea:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n }\n\n /* Kill glass - materials already zero blur; keep surfaces opaque */\n .backdrop-blur-sm,\n .backdrop-blur,\n .backdrop-blur-md,\n .backdrop-blur-lg,\n .backdrop-blur-xl,\n .backdrop-blur-2xl,\n .backdrop-blur-3xl {\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n`;\nvar LEATHER_GRAIN = `\n background-image:\n radial-gradient(ellipse at 18% 8%, rgb(140 80 45 / 0.22), transparent 42%),\n radial-gradient(ellipse at 82% 92%, rgb(30 14 8 / 0.35), transparent 48%),\n repeating-linear-gradient(\n 118deg,\n rgb(255 230 180 / 0.025) 0 1px,\n transparent 1px 4px\n ),\n repeating-linear-gradient(\n 28deg,\n rgb(0 0 0 / 0.04) 0 2px,\n transparent 2px 5px\n );\n`;\nvar STEEL_BRUSH = `\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.06), transparent 35%),\n repeating-linear-gradient(\n 90deg,\n rgb(255 255 255 / 0.035) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 0deg,\n rgb(0 0 0 / 0.04) 0 1px,\n transparent 1px 2px\n );\n`;\nvar JOURNAL_FIBER = `\n background-image:\n radial-gradient(ellipse at 50% 0%, rgb(255 255 255 / 0.55), transparent 55%),\n repeating-linear-gradient(\n 0deg,\n rgb(40 30 20 / 0.03) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 90deg,\n rgb(40 30 20 / 0.02) 0 1px,\n transparent 1px 4px\n );\n`;\nvar WALNUT_GRAIN = `\n background-image:\n radial-gradient(ellipse at 30% 20%, rgb(160 100 50 / 0.15), transparent 50%),\n repeating-linear-gradient(\n 95deg,\n rgb(255 210 150 / 0.03) 0 2px,\n transparent 2px 7px\n ),\n repeating-linear-gradient(\n 5deg,\n rgb(0 0 0 / 0.06) 0 1px,\n transparent 1px 6px\n );\n`;\n\n// plugins/theme-skeuomorph/src/themes.ts\nvar FRAUNCES = {\n id: \"fraunces-display\",\n name: \"Fraunces\",\n family: \"'Fraunces', 'Georgia', serif\",\n category: \"display\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-3\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar IBM_PLEX_MONO = {\n id: \"ibm-plex-mono-steel\",\n name: \"IBM Plex Mono\",\n family: \"'IBM Plex Mono', ui-monospace, monospace\",\n category: \"mono\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap\",\n targets: [\"mono\"]\n};\nvar LITERATA = {\n id: \"literata-journal\",\n name: \"Literata\",\n family: \"'Literata', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SKEUO_FONTS = [FRAUNCES, SOURCE_SANS, IBM_PLEX_MONO, LITERATA];\nvar PHYSICAL_MATERIALS_BASE = {\n surfaceBlur: \"0px\",\n borderWidth: \"1px\"\n};\nvar LEATHER_DESK_THEME = {\n id: \"leather-desk\",\n name: \"Leather Desk\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Walnut blotter and brass actuators - embossed cards, recessed trays, leather grain.\",\n colors: {\n background: \"25 28% 12%\",\n foreground: \"36 40% 88%\",\n card: \"25 24% 16%\",\n cardForeground: \"36 40% 88%\",\n border: \"30 22% 28%\",\n primary: \"36 55% 48%\",\n primaryForeground: \"25 40% 10%\",\n secondary: \"25 18% 20%\",\n secondaryForeground: \"36 30% 82%\",\n muted: \"25 16% 18%\",\n mutedForeground: \"30 14% 58%\",\n accent: \"36 55% 48%\",\n accentForeground: \"25 40% 10%\",\n destructive: \"6 70% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"142 40% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 48%\",\n warningForeground: \"25 40% 10%\",\n info: \"200 40% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"25 22% 14%\",\n ring: \"36 55% 52%\",\n heading1: \"36 60% 72%\",\n heading2: \"34 45% 66%\",\n heading3: \"32 35% 60%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: SOURCE_SANS\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.65rem\",\n radiusSm: \"0.4rem\",\n radiusMd: \"0.5rem\",\n radiusLg: \"0.65rem\",\n radiusXl: \"0.85rem\",\n radius2xl: \"1rem\",\n shadowSm: \"0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)\",\n shadowMd: \"0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)\",\n shadowXl: \"0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 230 180 / 0.22)\",\n insetShadow: \"inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)\"\n },\n stylesheet: `${LEATHER_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BRUSHED_STEEL_THEME = {\n id: \"brushed-steel\",\n name: \"Brushed Steel\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Cold instrument panel - machined aluminum grain, tight radii, cyan status LEDs.\",\n colors: {\n background: \"210 12% 14%\",\n foreground: \"210 20% 92%\",\n card: \"210 10% 18%\",\n cardForeground: \"210 20% 92%\",\n border: \"210 8% 32%\",\n primary: \"198 72% 48%\",\n primaryForeground: \"210 30% 8%\",\n secondary: \"210 10% 22%\",\n secondaryForeground: \"210 15% 85%\",\n muted: \"210 8% 20%\",\n mutedForeground: \"210 8% 58%\",\n accent: \"198 72% 48%\",\n accentForeground: \"210 30% 8%\",\n destructive: \"0 65% 50%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 45% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 85% 50%\",\n warningForeground: \"210 30% 8%\",\n info: \"198 72% 52%\",\n infoForeground: \"210 30% 8%\",\n input: \"210 12% 16%\",\n ring: \"198 72% 52%\",\n heading1: \"198 70% 72%\",\n heading2: \"200 45% 68%\",\n heading3: \"205 30% 64%\"\n },\n fonts: {\n display: SOURCE_SANS,\n body: SOURCE_SANS,\n editor: SOURCE_SANS,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.35rem\",\n radiusSm: \"0.2rem\",\n radiusMd: \"0.28rem\",\n radiusLg: \"0.35rem\",\n radiusXl: \"0.45rem\",\n radius2xl: \"0.55rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.14), 0 1px 2px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.1), 0 3px 8px rgb(0 0 0 / 0.45), inset 0 -1px 0 rgb(0 0 0 / 0.25)\",\n shadowLg: \"0 10px 24px rgb(0 0 0 / 0.5), 0 1px 0 rgb(255 255 255 / 0.08)\",\n shadowXl: \"0 18px 36px rgb(0 0 0 / 0.55)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.28)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.55), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${STEEL_BRUSH}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BOUND_JOURNAL_THEME = {\n id: \"bound-journal\",\n name: \"Bound Journal\",\n type: \"light\",\n author: \"ReaderGo Materials\",\n description: \"Cloth-bound notebook - inked linen fiber, soft pressed pages, midnight ink accents.\",\n colors: {\n background: \"40 18% 93%\",\n foreground: \"220 25% 16%\",\n card: \"40 22% 97%\",\n cardForeground: \"220 25% 16%\",\n border: \"35 12% 78%\",\n primary: \"222 35% 28%\",\n primaryForeground: \"40 30% 96%\",\n secondary: \"38 14% 88%\",\n secondaryForeground: \"220 20% 22%\",\n muted: \"38 12% 90%\",\n mutedForeground: \"220 10% 42%\",\n accent: \"160 28% 32%\",\n accentForeground: \"40 30% 96%\",\n destructive: \"4 65% 42%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 35% 32%\",\n successForeground: \"0 0% 100%\",\n warning: \"32 70% 38%\",\n warningForeground: \"0 0% 100%\",\n info: \"210 40% 38%\",\n infoForeground: \"0 0% 100%\",\n input: \"40 20% 95%\",\n ring: \"222 35% 32%\",\n heading1: \"222 40% 22%\",\n heading2: \"220 28% 28%\",\n heading3: \"218 20% 34%\"\n },\n fonts: {\n display: LITERATA,\n body: SOURCE_SANS,\n editor: LITERATA,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.55rem\",\n radiusSm: \"0.35rem\",\n radiusMd: \"0.45rem\",\n radiusLg: \"0.55rem\",\n radiusXl: \"0.7rem\",\n radius2xl: \"0.85rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.85), 0 1px 2px rgb(40 30 20 / 0.12)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.9), 0 4px 12px rgb(40 30 20 / 0.12), 0 1px 3px rgb(40 30 20 / 0.08)\",\n shadowLg: \"0 12px 28px rgb(40 30 20 / 0.14), 0 2px 6px rgb(40 30 20 / 0.08)\",\n shadowXl: \"0 20px 40px rgb(40 30 20 / 0.16)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.95)\",\n insetShadow: \"inset 0 2px 4px rgb(40 30 20 / 0.12), inset 0 1px 0 rgb(40 30 20 / 0.06)\"\n },\n stylesheet: `${JOURNAL_FIBER}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar WALNUT_LIBRARY_THEME = {\n id: \"walnut-library\",\n name: \"Walnut Library\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Deep library shelves - warm wood grain, amber lamps, wide embossed panels.\",\n colors: {\n background: \"28 32% 10%\",\n foreground: \"38 35% 86%\",\n card: \"28 28% 14%\",\n cardForeground: \"38 35% 86%\",\n border: \"32 24% 24%\",\n primary: \"32 70% 46%\",\n primaryForeground: \"28 40% 8%\",\n secondary: \"28 22% 18%\",\n secondaryForeground: \"38 28% 80%\",\n muted: \"28 20% 15%\",\n mutedForeground: \"32 16% 52%\",\n accent: \"150 35% 40%\",\n accentForeground: \"28 40% 8%\",\n destructive: \"8 68% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"150 35% 40%\",\n successForeground: \"0 0% 100%\",\n warning: \"36 78% 48%\",\n warningForeground: \"28 40% 8%\",\n info: \"200 35% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"28 26% 12%\",\n ring: \"32 70% 50%\",\n heading1: \"38 55% 70%\",\n heading2: \"34 42% 64%\",\n heading3: \"30 32% 58%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.75rem\",\n radiusSm: \"0.45rem\",\n radiusMd: \"0.55rem\",\n radiusLg: \"0.75rem\",\n radiusXl: \"1rem\",\n radius2xl: \"1.15rem\",\n shadowSm: \"0 1px 0 rgb(255 200 120 / 0.1), 0 1px 3px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 200 120 / 0.08), 0 6px 14px rgb(0 0 0 / 0.45), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 14px 32px rgb(0 0 0 / 0.55), 0 4px 10px rgb(0 0 0 / 0.4)\",\n shadowXl: \"0 24px 48px rgb(0 0 0 / 0.6)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 210 140 / 0.18)\",\n insetShadow: \"inset 0 3px 6px rgb(0 0 0 / 0.5), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${WALNUT_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar SKEUO_THEMES = [\n LEATHER_DESK_THEME,\n BRUSHED_STEEL_THEME,\n BOUND_JOURNAL_THEME,\n WALNUT_LIBRARY_THEME\n];\nvar SKEUO_THEME_IDS = SKEUO_THEMES.map((t) => t.id);\n\n// plugins/theme-skeuomorph/src/index.ts\nvar SkeuomorphThemePlugin = {\n manifest: {\n id: \"readergo.theme.skeuomorph\",\n name: \"Skeuomorph Suite\",\n version: \"1.1.1\",\n description: \"Physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, and Walnut Library - materials tokens plus scoped grain stylesheets.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(\"Skeuomorph Suite activating (4 physical atmospheres)...\");\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => SKEUO_THEMES\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => SKEUO_FONTS\n });\n const enable = async (themeId) => {\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId });\n return { activeTheme: themeId };\n };\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableLeather\",\n title: \"Theme: Leather Desk\",\n handler: async () => enable(LEATHER_DESK_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableSteel\",\n title: \"Theme: Brushed Steel\",\n handler: async () => enable(BRUSHED_STEEL_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableJournal\",\n title: \"Theme: Bound Journal\",\n handler: async () => enable(BOUND_JOURNAL_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.enableWalnut\",\n title: \"Theme: Walnut Library\",\n handler: async () => enable(WALNUT_LIBRARY_THEME.id)\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.cycle\",\n title: \"Theme: Cycle Skeuomorph Atmosphere\",\n handler: async () => {\n const active = await context.executeCommand(\"readergo.theme.getActiveTheme\");\n const currentId = active?.id || LEATHER_DESK_THEME.id;\n const idx = SKEUO_THEME_IDS.indexOf(currentId);\n const next = SKEUO_THEME_IDS[idx >= 0 ? (idx + 1) % SKEUO_THEME_IDS.length : 0];\n return enable(next);\n }\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.getModes\",\n title: \"Theme: List Skeuomorph Atmospheres\",\n handler: async () => SKEUO_THEMES.map((t) => ({\n id: t.id,\n name: t.name,\n type: t.type,\n description: t.description\n }))\n });\n },\n deactivate(context) {\n context.log.info(\"Skeuomorph Suite deactivated.\");\n }\n};\nvar index_default = SkeuomorphThemePlugin;\n\n\n return { ACTIVITY_BAR_CHROME: ACTIVITY_BAR_CHROME, BOUND_JOURNAL_THEME: BOUND_JOURNAL_THEME, BRUSHED_STEEL_THEME: BRUSHED_STEEL_THEME, FRAUNCES: FRAUNCES, IBM_PLEX_MONO: IBM_PLEX_MONO, JOURNAL_FIBER: JOURNAL_FIBER, LEATHER_DESK_THEME: LEATHER_DESK_THEME, LEATHER_GRAIN: LEATHER_GRAIN, LITERATA: LITERATA, SHARED_CHROME: SHARED_CHROME, SKEUO_FONTS: SKEUO_FONTS, SKEUO_THEMES: SKEUO_THEMES, SKEUO_THEME_IDS: SKEUO_THEME_IDS, SOURCE_SANS: SOURCE_SANS, STEEL_BRUSH: STEEL_BRUSH, SkeuomorphThemePlugin: SkeuomorphThemePlugin, WALNUT_GRAIN: WALNUT_GRAIN, WALNUT_LIBRARY_THEME: WALNUT_LIBRARY_THEME, default: index_default };\n}\n" + "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-skeuomorph/src/chrome.ts\nvar ACTIVITY_BAR_CHROME = `\n /* Outer rail: darker recessed channel with a hard metal/leather edge */\n [data-rg-chrome=\"activity-bar\"] {\n background-color: hsl(var(--background));\n background-image:\n linear-gradient(90deg, rgb(0 0 0 / 0.28), transparent 55%),\n linear-gradient(180deg, rgb(255 255 255 / 0.04), transparent 30%);\n border-right-color: hsl(var(--border));\n border-right-width: 1px;\n box-shadow:\n inset -1px 0 0 rgb(255 255 255 / 0.06),\n inset 2px 0 6px rgb(0 0 0 / 0.35),\n 2px 0 10px rgb(0 0 0 / 0.25);\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n\n [data-rg-chrome=\"activity-panel\"] {\n background-color: hsl(var(--card));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.05), transparent 28%),\n linear-gradient(90deg, rgb(0 0 0 / 0.12), transparent 40%);\n box-shadow: var(--inset-shadow), 4px 0 18px rgb(0 0 0 / 0.2);\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n\n [data-rg-chrome=\"activity-bottom\"] {\n border-top-color: hsl(var(--border));\n box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.06);\n }\n\n /* Brand plate at the top of the rail */\n [data-rg-chrome=\"activity-brand\"] {\n margin: 0.35rem 0.35rem 0.15rem;\n width: calc(3rem - 0.7rem) !important;\n height: 2.75rem !important;\n border-radius: var(--radius-md);\n border: 1px solid hsl(var(--border));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.1), transparent 55%),\n linear-gradient(0deg, rgb(0 0 0 / 0.2), transparent 40%);\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n }\n\n [data-rg-chrome=\"activity-brand\"]:hover {\n background-color: hsl(var(--muted));\n }\n\n /* Icon wells - physical buttons sitting in the channel */\n [data-rg-chrome=\"activity-item\"],\n [data-rg-chrome=\"activity-collapse\"] {\n margin: 0.15rem 0.35rem;\n width: calc(3rem - 0.7rem) !important;\n height: calc(3rem - 0.55rem) !important;\n border-radius: var(--radius-md);\n border: 1px solid transparent;\n background-image: linear-gradient(180deg, rgb(255 255 255 / 0.03), transparent 60%);\n }\n\n [data-rg-chrome=\"activity-item\"]:hover,\n [data-rg-chrome=\"activity-collapse\"]:hover {\n border-color: hsl(var(--border));\n background-color: hsl(var(--muted));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.1), transparent 50%),\n linear-gradient(0deg, rgb(0 0 0 / 0.15), transparent 40%);\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n color: hsl(var(--foreground));\n }\n\n /* Active tool - pressed / latched into the rail */\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"] {\n border-color: hsl(var(--primary) / 0.45);\n background-color: hsl(var(--primary) / 0.16);\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 45%),\n linear-gradient(0deg, rgb(0 0 0 / 0.28), transparent 50%);\n box-shadow:\n var(--inset-shadow),\n 0 0 0 1px hsl(var(--primary) / 0.2),\n inset 0 0 10px hsl(var(--primary) / 0.12);\n color: hsl(var(--primary));\n }\n\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"]:hover {\n background-color: hsl(var(--primary) / 0.2);\n }\n\n /* Inlaid active indicator - brass/LED strip instead of a flat bar */\n [data-rg-chrome=\"activity-indicator\"] {\n left: 0.1rem !important;\n width: 3px !important;\n border-radius: 999px;\n box-shadow:\n 0 0 6px hsl(var(--primary) / 0.55),\n inset 0 1px 0 rgb(255 255 255 / 0.35);\n }\n\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"] [data-rg-chrome=\"activity-indicator\"] {\n opacity: 1 !important;\n background: linear-gradient(\n 180deg,\n hsl(var(--primary)),\n hsl(var(--primary) / 0.65)\n ) !important;\n }\n`;\nvar SHARED_CHROME = `\n ${ACTIVITY_BAR_CHROME}\n\n /* Recessed trays (inspector / misc side rails) */\n aside,\n [data-sidebar],\n nav[aria-label] {\n box-shadow: var(--inset-shadow);\n }\n\n /* Embossed cards / popovers */\n .bg-card,\n .bg-card\\\\/40,\n .bg-card\\\\/50,\n .bg-card\\\\/60,\n .bg-card\\\\/70,\n .bg-card\\\\/75,\n .bg-card\\\\/80,\n .bg-card\\\\/85,\n .bg-popover,\n .bg-popover\\\\/95 {\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 42%),\n linear-gradient(0deg, rgb(0 0 0 / 0.14), transparent 38%);\n box-shadow: var(--inset-highlight), var(--shadow-md);\n border-color: hsl(var(--border));\n }\n\n /* Raised actuators - skip activity-bar items (styled above) */\n button:not([data-rg-chrome^=\"activity\"]),\n [role=\"button\"]:not([data-rg-chrome^=\"activity\"]),\n .bg-primary {\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n }\n\n button:not([data-rg-chrome^=\"activity\"]):active,\n [role=\"button\"]:not([data-rg-chrome^=\"activity\"]):active {\n box-shadow: var(--inset-shadow);\n transform: translateY(1px);\n }\n\n /* Recessed fields */\n input,\n textarea,\n select,\n [data-slot=\"input\"] {\n box-shadow: var(--inset-shadow);\n background-image: linear-gradient(180deg, rgb(0 0 0 / 0.1), transparent 55%);\n }\n\n /* Hairline metal/leather edge on focus */\n button:focus-visible,\n [role=\"button\"]:focus-visible,\n a:focus-visible,\n input:focus-visible,\n textarea:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n }\n\n /* Kill glass - materials already zero blur; keep surfaces opaque */\n .backdrop-blur-sm,\n .backdrop-blur,\n .backdrop-blur-md,\n .backdrop-blur-lg,\n .backdrop-blur-xl,\n .backdrop-blur-2xl,\n .backdrop-blur-3xl {\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n`;\nvar LEATHER_GRAIN = `\n background-image:\n radial-gradient(ellipse at 18% 8%, rgb(140 80 45 / 0.22), transparent 42%),\n radial-gradient(ellipse at 82% 92%, rgb(30 14 8 / 0.35), transparent 48%),\n repeating-linear-gradient(\n 118deg,\n rgb(255 230 180 / 0.025) 0 1px,\n transparent 1px 4px\n ),\n repeating-linear-gradient(\n 28deg,\n rgb(0 0 0 / 0.04) 0 2px,\n transparent 2px 5px\n );\n`;\nvar STEEL_BRUSH = `\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.06), transparent 35%),\n repeating-linear-gradient(\n 90deg,\n rgb(255 255 255 / 0.035) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 0deg,\n rgb(0 0 0 / 0.04) 0 1px,\n transparent 1px 2px\n );\n`;\nvar JOURNAL_FIBER = `\n background-image:\n radial-gradient(ellipse at 50% 0%, rgb(255 255 255 / 0.55), transparent 55%),\n repeating-linear-gradient(\n 0deg,\n rgb(40 30 20 / 0.03) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 90deg,\n rgb(40 30 20 / 0.02) 0 1px,\n transparent 1px 4px\n );\n`;\nvar WALNUT_GRAIN = `\n background-image:\n radial-gradient(ellipse at 30% 20%, rgb(160 100 50 / 0.15), transparent 50%),\n repeating-linear-gradient(\n 95deg,\n rgb(255 210 150 / 0.03) 0 2px,\n transparent 2px 7px\n ),\n repeating-linear-gradient(\n 5deg,\n rgb(0 0 0 / 0.06) 0 1px,\n transparent 1px 6px\n );\n`;\nvar PORCELAIN_GLOSS = `\n background-image:\n radial-gradient(ellipse at 20% 0%, rgb(255 255 255 / 0.9), transparent 45%),\n radial-gradient(ellipse at 80% 100%, rgb(180 200 220 / 0.18), transparent 50%),\n linear-gradient(180deg, rgb(255 255 255 / 0.35), transparent 40%);\n`;\nvar LACQUER_SHEEN = `\n background-image:\n radial-gradient(ellipse at 15% 10%, rgb(180 40 40 / 0.22), transparent 40%),\n radial-gradient(ellipse at 85% 90%, rgb(0 0 0 / 0.45), transparent 45%),\n linear-gradient(135deg, rgb(255 200 160 / 0.05), transparent 40%),\n repeating-linear-gradient(\n 120deg,\n rgb(255 255 255 / 0.02) 0 1px,\n transparent 1px 5px\n );\n`;\nvar DENIM_TWILL = `\n background-image:\n repeating-linear-gradient(\n 45deg,\n rgb(255 255 255 / 0.03) 0 1px,\n transparent 1px 4px\n ),\n repeating-linear-gradient(\n -45deg,\n rgb(0 0 0 / 0.05) 0 1px,\n transparent 1px 4px\n ),\n radial-gradient(ellipse at 50% 0%, rgb(100 140 200 / 0.12), transparent 55%);\n`;\nvar BRASS_PATINA = `\n background-image:\n radial-gradient(ellipse at 25% 15%, rgb(220 170 80 / 0.14), transparent 45%),\n radial-gradient(ellipse at 75% 85%, rgb(40 25 10 / 0.35), transparent 50%),\n repeating-linear-gradient(\n 92deg,\n rgb(255 210 120 / 0.04) 0 1px,\n transparent 1px 3px\n );\n`;\n\n// plugins/theme-skeuomorph/src/themes.ts\nvar FRAUNCES = {\n id: \"fraunces-display\",\n name: \"Fraunces\",\n family: \"'Fraunces', 'Georgia', serif\",\n category: \"display\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-3\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar IBM_PLEX_MONO = {\n id: \"ibm-plex-mono-steel\",\n name: \"IBM Plex Mono\",\n family: \"'IBM Plex Mono', ui-monospace, monospace\",\n category: \"mono\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap\",\n targets: [\"mono\"]\n};\nvar LITERATA = {\n id: \"literata-journal\",\n name: \"Literata\",\n family: \"'Literata', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SKEUO_FONTS = [FRAUNCES, SOURCE_SANS, IBM_PLEX_MONO, LITERATA];\nvar PHYSICAL_MATERIALS_BASE = {\n surfaceBlur: \"0px\",\n borderWidth: \"1px\"\n};\nvar LEATHER_DESK_THEME = {\n id: \"leather-desk\",\n name: \"Leather Desk\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Walnut blotter and brass actuators - embossed cards, recessed trays, leather grain.\",\n colors: {\n background: \"25 28% 12%\",\n foreground: \"36 40% 88%\",\n card: \"25 24% 16%\",\n cardForeground: \"36 40% 88%\",\n border: \"30 22% 28%\",\n primary: \"36 55% 48%\",\n primaryForeground: \"25 40% 10%\",\n secondary: \"25 18% 20%\",\n secondaryForeground: \"36 30% 82%\",\n muted: \"25 16% 18%\",\n mutedForeground: \"30 14% 58%\",\n accent: \"36 55% 48%\",\n accentForeground: \"25 40% 10%\",\n destructive: \"6 70% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"142 40% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 48%\",\n warningForeground: \"25 40% 10%\",\n info: \"200 40% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"25 22% 14%\",\n ring: \"36 55% 52%\",\n heading1: \"36 60% 72%\",\n heading2: \"34 45% 66%\",\n heading3: \"32 35% 60%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: SOURCE_SANS\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.65rem\",\n radiusSm: \"0.4rem\",\n radiusMd: \"0.5rem\",\n radiusLg: \"0.65rem\",\n radiusXl: \"0.85rem\",\n radius2xl: \"1rem\",\n shadowSm: \"0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)\",\n shadowMd: \"0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)\",\n shadowXl: \"0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 230 180 / 0.22)\",\n insetShadow: \"inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)\"\n },\n stylesheet: `${LEATHER_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BRUSHED_STEEL_THEME = {\n id: \"brushed-steel\",\n name: \"Brushed Steel\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Cold instrument panel - machined aluminum grain, tight radii, cyan status LEDs.\",\n colors: {\n background: \"210 12% 14%\",\n foreground: \"210 20% 92%\",\n card: \"210 10% 18%\",\n cardForeground: \"210 20% 92%\",\n border: \"210 8% 32%\",\n primary: \"198 72% 48%\",\n primaryForeground: \"210 30% 8%\",\n secondary: \"210 10% 22%\",\n secondaryForeground: \"210 15% 85%\",\n muted: \"210 8% 20%\",\n mutedForeground: \"210 8% 58%\",\n accent: \"198 72% 48%\",\n accentForeground: \"210 30% 8%\",\n destructive: \"0 65% 50%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 45% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 85% 50%\",\n warningForeground: \"210 30% 8%\",\n info: \"198 72% 52%\",\n infoForeground: \"210 30% 8%\",\n input: \"210 12% 16%\",\n ring: \"198 72% 52%\",\n heading1: \"198 70% 72%\",\n heading2: \"200 45% 68%\",\n heading3: \"205 30% 64%\"\n },\n fonts: {\n display: SOURCE_SANS,\n body: SOURCE_SANS,\n editor: SOURCE_SANS,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.35rem\",\n radiusSm: \"0.2rem\",\n radiusMd: \"0.28rem\",\n radiusLg: \"0.35rem\",\n radiusXl: \"0.45rem\",\n radius2xl: \"0.55rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.14), 0 1px 2px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.1), 0 3px 8px rgb(0 0 0 / 0.45), inset 0 -1px 0 rgb(0 0 0 / 0.25)\",\n shadowLg: \"0 10px 24px rgb(0 0 0 / 0.5), 0 1px 0 rgb(255 255 255 / 0.08)\",\n shadowXl: \"0 18px 36px rgb(0 0 0 / 0.55)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.28)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.55), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${STEEL_BRUSH}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BOUND_JOURNAL_THEME = {\n id: \"bound-journal\",\n name: \"Bound Journal\",\n type: \"light\",\n author: \"ReaderGo Materials\",\n description: \"Cloth-bound notebook - inked linen fiber, soft pressed pages, midnight ink accents.\",\n colors: {\n background: \"40 18% 93%\",\n foreground: \"220 25% 16%\",\n card: \"40 22% 97%\",\n cardForeground: \"220 25% 16%\",\n border: \"35 12% 78%\",\n primary: \"222 35% 28%\",\n primaryForeground: \"40 30% 96%\",\n secondary: \"38 14% 88%\",\n secondaryForeground: \"220 20% 22%\",\n muted: \"38 12% 90%\",\n mutedForeground: \"220 10% 42%\",\n accent: \"160 28% 32%\",\n accentForeground: \"40 30% 96%\",\n destructive: \"4 65% 42%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 35% 32%\",\n successForeground: \"0 0% 100%\",\n warning: \"32 70% 38%\",\n warningForeground: \"0 0% 100%\",\n info: \"210 40% 38%\",\n infoForeground: \"0 0% 100%\",\n input: \"40 20% 95%\",\n ring: \"222 35% 32%\",\n heading1: \"222 40% 22%\",\n heading2: \"220 28% 28%\",\n heading3: \"218 20% 34%\"\n },\n fonts: {\n display: LITERATA,\n body: SOURCE_SANS,\n editor: LITERATA,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.55rem\",\n radiusSm: \"0.35rem\",\n radiusMd: \"0.45rem\",\n radiusLg: \"0.55rem\",\n radiusXl: \"0.7rem\",\n radius2xl: \"0.85rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.85), 0 1px 2px rgb(40 30 20 / 0.12)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.9), 0 4px 12px rgb(40 30 20 / 0.12), 0 1px 3px rgb(40 30 20 / 0.08)\",\n shadowLg: \"0 12px 28px rgb(40 30 20 / 0.14), 0 2px 6px rgb(40 30 20 / 0.08)\",\n shadowXl: \"0 20px 40px rgb(40 30 20 / 0.16)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.95)\",\n insetShadow: \"inset 0 2px 4px rgb(40 30 20 / 0.12), inset 0 1px 0 rgb(40 30 20 / 0.06)\"\n },\n stylesheet: `${JOURNAL_FIBER}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar WALNUT_LIBRARY_THEME = {\n id: \"walnut-library\",\n name: \"Walnut Library\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Deep library shelves - warm wood grain, amber lamps, wide embossed panels.\",\n colors: {\n background: \"28 32% 10%\",\n foreground: \"38 35% 86%\",\n card: \"28 28% 14%\",\n cardForeground: \"38 35% 86%\",\n border: \"32 24% 24%\",\n primary: \"32 70% 46%\",\n primaryForeground: \"28 40% 8%\",\n secondary: \"28 22% 18%\",\n secondaryForeground: \"38 28% 80%\",\n muted: \"28 20% 15%\",\n mutedForeground: \"32 16% 52%\",\n accent: \"150 35% 40%\",\n accentForeground: \"28 40% 8%\",\n destructive: \"8 68% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"150 35% 40%\",\n successForeground: \"0 0% 100%\",\n warning: \"36 78% 48%\",\n warningForeground: \"28 40% 8%\",\n info: \"200 35% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"28 26% 12%\",\n ring: \"32 70% 50%\",\n heading1: \"38 55% 70%\",\n heading2: \"34 42% 64%\",\n heading3: \"30 32% 58%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.75rem\",\n radiusSm: \"0.45rem\",\n radiusMd: \"0.55rem\",\n radiusLg: \"0.75rem\",\n radiusXl: \"1rem\",\n radius2xl: \"1.15rem\",\n shadowSm: \"0 1px 0 rgb(255 200 120 / 0.1), 0 1px 3px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 200 120 / 0.08), 0 6px 14px rgb(0 0 0 / 0.45), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 14px 32px rgb(0 0 0 / 0.55), 0 4px 10px rgb(0 0 0 / 0.4)\",\n shadowXl: \"0 24px 48px rgb(0 0 0 / 0.6)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 210 140 / 0.18)\",\n insetShadow: \"inset 0 3px 6px rgb(0 0 0 / 0.5), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${WALNUT_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar SOFT_PORCELAIN_THEME = {\n id: \"soft-porcelain\",\n name: \"Soft Porcelain\",\n type: \"light\",\n author: \"ReaderGo Materials\",\n description: \"Glazed ceramic workspace - soft gloss plates, cool slate ink, pillowy radius.\",\n colors: {\n background: \"210 25% 96%\",\n foreground: \"220 28% 18%\",\n card: \"0 0% 100%\",\n cardForeground: \"220 28% 18%\",\n border: \"210 16% 84%\",\n primary: \"205 55% 42%\",\n primaryForeground: \"0 0% 100%\",\n secondary: \"210 18% 92%\",\n secondaryForeground: \"220 22% 24%\",\n muted: \"210 16% 93%\",\n mutedForeground: \"215 12% 46%\",\n accent: \"340 45% 48%\",\n accentForeground: \"0 0% 100%\",\n destructive: \"4 70% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 40% 36%\",\n successForeground: \"0 0% 100%\",\n warning: \"32 75% 42%\",\n warningForeground: \"0 0% 100%\",\n info: \"205 55% 44%\",\n infoForeground: \"0 0% 100%\",\n input: \"210 20% 97%\",\n ring: \"205 55% 44%\",\n heading1: \"220 35% 22%\",\n heading2: \"215 28% 28%\",\n heading3: \"210 22% 34%\"\n },\n fonts: {\n display: SOURCE_SANS,\n body: SOURCE_SANS,\n editor: SOURCE_SANS,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.9rem\",\n radiusSm: \"0.5rem\",\n radiusMd: \"0.7rem\",\n radiusLg: \"0.9rem\",\n radiusXl: \"1.1rem\",\n radius2xl: \"1.35rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.95), 0 1px 3px rgb(40 60 90 / 0.08)\",\n shadowMd: \"0 1px 0 rgb(255 255 255), 0 6px 16px rgb(40 60 90 / 0.1), 0 2px 4px rgb(40 60 90 / 0.06)\",\n shadowLg: \"0 14px 32px rgb(40 60 90 / 0.12)\",\n shadowXl: \"0 22px 44px rgb(40 60 90 / 0.14)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255)\",\n insetShadow: \"inset 0 2px 4px rgb(40 60 90 / 0.08)\"\n },\n stylesheet: `${PORCELAIN_GLOSS}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar CINNABAR_LACQUER_THEME = {\n id: \"cinnabar-lacquer\",\n name: \"Cinnabar Lacquer\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Deep lacquer trays with cinnabar accents - glossy sheen, tight metal radius, gold edge light.\",\n colors: {\n background: \"0 35% 8%\",\n foreground: \"30 30% 90%\",\n card: \"0 28% 12%\",\n cardForeground: \"30 30% 90%\",\n border: \"8 30% 22%\",\n primary: \"6 72% 46%\",\n primaryForeground: \"30 40% 96%\",\n secondary: \"0 20% 16%\",\n secondaryForeground: \"30 25% 82%\",\n muted: \"0 18% 14%\",\n mutedForeground: \"20 12% 55%\",\n accent: \"38 70% 48%\",\n accentForeground: \"0 40% 8%\",\n destructive: \"0 75% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"145 35% 40%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 48%\",\n warningForeground: \"0 40% 8%\",\n info: \"200 40% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"0 24% 10%\",\n ring: \"6 72% 50%\",\n heading1: \"38 65% 68%\",\n heading2: \"20 50% 64%\",\n heading3: \"8 40% 60%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.4rem\",\n radiusSm: \"0.25rem\",\n radiusMd: \"0.35rem\",\n radiusLg: \"0.4rem\",\n radiusXl: \"0.55rem\",\n radius2xl: \"0.7rem\",\n shadowSm: \"0 1px 0 rgb(255 180 120 / 0.12), 0 1px 3px rgb(0 0 0 / 0.55)\",\n shadowMd: \"0 1px 0 rgb(255 180 120 / 0.1), 0 5px 14px rgb(0 0 0 / 0.5), 0 2px 4px rgb(80 0 0 / 0.25)\",\n shadowLg: \"0 14px 30px rgb(0 0 0 / 0.55)\",\n shadowXl: \"0 22px 44px rgb(0 0 0 / 0.6)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 200 160 / 0.2)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.55)\"\n },\n stylesheet: `${LACQUER_SHEEN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar DENIM_BENCH_THEME = {\n id: \"denim-bench\",\n name: \"Denim Bench\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Indigo workbench with twill texture - copper rivets, stitched borders, utility chrome.\",\n colors: {\n background: \"218 28% 14%\",\n foreground: \"210 25% 92%\",\n card: \"218 24% 18%\",\n cardForeground: \"210 25% 92%\",\n border: \"214 20% 30%\",\n primary: \"28 65% 52%\",\n primaryForeground: \"218 40% 10%\",\n secondary: \"218 20% 22%\",\n secondaryForeground: \"210 20% 85%\",\n muted: \"218 18% 20%\",\n mutedForeground: \"214 14% 58%\",\n accent: \"28 65% 52%\",\n accentForeground: \"218 40% 10%\",\n destructive: \"4 70% 50%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 40% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 50%\",\n warningForeground: \"218 40% 10%\",\n info: \"200 55% 52%\",\n infoForeground: \"218 40% 10%\",\n input: \"218 22% 16%\",\n ring: \"28 65% 54%\",\n heading1: \"28 70% 68%\",\n heading2: \"210 40% 78%\",\n heading3: \"214 30% 70%\"\n },\n fonts: {\n display: SOURCE_SANS,\n body: SOURCE_SANS,\n editor: SOURCE_SANS,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.5rem\",\n radiusSm: \"0.3rem\",\n radiusMd: \"0.4rem\",\n radiusLg: \"0.5rem\",\n radiusXl: \"0.65rem\",\n radius2xl: \"0.8rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.08), 0 1px 3px rgb(0 0 0 / 0.45)\",\n shadowMd: \"0 1px 0 rgb(255 200 140 / 0.08), 0 5px 12px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 20 60 / 0.3)\",\n shadowLg: \"0 12px 28px rgb(0 0 0 / 0.5)\",\n shadowXl: \"0 20px 40px rgb(0 0 0 / 0.55)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.14)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.5)\"\n },\n stylesheet: `${DENIM_TWILL}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BRASS_CONSOLE_THEME = {\n id: \"brass-console\",\n name: \"Brass Console\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Warm instrument console - oxidized brass bezels, olive panels, engraved mono telemetry.\",\n colors: {\n background: \"40 18% 11%\",\n foreground: \"42 35% 86%\",\n card: \"40 16% 15%\",\n cardForeground: \"42 35% 86%\",\n border: \"38 22% 26%\",\n primary: \"42 62% 48%\",\n primaryForeground: \"40 40% 8%\",\n secondary: \"80 12% 18%\",\n secondaryForeground: \"42 28% 80%\",\n muted: \"40 12% 16%\",\n mutedForeground: \"40 12% 54%\",\n accent: \"80 30% 40%\",\n accentForeground: \"42 40% 92%\",\n destructive: \"8 68% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"80 35% 40%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 75% 48%\",\n warningForeground: \"40 40% 8%\",\n info: \"195 35% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"40 14% 13%\",\n ring: \"42 62% 50%\",\n heading1: \"42 60% 68%\",\n heading2: \"80 25% 62%\",\n heading3: \"40 30% 58%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: IBM_PLEX_MONO,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.45rem\",\n radiusSm: \"0.25rem\",\n radiusMd: \"0.35rem\",\n radiusLg: \"0.45rem\",\n radiusXl: \"0.6rem\",\n radius2xl: \"0.75rem\",\n shadowSm: \"0 1px 0 rgb(255 210 120 / 0.14), 0 1px 3px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 210 120 / 0.12), 0 5px 12px rgb(0 0 0 / 0.45), inset 0 -1px 0 rgb(0 0 0 / 0.3)\",\n shadowLg: \"0 12px 28px rgb(0 0 0 / 0.55)\",\n shadowXl: \"0 20px 40px rgb(0 0 0 / 0.6)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 220 140 / 0.22)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.55)\"\n },\n stylesheet: `${BRASS_PATINA}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar SKEUO_THEMES = [\n LEATHER_DESK_THEME,\n BRUSHED_STEEL_THEME,\n BOUND_JOURNAL_THEME,\n WALNUT_LIBRARY_THEME,\n SOFT_PORCELAIN_THEME,\n CINNABAR_LACQUER_THEME,\n DENIM_BENCH_THEME,\n BRASS_CONSOLE_THEME\n];\nvar SKEUO_THEME_IDS = SKEUO_THEMES.map((t) => t.id);\n\n// plugins/theme-skeuomorph/src/index.ts\nvar SkeuomorphThemePlugin = {\n manifest: {\n id: \"readergo.theme.skeuomorph\",\n name: \"Skeuomorph Suite\",\n version: \"1.2.0\",\n description: \"Eight physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, and Brass Console.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(`Skeuomorph Suite activating (${SKEUO_THEMES.length} physical atmospheres)...`);\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => SKEUO_THEMES\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => SKEUO_FONTS\n });\n const enable = async (themeId) => {\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId });\n return { activeTheme: themeId };\n };\n const commands = [\n { id: \"readergo.theme.skeuomorph.enableLeather\", title: \"Theme: Leather Desk\", themeId: LEATHER_DESK_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableSteel\", title: \"Theme: Brushed Steel\", themeId: BRUSHED_STEEL_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableJournal\", title: \"Theme: Bound Journal\", themeId: BOUND_JOURNAL_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableWalnut\", title: \"Theme: Walnut Library\", themeId: WALNUT_LIBRARY_THEME.id },\n { id: \"readergo.theme.skeuomorph.enablePorcelain\", title: \"Theme: Soft Porcelain\", themeId: SOFT_PORCELAIN_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableLacquer\", title: \"Theme: Cinnabar Lacquer\", themeId: CINNABAR_LACQUER_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableDenim\", title: \"Theme: Denim Bench\", themeId: DENIM_BENCH_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableBrass\", title: \"Theme: Brass Console\", themeId: BRASS_CONSOLE_THEME.id }\n ];\n for (const cmd of commands) {\n await context.registerCommand({\n id: cmd.id,\n title: cmd.title,\n handler: async () => enable(cmd.themeId)\n });\n }\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.cycle\",\n title: \"Theme: Cycle Skeuomorph Atmosphere\",\n handler: async () => {\n const active = await context.executeCommand(\"readergo.theme.getActiveTheme\");\n const currentId = active?.id || LEATHER_DESK_THEME.id;\n const idx = SKEUO_THEME_IDS.indexOf(currentId);\n const next = SKEUO_THEME_IDS[idx >= 0 ? (idx + 1) % SKEUO_THEME_IDS.length : 0];\n return enable(next);\n }\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.getModes\",\n title: \"Theme: List Skeuomorph Atmospheres\",\n handler: async () => SKEUO_THEMES.map((t) => ({\n id: t.id,\n name: t.name,\n type: t.type,\n description: t.description\n }))\n });\n },\n deactivate(context) {\n context.log.info(\"Skeuomorph Suite deactivated.\");\n }\n};\nvar index_default = SkeuomorphThemePlugin;\n\n\n return { ACTIVITY_BAR_CHROME: ACTIVITY_BAR_CHROME, BOUND_JOURNAL_THEME: BOUND_JOURNAL_THEME, BRASS_CONSOLE_THEME: BRASS_CONSOLE_THEME, BRASS_PATINA: BRASS_PATINA, BRUSHED_STEEL_THEME: BRUSHED_STEEL_THEME, CINNABAR_LACQUER_THEME: CINNABAR_LACQUER_THEME, DENIM_BENCH_THEME: DENIM_BENCH_THEME, DENIM_TWILL: DENIM_TWILL, FRAUNCES: FRAUNCES, IBM_PLEX_MONO: IBM_PLEX_MONO, JOURNAL_FIBER: JOURNAL_FIBER, LACQUER_SHEEN: LACQUER_SHEEN, LEATHER_DESK_THEME: LEATHER_DESK_THEME, LEATHER_GRAIN: LEATHER_GRAIN, LITERATA: LITERATA, PORCELAIN_GLOSS: PORCELAIN_GLOSS, SHARED_CHROME: SHARED_CHROME, SKEUO_FONTS: SKEUO_FONTS, SKEUO_THEMES: SKEUO_THEMES, SKEUO_THEME_IDS: SKEUO_THEME_IDS, SOFT_PORCELAIN_THEME: SOFT_PORCELAIN_THEME, SOURCE_SANS: SOURCE_SANS, STEEL_BRUSH: STEEL_BRUSH, SkeuomorphThemePlugin: SkeuomorphThemePlugin, WALNUT_GRAIN: WALNUT_GRAIN, WALNUT_LIBRARY_THEME: WALNUT_LIBRARY_THEME, default: index_default };\n}\n" } \ No newline at end of file From e675f186ca57e22d2e745e5825835ab4fbf029e6 Mon Sep 17 00:00:00 2001 From: Amit Date: Fri, 6 Nov 2026 16:45:39 +0530 Subject: [PATCH 5/6] Add five standalone theme plugins with distinct aesthetics. Abyss Teal, Sakura Ink, Forest Moss, Arcade Neon, and Newsprint - each with its own palette, fonts, and light materials/stylesheet character. Co-authored-by: Cursor --- plugins/theme-abyss-teal/manifest.json | 21 +++++ plugins/theme-abyss-teal/src/index.ts | 73 +++++++++++++++ plugins/theme-arcade-neon/manifest.json | 21 +++++ plugins/theme-arcade-neon/src/index.ts | 94 ++++++++++++++++++++ plugins/theme-forest-moss/manifest.json | 21 +++++ plugins/theme-forest-moss/src/index.ts | 88 +++++++++++++++++++ plugins/theme-newsprint/manifest.json | 21 +++++ plugins/theme-newsprint/src/index.ts | 112 ++++++++++++++++++++++++ plugins/theme-sakura-ink/manifest.json | 21 +++++ plugins/theme-sakura-ink/src/index.ts | 89 +++++++++++++++++++ public/catalog.json | 70 +++++++++++++++ public/theme-abyss-teal.bundle.json | 24 +++++ public/theme-arcade-neon.bundle.json | 24 +++++ public/theme-forest-moss.bundle.json | 24 +++++ public/theme-newsprint.bundle.json | 24 +++++ public/theme-sakura-ink.bundle.json | 24 +++++ 16 files changed, 751 insertions(+) create mode 100644 plugins/theme-abyss-teal/manifest.json create mode 100644 plugins/theme-abyss-teal/src/index.ts create mode 100644 plugins/theme-arcade-neon/manifest.json create mode 100644 plugins/theme-arcade-neon/src/index.ts create mode 100644 plugins/theme-forest-moss/manifest.json create mode 100644 plugins/theme-forest-moss/src/index.ts create mode 100644 plugins/theme-newsprint/manifest.json create mode 100644 plugins/theme-newsprint/src/index.ts create mode 100644 plugins/theme-sakura-ink/manifest.json create mode 100644 plugins/theme-sakura-ink/src/index.ts create mode 100644 public/theme-abyss-teal.bundle.json create mode 100644 public/theme-arcade-neon.bundle.json create mode 100644 public/theme-forest-moss.bundle.json create mode 100644 public/theme-newsprint.bundle.json create mode 100644 public/theme-sakura-ink.bundle.json diff --git a/plugins/theme-abyss-teal/manifest.json b/plugins/theme-abyss-teal/manifest.json new file mode 100644 index 0000000..1c7667f --- /dev/null +++ b/plugins/theme-abyss-teal/manifest.json @@ -0,0 +1,21 @@ +{ + "id": "readergo.theme.abyss-teal", + "name": "Abyss Teal", + "version": "1.0.0", + "description": "Deep ocean workspace with teal phosphor accents and calm DM Sans typography.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } +} diff --git a/plugins/theme-abyss-teal/src/index.ts b/plugins/theme-abyss-teal/src/index.ts new file mode 100644 index 0000000..85a0153 --- /dev/null +++ b/plugins/theme-abyss-teal/src/index.ts @@ -0,0 +1,73 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Plugin, PluginContext } from '@readergo/plugin-sdk'; + +const DM_SANS = { + id: 'dm-sans-abyss', + name: 'DM Sans', + family: "'DM Sans', system-ui, sans-serif", + category: 'sans' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,600;0,9..40,700;1,9..40,400&display=swap', + targets: ['all'] as const, +}; + +const THEME = { + id: 'abyss-teal', + name: 'Abyss Teal', + type: 'dark' as const, + author: 'ReaderGo Studio', + description: 'Deep ocean trench palette with teal phosphor signals and soft cyan focus rings.', + colors: { + background: '198 40% 7%', + foreground: '186 35% 92%', + card: '198 32% 11%', + cardForeground: '186 35% 92%', + border: '196 24% 22%', + primary: '174 62% 48%', + primaryForeground: '198 40% 6%', + secondary: '198 28% 15%', + secondaryForeground: '186 30% 86%', + muted: '198 26% 13%', + mutedForeground: '190 14% 55%', + accent: '186 70% 52%', + accentForeground: '198 40% 6%', + destructive: '4 70% 52%', + destructiveForeground: '0 0% 100%', + success: '160 50% 42%', + successForeground: '0 0% 100%', + warning: '38 80% 52%', + warningForeground: '198 40% 6%', + info: '186 70% 52%', + infoForeground: '198 40% 6%', + input: '198 30% 10%', + ring: '174 62% 48%', + heading1: '174 70% 68%', + heading2: '186 55% 66%', + heading3: '190 40% 64%', + }, + fonts: { display: DM_SANS, body: DM_SANS, editor: DM_SANS, mono: DM_SANS }, + materials: { + radius: '0.55rem', + radius2xl: '0.9rem', + surfaceBlur: '8px', + shadowMd: '0 4px 18px rgb(0 40 50 / 0.45)', + }, +}; + +export const AbyssTealThemePlugin: Plugin = { + manifest: { + id: 'readergo.theme.abyss-teal', + name: 'Abyss Teal', + version: '1.0.0', + description: 'Deep ocean workspace with teal phosphor accents and calm DM Sans typography.', + category: 'feature', + provides: ['theme-provider', 'font-provider'], + permissions: [], + }, + async activate(context: PluginContext) { + await context.registerCapability('theme-provider', { getThemes: () => [THEME] }); + await context.registerCapability('font-provider', { getFonts: () => [DM_SANS] }); + }, + deactivate() {}, +}; + +export default AbyssTealThemePlugin; diff --git a/plugins/theme-arcade-neon/manifest.json b/plugins/theme-arcade-neon/manifest.json new file mode 100644 index 0000000..f286479 --- /dev/null +++ b/plugins/theme-arcade-neon/manifest.json @@ -0,0 +1,21 @@ +{ + "id": "readergo.theme.arcade-neon", + "name": "Arcade Neon", + "version": "1.0.0", + "description": "Night-arcade dark with magenta and cyan neon signals plus Orbitron display type.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } +} diff --git a/plugins/theme-arcade-neon/src/index.ts b/plugins/theme-arcade-neon/src/index.ts new file mode 100644 index 0000000..2940f30 --- /dev/null +++ b/plugins/theme-arcade-neon/src/index.ts @@ -0,0 +1,94 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Plugin, PluginContext } from '@readergo/plugin-sdk'; + +const ORBITRON = { + id: 'orbitron-arcade', + name: 'Orbitron', + family: "'Orbitron', system-ui, sans-serif", + category: 'display' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&display=swap', + targets: ['display'] as const, +}; + +const EXO = { + id: 'exo-2-arcade', + name: 'Exo 2', + family: "'Exo 2', system-ui, sans-serif", + category: 'sans' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=Exo+2:ital,wght@0,400;0,600;0,700;1,400&display=swap', + targets: ['body', 'editor', 'all'] as const, +}; + +const THEME = { + id: 'arcade-neon', + name: 'Arcade Neon', + type: 'dark' as const, + author: 'ReaderGo Studio', + description: 'Cabinet-black night with magenta / cyan neon actuators and hard geometric chrome.', + colors: { + background: '260 30% 6%', + foreground: '300 20% 94%', + card: '260 28% 10%', + cardForeground: '300 20% 94%', + border: '280 25% 22%', + primary: '320 85% 58%', + primaryForeground: '260 40% 6%', + secondary: '260 22% 14%', + secondaryForeground: '180 40% 80%', + muted: '260 20% 12%', + mutedForeground: '270 12% 55%', + accent: '180 90% 48%', + accentForeground: '260 40% 6%', + destructive: '0 85% 55%', + destructiveForeground: '0 0% 100%', + success: '150 80% 45%', + successForeground: '260 40% 6%', + warning: '45 95% 55%', + warningForeground: '260 40% 6%', + info: '180 90% 48%', + infoForeground: '260 40% 6%', + input: '260 26% 9%', + ring: '320 85% 58%', + heading1: '320 90% 72%', + heading2: '180 85% 65%', + heading3: '280 50% 70%', + }, + fonts: { display: ORBITRON, body: EXO, editor: EXO, mono: EXO }, + materials: { + radius: '0.25rem', + radiusSm: '0.15rem', + radiusMd: '0.2rem', + radiusLg: '0.25rem', + radiusXl: '0.35rem', + radius2xl: '0.45rem', + surfaceBlur: '0px', + shadowMd: '0 0 0 1px rgb(255 0 180 / 0.15), 0 8px 24px rgb(0 0 0 / 0.55)', + insetHighlight: 'inset 0 1px 0 rgb(255 100 220 / 0.15)', + }, + stylesheet: ` + background-image: + radial-gradient(ellipse at 10% 0%, rgb(255 0 160 / 0.12), transparent 40%), + radial-gradient(ellipse at 90% 100%, rgb(0 255 220 / 0.1), transparent 45%), + linear-gradient(180deg, transparent 60%, rgb(0 0 0 / 0.35)); + `, + stylesheetScoped: true, +}; + +export const ArcadeNeonThemePlugin: Plugin = { + manifest: { + id: 'readergo.theme.arcade-neon', + name: 'Arcade Neon', + version: '1.0.0', + description: 'Night-arcade dark with magenta and cyan neon signals plus Orbitron display type.', + category: 'feature', + provides: ['theme-provider', 'font-provider'], + permissions: [], + }, + async activate(context: PluginContext) { + await context.registerCapability('theme-provider', { getThemes: () => [THEME] }); + await context.registerCapability('font-provider', { getFonts: () => [ORBITRON, EXO] }); + }, + deactivate() {}, +}; + +export default ArcadeNeonThemePlugin; diff --git a/plugins/theme-forest-moss/manifest.json b/plugins/theme-forest-moss/manifest.json new file mode 100644 index 0000000..51fdf02 --- /dev/null +++ b/plugins/theme-forest-moss/manifest.json @@ -0,0 +1,21 @@ +{ + "id": "readergo.theme.forest-moss", + "name": "Forest Moss", + "version": "1.0.0", + "description": "Canopy-dark greens with lichen accents and Literata reading typography.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } +} diff --git a/plugins/theme-forest-moss/src/index.ts b/plugins/theme-forest-moss/src/index.ts new file mode 100644 index 0000000..09c9442 --- /dev/null +++ b/plugins/theme-forest-moss/src/index.ts @@ -0,0 +1,88 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Plugin, PluginContext } from '@readergo/plugin-sdk'; + +const LITERATA = { + id: 'literata-forest', + name: 'Literata', + family: "'Literata', 'Georgia', serif", + category: 'serif' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap', + targets: ['display', 'editor'] as const, +}; + +const SOURCE_SANS = { + id: 'source-sans-forest', + name: 'Source Sans 3', + family: "'Source Sans 3', system-ui, sans-serif", + category: 'sans' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap', + targets: ['body', 'all'] as const, +}; + +const THEME = { + id: 'forest-moss', + name: 'Forest Moss', + type: 'dark' as const, + author: 'ReaderGo Studio', + description: 'Under-canopy greens with lichen yellow accents for long reading sessions.', + colors: { + background: '140 22% 9%', + foreground: '90 18% 90%', + card: '140 18% 13%', + cardForeground: '90 18% 90%', + border: '140 14% 22%', + primary: '118 42% 48%', + primaryForeground: '140 30% 6%', + secondary: '140 14% 17%', + secondaryForeground: '90 14% 84%', + muted: '140 12% 15%', + mutedForeground: '120 10% 55%', + accent: '72 45% 48%', + accentForeground: '140 30% 6%', + destructive: '8 65% 48%', + destructiveForeground: '0 0% 100%', + success: '118 42% 42%', + successForeground: '0 0% 100%', + warning: '48 70% 48%', + warningForeground: '140 30% 6%', + info: '170 40% 45%', + infoForeground: '0 0% 100%', + input: '140 16% 11%', + ring: '118 42% 48%', + heading1: '90 40% 72%', + heading2: '118 35% 66%', + heading3: '72 35% 62%', + }, + fonts: { display: LITERATA, body: SOURCE_SANS, editor: LITERATA, mono: SOURCE_SANS }, + materials: { + radius: '0.6rem', + radius2xl: '1rem', + surfaceBlur: '0px', + shadowMd: '0 6px 20px rgb(0 20 10 / 0.45)', + }, + stylesheet: ` + background-image: + radial-gradient(ellipse at 15% 20%, rgb(60 120 70 / 0.18), transparent 45%), + radial-gradient(ellipse at 85% 80%, rgb(20 40 20 / 0.35), transparent 50%); + `, + stylesheetScoped: true, +}; + +export const ForestMossThemePlugin: Plugin = { + manifest: { + id: 'readergo.theme.forest-moss', + name: 'Forest Moss', + version: '1.0.0', + description: 'Canopy-dark greens with lichen accents and Literata reading typography.', + category: 'feature', + provides: ['theme-provider', 'font-provider'], + permissions: [], + }, + async activate(context: PluginContext) { + await context.registerCapability('theme-provider', { getThemes: () => [THEME] }); + await context.registerCapability('font-provider', { getFonts: () => [LITERATA, SOURCE_SANS] }); + }, + deactivate() {}, +}; + +export default ForestMossThemePlugin; diff --git a/plugins/theme-newsprint/manifest.json b/plugins/theme-newsprint/manifest.json new file mode 100644 index 0000000..7034b45 --- /dev/null +++ b/plugins/theme-newsprint/manifest.json @@ -0,0 +1,21 @@ +{ + "id": "readergo.theme.newsprint", + "name": "Newsprint", + "version": "1.0.0", + "description": "Stark editorial monochrome with hairline rules and Libre Baskerville / IBM Plex typography.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } +} diff --git a/plugins/theme-newsprint/src/index.ts b/plugins/theme-newsprint/src/index.ts new file mode 100644 index 0000000..e0d9201 --- /dev/null +++ b/plugins/theme-newsprint/src/index.ts @@ -0,0 +1,112 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Plugin, PluginContext } from '@readergo/plugin-sdk'; + +const BASKERVILLE = { + id: 'libre-baskerville', + name: 'Libre Baskerville', + family: "'Libre Baskerville', 'Georgia', serif", + category: 'serif' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&display=swap', + targets: ['display', 'editor'] as const, +}; + +const IBM_PLEX = { + id: 'ibm-plex-sans-news', + name: 'IBM Plex Sans', + family: "'IBM Plex Sans', system-ui, sans-serif", + category: 'sans' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap', + targets: ['body', 'all'] as const, +}; + +const IBM_MONO = { + id: 'ibm-plex-mono-news', + name: 'IBM Plex Mono', + family: "'IBM Plex Mono', ui-monospace, monospace", + category: 'mono' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap', + targets: ['mono'] as const, +}; + +const THEME = { + id: 'newsprint', + name: 'Newsprint', + type: 'light' as const, + author: 'ReaderGo Studio', + description: 'Broadsheet monochrome - India ink on cold paper, hairline borders, zero chrome glow.', + colors: { + background: '40 10% 96%', + foreground: '0 0% 8%', + card: '0 0% 100%', + cardForeground: '0 0% 8%', + border: '0 0% 78%', + primary: '0 0% 10%', + primaryForeground: '0 0% 98%', + secondary: '40 8% 92%', + secondaryForeground: '0 0% 12%', + muted: '40 6% 93%', + mutedForeground: '0 0% 38%', + accent: '0 0% 22%', + accentForeground: '0 0% 98%', + destructive: '0 0% 20%', + destructiveForeground: '0 0% 100%', + success: '0 0% 25%', + successForeground: '0 0% 100%', + warning: '0 0% 30%', + warningForeground: '0 0% 100%', + info: '0 0% 28%', + infoForeground: '0 0% 100%', + input: '0 0% 100%', + ring: '0 0% 10%', + heading1: '0 0% 5%', + heading2: '0 0% 12%', + heading3: '0 0% 18%', + }, + fonts: { display: BASKERVILLE, body: IBM_PLEX, editor: BASKERVILLE, mono: IBM_MONO }, + materials: { + radius: '0.15rem', + radiusSm: '0.1rem', + radiusMd: '0.12rem', + radiusLg: '0.15rem', + radiusXl: '0.2rem', + radius2xl: '0.25rem', + surfaceBlur: '0px', + shadowSm: 'none', + shadowMd: '0 1px 0 rgb(0 0 0 / 0.08)', + shadowLg: '0 2px 0 rgb(0 0 0 / 0.06)', + shadowXl: '0 3px 0 rgb(0 0 0 / 0.05)', + insetHighlight: 'none', + insetShadow: 'none', + borderWidth: '1px', + }, + stylesheet: ` + background-image: + repeating-linear-gradient( + 0deg, + rgb(0 0 0 / 0.015) 0 1px, + transparent 1px 4px + ); + `, + stylesheetScoped: true, +}; + +export const NewsprintThemePlugin: Plugin = { + manifest: { + id: 'readergo.theme.newsprint', + name: 'Newsprint', + version: '1.0.0', + description: 'Stark editorial monochrome with hairline rules and Libre Baskerville / IBM Plex typography.', + category: 'feature', + provides: ['theme-provider', 'font-provider'], + permissions: [], + }, + async activate(context: PluginContext) { + await context.registerCapability('theme-provider', { getThemes: () => [THEME] }); + await context.registerCapability('font-provider', { + getFonts: () => [BASKERVILLE, IBM_PLEX, IBM_MONO], + }); + }, + deactivate() {}, +}; + +export default NewsprintThemePlugin; diff --git a/plugins/theme-sakura-ink/manifest.json b/plugins/theme-sakura-ink/manifest.json new file mode 100644 index 0000000..10f4b71 --- /dev/null +++ b/plugins/theme-sakura-ink/manifest.json @@ -0,0 +1,21 @@ +{ + "id": "readergo.theme.sakura-ink", + "name": "Sakura Ink", + "version": "1.0.0", + "description": "Light ink-wash workspace with cherry blossom accents and Shippori Mincho headings.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } +} diff --git a/plugins/theme-sakura-ink/src/index.ts b/plugins/theme-sakura-ink/src/index.ts new file mode 100644 index 0000000..3c16663 --- /dev/null +++ b/plugins/theme-sakura-ink/src/index.ts @@ -0,0 +1,89 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Plugin, PluginContext } from '@readergo/plugin-sdk'; + +const SHIPPORI = { + id: 'shippori-mincho', + name: 'Shippori Mincho', + family: "'Shippori Mincho', 'Georgia', serif", + category: 'serif' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=Shippori+Mincho:wght@400;600;700&display=swap', + targets: ['display', 'editor'] as const, +}; + +const NOTO_SANS = { + id: 'noto-sans-jp-ui', + name: 'Noto Sans', + family: "'Noto Sans', system-ui, sans-serif", + category: 'sans' as const, + cssUrl: 'https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,600;0,700;1,400&display=swap', + targets: ['body', 'all'] as const, +}; + +const THEME = { + id: 'sakura-ink', + name: 'Sakura Ink', + type: 'light' as const, + author: 'ReaderGo Studio', + description: 'Paper-white ink wash with soft sakura pink signals and scholarly serif headings.', + colors: { + background: '0 0% 98%', + foreground: '220 20% 16%', + card: '0 0% 100%', + cardForeground: '220 20% 16%', + border: '340 12% 88%', + primary: '340 55% 48%', + primaryForeground: '0 0% 100%', + secondary: '340 20% 95%', + secondaryForeground: '220 18% 22%', + muted: '220 10% 95%', + mutedForeground: '220 8% 42%', + accent: '200 35% 42%', + accentForeground: '0 0% 100%', + destructive: '4 70% 46%', + destructiveForeground: '0 0% 100%', + success: '152 40% 36%', + successForeground: '0 0% 100%', + warning: '32 70% 42%', + warningForeground: '0 0% 100%', + info: '200 40% 42%', + infoForeground: '0 0% 100%', + input: '0 0% 97%', + ring: '340 55% 48%', + heading1: '340 50% 38%', + heading2: '220 25% 28%', + heading3: '200 30% 36%', + }, + fonts: { display: SHIPPORI, body: NOTO_SANS, editor: SHIPPORI, mono: NOTO_SANS }, + materials: { + radius: '0.4rem', + radius2xl: '0.75rem', + surfaceBlur: '0px', + shadowMd: '0 2px 10px rgb(40 20 30 / 0.06)', + insetShadow: 'inset 0 1px 2px rgb(40 20 30 / 0.05)', + }, + stylesheet: ` + background-image: + radial-gradient(ellipse at 90% 5%, rgb(255 180 200 / 0.18), transparent 40%), + radial-gradient(ellipse at 10% 90%, rgb(180 210 230 / 0.12), transparent 45%); + `, + stylesheetScoped: true, +}; + +export const SakuraInkThemePlugin: Plugin = { + manifest: { + id: 'readergo.theme.sakura-ink', + name: 'Sakura Ink', + version: '1.0.0', + description: 'Light ink-wash workspace with cherry blossom accents and Shippori Mincho headings.', + category: 'feature', + provides: ['theme-provider', 'font-provider'], + permissions: [], + }, + async activate(context: PluginContext) { + await context.registerCapability('theme-provider', { getThemes: () => [THEME] }); + await context.registerCapability('font-provider', { getFonts: () => [SHIPPORI, NOTO_SANS] }); + }, + deactivate() {}, +}; + +export default SakuraInkThemePlugin; diff --git a/public/catalog.json b/public/catalog.json index 5655cc3..1527723 100644 --- a/public/catalog.json +++ b/public/catalog.json @@ -1,5 +1,19 @@ { "plugins": [ + { + "id": "readergo.theme.abyss-teal", + "name": "Abyss Teal", + "description": "Deep ocean workspace with teal phosphor accents and calm DM Sans typography.", + "category": "feature", + "version": "1.0.0", + "provides": [ + "theme-provider", + "font-provider" + ], + "bundleUrl": "theme-abyss-teal.bundle.json", + "bundleHash": "768d75b55c861a74", + "hash": "768d75b55c861a74" + }, { "id": "readergo.theme.amber", "name": "Amber CRT Terminal", @@ -14,6 +28,20 @@ "bundleHash": "e97b7a81f143f8f1", "hash": "e97b7a81f143f8f1" }, + { + "id": "readergo.theme.arcade-neon", + "name": "Arcade Neon", + "description": "Night-arcade dark with magenta and cyan neon signals plus Orbitron display type.", + "category": "feature", + "version": "1.0.0", + "provides": [ + "theme-provider", + "font-provider" + ], + "bundleUrl": "theme-arcade-neon.bundle.json", + "bundleHash": "1ad61e8948574967", + "hash": "1ad61e8948574967" + }, { "id": "readergo.editor.canvas", "name": "Canvas", @@ -168,6 +196,20 @@ "bundleHash": "0ea8c4f5a1dd865c", "hash": "0ea8c4f5a1dd865c" }, + { + "id": "readergo.theme.forest-moss", + "name": "Forest Moss", + "description": "Canopy-dark greens with lichen accents and Literata reading typography.", + "category": "feature", + "version": "1.0.0", + "provides": [ + "theme-provider", + "font-provider" + ], + "bundleUrl": "theme-forest-moss.bundle.json", + "bundleHash": "1bf334069f2c59fe", + "hash": "1bf334069f2c59fe" + }, { "id": "readergo.editor.graph", "name": "Graph", @@ -261,6 +303,20 @@ "bundleHash": "d45ac80ab01da340", "hash": "d45ac80ab01da340" }, + { + "id": "readergo.theme.newsprint", + "name": "Newsprint", + "description": "Stark editorial monochrome with hairline rules and Libre Baskerville / IBM Plex typography.", + "category": "feature", + "version": "1.0.0", + "provides": [ + "theme-provider", + "font-provider" + ], + "bundleUrl": "theme-newsprint.bundle.json", + "bundleHash": "9ffb89830441c09c", + "hash": "9ffb89830441c09c" + }, { "id": "readergo.theme.nord", "name": "Nord Frost Theme", @@ -405,6 +461,20 @@ "bundleHash": "d619a01067d3d0ee", "hash": "d619a01067d3d0ee" }, + { + "id": "readergo.theme.sakura-ink", + "name": "Sakura Ink", + "description": "Light ink-wash workspace with cherry blossom accents and Shippori Mincho headings.", + "category": "feature", + "version": "1.0.0", + "provides": [ + "theme-provider", + "font-provider" + ], + "bundleUrl": "theme-sakura-ink.bundle.json", + "bundleHash": "e3ecd2326a8881c1", + "hash": "e3ecd2326a8881c1" + }, { "id": "readergo.features.selection-actions", "name": "Selection Actions", diff --git a/public/theme-abyss-teal.bundle.json b/public/theme-abyss-teal.bundle.json new file mode 100644 index 0000000..5389ecb --- /dev/null +++ b/public/theme-abyss-teal.bundle.json @@ -0,0 +1,24 @@ +{ + "manifest": { + "id": "readergo.theme.abyss-teal", + "name": "Abyss Teal", + "version": "1.0.0", + "description": "Deep ocean workspace with teal phosphor accents and calm DM Sans typography.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } + }, + "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-abyss-teal/src/index.ts\nvar DM_SANS = {\n id: \"dm-sans-abyss\",\n name: \"DM Sans\",\n family: \"'DM Sans', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,600;0,9..40,700;1,9..40,400&display=swap\",\n targets: [\"all\"]\n};\nvar THEME = {\n id: \"abyss-teal\",\n name: \"Abyss Teal\",\n type: \"dark\",\n author: \"ReaderGo Studio\",\n description: \"Deep ocean trench palette with teal phosphor signals and soft cyan focus rings.\",\n colors: {\n background: \"198 40% 7%\",\n foreground: \"186 35% 92%\",\n card: \"198 32% 11%\",\n cardForeground: \"186 35% 92%\",\n border: \"196 24% 22%\",\n primary: \"174 62% 48%\",\n primaryForeground: \"198 40% 6%\",\n secondary: \"198 28% 15%\",\n secondaryForeground: \"186 30% 86%\",\n muted: \"198 26% 13%\",\n mutedForeground: \"190 14% 55%\",\n accent: \"186 70% 52%\",\n accentForeground: \"198 40% 6%\",\n destructive: \"4 70% 52%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"160 50% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 52%\",\n warningForeground: \"198 40% 6%\",\n info: \"186 70% 52%\",\n infoForeground: \"198 40% 6%\",\n input: \"198 30% 10%\",\n ring: \"174 62% 48%\",\n heading1: \"174 70% 68%\",\n heading2: \"186 55% 66%\",\n heading3: \"190 40% 64%\"\n },\n fonts: { display: DM_SANS, body: DM_SANS, editor: DM_SANS, mono: DM_SANS },\n materials: {\n radius: \"0.55rem\",\n radius2xl: \"0.9rem\",\n surfaceBlur: \"8px\",\n shadowMd: \"0 4px 18px rgb(0 40 50 / 0.45)\"\n }\n};\nvar AbyssTealThemePlugin = {\n manifest: {\n id: \"readergo.theme.abyss-teal\",\n name: \"Abyss Teal\",\n version: \"1.0.0\",\n description: \"Deep ocean workspace with teal phosphor accents and calm DM Sans typography.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", { getThemes: () => [THEME] });\n await context.registerCapability(\"font-provider\", { getFonts: () => [DM_SANS] });\n },\n deactivate() {\n }\n};\nvar index_default = AbyssTealThemePlugin;\n\n\n return { AbyssTealThemePlugin: AbyssTealThemePlugin, default: index_default };\n}\n" +} \ No newline at end of file diff --git a/public/theme-arcade-neon.bundle.json b/public/theme-arcade-neon.bundle.json new file mode 100644 index 0000000..462beba --- /dev/null +++ b/public/theme-arcade-neon.bundle.json @@ -0,0 +1,24 @@ +{ + "manifest": { + "id": "readergo.theme.arcade-neon", + "name": "Arcade Neon", + "version": "1.0.0", + "description": "Night-arcade dark with magenta and cyan neon signals plus Orbitron display type.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } + }, + "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-arcade-neon/src/index.ts\nvar ORBITRON = {\n id: \"orbitron-arcade\",\n name: \"Orbitron\",\n family: \"'Orbitron', system-ui, sans-serif\",\n category: \"display\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&display=swap\",\n targets: [\"display\"]\n};\nvar EXO = {\n id: \"exo-2-arcade\",\n name: \"Exo 2\",\n family: \"'Exo 2', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Exo+2:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"editor\", \"all\"]\n};\nvar THEME = {\n id: \"arcade-neon\",\n name: \"Arcade Neon\",\n type: \"dark\",\n author: \"ReaderGo Studio\",\n description: \"Cabinet-black night with magenta / cyan neon actuators and hard geometric chrome.\",\n colors: {\n background: \"260 30% 6%\",\n foreground: \"300 20% 94%\",\n card: \"260 28% 10%\",\n cardForeground: \"300 20% 94%\",\n border: \"280 25% 22%\",\n primary: \"320 85% 58%\",\n primaryForeground: \"260 40% 6%\",\n secondary: \"260 22% 14%\",\n secondaryForeground: \"180 40% 80%\",\n muted: \"260 20% 12%\",\n mutedForeground: \"270 12% 55%\",\n accent: \"180 90% 48%\",\n accentForeground: \"260 40% 6%\",\n destructive: \"0 85% 55%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"150 80% 45%\",\n successForeground: \"260 40% 6%\",\n warning: \"45 95% 55%\",\n warningForeground: \"260 40% 6%\",\n info: \"180 90% 48%\",\n infoForeground: \"260 40% 6%\",\n input: \"260 26% 9%\",\n ring: \"320 85% 58%\",\n heading1: \"320 90% 72%\",\n heading2: \"180 85% 65%\",\n heading3: \"280 50% 70%\"\n },\n fonts: { display: ORBITRON, body: EXO, editor: EXO, mono: EXO },\n materials: {\n radius: \"0.25rem\",\n radiusSm: \"0.15rem\",\n radiusMd: \"0.2rem\",\n radiusLg: \"0.25rem\",\n radiusXl: \"0.35rem\",\n radius2xl: \"0.45rem\",\n surfaceBlur: \"0px\",\n shadowMd: \"0 0 0 1px rgb(255 0 180 / 0.15), 0 8px 24px rgb(0 0 0 / 0.55)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 100 220 / 0.15)\"\n },\n stylesheet: `\n background-image:\n radial-gradient(ellipse at 10% 0%, rgb(255 0 160 / 0.12), transparent 40%),\n radial-gradient(ellipse at 90% 100%, rgb(0 255 220 / 0.1), transparent 45%),\n linear-gradient(180deg, transparent 60%, rgb(0 0 0 / 0.35));\n `,\n stylesheetScoped: true\n};\nvar ArcadeNeonThemePlugin = {\n manifest: {\n id: \"readergo.theme.arcade-neon\",\n name: \"Arcade Neon\",\n version: \"1.0.0\",\n description: \"Night-arcade dark with magenta and cyan neon signals plus Orbitron display type.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", { getThemes: () => [THEME] });\n await context.registerCapability(\"font-provider\", { getFonts: () => [ORBITRON, EXO] });\n },\n deactivate() {\n }\n};\nvar index_default = ArcadeNeonThemePlugin;\n\n\n return { ArcadeNeonThemePlugin: ArcadeNeonThemePlugin, default: index_default };\n}\n" +} \ No newline at end of file diff --git a/public/theme-forest-moss.bundle.json b/public/theme-forest-moss.bundle.json new file mode 100644 index 0000000..883b27c --- /dev/null +++ b/public/theme-forest-moss.bundle.json @@ -0,0 +1,24 @@ +{ + "manifest": { + "id": "readergo.theme.forest-moss", + "name": "Forest Moss", + "version": "1.0.0", + "description": "Canopy-dark greens with lichen accents and Literata reading typography.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } + }, + "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-forest-moss/src/index.ts\nvar LITERATA = {\n id: \"literata-forest\",\n name: \"Literata\",\n family: \"'Literata', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-forest\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar THEME = {\n id: \"forest-moss\",\n name: \"Forest Moss\",\n type: \"dark\",\n author: \"ReaderGo Studio\",\n description: \"Under-canopy greens with lichen yellow accents for long reading sessions.\",\n colors: {\n background: \"140 22% 9%\",\n foreground: \"90 18% 90%\",\n card: \"140 18% 13%\",\n cardForeground: \"90 18% 90%\",\n border: \"140 14% 22%\",\n primary: \"118 42% 48%\",\n primaryForeground: \"140 30% 6%\",\n secondary: \"140 14% 17%\",\n secondaryForeground: \"90 14% 84%\",\n muted: \"140 12% 15%\",\n mutedForeground: \"120 10% 55%\",\n accent: \"72 45% 48%\",\n accentForeground: \"140 30% 6%\",\n destructive: \"8 65% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"118 42% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"48 70% 48%\",\n warningForeground: \"140 30% 6%\",\n info: \"170 40% 45%\",\n infoForeground: \"0 0% 100%\",\n input: \"140 16% 11%\",\n ring: \"118 42% 48%\",\n heading1: \"90 40% 72%\",\n heading2: \"118 35% 66%\",\n heading3: \"72 35% 62%\"\n },\n fonts: { display: LITERATA, body: SOURCE_SANS, editor: LITERATA, mono: SOURCE_SANS },\n materials: {\n radius: \"0.6rem\",\n radius2xl: \"1rem\",\n surfaceBlur: \"0px\",\n shadowMd: \"0 6px 20px rgb(0 20 10 / 0.45)\"\n },\n stylesheet: `\n background-image:\n radial-gradient(ellipse at 15% 20%, rgb(60 120 70 / 0.18), transparent 45%),\n radial-gradient(ellipse at 85% 80%, rgb(20 40 20 / 0.35), transparent 50%);\n `,\n stylesheetScoped: true\n};\nvar ForestMossThemePlugin = {\n manifest: {\n id: \"readergo.theme.forest-moss\",\n name: \"Forest Moss\",\n version: \"1.0.0\",\n description: \"Canopy-dark greens with lichen accents and Literata reading typography.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", { getThemes: () => [THEME] });\n await context.registerCapability(\"font-provider\", { getFonts: () => [LITERATA, SOURCE_SANS] });\n },\n deactivate() {\n }\n};\nvar index_default = ForestMossThemePlugin;\n\n\n return { ForestMossThemePlugin: ForestMossThemePlugin, default: index_default };\n}\n" +} \ No newline at end of file diff --git a/public/theme-newsprint.bundle.json b/public/theme-newsprint.bundle.json new file mode 100644 index 0000000..164d6a7 --- /dev/null +++ b/public/theme-newsprint.bundle.json @@ -0,0 +1,24 @@ +{ + "manifest": { + "id": "readergo.theme.newsprint", + "name": "Newsprint", + "version": "1.0.0", + "description": "Stark editorial monochrome with hairline rules and Libre Baskerville / IBM Plex typography.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } + }, + "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-newsprint/src/index.ts\nvar BASKERVILLE = {\n id: \"libre-baskerville\",\n name: \"Libre Baskerville\",\n family: \"'Libre Baskerville', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar IBM_PLEX = {\n id: \"ibm-plex-sans-news\",\n name: \"IBM Plex Sans\",\n family: \"'IBM Plex Sans', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar IBM_MONO = {\n id: \"ibm-plex-mono-news\",\n name: \"IBM Plex Mono\",\n family: \"'IBM Plex Mono', ui-monospace, monospace\",\n category: \"mono\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap\",\n targets: [\"mono\"]\n};\nvar THEME = {\n id: \"newsprint\",\n name: \"Newsprint\",\n type: \"light\",\n author: \"ReaderGo Studio\",\n description: \"Broadsheet monochrome - India ink on cold paper, hairline borders, zero chrome glow.\",\n colors: {\n background: \"40 10% 96%\",\n foreground: \"0 0% 8%\",\n card: \"0 0% 100%\",\n cardForeground: \"0 0% 8%\",\n border: \"0 0% 78%\",\n primary: \"0 0% 10%\",\n primaryForeground: \"0 0% 98%\",\n secondary: \"40 8% 92%\",\n secondaryForeground: \"0 0% 12%\",\n muted: \"40 6% 93%\",\n mutedForeground: \"0 0% 38%\",\n accent: \"0 0% 22%\",\n accentForeground: \"0 0% 98%\",\n destructive: \"0 0% 20%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"0 0% 25%\",\n successForeground: \"0 0% 100%\",\n warning: \"0 0% 30%\",\n warningForeground: \"0 0% 100%\",\n info: \"0 0% 28%\",\n infoForeground: \"0 0% 100%\",\n input: \"0 0% 100%\",\n ring: \"0 0% 10%\",\n heading1: \"0 0% 5%\",\n heading2: \"0 0% 12%\",\n heading3: \"0 0% 18%\"\n },\n fonts: { display: BASKERVILLE, body: IBM_PLEX, editor: BASKERVILLE, mono: IBM_MONO },\n materials: {\n radius: \"0.15rem\",\n radiusSm: \"0.1rem\",\n radiusMd: \"0.12rem\",\n radiusLg: \"0.15rem\",\n radiusXl: \"0.2rem\",\n radius2xl: \"0.25rem\",\n surfaceBlur: \"0px\",\n shadowSm: \"none\",\n shadowMd: \"0 1px 0 rgb(0 0 0 / 0.08)\",\n shadowLg: \"0 2px 0 rgb(0 0 0 / 0.06)\",\n shadowXl: \"0 3px 0 rgb(0 0 0 / 0.05)\",\n insetHighlight: \"none\",\n insetShadow: \"none\",\n borderWidth: \"1px\"\n },\n stylesheet: `\n background-image:\n repeating-linear-gradient(\n 0deg,\n rgb(0 0 0 / 0.015) 0 1px,\n transparent 1px 4px\n );\n `,\n stylesheetScoped: true\n};\nvar NewsprintThemePlugin = {\n manifest: {\n id: \"readergo.theme.newsprint\",\n name: \"Newsprint\",\n version: \"1.0.0\",\n description: \"Stark editorial monochrome with hairline rules and Libre Baskerville / IBM Plex typography.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", { getThemes: () => [THEME] });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => [BASKERVILLE, IBM_PLEX, IBM_MONO]\n });\n },\n deactivate() {\n }\n};\nvar index_default = NewsprintThemePlugin;\n\n\n return { NewsprintThemePlugin: NewsprintThemePlugin, default: index_default };\n}\n" +} \ No newline at end of file diff --git a/public/theme-sakura-ink.bundle.json b/public/theme-sakura-ink.bundle.json new file mode 100644 index 0000000..a503e41 --- /dev/null +++ b/public/theme-sakura-ink.bundle.json @@ -0,0 +1,24 @@ +{ + "manifest": { + "id": "readergo.theme.sakura-ink", + "name": "Sakura Ink", + "version": "1.0.0", + "description": "Light ink-wash workspace with cherry blossom accents and Shippori Mincho headings.", + "category": "feature", + "provides": [ + "theme-provider", + "font-provider" + ], + "requires": [], + "permissions": [], + "trust": "trusted", + "source": "external", + "main": "dist/ui.js", + "runtime": "local", + "autoActivate": true, + "compile": { + "ui": "./src/index.ts" + } + }, + "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-sakura-ink/src/index.ts\nvar SHIPPORI = {\n id: \"shippori-mincho\",\n name: \"Shippori Mincho\",\n family: \"'Shippori Mincho', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Shippori+Mincho:wght@400;600;700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar NOTO_SANS = {\n id: \"noto-sans-jp-ui\",\n name: \"Noto Sans\",\n family: \"'Noto Sans', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar THEME = {\n id: \"sakura-ink\",\n name: \"Sakura Ink\",\n type: \"light\",\n author: \"ReaderGo Studio\",\n description: \"Paper-white ink wash with soft sakura pink signals and scholarly serif headings.\",\n colors: {\n background: \"0 0% 98%\",\n foreground: \"220 20% 16%\",\n card: \"0 0% 100%\",\n cardForeground: \"220 20% 16%\",\n border: \"340 12% 88%\",\n primary: \"340 55% 48%\",\n primaryForeground: \"0 0% 100%\",\n secondary: \"340 20% 95%\",\n secondaryForeground: \"220 18% 22%\",\n muted: \"220 10% 95%\",\n mutedForeground: \"220 8% 42%\",\n accent: \"200 35% 42%\",\n accentForeground: \"0 0% 100%\",\n destructive: \"4 70% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 40% 36%\",\n successForeground: \"0 0% 100%\",\n warning: \"32 70% 42%\",\n warningForeground: \"0 0% 100%\",\n info: \"200 40% 42%\",\n infoForeground: \"0 0% 100%\",\n input: \"0 0% 97%\",\n ring: \"340 55% 48%\",\n heading1: \"340 50% 38%\",\n heading2: \"220 25% 28%\",\n heading3: \"200 30% 36%\"\n },\n fonts: { display: SHIPPORI, body: NOTO_SANS, editor: SHIPPORI, mono: NOTO_SANS },\n materials: {\n radius: \"0.4rem\",\n radius2xl: \"0.75rem\",\n surfaceBlur: \"0px\",\n shadowMd: \"0 2px 10px rgb(40 20 30 / 0.06)\",\n insetShadow: \"inset 0 1px 2px rgb(40 20 30 / 0.05)\"\n },\n stylesheet: `\n background-image:\n radial-gradient(ellipse at 90% 5%, rgb(255 180 200 / 0.18), transparent 40%),\n radial-gradient(ellipse at 10% 90%, rgb(180 210 230 / 0.12), transparent 45%);\n `,\n stylesheetScoped: true\n};\nvar SakuraInkThemePlugin = {\n manifest: {\n id: \"readergo.theme.sakura-ink\",\n name: \"Sakura Ink\",\n version: \"1.0.0\",\n description: \"Light ink-wash workspace with cherry blossom accents and Shippori Mincho headings.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", { getThemes: () => [THEME] });\n await context.registerCapability(\"font-provider\", { getFonts: () => [SHIPPORI, NOTO_SANS] });\n },\n deactivate() {\n }\n};\nvar index_default = SakuraInkThemePlugin;\n\n\n return { SakuraInkThemePlugin: SakuraInkThemePlugin, default: index_default };\n}\n" +} \ No newline at end of file From eb01876c29de2b1c2b1374a322f2564132e1b6f3 Mon Sep 17 00:00:00 2001 From: Amit Date: Fri, 6 Nov 2026 16:58:20 +0530 Subject: [PATCH 6/6] Ship theme category metadata and generated preview screenshots. Marks theme plugins as category theme with style, tags, long descriptions, and SVG workspace previews in the catalog. Co-authored-by: Cursor --- plugins/theme-abyss-teal/manifest.json | 20 +- plugins/theme-amber-terminal/manifest.json | 20 +- plugins/theme-arcade-neon/manifest.json | 20 +- plugins/theme-catppuccin/manifest.json | 20 +- plugins/theme-eink/manifest.json | 20 +- plugins/theme-forest-moss/manifest.json | 20 +- plugins/theme-gruvbox/manifest.json | 20 +- plugins/theme-newsprint/manifest.json | 20 +- plugins/theme-nord/manifest.json | 20 +- plugins/theme-rose-pine/manifest.json | 20 +- plugins/theme-sakura-ink/manifest.json | 20 +- plugins/theme-skeuomorph/manifest.json | 20 +- plugins/theme-solarized/manifest.json | 20 +- public/catalog.json | 326 +++++++++++++++++--- public/screenshots/theme-abyss-teal.svg | 69 +++++ public/screenshots/theme-amber-terminal.svg | 69 +++++ public/screenshots/theme-arcade-neon.svg | 69 +++++ public/screenshots/theme-catppuccin.svg | 69 +++++ public/screenshots/theme-eink.svg | 69 +++++ public/screenshots/theme-forest-moss.svg | 69 +++++ public/screenshots/theme-gruvbox.svg | 69 +++++ public/screenshots/theme-newsprint.svg | 69 +++++ public/screenshots/theme-nord.svg | 69 +++++ public/screenshots/theme-rose-pine.svg | 69 +++++ public/screenshots/theme-sakura-ink.svg | 69 +++++ public/screenshots/theme-skeuomorph.svg | 69 +++++ public/screenshots/theme-solarized.svg | 69 +++++ public/theme-abyss-teal.bundle.json | 20 +- public/theme-amber-terminal.bundle.json | 20 +- public/theme-arcade-neon.bundle.json | 20 +- public/theme-catppuccin.bundle.json | 20 +- public/theme-eink.bundle.json | 20 +- public/theme-forest-moss.bundle.json | 20 +- public/theme-gruvbox.bundle.json | 20 +- public/theme-newsprint.bundle.json | 20 +- public/theme-nord.bundle.json | 20 +- public/theme-rose-pine.bundle.json | 20 +- public/theme-sakura-ink.bundle.json | 20 +- public/theme-skeuomorph.bundle.json | 20 +- public/theme-solarized.bundle.json | 20 +- scripts/build-catalog.mjs | 60 +++- scripts/theme-preview-svg.mjs | 100 ++++++ 42 files changed, 1836 insertions(+), 67 deletions(-) create mode 100644 public/screenshots/theme-abyss-teal.svg create mode 100644 public/screenshots/theme-amber-terminal.svg create mode 100644 public/screenshots/theme-arcade-neon.svg create mode 100644 public/screenshots/theme-catppuccin.svg create mode 100644 public/screenshots/theme-eink.svg create mode 100644 public/screenshots/theme-forest-moss.svg create mode 100644 public/screenshots/theme-gruvbox.svg create mode 100644 public/screenshots/theme-newsprint.svg create mode 100644 public/screenshots/theme-nord.svg create mode 100644 public/screenshots/theme-rose-pine.svg create mode 100644 public/screenshots/theme-sakura-ink.svg create mode 100644 public/screenshots/theme-skeuomorph.svg create mode 100644 public/screenshots/theme-solarized.svg create mode 100644 scripts/theme-preview-svg.mjs diff --git a/plugins/theme-abyss-teal/manifest.json b/plugins/theme-abyss-teal/manifest.json index 1c7667f..8fa607d 100644 --- a/plugins/theme-abyss-teal/manifest.json +++ b/plugins/theme-abyss-teal/manifest.json @@ -3,7 +3,7 @@ "name": "Abyss Teal", "version": "1.0.0", "description": "Deep ocean workspace with teal phosphor accents and calm DM Sans typography.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Ocean · Dark · Teal phosphor", + "tags": [ + "dark", + "ocean", + "teal", + "calm" + ], + "longDescription": "A deep-ocean workspace for focused reading and writing. Cool teal actuators sit on trench-dark panels with soft cyan focus rings. Best when you want a calm, aquatic alternative to purple-heavy dark themes.", + "preview": { + "background": "198 40% 7%", + "foreground": "186 35% 92%", + "card": "198 32% 11%", + "primary": "174 62% 48%", + "accent": "186 70% 52%", + "border": "196 24% 22%", + "muted": "198 26% 13%", + "type": "dark" } } diff --git a/plugins/theme-amber-terminal/manifest.json b/plugins/theme-amber-terminal/manifest.json index 6d4c01e..535067e 100644 --- a/plugins/theme-amber-terminal/manifest.json +++ b/plugins/theme-amber-terminal/manifest.json @@ -3,7 +3,7 @@ "name": "Amber CRT Terminal", "version": "1.0.0", "description": "Vintage 1980s monochrome phosphor amber theme on matte obsidian for retro computing aesthetics.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Retro CRT · Dark · Monochrome amber", + "tags": [ + "dark", + "retro", + "crt", + "monospace" + ], + "longDescription": "1980s phosphor terminal vibes: radiant amber ink on matte obsidian, VT323 monospace everywhere. Ideal for telemetry-heavy workspaces and nostalgia without sacrificing readability.", + "preview": { + "background": "0 0% 8%", + "foreground": "38 95% 62%", + "card": "0 0% 12%", + "primary": "38 95% 54%", + "accent": "38 95% 54%", + "border": "38 45% 24%", + "muted": "0 0% 13%", + "type": "dark" } } diff --git a/plugins/theme-arcade-neon/manifest.json b/plugins/theme-arcade-neon/manifest.json index f286479..1dcc0b3 100644 --- a/plugins/theme-arcade-neon/manifest.json +++ b/plugins/theme-arcade-neon/manifest.json @@ -3,7 +3,7 @@ "name": "Arcade Neon", "version": "1.0.0", "description": "Night-arcade dark with magenta and cyan neon signals plus Orbitron display type.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Synthwave · Dark · Neon magenta/cyan", + "tags": [ + "dark", + "neon", + "arcade", + "display" + ], + "longDescription": "Night-arcade cabinet black with hard geometric radii, magenta primary, and cyan accent LEDs. Orbitron headings sell the scoreboard feel - loud by design for creative sessions.", + "preview": { + "background": "260 30% 6%", + "foreground": "300 20% 94%", + "card": "260 28% 10%", + "primary": "320 85% 58%", + "accent": "180 90% 48%", + "border": "280 25% 22%", + "muted": "260 20% 12%", + "type": "dark" } } diff --git a/plugins/theme-catppuccin/manifest.json b/plugins/theme-catppuccin/manifest.json index a89e7f0..fadc102 100644 --- a/plugins/theme-catppuccin/manifest.json +++ b/plugins/theme-catppuccin/manifest.json @@ -3,7 +3,7 @@ "name": "Catppuccin Mocha", "version": "1.0.0", "description": "Soothing pastel dark theme (Mocha) with mauve accents and Nunito typography.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Pastel · Dark · Mocha comfort", + "tags": [ + "dark", + "pastel", + "mocha", + "soft" + ], + "longDescription": "Catppuccin Mocha pastel dark: soft mauve accents, low-glare surfaces, and Nunito typography. A cozy late-night palette that stays gentle on the eyes.", + "preview": { + "background": "240 21% 15%", + "foreground": "226 64% 88%", + "card": "240 21% 12%", + "primary": "267 84% 81%", + "accent": "316 72% 78%", + "border": "237 16% 23%", + "muted": "240 21% 18%", + "type": "dark" } } diff --git a/plugins/theme-eink/manifest.json b/plugins/theme-eink/manifest.json index 4cf1939..a241a46 100644 --- a/plugins/theme-eink/manifest.json +++ b/plugins/theme-eink/manifest.json @@ -3,7 +3,7 @@ "name": "E-Ink Reading Suite", "version": "1.0.0", "description": "Comprehensive high-contrast monochromatic e-paper themes, print typography, and anti-ghosting performance optimizations for E-Ink tablets and distraction-free reading.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "E-paper · Multi-mode · High contrast", + "tags": [ + "eink", + "reading", + "print", + "high-contrast" + ], + "longDescription": "Suite of e-paper atmospheres (Carta, Warm, Night, High Contrast) with print typography and anti-ghosting CSS. Built for distraction-free reading on E-Ink tablets and stark focus modes.", + "preview": { + "background": "0 0% 100%", + "foreground": "0 0% 0%", + "card": "0 0% 100%", + "primary": "0 0% 0%", + "accent": "0 0% 35%", + "border": "0 0% 0%", + "muted": "0 0% 93%", + "type": "light" } } diff --git a/plugins/theme-forest-moss/manifest.json b/plugins/theme-forest-moss/manifest.json index 51fdf02..182e82e 100644 --- a/plugins/theme-forest-moss/manifest.json +++ b/plugins/theme-forest-moss/manifest.json @@ -3,7 +3,7 @@ "name": "Forest Moss", "version": "1.0.0", "description": "Canopy-dark greens with lichen accents and Literata reading typography.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Nature · Dark · Canopy green", + "tags": [ + "dark", + "green", + "reading", + "organic" + ], + "longDescription": "Under-canopy greens with lichen yellow accents and Literata for long-form reading. Feels like a desk under trees - organic, quiet, and easy on night vision.", + "preview": { + "background": "140 22% 9%", + "foreground": "90 18% 90%", + "card": "140 18% 13%", + "primary": "118 42% 48%", + "accent": "72 45% 48%", + "border": "140 14% 22%", + "muted": "140 12% 15%", + "type": "dark" } } diff --git a/plugins/theme-gruvbox/manifest.json b/plugins/theme-gruvbox/manifest.json index c300814..48fa413 100644 --- a/plugins/theme-gruvbox/manifest.json +++ b/plugins/theme-gruvbox/manifest.json @@ -3,7 +3,7 @@ "name": "Gruvbox Dark", "version": "1.0.0", "description": "Warm retro-groove dark theme with orange accents and IBM Plex Sans.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Retro warm · Dark · Earthy orange", + "tags": [ + "dark", + "warm", + "retro", + "earthy" + ], + "longDescription": "Classic Gruvbox Dark: warm earth tones, soft orange accents, IBM Plex Sans. Designed for long coding and reading sessions without cold blue glare.", + "preview": { + "background": "0 0% 16%", + "foreground": "43 59% 81%", + "card": "20 5% 22%", + "primary": "25 80% 55%", + "accent": "40 70% 55%", + "border": "20 5% 30%", + "muted": "20 5% 20%", + "type": "dark" } } diff --git a/plugins/theme-newsprint/manifest.json b/plugins/theme-newsprint/manifest.json index 7034b45..b38e5ac 100644 --- a/plugins/theme-newsprint/manifest.json +++ b/plugins/theme-newsprint/manifest.json @@ -3,7 +3,7 @@ "name": "Newsprint", "version": "1.0.0", "description": "Stark editorial monochrome with hairline rules and Libre Baskerville / IBM Plex typography.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Editorial · Light · Monochrome broadsheet", + "tags": [ + "light", + "mono", + "editorial", + "print" + ], + "longDescription": "Stark broadsheet monochrome - India ink on cold paper, hairline rules, near-zero radius. Libre Baskerville for headlines and IBM Plex for UI. Feels like a newspaper layout tool.", + "preview": { + "background": "40 10% 96%", + "foreground": "0 0% 8%", + "card": "0 0% 100%", + "primary": "0 0% 10%", + "accent": "0 0% 22%", + "border": "0 0% 78%", + "muted": "40 6% 93%", + "type": "light" } } diff --git a/plugins/theme-nord/manifest.json b/plugins/theme-nord/manifest.json index 1267be1..6405b2a 100644 --- a/plugins/theme-nord/manifest.json +++ b/plugins/theme-nord/manifest.json @@ -3,7 +3,7 @@ "name": "Nord Frost Theme", "version": "1.0.0", "description": "Arctic, north-bluish palette engineered for calm focus and reduced eye strain.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Arctic · Dark · Frost cyan", + "tags": [ + "dark", + "nord", + "cool", + "calm" + ], + "longDescription": "Nord Frost arctic palette: north-bluish surfaces, cyan frost primary, mint accents. Clean Plus Jakarta Sans typography for calm, low-strain focus.", + "preview": { + "background": "220 16% 14%", + "foreground": "218 27% 92%", + "card": "222 16% 19%", + "primary": "193 43% 67%", + "accent": "179 25% 65%", + "border": "220 17% 28%", + "muted": "222 16% 19%", + "type": "dark" } } diff --git a/plugins/theme-rose-pine/manifest.json b/plugins/theme-rose-pine/manifest.json index 316e7ae..5f17ff1 100644 --- a/plugins/theme-rose-pine/manifest.json +++ b/plugins/theme-rose-pine/manifest.json @@ -3,7 +3,7 @@ "name": "Rosé Pine", "version": "1.0.0", "description": "All natural pine, faux fur and a bit of soho vibes for the classy minimalist. Instrument Serif headings.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Poetic · Dark · Rose pine", + "tags": [ + "dark", + "soft", + "rose", + "serif" + ], + "longDescription": "Rose Pine natural dark with soft rose accents and Instrument Serif display type. A quieter, literary alternative to high-contrast neon themes.", + "preview": { + "background": "249 22% 12%", + "foreground": "245 50% 91%", + "card": "247 23% 15%", + "primary": "2 55% 75%", + "accent": "197 49% 65%", + "border": "248 15% 25%", + "muted": "247 15% 18%", + "type": "dark" } } diff --git a/plugins/theme-sakura-ink/manifest.json b/plugins/theme-sakura-ink/manifest.json index 10f4b71..6762f5b 100644 --- a/plugins/theme-sakura-ink/manifest.json +++ b/plugins/theme-sakura-ink/manifest.json @@ -3,7 +3,7 @@ "name": "Sakura Ink", "version": "1.0.0", "description": "Light ink-wash workspace with cherry blossom accents and Shippori Mincho headings.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Ink wash · Light · Sakura accents", + "tags": [ + "light", + "japanese", + "ink", + "serif" + ], + "longDescription": "Paper-white ink wash with soft sakura pink signals and Shippori Mincho headings. Scholarly light theme for prose and notes without cream-terracotta clichés.", + "preview": { + "background": "0 0% 98%", + "foreground": "220 20% 16%", + "card": "0 0% 100%", + "primary": "340 55% 48%", + "accent": "200 35% 42%", + "border": "340 12% 88%", + "muted": "220 10% 95%", + "type": "light" } } diff --git a/plugins/theme-skeuomorph/manifest.json b/plugins/theme-skeuomorph/manifest.json index d8bba8c..866f200 100644 --- a/plugins/theme-skeuomorph/manifest.json +++ b/plugins/theme-skeuomorph/manifest.json @@ -3,7 +3,7 @@ "name": "Skeuomorph Suite", "version": "1.2.0", "description": "Eight physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, and Brass Console.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Skeuomorphic · Suite · Physical chrome", + "tags": [ + "skeuomorph", + "materials", + "suite", + "physical" + ], + "longDescription": "Eight physical atmospheres (Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, Brass Console). Uses materials tokens and scoped grain stylesheets for embossed cards, recessed trays, and a tactile activity rail.", + "preview": { + "background": "25 28% 12%", + "foreground": "36 40% 88%", + "card": "25 24% 16%", + "primary": "36 55% 48%", + "accent": "36 55% 48%", + "border": "30 22% 28%", + "muted": "25 16% 18%", + "type": "dark" } } diff --git a/plugins/theme-solarized/manifest.json b/plugins/theme-solarized/manifest.json index 38ba632..6c43f37 100644 --- a/plugins/theme-solarized/manifest.json +++ b/plugins/theme-solarized/manifest.json @@ -3,7 +3,7 @@ "name": "Solarized Light", "version": "1.0.0", "description": "Ethan Schoonover's Solarized Light palette with Source Serif reading type.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -17,5 +17,23 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Solarized · Dark · Precision reading", + "tags": [ + "dark", + "solarized", + "classic", + "serif" + ], + "longDescription": "Solarized Dark precision palette with Source Serif for reading and Source Sans for UI. A classic low-contrast scientific look that ages well.", + "preview": { + "background": "192 100% 11%", + "foreground": "44 87% 94%", + "card": "192 81% 14%", + "primary": "45 100% 35%", + "accent": "68 100% 30%", + "border": "192 20% 25%", + "muted": "192 40% 16%", + "type": "dark" } } diff --git a/public/catalog.json b/public/catalog.json index 1527723..fdf5d36 100644 --- a/public/catalog.json +++ b/public/catalog.json @@ -4,43 +4,100 @@ "id": "readergo.theme.abyss-teal", "name": "Abyss Teal", "description": "Deep ocean workspace with teal phosphor accents and calm DM Sans typography.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "A deep-ocean workspace for focused reading and writing. Cool teal actuators sit on trench-dark panels with soft cyan focus rings. Best when you want a calm, aquatic alternative to purple-heavy dark themes.", + "style": "Ocean · Dark · Teal phosphor", + "tags": [ + "dark", + "ocean", + "teal", + "calm" + ], + "preview": { + "background": "198 40% 7%", + "foreground": "186 35% 92%", + "card": "198 32% 11%", + "primary": "174 62% 48%", + "accent": "186 70% 52%", + "border": "196 24% 22%", + "muted": "198 26% 13%", + "type": "dark" + }, "bundleUrl": "theme-abyss-teal.bundle.json", - "bundleHash": "768d75b55c861a74", - "hash": "768d75b55c861a74" + "bundleHash": "72d25faeb1e95c7d", + "hash": "72d25faeb1e95c7d", + "screenshot": "screenshots/theme-abyss-teal.svg" }, { "id": "readergo.theme.amber", "name": "Amber CRT Terminal", "description": "Vintage 1980s monochrome phosphor amber theme on matte obsidian for retro computing aesthetics.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "1980s phosphor terminal vibes: radiant amber ink on matte obsidian, VT323 monospace everywhere. Ideal for telemetry-heavy workspaces and nostalgia without sacrificing readability.", + "style": "Retro CRT · Dark · Monochrome amber", + "tags": [ + "dark", + "retro", + "crt", + "monospace" + ], + "preview": { + "background": "0 0% 8%", + "foreground": "38 95% 62%", + "card": "0 0% 12%", + "primary": "38 95% 54%", + "accent": "38 95% 54%", + "border": "38 45% 24%", + "muted": "0 0% 13%", + "type": "dark" + }, "bundleUrl": "theme-amber-terminal.bundle.json", - "bundleHash": "e97b7a81f143f8f1", - "hash": "e97b7a81f143f8f1" + "bundleHash": "c958f7e0ac0d48fb", + "hash": "c958f7e0ac0d48fb", + "screenshot": "screenshots/theme-amber-terminal.svg" }, { "id": "readergo.theme.arcade-neon", "name": "Arcade Neon", "description": "Night-arcade dark with magenta and cyan neon signals plus Orbitron display type.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Night-arcade cabinet black with hard geometric radii, magenta primary, and cyan accent LEDs. Orbitron headings sell the scoreboard feel - loud by design for creative sessions.", + "style": "Synthwave · Dark · Neon magenta/cyan", + "tags": [ + "dark", + "neon", + "arcade", + "display" + ], + "preview": { + "background": "260 30% 6%", + "foreground": "300 20% 94%", + "card": "260 28% 10%", + "primary": "320 85% 58%", + "accent": "180 90% 48%", + "border": "280 25% 22%", + "muted": "260 20% 12%", + "type": "dark" + }, "bundleUrl": "theme-arcade-neon.bundle.json", - "bundleHash": "1ad61e8948574967", - "hash": "1ad61e8948574967" + "bundleHash": "78c81ce2cf449768", + "hash": "78c81ce2cf449768", + "screenshot": "screenshots/theme-arcade-neon.svg" }, { "id": "readergo.editor.canvas", @@ -60,15 +117,34 @@ "id": "readergo.theme.catppuccin", "name": "Catppuccin Mocha", "description": "Soothing pastel dark theme (Mocha) with mauve accents and Nunito typography.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Catppuccin Mocha pastel dark: soft mauve accents, low-glare surfaces, and Nunito typography. A cozy late-night palette that stays gentle on the eyes.", + "style": "Pastel · Dark · Mocha comfort", + "tags": [ + "dark", + "pastel", + "mocha", + "soft" + ], + "preview": { + "background": "240 21% 15%", + "foreground": "226 64% 88%", + "card": "240 21% 12%", + "primary": "267 84% 81%", + "accent": "316 72% 78%", + "border": "237 16% 23%", + "muted": "240 21% 18%", + "type": "dark" + }, "bundleUrl": "theme-catppuccin.bundle.json", - "bundleHash": "bb514571d9689398", - "hash": "bb514571d9689398" + "bundleHash": "77ba839cadf37be3", + "hash": "77ba839cadf37be3", + "screenshot": "screenshots/theme-catppuccin.svg" }, { "id": "readergo.chat-store.sqlite", @@ -86,6 +162,7 @@ "id": "demo.external.plugin", "name": "Demo External Plugin", "description": "", + "category": "feature", "version": "1.0.0", "provides": [], "bundleUrl": "demo-external.bundle.json", @@ -109,15 +186,34 @@ "id": "readergo.theme.eink", "name": "E-Ink Reading Suite", "description": "Comprehensive high-contrast monochromatic e-paper themes, print typography, and anti-ghosting performance optimizations for E-Ink tablets and distraction-free reading.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Suite of e-paper atmospheres (Carta, Warm, Night, High Contrast) with print typography and anti-ghosting CSS. Built for distraction-free reading on E-Ink tablets and stark focus modes.", + "style": "E-paper · Multi-mode · High contrast", + "tags": [ + "eink", + "reading", + "print", + "high-contrast" + ], + "preview": { + "background": "0 0% 100%", + "foreground": "0 0% 0%", + "card": "0 0% 100%", + "primary": "0 0% 0%", + "accent": "0 0% 35%", + "border": "0 0% 0%", + "muted": "0 0% 93%", + "type": "light" + }, "bundleUrl": "theme-eink.bundle.json", - "bundleHash": "c407d701155810a2", - "hash": "c407d701155810a2" + "bundleHash": "116deeac1c76fa28", + "hash": "116deeac1c76fa28", + "screenshot": "screenshots/theme-eink.svg" }, { "id": "readergo.embeddings.local", @@ -200,15 +296,34 @@ "id": "readergo.theme.forest-moss", "name": "Forest Moss", "description": "Canopy-dark greens with lichen accents and Literata reading typography.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Under-canopy greens with lichen yellow accents and Literata for long-form reading. Feels like a desk under trees - organic, quiet, and easy on night vision.", + "style": "Nature · Dark · Canopy green", + "tags": [ + "dark", + "green", + "reading", + "organic" + ], + "preview": { + "background": "140 22% 9%", + "foreground": "90 18% 90%", + "card": "140 18% 13%", + "primary": "118 42% 48%", + "accent": "72 45% 48%", + "border": "140 14% 22%", + "muted": "140 12% 15%", + "type": "dark" + }, "bundleUrl": "theme-forest-moss.bundle.json", - "bundleHash": "1bf334069f2c59fe", - "hash": "1bf334069f2c59fe" + "bundleHash": "89ab70eec0a56abf", + "hash": "89ab70eec0a56abf", + "screenshot": "screenshots/theme-forest-moss.svg" }, { "id": "readergo.editor.graph", @@ -229,15 +344,34 @@ "id": "readergo.theme.gruvbox", "name": "Gruvbox Dark", "description": "Warm retro-groove dark theme with orange accents and IBM Plex Sans.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Classic Gruvbox Dark: warm earth tones, soft orange accents, IBM Plex Sans. Designed for long coding and reading sessions without cold blue glare.", + "style": "Retro warm · Dark · Earthy orange", + "tags": [ + "dark", + "warm", + "retro", + "earthy" + ], + "preview": { + "background": "0 0% 16%", + "foreground": "43 59% 81%", + "card": "20 5% 22%", + "primary": "25 80% 55%", + "accent": "40 70% 55%", + "border": "20 5% 30%", + "muted": "20 5% 20%", + "type": "dark" + }, "bundleUrl": "theme-gruvbox.bundle.json", - "bundleHash": "f23135733f2b3aad", - "hash": "f23135733f2b3aad" + "bundleHash": "6e64a4f7c025aad1", + "hash": "6e64a4f7c025aad1", + "screenshot": "screenshots/theme-gruvbox.svg" }, { "id": "readergo.examples.hello-world", @@ -307,29 +441,67 @@ "id": "readergo.theme.newsprint", "name": "Newsprint", "description": "Stark editorial monochrome with hairline rules and Libre Baskerville / IBM Plex typography.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Stark broadsheet monochrome - India ink on cold paper, hairline rules, near-zero radius. Libre Baskerville for headlines and IBM Plex for UI. Feels like a newspaper layout tool.", + "style": "Editorial · Light · Monochrome broadsheet", + "tags": [ + "light", + "mono", + "editorial", + "print" + ], + "preview": { + "background": "40 10% 96%", + "foreground": "0 0% 8%", + "card": "0 0% 100%", + "primary": "0 0% 10%", + "accent": "0 0% 22%", + "border": "0 0% 78%", + "muted": "40 6% 93%", + "type": "light" + }, "bundleUrl": "theme-newsprint.bundle.json", - "bundleHash": "9ffb89830441c09c", - "hash": "9ffb89830441c09c" + "bundleHash": "7add2857ab45efc4", + "hash": "7add2857ab45efc4", + "screenshot": "screenshots/theme-newsprint.svg" }, { "id": "readergo.theme.nord", "name": "Nord Frost Theme", "description": "Arctic, north-bluish palette engineered for calm focus and reduced eye strain.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Nord Frost arctic palette: north-bluish surfaces, cyan frost primary, mint accents. Clean Plus Jakarta Sans typography for calm, low-strain focus.", + "style": "Arctic · Dark · Frost cyan", + "tags": [ + "dark", + "nord", + "cool", + "calm" + ], + "preview": { + "background": "220 16% 14%", + "foreground": "218 27% 92%", + "card": "222 16% 19%", + "primary": "193 43% 67%", + "accent": "179 25% 65%", + "border": "220 17% 28%", + "muted": "222 16% 19%", + "type": "dark" + }, "bundleUrl": "theme-nord.bundle.json", - "bundleHash": "6001dcfbc613aa3b", - "hash": "6001dcfbc613aa3b" + "bundleHash": "c32773343075cece", + "hash": "c32773343075cece", + "screenshot": "screenshots/theme-nord.svg" }, { "id": "readergo.tools.note-digest", @@ -451,29 +623,67 @@ "id": "readergo.theme.rose-pine", "name": "Rosé Pine", "description": "All natural pine, faux fur and a bit of soho vibes for the classy minimalist. Instrument Serif headings.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Rose Pine natural dark with soft rose accents and Instrument Serif display type. A quieter, literary alternative to high-contrast neon themes.", + "style": "Poetic · Dark · Rose pine", + "tags": [ + "dark", + "soft", + "rose", + "serif" + ], + "preview": { + "background": "249 22% 12%", + "foreground": "245 50% 91%", + "card": "247 23% 15%", + "primary": "2 55% 75%", + "accent": "197 49% 65%", + "border": "248 15% 25%", + "muted": "247 15% 18%", + "type": "dark" + }, "bundleUrl": "theme-rose-pine.bundle.json", - "bundleHash": "d619a01067d3d0ee", - "hash": "d619a01067d3d0ee" + "bundleHash": "f9816a7dee125cbd", + "hash": "f9816a7dee125cbd", + "screenshot": "screenshots/theme-rose-pine.svg" }, { "id": "readergo.theme.sakura-ink", "name": "Sakura Ink", "description": "Light ink-wash workspace with cherry blossom accents and Shippori Mincho headings.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Paper-white ink wash with soft sakura pink signals and Shippori Mincho headings. Scholarly light theme for prose and notes without cream-terracotta clichés.", + "style": "Ink wash · Light · Sakura accents", + "tags": [ + "light", + "japanese", + "ink", + "serif" + ], + "preview": { + "background": "0 0% 98%", + "foreground": "220 20% 16%", + "card": "0 0% 100%", + "primary": "340 55% 48%", + "accent": "200 35% 42%", + "border": "340 12% 88%", + "muted": "220 10% 95%", + "type": "light" + }, "bundleUrl": "theme-sakura-ink.bundle.json", - "bundleHash": "e3ecd2326a8881c1", - "hash": "e3ecd2326a8881c1" + "bundleHash": "27187e36a83a7bfe", + "hash": "27187e36a83a7bfe", + "screenshot": "screenshots/theme-sakura-ink.svg" }, { "id": "readergo.features.selection-actions", @@ -529,29 +739,67 @@ "id": "readergo.theme.skeuomorph", "name": "Skeuomorph Suite", "description": "Eight physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, and Brass Console.", - "category": "feature", + "category": "theme", "version": "1.2.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Eight physical atmospheres (Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, Brass Console). Uses materials tokens and scoped grain stylesheets for embossed cards, recessed trays, and a tactile activity rail.", + "style": "Skeuomorphic · Suite · Physical chrome", + "tags": [ + "skeuomorph", + "materials", + "suite", + "physical" + ], + "preview": { + "background": "25 28% 12%", + "foreground": "36 40% 88%", + "card": "25 24% 16%", + "primary": "36 55% 48%", + "accent": "36 55% 48%", + "border": "30 22% 28%", + "muted": "25 16% 18%", + "type": "dark" + }, "bundleUrl": "theme-skeuomorph.bundle.json", - "bundleHash": "2927617fc4d3b6de", - "hash": "2927617fc4d3b6de" + "bundleHash": "b9c70b6f8a3bc378", + "hash": "b9c70b6f8a3bc378", + "screenshot": "screenshots/theme-skeuomorph.svg" }, { "id": "readergo.theme.solarized", "name": "Solarized Light", "description": "Ethan Schoonover's Solarized Light palette with Source Serif reading type.", - "category": "feature", + "category": "theme", "version": "1.0.0", "provides": [ "theme-provider", "font-provider" ], + "longDescription": "Solarized Dark precision palette with Source Serif for reading and Source Sans for UI. A classic low-contrast scientific look that ages well.", + "style": "Solarized · Dark · Precision reading", + "tags": [ + "dark", + "solarized", + "classic", + "serif" + ], + "preview": { + "background": "192 100% 11%", + "foreground": "44 87% 94%", + "card": "192 81% 14%", + "primary": "45 100% 35%", + "accent": "68 100% 30%", + "border": "192 20% 25%", + "muted": "192 40% 16%", + "type": "dark" + }, "bundleUrl": "theme-solarized.bundle.json", - "bundleHash": "380cf2e0bb0c7c9e", - "hash": "380cf2e0bb0c7c9e" + "bundleHash": "d31a592e6bd2700e", + "hash": "d31a592e6bd2700e", + "screenshot": "screenshots/theme-solarized.svg" }, { "id": "readergo.editor.spreadsheet", diff --git a/public/screenshots/theme-abyss-teal.svg b/public/screenshots/theme-abyss-teal.svg new file mode 100644 index 0000000..10f483a --- /dev/null +++ b/public/screenshots/theme-abyss-teal.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Abyss Teal + Ocean · Dark · Teal phosphor + + + + \ No newline at end of file diff --git a/public/screenshots/theme-amber-terminal.svg b/public/screenshots/theme-amber-terminal.svg new file mode 100644 index 0000000..a9dbb0c --- /dev/null +++ b/public/screenshots/theme-amber-terminal.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Amber CRT Terminal + Retro CRT · Dark · Monochrome amber + + + + \ No newline at end of file diff --git a/public/screenshots/theme-arcade-neon.svg b/public/screenshots/theme-arcade-neon.svg new file mode 100644 index 0000000..248850d --- /dev/null +++ b/public/screenshots/theme-arcade-neon.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Arcade Neon + Synthwave · Dark · Neon magenta/cyan + + + + \ No newline at end of file diff --git a/public/screenshots/theme-catppuccin.svg b/public/screenshots/theme-catppuccin.svg new file mode 100644 index 0000000..72751f4 --- /dev/null +++ b/public/screenshots/theme-catppuccin.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Catppuccin Mocha + Pastel · Dark · Mocha comfort + + + + \ No newline at end of file diff --git a/public/screenshots/theme-eink.svg b/public/screenshots/theme-eink.svg new file mode 100644 index 0000000..3e0bf84 --- /dev/null +++ b/public/screenshots/theme-eink.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + E-Ink Reading Suite + E-paper · Multi-mode · High contrast + + + + \ No newline at end of file diff --git a/public/screenshots/theme-forest-moss.svg b/public/screenshots/theme-forest-moss.svg new file mode 100644 index 0000000..aad555d --- /dev/null +++ b/public/screenshots/theme-forest-moss.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Forest Moss + Nature · Dark · Canopy green + + + + \ No newline at end of file diff --git a/public/screenshots/theme-gruvbox.svg b/public/screenshots/theme-gruvbox.svg new file mode 100644 index 0000000..b268ea7 --- /dev/null +++ b/public/screenshots/theme-gruvbox.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gruvbox Dark + Retro warm · Dark · Earthy orange + + + + \ No newline at end of file diff --git a/public/screenshots/theme-newsprint.svg b/public/screenshots/theme-newsprint.svg new file mode 100644 index 0000000..3464f6e --- /dev/null +++ b/public/screenshots/theme-newsprint.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Newsprint + Editorial · Light · Monochrome broadsheet + + + + \ No newline at end of file diff --git a/public/screenshots/theme-nord.svg b/public/screenshots/theme-nord.svg new file mode 100644 index 0000000..8068c78 --- /dev/null +++ b/public/screenshots/theme-nord.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Nord Frost Theme + Arctic · Dark · Frost cyan + + + + \ No newline at end of file diff --git a/public/screenshots/theme-rose-pine.svg b/public/screenshots/theme-rose-pine.svg new file mode 100644 index 0000000..a6364dd --- /dev/null +++ b/public/screenshots/theme-rose-pine.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Rosé Pine + Poetic · Dark · Rose pine + + + + \ No newline at end of file diff --git a/public/screenshots/theme-sakura-ink.svg b/public/screenshots/theme-sakura-ink.svg new file mode 100644 index 0000000..e2bb557 --- /dev/null +++ b/public/screenshots/theme-sakura-ink.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sakura Ink + Ink wash · Light · Sakura accents + + + + \ No newline at end of file diff --git a/public/screenshots/theme-skeuomorph.svg b/public/screenshots/theme-skeuomorph.svg new file mode 100644 index 0000000..df4565a --- /dev/null +++ b/public/screenshots/theme-skeuomorph.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skeuomorph Suite + Skeuomorphic · Suite · Physical chrome + + + + \ No newline at end of file diff --git a/public/screenshots/theme-solarized.svg b/public/screenshots/theme-solarized.svg new file mode 100644 index 0000000..a8043e9 --- /dev/null +++ b/public/screenshots/theme-solarized.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Solarized Light + Solarized · Dark · Precision reading + + + + \ No newline at end of file diff --git a/public/theme-abyss-teal.bundle.json b/public/theme-abyss-teal.bundle.json index 5389ecb..37fd173 100644 --- a/public/theme-abyss-teal.bundle.json +++ b/public/theme-abyss-teal.bundle.json @@ -4,7 +4,7 @@ "name": "Abyss Teal", "version": "1.0.0", "description": "Deep ocean workspace with teal phosphor accents and calm DM Sans typography.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Ocean · Dark · Teal phosphor", + "tags": [ + "dark", + "ocean", + "teal", + "calm" + ], + "longDescription": "A deep-ocean workspace for focused reading and writing. Cool teal actuators sit on trench-dark panels with soft cyan focus rings. Best when you want a calm, aquatic alternative to purple-heavy dark themes.", + "preview": { + "background": "198 40% 7%", + "foreground": "186 35% 92%", + "card": "198 32% 11%", + "primary": "174 62% 48%", + "accent": "186 70% 52%", + "border": "196 24% 22%", + "muted": "198 26% 13%", + "type": "dark" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-abyss-teal/src/index.ts\nvar DM_SANS = {\n id: \"dm-sans-abyss\",\n name: \"DM Sans\",\n family: \"'DM Sans', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,600;0,9..40,700;1,9..40,400&display=swap\",\n targets: [\"all\"]\n};\nvar THEME = {\n id: \"abyss-teal\",\n name: \"Abyss Teal\",\n type: \"dark\",\n author: \"ReaderGo Studio\",\n description: \"Deep ocean trench palette with teal phosphor signals and soft cyan focus rings.\",\n colors: {\n background: \"198 40% 7%\",\n foreground: \"186 35% 92%\",\n card: \"198 32% 11%\",\n cardForeground: \"186 35% 92%\",\n border: \"196 24% 22%\",\n primary: \"174 62% 48%\",\n primaryForeground: \"198 40% 6%\",\n secondary: \"198 28% 15%\",\n secondaryForeground: \"186 30% 86%\",\n muted: \"198 26% 13%\",\n mutedForeground: \"190 14% 55%\",\n accent: \"186 70% 52%\",\n accentForeground: \"198 40% 6%\",\n destructive: \"4 70% 52%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"160 50% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 52%\",\n warningForeground: \"198 40% 6%\",\n info: \"186 70% 52%\",\n infoForeground: \"198 40% 6%\",\n input: \"198 30% 10%\",\n ring: \"174 62% 48%\",\n heading1: \"174 70% 68%\",\n heading2: \"186 55% 66%\",\n heading3: \"190 40% 64%\"\n },\n fonts: { display: DM_SANS, body: DM_SANS, editor: DM_SANS, mono: DM_SANS },\n materials: {\n radius: \"0.55rem\",\n radius2xl: \"0.9rem\",\n surfaceBlur: \"8px\",\n shadowMd: \"0 4px 18px rgb(0 40 50 / 0.45)\"\n }\n};\nvar AbyssTealThemePlugin = {\n manifest: {\n id: \"readergo.theme.abyss-teal\",\n name: \"Abyss Teal\",\n version: \"1.0.0\",\n description: \"Deep ocean workspace with teal phosphor accents and calm DM Sans typography.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", { getThemes: () => [THEME] });\n await context.registerCapability(\"font-provider\", { getFonts: () => [DM_SANS] });\n },\n deactivate() {\n }\n};\nvar index_default = AbyssTealThemePlugin;\n\n\n return { AbyssTealThemePlugin: AbyssTealThemePlugin, default: index_default };\n}\n" diff --git a/public/theme-amber-terminal.bundle.json b/public/theme-amber-terminal.bundle.json index dc08010..2ac8238 100644 --- a/public/theme-amber-terminal.bundle.json +++ b/public/theme-amber-terminal.bundle.json @@ -4,7 +4,7 @@ "name": "Amber CRT Terminal", "version": "1.0.0", "description": "Vintage 1980s monochrome phosphor amber theme on matte obsidian for retro computing aesthetics.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Retro CRT · Dark · Monochrome amber", + "tags": [ + "dark", + "retro", + "crt", + "monospace" + ], + "longDescription": "1980s phosphor terminal vibes: radiant amber ink on matte obsidian, VT323 monospace everywhere. Ideal for telemetry-heavy workspaces and nostalgia without sacrificing readability.", + "preview": { + "background": "0 0% 8%", + "foreground": "38 95% 62%", + "card": "0 0% 12%", + "primary": "38 95% 54%", + "accent": "38 95% 54%", + "border": "38 45% 24%", + "muted": "0 0% 13%", + "type": "dark" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-amber-terminal/src/index.ts\nvar VT323_FONT = {\n id: \"vt323\",\n name: \"VT323 Retro CRT\",\n family: \"'VT323', monospace\",\n category: \"mono\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=VT323&display=swap\",\n targets: [\"all\"]\n};\nvar AMBER_THEME = {\n id: \"amber-terminal\",\n name: \"Amber CRT Terminal\",\n type: \"dark\",\n author: \"Sovereign Telemetry\",\n description: \"1980s monochrome phosphor amber on matte obsidian carbon with authentic CRT monospace typography.\",\n colors: {\n background: \"0 0% 8%\",\n // Pure matte obsidian\n foreground: \"38 95% 62%\",\n // Radiant Phosphor Amber #fbb034\n card: \"0 0% 12%\",\n // Dark instrument tray\n cardForeground: \"38 95% 62%\",\n border: \"38 45% 24%\",\n // Hairline amber rule\n primary: \"38 95% 54%\",\n // Saturated amber key\n primaryForeground: \"0 0% 8%\",\n secondary: \"0 0% 16%\",\n secondaryForeground: \"38 90% 58%\",\n muted: \"0 0% 13%\",\n mutedForeground: \"38 40% 45%\",\n // Dim amber glow\n accent: \"38 95% 54%\",\n // Phosphor amber LED\n accentForeground: \"0 0% 8%\",\n destructive: \"0 75% 55%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"38 95% 58%\",\n // Amber phosphor sync beacon\n successForeground: \"0 0% 8%\",\n warning: \"25 95% 52%\",\n // Warm amber dirty warning\n warningForeground: \"0 0% 8%\",\n info: \"45 90% 52%\",\n // Soft amber saving pulse\n infoForeground: \"0 0% 8%\",\n input: \"0 0% 12%\",\n ring: \"38 95% 54%\",\n heading1: \"38 95% 72%\",\n heading2: \"38 85% 65%\",\n heading3: \"38 75% 58%\"\n },\n fonts: {\n display: VT323_FONT,\n body: VT323_FONT,\n mono: VT323_FONT,\n editor: VT323_FONT\n }\n};\nvar AmberThemePlugin = {\n manifest: {\n id: \"readergo.theme.amber\",\n name: \"Amber CRT Terminal\",\n version: \"1.1.0\",\n description: \"Vintage 1980s monochrome phosphor amber theme on matte obsidian with authentic VT323 CRT typography.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(\"\\u{1F4DF} Amber CRT Terminal theme plugin activating with VT323 typography...\");\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => [AMBER_THEME]\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => [VT323_FONT]\n });\n },\n deactivate(context) {\n context.log.info(\"\\u{1F4DF} Amber CRT Terminal theme plugin deactivated.\");\n }\n};\nvar index_default = AmberThemePlugin;\n\n\n return { AmberThemePlugin: AmberThemePlugin, default: index_default };\n}\n" diff --git a/public/theme-arcade-neon.bundle.json b/public/theme-arcade-neon.bundle.json index 462beba..2bc002e 100644 --- a/public/theme-arcade-neon.bundle.json +++ b/public/theme-arcade-neon.bundle.json @@ -4,7 +4,7 @@ "name": "Arcade Neon", "version": "1.0.0", "description": "Night-arcade dark with magenta and cyan neon signals plus Orbitron display type.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Synthwave · Dark · Neon magenta/cyan", + "tags": [ + "dark", + "neon", + "arcade", + "display" + ], + "longDescription": "Night-arcade cabinet black with hard geometric radii, magenta primary, and cyan accent LEDs. Orbitron headings sell the scoreboard feel - loud by design for creative sessions.", + "preview": { + "background": "260 30% 6%", + "foreground": "300 20% 94%", + "card": "260 28% 10%", + "primary": "320 85% 58%", + "accent": "180 90% 48%", + "border": "280 25% 22%", + "muted": "260 20% 12%", + "type": "dark" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-arcade-neon/src/index.ts\nvar ORBITRON = {\n id: \"orbitron-arcade\",\n name: \"Orbitron\",\n family: \"'Orbitron', system-ui, sans-serif\",\n category: \"display\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Orbitron:wght@500;600;700&display=swap\",\n targets: [\"display\"]\n};\nvar EXO = {\n id: \"exo-2-arcade\",\n name: \"Exo 2\",\n family: \"'Exo 2', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Exo+2:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"editor\", \"all\"]\n};\nvar THEME = {\n id: \"arcade-neon\",\n name: \"Arcade Neon\",\n type: \"dark\",\n author: \"ReaderGo Studio\",\n description: \"Cabinet-black night with magenta / cyan neon actuators and hard geometric chrome.\",\n colors: {\n background: \"260 30% 6%\",\n foreground: \"300 20% 94%\",\n card: \"260 28% 10%\",\n cardForeground: \"300 20% 94%\",\n border: \"280 25% 22%\",\n primary: \"320 85% 58%\",\n primaryForeground: \"260 40% 6%\",\n secondary: \"260 22% 14%\",\n secondaryForeground: \"180 40% 80%\",\n muted: \"260 20% 12%\",\n mutedForeground: \"270 12% 55%\",\n accent: \"180 90% 48%\",\n accentForeground: \"260 40% 6%\",\n destructive: \"0 85% 55%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"150 80% 45%\",\n successForeground: \"260 40% 6%\",\n warning: \"45 95% 55%\",\n warningForeground: \"260 40% 6%\",\n info: \"180 90% 48%\",\n infoForeground: \"260 40% 6%\",\n input: \"260 26% 9%\",\n ring: \"320 85% 58%\",\n heading1: \"320 90% 72%\",\n heading2: \"180 85% 65%\",\n heading3: \"280 50% 70%\"\n },\n fonts: { display: ORBITRON, body: EXO, editor: EXO, mono: EXO },\n materials: {\n radius: \"0.25rem\",\n radiusSm: \"0.15rem\",\n radiusMd: \"0.2rem\",\n radiusLg: \"0.25rem\",\n radiusXl: \"0.35rem\",\n radius2xl: \"0.45rem\",\n surfaceBlur: \"0px\",\n shadowMd: \"0 0 0 1px rgb(255 0 180 / 0.15), 0 8px 24px rgb(0 0 0 / 0.55)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 100 220 / 0.15)\"\n },\n stylesheet: `\n background-image:\n radial-gradient(ellipse at 10% 0%, rgb(255 0 160 / 0.12), transparent 40%),\n radial-gradient(ellipse at 90% 100%, rgb(0 255 220 / 0.1), transparent 45%),\n linear-gradient(180deg, transparent 60%, rgb(0 0 0 / 0.35));\n `,\n stylesheetScoped: true\n};\nvar ArcadeNeonThemePlugin = {\n manifest: {\n id: \"readergo.theme.arcade-neon\",\n name: \"Arcade Neon\",\n version: \"1.0.0\",\n description: \"Night-arcade dark with magenta and cyan neon signals plus Orbitron display type.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", { getThemes: () => [THEME] });\n await context.registerCapability(\"font-provider\", { getFonts: () => [ORBITRON, EXO] });\n },\n deactivate() {\n }\n};\nvar index_default = ArcadeNeonThemePlugin;\n\n\n return { ArcadeNeonThemePlugin: ArcadeNeonThemePlugin, default: index_default };\n}\n" diff --git a/public/theme-catppuccin.bundle.json b/public/theme-catppuccin.bundle.json index 28af99f..6722eb4 100644 --- a/public/theme-catppuccin.bundle.json +++ b/public/theme-catppuccin.bundle.json @@ -4,7 +4,7 @@ "name": "Catppuccin Mocha", "version": "1.0.0", "description": "Soothing pastel dark theme (Mocha) with mauve accents and Nunito typography.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Pastel · Dark · Mocha comfort", + "tags": [ + "dark", + "pastel", + "mocha", + "soft" + ], + "longDescription": "Catppuccin Mocha pastel dark: soft mauve accents, low-glare surfaces, and Nunito typography. A cozy late-night palette that stays gentle on the eyes.", + "preview": { + "background": "240 21% 15%", + "foreground": "226 64% 88%", + "card": "240 21% 12%", + "primary": "267 84% 81%", + "accent": "316 72% 78%", + "border": "237 16% 23%", + "muted": "240 21% 18%", + "type": "dark" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-catppuccin/src/index.ts\nvar NUNITO = {\n id: \"nunito\",\n name: \"Nunito\",\n family: \"'Nunito', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"all\"]\n};\nvar THEME = {\n id: \"catppuccin-mocha\",\n name: \"Catppuccin Mocha\",\n type: \"dark\",\n author: \"Catppuccin\",\n description: \"Soothing pastel mocha palette with mauve highlights for late-night reading.\",\n colors: {\n background: \"240 21% 15%\",\n foreground: \"226 64% 88%\",\n card: \"240 21% 12%\",\n cardForeground: \"226 64% 88%\",\n border: \"237 16% 23%\",\n primary: \"267 84% 81%\",\n primaryForeground: \"240 21% 15%\",\n secondary: \"237 16% 23%\",\n secondaryForeground: \"226 64% 88%\",\n muted: \"237 16% 23%\",\n mutedForeground: \"228 17% 64%\",\n accent: \"199 76% 69%\",\n accentForeground: \"240 21% 15%\",\n destructive: \"343 81% 75%\",\n destructiveForeground: \"240 21% 15%\",\n success: \"115 54% 76%\",\n successForeground: \"240 21% 15%\",\n warning: \"41 86% 83%\",\n warningForeground: \"240 21% 15%\",\n info: \"217 92% 76%\",\n infoForeground: \"240 21% 15%\",\n input: \"240 21% 12%\",\n ring: \"267 84% 81%\",\n heading1: \"267 84% 81%\",\n heading2: \"199 76% 69%\",\n heading3: \"217 92% 76%\"\n },\n fonts: {\n display: NUNITO,\n body: NUNITO\n }\n};\nvar CatppuccinThemePlugin = {\n manifest: {\n id: \"readergo.theme.catppuccin\",\n name: \"Catppuccin Mocha\",\n version: \"1.0.0\",\n description: \"Soothing pastel dark theme (Mocha) with mauve accents and Nunito typography.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => [THEME]\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => [NUNITO]\n });\n context.log.info(\"Catppuccin Mocha theme activated\");\n },\n deactivate(context) {\n context.log.info(\"Catppuccin Mocha theme deactivated\");\n }\n};\nvar index_default = CatppuccinThemePlugin;\n\n\n return { CatppuccinThemePlugin: CatppuccinThemePlugin, default: index_default };\n}\n" diff --git a/public/theme-eink.bundle.json b/public/theme-eink.bundle.json index 4b12be0..24b1eeb 100644 --- a/public/theme-eink.bundle.json +++ b/public/theme-eink.bundle.json @@ -4,7 +4,7 @@ "name": "E-Ink Reading Suite", "version": "1.0.0", "description": "Comprehensive high-contrast monochromatic e-paper themes, print typography, and anti-ghosting performance optimizations for E-Ink tablets and distraction-free reading.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "E-paper · Multi-mode · High contrast", + "tags": [ + "eink", + "reading", + "print", + "high-contrast" + ], + "longDescription": "Suite of e-paper atmospheres (Carta, Warm, Night, High Contrast) with print typography and anti-ghosting CSS. Built for distraction-free reading on E-Ink tablets and stark focus modes.", + "preview": { + "background": "0 0% 100%", + "foreground": "0 0% 0%", + "card": "0 0% 100%", + "primary": "0 0% 0%", + "accent": "0 0% 35%", + "border": "0 0% 0%", + "muted": "0 0% 93%", + "type": "light" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-eink/src/einkThemes.ts\nvar EINK_FONT_LITERATA = {\n id: \"eink-literata\",\n name: \"Literata (Digital Book Serif)\",\n family: \"'Literata', 'Charter', 'Merriweather', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap\",\n targets: [\"all\"]\n};\nvar EINK_FONT_COURIER_PRIME = {\n id: \"eink-courier-prime\",\n name: \"Courier Prime (Typewriter Print)\",\n family: \"'Courier Prime', 'Courier New', monospace\",\n category: \"mono\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Courier+Prime:ital,wght@0,400;0,700;1,400&display=swap\",\n targets: [\"all\"]\n};\nvar EINK_FONT_ATKINSON = {\n id: \"eink-atkinson\",\n name: \"Atkinson Hyperlegible (Low Glare Sans)\",\n family: \"'Atkinson Hyperlegible', system-ui, -apple-system, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible:ital,wght@0,400;0,700;1,400&display=swap\",\n targets: [\"all\"]\n};\nvar EINK_FONTS = [\n EINK_FONT_LITERATA,\n EINK_FONT_COURIER_PRIME,\n EINK_FONT_ATKINSON\n];\nvar EINK_PAPER_THEME = {\n id: \"eink-paper\",\n name: \"E-Ink Carta Paper\",\n type: \"light\",\n author: \"E-Ink Reading Suite\",\n description: \"Reflective digital paper with India ink typography and zero ghosting for daytime e-paper reading.\",\n colors: {\n background: \"0 0% 100%\",\n foreground: \"0 0% 0%\",\n card: \"0 0% 100%\",\n cardForeground: \"0 0% 0%\",\n border: \"0 0% 0%\",\n primary: \"0 0% 0%\",\n primaryForeground: \"0 0% 100%\",\n secondary: \"0 0% 95%\",\n secondaryForeground: \"0 0% 0%\",\n muted: \"0 0% 93%\",\n mutedForeground: \"0 0% 28%\",\n accent: \"0 0% 35%\",\n accentForeground: \"0 0% 100%\",\n destructive: \"0 0% 20%\",\n destructiveForeground: \"0 0% 100%\",\n input: \"0 0% 100%\",\n ring: \"0 0% 0%\",\n heading1: \"0 0% 0%\",\n heading2: \"0 0% 0%\",\n heading3: \"0 0% 15%\",\n success: \"0 0% 20%\",\n warning: \"0 0% 30%\",\n info: \"0 0% 25%\"\n },\n fonts: {\n display: EINK_FONT_LITERATA,\n body: EINK_FONT_ATKINSON,\n editor: EINK_FONT_LITERATA,\n mono: EINK_FONT_COURIER_PRIME\n },\n customVars: {\n \"eink-mode\": \"paper\",\n \"eink-border-width\": \"1.5px\"\n }\n};\nvar EINK_WARM_THEME = {\n id: \"eink-warm\",\n name: \"E-Ink Warm Amber\",\n type: \"light\",\n author: \"E-Ink Reading Suite\",\n description: \"Natural warm paperback newsprint tone designed for long-form reading with warm backlights.\",\n colors: {\n background: \"40 28% 96%\",\n foreground: \"30 15% 10%\",\n card: \"40 25% 98%\",\n cardForeground: \"30 15% 10%\",\n border: \"30 12% 25%\",\n primary: \"30 18% 12%\",\n primaryForeground: \"40 28% 96%\",\n secondary: \"38 20% 91%\",\n secondaryForeground: \"30 15% 10%\",\n muted: \"38 18% 90%\",\n mutedForeground: \"30 10% 38%\",\n accent: \"35 25% 32%\",\n accentForeground: \"40 28% 96%\",\n destructive: \"15 35% 25%\",\n destructiveForeground: \"40 28% 96%\",\n input: \"40 25% 98%\",\n ring: \"30 18% 12%\",\n heading1: \"30 18% 8%\",\n heading2: \"30 18% 12%\",\n heading3: \"30 14% 20%\",\n success: \"35 25% 25%\",\n warning: \"35 30% 35%\",\n info: \"30 20% 30%\"\n },\n fonts: {\n display: EINK_FONT_LITERATA,\n body: EINK_FONT_ATKINSON,\n editor: EINK_FONT_LITERATA,\n mono: EINK_FONT_COURIER_PRIME\n },\n customVars: {\n \"eink-mode\": \"warm\",\n \"eink-border-width\": \"1.5px\"\n }\n};\nvar EINK_NIGHT_THEME = {\n id: \"eink-night\",\n name: \"E-Ink Onyx Night\",\n type: \"dark\",\n author: \"E-Ink Reading Suite\",\n description: \"Inverted pitch black e-paper mode with stark white ink and zero glare for night reading on frontlit tablets.\",\n colors: {\n background: \"0 0% 0%\",\n foreground: \"0 0% 100%\",\n card: \"0 0% 0%\",\n cardForeground: \"0 0% 100%\",\n border: \"0 0% 85%\",\n primary: \"0 0% 100%\",\n primaryForeground: \"0 0% 0%\",\n secondary: \"0 0% 12%\",\n secondaryForeground: \"0 0% 100%\",\n muted: \"0 0% 15%\",\n mutedForeground: \"0 0% 75%\",\n accent: \"0 0% 70%\",\n accentForeground: \"0 0% 0%\",\n destructive: \"0 0% 80%\",\n destructiveForeground: \"0 0% 0%\",\n input: \"0 0% 0%\",\n ring: \"0 0% 100%\",\n heading1: \"0 0% 100%\",\n heading2: \"0 0% 100%\",\n heading3: \"0 0% 88%\",\n success: \"0 0% 85%\",\n warning: \"0 0% 75%\",\n info: \"0 0% 80%\"\n },\n fonts: {\n display: EINK_FONT_LITERATA,\n body: EINK_FONT_ATKINSON,\n editor: EINK_FONT_LITERATA,\n mono: EINK_FONT_COURIER_PRIME\n },\n customVars: {\n \"eink-mode\": \"night\",\n \"eink-border-width\": \"1.5px\"\n }\n};\nvar EINK_HIGH_CONTRAST_THEME = {\n id: \"eink-high-contrast\",\n name: \"E-Ink 1-Bit High Contrast\",\n type: \"light\",\n author: \"E-Ink Reading Suite\",\n description: \"Strict 1-bit black & white palette. No midtone gray dithering. Ideal for direct sunlight and fast A2 refresh modes.\",\n colors: {\n background: \"0 0% 100%\",\n foreground: \"0 0% 0%\",\n card: \"0 0% 100%\",\n cardForeground: \"0 0% 0%\",\n border: \"0 0% 0%\",\n primary: \"0 0% 0%\",\n primaryForeground: \"0 0% 100%\",\n secondary: \"0 0% 100%\",\n secondaryForeground: \"0 0% 0%\",\n muted: \"0 0% 100%\",\n mutedForeground: \"0 0% 0%\",\n accent: \"0 0% 0%\",\n accentForeground: \"0 0% 100%\",\n destructive: \"0 0% 0%\",\n destructiveForeground: \"0 0% 100%\",\n input: \"0 0% 100%\",\n ring: \"0 0% 0%\",\n heading1: \"0 0% 0%\",\n heading2: \"0 0% 0%\",\n heading3: \"0 0% 0%\",\n success: \"0 0% 0%\",\n warning: \"0 0% 0%\",\n info: \"0 0% 0%\"\n },\n fonts: {\n display: EINK_FONT_ATKINSON,\n body: EINK_FONT_ATKINSON,\n editor: EINK_FONT_ATKINSON,\n mono: EINK_FONT_COURIER_PRIME\n },\n customVars: {\n \"eink-mode\": \"high-contrast\",\n \"eink-border-width\": \"2px\"\n }\n};\nvar EINK_THEMES = [\n EINK_PAPER_THEME,\n EINK_WARM_THEME,\n EINK_NIGHT_THEME,\n EINK_HIGH_CONTRAST_THEME\n];\nvar EINK_THEME_IDS = EINK_THEMES.map((t) => t.id);\n\n// plugins/theme-eink/src/einkStyles.ts\nvar STYLE_ELEMENT_ID = \"readergo-eink-runtime-styles\";\nvar EINK_GLOBAL_CSS = `\n/* -------------------------------------------------------------\n * ReaderGo E-Ink Performance & Anti-Ghosting Styles\n * Active whenever an e-ink theme is selected (data-theme=\"eink-*\")\n * ------------------------------------------------------------- */\n\n[data-theme^=\"eink-\"] *,\n[data-theme^=\"eink-\"] *::before,\n[data-theme^=\"eink-\"] *::after {\n /* Eliminate animated frame renders that cause visual ghosting on e-paper */\n transition-duration: 0.0001ms !important;\n transition-delay: 0s !important;\n animation-duration: 0.0001ms !important;\n animation-delay: 0s !important;\n animation-iteration-count: 1 !important;\n scroll-behavior: auto !important;\n\n /* Remove subtle blurs, glowing rings, and drop shadows that cause dithering smudges */\n box-shadow: none !important;\n text-shadow: none !important;\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n}\n\n/* Crisp, high-contrast borders on interactive controls */\n[data-theme^=\"eink-\"] button,\n[data-theme^=\"eink-\"] input,\n[data-theme^=\"eink-\"] select,\n[data-theme^=\"eink-\"] textarea {\n border-width: 1.5px !important;\n}\n\n/* Sharp focus outlines instead of soft colored glow rings */\n[data-theme^=\"eink-\"] button:focus-visible,\n[data-theme^=\"eink-\"] input:focus-visible,\n[data-theme^=\"eink-\"] select:focus-visible,\n[data-theme^=\"eink-\"] textarea:focus-visible,\n[data-theme^=\"eink-\"] [tabindex]:focus-visible {\n outline: 2px solid currentColor !important;\n outline-offset: 2px !important;\n}\n\n/* Strict 1-bit solid black outlines for extreme sunlight contrast */\n[data-theme=\"eink-high-contrast\"] button,\n[data-theme=\"eink-high-contrast\"] input,\n[data-theme=\"eink-high-contrast\"] select,\n[data-theme=\"eink-high-contrast\"] textarea,\n[data-theme=\"eink-high-contrast\"] [role=\"button\"],\n[data-theme=\"eink-high-contrast\"] .border {\n border-width: 2px !important;\n border-color: #000000 !important;\n}\n\n/* Ensure code blocks and blockquotes are clearly boxed */\n[data-theme^=\"eink-\"] pre,\n[data-theme^=\"eink-\"] code {\n border-width: 1px !important;\n border-style: solid !important;\n}\n\n/* High-contrast active selection */\n[data-theme^=\"eink-\"] ::selection {\n background-color: #000000 !important;\n color: #FFFFFF !important;\n}\n\n[data-theme=\"eink-night\"] ::selection {\n background-color: #FFFFFF !important;\n color: #000000 !important;\n}\n`;\nfunction injectEinkStyles() {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(STYLE_ELEMENT_ID)) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ELEMENT_ID;\n style.textContent = EINK_GLOBAL_CSS;\n document.head.appendChild(style);\n}\nfunction removeEinkStyles() {\n if (typeof document === \"undefined\") return;\n const existing = document.getElementById(STYLE_ELEMENT_ID);\n if (existing) {\n existing.remove();\n }\n}\nfunction triggerEinkScreenRefresh() {\n if (typeof document === \"undefined\") return Promise.resolve();\n return new Promise((resolve) => {\n const existing = document.getElementById(\"readergo-eink-flash-overlay\");\n if (existing) existing.remove();\n const flash = document.createElement(\"div\");\n flash.id = \"readergo-eink-flash-overlay\";\n flash.style.position = \"fixed\";\n flash.style.inset = \"0\";\n flash.style.zIndex = \"999999\";\n flash.style.pointerEvents = \"none\";\n flash.style.backgroundColor = \"#000000\";\n flash.style.opacity = \"1\";\n flash.style.transition = \"none\";\n document.body.appendChild(flash);\n setTimeout(() => {\n flash.style.backgroundColor = \"#FFFFFF\";\n setTimeout(() => {\n flash.remove();\n resolve();\n }, 70);\n }, 70);\n });\n}\n\n// plugins/theme-eink/src/index.ts\nvar EinkThemePlugin = {\n manifest: {\n id: \"readergo.theme.eink\",\n name: \"E-Ink Reading Suite\",\n version: \"1.0.0\",\n description: \"Comprehensive high-contrast monochromatic e-paper themes, print typography, and anti-ghosting performance optimizations for E-Ink tablets and distraction-free reading.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(\"\\u{1F4D6} E-Ink Reading Suite activating with 4 e-paper atmospheres & typography...\");\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => EINK_THEMES\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => EINK_FONTS\n });\n await context.registerCommand({\n id: \"readergo.eink.enablePaper\",\n title: \"E-Ink: Carta Paper Mode\",\n handler: async () => {\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId: EINK_PAPER_THEME.id });\n return { activeTheme: EINK_PAPER_THEME.id };\n }\n });\n await context.registerCommand({\n id: \"readergo.eink.enableWarm\",\n title: \"E-Ink: Warm Amber Newsprint Mode\",\n handler: async () => {\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId: EINK_WARM_THEME.id });\n return { activeTheme: EINK_WARM_THEME.id };\n }\n });\n await context.registerCommand({\n id: \"readergo.eink.enableNight\",\n title: \"E-Ink: Onyx Night Inverted Mode\",\n handler: async () => {\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId: EINK_NIGHT_THEME.id });\n return { activeTheme: EINK_NIGHT_THEME.id };\n }\n });\n await context.registerCommand({\n id: \"readergo.eink.enableHighContrast\",\n title: \"E-Ink: 1-Bit High Contrast Mode\",\n handler: async () => {\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId: EINK_HIGH_CONTRAST_THEME.id });\n return { activeTheme: EINK_HIGH_CONTRAST_THEME.id };\n }\n });\n await context.registerCommand({\n id: \"readergo.eink.cycleMode\",\n title: \"E-Ink: Cycle Reading Atmosphere\",\n handler: async () => {\n const activeTheme = await context.executeCommand(\"readergo.theme.getActiveTheme\");\n const currentId = activeTheme?.id || EINK_PAPER_THEME.id;\n const currentIndex = EINK_THEME_IDS.indexOf(currentId);\n const nextIndex = currentIndex >= 0 ? (currentIndex + 1) % EINK_THEME_IDS.length : 0;\n const nextThemeId = EINK_THEME_IDS[nextIndex];\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId: nextThemeId });\n return { activeTheme: nextThemeId };\n }\n });\n await context.registerCommand({\n id: \"readergo.eink.triggerFullRefresh\",\n title: \"E-Ink: Trigger Hardware Screen Refresh (Clear Ghosting)\",\n handler: async () => {\n await triggerEinkScreenRefresh();\n return { refreshed: true };\n }\n });\n await context.registerCommand({\n id: \"readergo.eink.getModes\",\n title: \"E-Ink: Get Available Reading Modes\",\n handler: async () => EINK_THEMES.map((t) => ({\n id: t.id,\n name: t.name,\n type: t.type,\n description: t.description\n }))\n });\n injectEinkStyles();\n context.log.info(\"\\u{1F4D6} E-Ink Reading Suite ready.\");\n },\n deactivate(context) {\n removeEinkStyles();\n context.log.info(\"\\u{1F4D6} E-Ink Reading Suite deactivated.\");\n }\n};\nvar index_default = EinkThemePlugin;\n\n\n return { EINK_FONTS: EINK_FONTS, EINK_FONT_ATKINSON: EINK_FONT_ATKINSON, EINK_FONT_COURIER_PRIME: EINK_FONT_COURIER_PRIME, EINK_FONT_LITERATA: EINK_FONT_LITERATA, EINK_HIGH_CONTRAST_THEME: EINK_HIGH_CONTRAST_THEME, EINK_NIGHT_THEME: EINK_NIGHT_THEME, EINK_PAPER_THEME: EINK_PAPER_THEME, EINK_THEMES: EINK_THEMES, EINK_THEME_IDS: EINK_THEME_IDS, EINK_WARM_THEME: EINK_WARM_THEME, EinkThemePlugin: EinkThemePlugin, default: index_default, injectEinkStyles: injectEinkStyles, removeEinkStyles: removeEinkStyles, triggerEinkScreenRefresh: triggerEinkScreenRefresh };\n}\n" diff --git a/public/theme-forest-moss.bundle.json b/public/theme-forest-moss.bundle.json index 883b27c..519e279 100644 --- a/public/theme-forest-moss.bundle.json +++ b/public/theme-forest-moss.bundle.json @@ -4,7 +4,7 @@ "name": "Forest Moss", "version": "1.0.0", "description": "Canopy-dark greens with lichen accents and Literata reading typography.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Nature · Dark · Canopy green", + "tags": [ + "dark", + "green", + "reading", + "organic" + ], + "longDescription": "Under-canopy greens with lichen yellow accents and Literata for long-form reading. Feels like a desk under trees - organic, quiet, and easy on night vision.", + "preview": { + "background": "140 22% 9%", + "foreground": "90 18% 90%", + "card": "140 18% 13%", + "primary": "118 42% 48%", + "accent": "72 45% 48%", + "border": "140 14% 22%", + "muted": "140 12% 15%", + "type": "dark" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-forest-moss/src/index.ts\nvar LITERATA = {\n id: \"literata-forest\",\n name: \"Literata\",\n family: \"'Literata', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-forest\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar THEME = {\n id: \"forest-moss\",\n name: \"Forest Moss\",\n type: \"dark\",\n author: \"ReaderGo Studio\",\n description: \"Under-canopy greens with lichen yellow accents for long reading sessions.\",\n colors: {\n background: \"140 22% 9%\",\n foreground: \"90 18% 90%\",\n card: \"140 18% 13%\",\n cardForeground: \"90 18% 90%\",\n border: \"140 14% 22%\",\n primary: \"118 42% 48%\",\n primaryForeground: \"140 30% 6%\",\n secondary: \"140 14% 17%\",\n secondaryForeground: \"90 14% 84%\",\n muted: \"140 12% 15%\",\n mutedForeground: \"120 10% 55%\",\n accent: \"72 45% 48%\",\n accentForeground: \"140 30% 6%\",\n destructive: \"8 65% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"118 42% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"48 70% 48%\",\n warningForeground: \"140 30% 6%\",\n info: \"170 40% 45%\",\n infoForeground: \"0 0% 100%\",\n input: \"140 16% 11%\",\n ring: \"118 42% 48%\",\n heading1: \"90 40% 72%\",\n heading2: \"118 35% 66%\",\n heading3: \"72 35% 62%\"\n },\n fonts: { display: LITERATA, body: SOURCE_SANS, editor: LITERATA, mono: SOURCE_SANS },\n materials: {\n radius: \"0.6rem\",\n radius2xl: \"1rem\",\n surfaceBlur: \"0px\",\n shadowMd: \"0 6px 20px rgb(0 20 10 / 0.45)\"\n },\n stylesheet: `\n background-image:\n radial-gradient(ellipse at 15% 20%, rgb(60 120 70 / 0.18), transparent 45%),\n radial-gradient(ellipse at 85% 80%, rgb(20 40 20 / 0.35), transparent 50%);\n `,\n stylesheetScoped: true\n};\nvar ForestMossThemePlugin = {\n manifest: {\n id: \"readergo.theme.forest-moss\",\n name: \"Forest Moss\",\n version: \"1.0.0\",\n description: \"Canopy-dark greens with lichen accents and Literata reading typography.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", { getThemes: () => [THEME] });\n await context.registerCapability(\"font-provider\", { getFonts: () => [LITERATA, SOURCE_SANS] });\n },\n deactivate() {\n }\n};\nvar index_default = ForestMossThemePlugin;\n\n\n return { ForestMossThemePlugin: ForestMossThemePlugin, default: index_default };\n}\n" diff --git a/public/theme-gruvbox.bundle.json b/public/theme-gruvbox.bundle.json index 5d938e0..0b17b44 100644 --- a/public/theme-gruvbox.bundle.json +++ b/public/theme-gruvbox.bundle.json @@ -4,7 +4,7 @@ "name": "Gruvbox Dark", "version": "1.0.0", "description": "Warm retro-groove dark theme with orange accents and IBM Plex Sans.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Retro warm · Dark · Earthy orange", + "tags": [ + "dark", + "warm", + "retro", + "earthy" + ], + "longDescription": "Classic Gruvbox Dark: warm earth tones, soft orange accents, IBM Plex Sans. Designed for long coding and reading sessions without cold blue glare.", + "preview": { + "background": "0 0% 16%", + "foreground": "43 59% 81%", + "card": "20 5% 22%", + "primary": "25 80% 55%", + "accent": "40 70% 55%", + "border": "20 5% 30%", + "muted": "20 5% 20%", + "type": "dark" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-gruvbox/src/index.ts\nvar IBM_PLEX = {\n id: \"ibm-plex-sans\",\n name: \"IBM Plex Sans\",\n family: \"'IBM Plex Sans', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap\",\n targets: [\"all\"]\n};\nvar THEME = {\n id: \"gruvbox-dark\",\n name: \"Gruvbox Dark\",\n type: \"dark\",\n author: \"Pavel Pertsev\",\n description: \"Earthy warm dark palette designed for long reading sessions without glare.\",\n colors: {\n background: \"0 0% 16%\",\n foreground: \"43 59% 81%\",\n card: \"20 5% 22%\",\n cardForeground: \"43 59% 81%\",\n border: \"20 6% 28%\",\n primary: \"27 99% 55%\",\n primaryForeground: \"0 0% 16%\",\n secondary: \"20 5% 22%\",\n secondaryForeground: \"43 59% 81%\",\n muted: \"20 5% 22%\",\n mutedForeground: \"34 24% 62%\",\n accent: \"61 66% 44%\",\n accentForeground: \"0 0% 16%\",\n destructive: \"6 74% 51%\",\n destructiveForeground: \"43 59% 81%\",\n success: \"80 61% 44%\",\n successForeground: \"0 0% 16%\",\n warning: \"42 87% 55%\",\n warningForeground: \"0 0% 16%\",\n info: \"157 16% 58%\",\n infoForeground: \"0 0% 16%\",\n input: \"20 5% 22%\",\n ring: \"27 99% 55%\",\n heading1: \"43 59% 81%\",\n heading2: \"27 99% 55%\",\n heading3: \"61 66% 50%\"\n },\n fonts: {\n display: IBM_PLEX,\n body: IBM_PLEX\n }\n};\nvar GruvboxThemePlugin = {\n manifest: {\n id: \"readergo.theme.gruvbox\",\n name: \"Gruvbox Dark\",\n version: \"1.0.0\",\n description: \"Warm retro-groove dark theme with orange accents and IBM Plex Sans.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => [THEME]\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => [IBM_PLEX]\n });\n context.log.info(\"Gruvbox Dark theme activated\");\n },\n deactivate(context) {\n context.log.info(\"Gruvbox Dark theme deactivated\");\n }\n};\nvar index_default = GruvboxThemePlugin;\n\n\n return { GruvboxThemePlugin: GruvboxThemePlugin, default: index_default };\n}\n" diff --git a/public/theme-newsprint.bundle.json b/public/theme-newsprint.bundle.json index 164d6a7..044ec1c 100644 --- a/public/theme-newsprint.bundle.json +++ b/public/theme-newsprint.bundle.json @@ -4,7 +4,7 @@ "name": "Newsprint", "version": "1.0.0", "description": "Stark editorial monochrome with hairline rules and Libre Baskerville / IBM Plex typography.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Editorial · Light · Monochrome broadsheet", + "tags": [ + "light", + "mono", + "editorial", + "print" + ], + "longDescription": "Stark broadsheet monochrome - India ink on cold paper, hairline rules, near-zero radius. Libre Baskerville for headlines and IBM Plex for UI. Feels like a newspaper layout tool.", + "preview": { + "background": "40 10% 96%", + "foreground": "0 0% 8%", + "card": "0 0% 100%", + "primary": "0 0% 10%", + "accent": "0 0% 22%", + "border": "0 0% 78%", + "muted": "40 6% 93%", + "type": "light" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-newsprint/src/index.ts\nvar BASKERVILLE = {\n id: \"libre-baskerville\",\n name: \"Libre Baskerville\",\n family: \"'Libre Baskerville', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar IBM_PLEX = {\n id: \"ibm-plex-sans-news\",\n name: \"IBM Plex Sans\",\n family: \"'IBM Plex Sans', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar IBM_MONO = {\n id: \"ibm-plex-mono-news\",\n name: \"IBM Plex Mono\",\n family: \"'IBM Plex Mono', ui-monospace, monospace\",\n category: \"mono\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap\",\n targets: [\"mono\"]\n};\nvar THEME = {\n id: \"newsprint\",\n name: \"Newsprint\",\n type: \"light\",\n author: \"ReaderGo Studio\",\n description: \"Broadsheet monochrome - India ink on cold paper, hairline borders, zero chrome glow.\",\n colors: {\n background: \"40 10% 96%\",\n foreground: \"0 0% 8%\",\n card: \"0 0% 100%\",\n cardForeground: \"0 0% 8%\",\n border: \"0 0% 78%\",\n primary: \"0 0% 10%\",\n primaryForeground: \"0 0% 98%\",\n secondary: \"40 8% 92%\",\n secondaryForeground: \"0 0% 12%\",\n muted: \"40 6% 93%\",\n mutedForeground: \"0 0% 38%\",\n accent: \"0 0% 22%\",\n accentForeground: \"0 0% 98%\",\n destructive: \"0 0% 20%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"0 0% 25%\",\n successForeground: \"0 0% 100%\",\n warning: \"0 0% 30%\",\n warningForeground: \"0 0% 100%\",\n info: \"0 0% 28%\",\n infoForeground: \"0 0% 100%\",\n input: \"0 0% 100%\",\n ring: \"0 0% 10%\",\n heading1: \"0 0% 5%\",\n heading2: \"0 0% 12%\",\n heading3: \"0 0% 18%\"\n },\n fonts: { display: BASKERVILLE, body: IBM_PLEX, editor: BASKERVILLE, mono: IBM_MONO },\n materials: {\n radius: \"0.15rem\",\n radiusSm: \"0.1rem\",\n radiusMd: \"0.12rem\",\n radiusLg: \"0.15rem\",\n radiusXl: \"0.2rem\",\n radius2xl: \"0.25rem\",\n surfaceBlur: \"0px\",\n shadowSm: \"none\",\n shadowMd: \"0 1px 0 rgb(0 0 0 / 0.08)\",\n shadowLg: \"0 2px 0 rgb(0 0 0 / 0.06)\",\n shadowXl: \"0 3px 0 rgb(0 0 0 / 0.05)\",\n insetHighlight: \"none\",\n insetShadow: \"none\",\n borderWidth: \"1px\"\n },\n stylesheet: `\n background-image:\n repeating-linear-gradient(\n 0deg,\n rgb(0 0 0 / 0.015) 0 1px,\n transparent 1px 4px\n );\n `,\n stylesheetScoped: true\n};\nvar NewsprintThemePlugin = {\n manifest: {\n id: \"readergo.theme.newsprint\",\n name: \"Newsprint\",\n version: \"1.0.0\",\n description: \"Stark editorial monochrome with hairline rules and Libre Baskerville / IBM Plex typography.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", { getThemes: () => [THEME] });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => [BASKERVILLE, IBM_PLEX, IBM_MONO]\n });\n },\n deactivate() {\n }\n};\nvar index_default = NewsprintThemePlugin;\n\n\n return { NewsprintThemePlugin: NewsprintThemePlugin, default: index_default };\n}\n" diff --git a/public/theme-nord.bundle.json b/public/theme-nord.bundle.json index 33d79e7..89083aa 100644 --- a/public/theme-nord.bundle.json +++ b/public/theme-nord.bundle.json @@ -4,7 +4,7 @@ "name": "Nord Frost Theme", "version": "1.0.0", "description": "Arctic, north-bluish palette engineered for calm focus and reduced eye strain.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Arctic · Dark · Frost cyan", + "tags": [ + "dark", + "nord", + "cool", + "calm" + ], + "longDescription": "Nord Frost arctic palette: north-bluish surfaces, cyan frost primary, mint accents. Clean Plus Jakarta Sans typography for calm, low-strain focus.", + "preview": { + "background": "220 16% 14%", + "foreground": "218 27% 92%", + "card": "222 16% 19%", + "primary": "193 43% 67%", + "accent": "179 25% 65%", + "border": "220 17% 28%", + "muted": "222 16% 19%", + "type": "dark" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-nord/src/index.ts\nvar JAKARTA_FONT = {\n id: \"plus-jakarta-sans\",\n name: \"Plus Jakarta Sans\",\n family: \"'Plus Jakarta Sans', sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap\",\n targets: [\"all\"]\n};\nvar NORD_THEME = {\n id: \"nord-frost\",\n name: \"Nord Frost\",\n type: \"dark\",\n author: \"Arctic Ice Studio\",\n description: \"An arctic, north-bluish palette engineered for calm focus with clean Plus Jakarta Sans typography.\",\n colors: {\n background: \"220 16% 14%\",\n // Nord 0 #2e3440\n foreground: \"218 27% 92%\",\n // Nord 6 #eceff4\n card: \"222 16% 19%\",\n // Nord 1 #3b4252\n cardForeground: \"218 27% 92%\",\n border: \"220 17% 28%\",\n // Nord 2 #434c5e\n primary: \"193 43% 67%\",\n // Nord 8 #88c0d0 Frost Cyan\n primaryForeground: \"220 16% 14%\",\n secondary: \"220 16% 22%\",\n // Nord 2\n secondaryForeground: \"218 27% 92%\",\n muted: \"222 16% 19%\",\n mutedForeground: \"219 14% 65%\",\n // Nord 4 #d8dee9\n accent: \"179 25% 65%\",\n // Nord 7 #8fbcbb Phosphor Mint\n accentForeground: \"220 16% 14%\",\n destructive: \"354 42% 56%\",\n // Nord 11 #bf616a Aurora Red\n destructiveForeground: \"218 27% 92%\",\n success: \"92 28% 65%\",\n // Nord 14 #a3be8c Aurora Green\n successForeground: \"220 16% 14%\",\n warning: \"40 71% 73%\",\n // Nord 13 #ebcb8b Aurora Yellow\n warningForeground: \"220 16% 14%\",\n info: \"193 43% 67%\",\n // Nord 8 #88c0d0 Frost Cyan\n infoForeground: \"220 16% 14%\",\n input: \"222 16% 19%\",\n ring: \"193 43% 67%\",\n heading1: \"193 43% 75%\",\n heading2: \"213 32% 72%\",\n heading3: \"179 25% 72%\"\n },\n fonts: {\n display: JAKARTA_FONT,\n body: JAKARTA_FONT\n }\n};\nvar NordThemePlugin = {\n manifest: {\n id: \"readergo.theme.nord\",\n name: \"Nord Frost Theme\",\n version: \"1.1.0\",\n description: \"Arctic, north-bluish clean palette engineered for calm focus with Plus Jakarta Sans typography.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(\"\\u2744\\uFE0F Nord Frost theme plugin activating with typography...\");\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => [NORD_THEME]\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => [JAKARTA_FONT]\n });\n },\n deactivate(context) {\n context.log.info(\"\\u2744\\uFE0F Nord Frost theme plugin deactivated.\");\n }\n};\nvar index_default = NordThemePlugin;\n\n\n return { NordThemePlugin: NordThemePlugin, default: index_default };\n}\n" diff --git a/public/theme-rose-pine.bundle.json b/public/theme-rose-pine.bundle.json index 79a59f2..7980490 100644 --- a/public/theme-rose-pine.bundle.json +++ b/public/theme-rose-pine.bundle.json @@ -4,7 +4,7 @@ "name": "Rosé Pine", "version": "1.0.0", "description": "All natural pine, faux fur and a bit of soho vibes for the classy minimalist. Instrument Serif headings.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Poetic · Dark · Rose pine", + "tags": [ + "dark", + "soft", + "rose", + "serif" + ], + "longDescription": "Rose Pine natural dark with soft rose accents and Instrument Serif display type. A quieter, literary alternative to high-contrast neon themes.", + "preview": { + "background": "249 22% 12%", + "foreground": "245 50% 91%", + "card": "247 23% 15%", + "primary": "2 55% 75%", + "accent": "197 49% 65%", + "border": "248 15% 25%", + "muted": "247 15% 18%", + "type": "dark" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-rose-pine/src/index.ts\nvar INSTRUMENT = {\n id: \"instrument-serif\",\n name: \"Instrument Serif\",\n family: \"'Instrument Serif', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar INTER = {\n id: \"inter-ui\",\n name: \"Inter\",\n family: \"'Inter', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap\",\n targets: [\"body\"]\n};\nvar THEME = {\n id: \"rose-pine\",\n name: \"Rose Pine\",\n type: \"dark\",\n author: \"Ros\\xE9 Pine\",\n description: \"Muted pine and rose palette for a calm, classy reading room.\",\n colors: {\n background: \"249 22% 12%\",\n foreground: \"245 50% 91%\",\n card: \"247 23% 15%\",\n cardForeground: \"245 50% 91%\",\n border: \"248 15% 22%\",\n primary: \"2 55% 83%\",\n primaryForeground: \"249 22% 12%\",\n secondary: \"247 23% 15%\",\n secondaryForeground: \"245 50% 91%\",\n muted: \"247 23% 15%\",\n mutedForeground: \"249 12% 47%\",\n accent: \"189 43% 73%\",\n accentForeground: \"249 22% 12%\",\n destructive: \"343 76% 68%\",\n destructiveForeground: \"245 50% 91%\",\n success: \"197 49% 38%\",\n successForeground: \"245 50% 91%\",\n warning: \"35 88% 80%\",\n warningForeground: \"249 22% 12%\",\n info: \"267 57% 78%\",\n infoForeground: \"249 22% 12%\",\n input: \"247 23% 15%\",\n ring: \"2 55% 83%\",\n heading1: \"2 55% 83%\",\n heading2: \"189 43% 73%\",\n heading3: \"267 57% 78%\"\n },\n fonts: {\n display: INSTRUMENT,\n body: INTER,\n editor: INSTRUMENT\n }\n};\nvar RosePineThemePlugin = {\n manifest: {\n id: \"readergo.theme.rose-pine\",\n name: \"Rose Pine\",\n version: \"1.0.0\",\n description: \"All natural pine, faux fur and a bit of soho vibes for the classy minimalist. Instrument Serif headings.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => [THEME]\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => [INSTRUMENT, INTER]\n });\n context.log.info(\"Rose Pine theme activated\");\n },\n deactivate(context) {\n context.log.info(\"Rose Pine theme deactivated\");\n }\n};\nvar index_default = RosePineThemePlugin;\n\n\n return { RosePineThemePlugin: RosePineThemePlugin, default: index_default };\n}\n" diff --git a/public/theme-sakura-ink.bundle.json b/public/theme-sakura-ink.bundle.json index a503e41..adc7760 100644 --- a/public/theme-sakura-ink.bundle.json +++ b/public/theme-sakura-ink.bundle.json @@ -4,7 +4,7 @@ "name": "Sakura Ink", "version": "1.0.0", "description": "Light ink-wash workspace with cherry blossom accents and Shippori Mincho headings.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Ink wash · Light · Sakura accents", + "tags": [ + "light", + "japanese", + "ink", + "serif" + ], + "longDescription": "Paper-white ink wash with soft sakura pink signals and Shippori Mincho headings. Scholarly light theme for prose and notes without cream-terracotta clichés.", + "preview": { + "background": "0 0% 98%", + "foreground": "220 20% 16%", + "card": "0 0% 100%", + "primary": "340 55% 48%", + "accent": "200 35% 42%", + "border": "340 12% 88%", + "muted": "220 10% 95%", + "type": "light" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-sakura-ink/src/index.ts\nvar SHIPPORI = {\n id: \"shippori-mincho\",\n name: \"Shippori Mincho\",\n family: \"'Shippori Mincho', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Shippori+Mincho:wght@400;600;700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar NOTO_SANS = {\n id: \"noto-sans-jp-ui\",\n name: \"Noto Sans\",\n family: \"'Noto Sans', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar THEME = {\n id: \"sakura-ink\",\n name: \"Sakura Ink\",\n type: \"light\",\n author: \"ReaderGo Studio\",\n description: \"Paper-white ink wash with soft sakura pink signals and scholarly serif headings.\",\n colors: {\n background: \"0 0% 98%\",\n foreground: \"220 20% 16%\",\n card: \"0 0% 100%\",\n cardForeground: \"220 20% 16%\",\n border: \"340 12% 88%\",\n primary: \"340 55% 48%\",\n primaryForeground: \"0 0% 100%\",\n secondary: \"340 20% 95%\",\n secondaryForeground: \"220 18% 22%\",\n muted: \"220 10% 95%\",\n mutedForeground: \"220 8% 42%\",\n accent: \"200 35% 42%\",\n accentForeground: \"0 0% 100%\",\n destructive: \"4 70% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 40% 36%\",\n successForeground: \"0 0% 100%\",\n warning: \"32 70% 42%\",\n warningForeground: \"0 0% 100%\",\n info: \"200 40% 42%\",\n infoForeground: \"0 0% 100%\",\n input: \"0 0% 97%\",\n ring: \"340 55% 48%\",\n heading1: \"340 50% 38%\",\n heading2: \"220 25% 28%\",\n heading3: \"200 30% 36%\"\n },\n fonts: { display: SHIPPORI, body: NOTO_SANS, editor: SHIPPORI, mono: NOTO_SANS },\n materials: {\n radius: \"0.4rem\",\n radius2xl: \"0.75rem\",\n surfaceBlur: \"0px\",\n shadowMd: \"0 2px 10px rgb(40 20 30 / 0.06)\",\n insetShadow: \"inset 0 1px 2px rgb(40 20 30 / 0.05)\"\n },\n stylesheet: `\n background-image:\n radial-gradient(ellipse at 90% 5%, rgb(255 180 200 / 0.18), transparent 40%),\n radial-gradient(ellipse at 10% 90%, rgb(180 210 230 / 0.12), transparent 45%);\n `,\n stylesheetScoped: true\n};\nvar SakuraInkThemePlugin = {\n manifest: {\n id: \"readergo.theme.sakura-ink\",\n name: \"Sakura Ink\",\n version: \"1.0.0\",\n description: \"Light ink-wash workspace with cherry blossom accents and Shippori Mincho headings.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", { getThemes: () => [THEME] });\n await context.registerCapability(\"font-provider\", { getFonts: () => [SHIPPORI, NOTO_SANS] });\n },\n deactivate() {\n }\n};\nvar index_default = SakuraInkThemePlugin;\n\n\n return { SakuraInkThemePlugin: SakuraInkThemePlugin, default: index_default };\n}\n" diff --git a/public/theme-skeuomorph.bundle.json b/public/theme-skeuomorph.bundle.json index 7618b0b..d8836b4 100644 --- a/public/theme-skeuomorph.bundle.json +++ b/public/theme-skeuomorph.bundle.json @@ -4,7 +4,7 @@ "name": "Skeuomorph Suite", "version": "1.2.0", "description": "Eight physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, and Brass Console.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Skeuomorphic · Suite · Physical chrome", + "tags": [ + "skeuomorph", + "materials", + "suite", + "physical" + ], + "longDescription": "Eight physical atmospheres (Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, Brass Console). Uses materials tokens and scoped grain stylesheets for embossed cards, recessed trays, and a tactile activity rail.", + "preview": { + "background": "25 28% 12%", + "foreground": "36 40% 88%", + "card": "25 24% 16%", + "primary": "36 55% 48%", + "accent": "36 55% 48%", + "border": "30 22% 28%", + "muted": "25 16% 18%", + "type": "dark" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-skeuomorph/src/chrome.ts\nvar ACTIVITY_BAR_CHROME = `\n /* Outer rail: darker recessed channel with a hard metal/leather edge */\n [data-rg-chrome=\"activity-bar\"] {\n background-color: hsl(var(--background));\n background-image:\n linear-gradient(90deg, rgb(0 0 0 / 0.28), transparent 55%),\n linear-gradient(180deg, rgb(255 255 255 / 0.04), transparent 30%);\n border-right-color: hsl(var(--border));\n border-right-width: 1px;\n box-shadow:\n inset -1px 0 0 rgb(255 255 255 / 0.06),\n inset 2px 0 6px rgb(0 0 0 / 0.35),\n 2px 0 10px rgb(0 0 0 / 0.25);\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n\n [data-rg-chrome=\"activity-panel\"] {\n background-color: hsl(var(--card));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.05), transparent 28%),\n linear-gradient(90deg, rgb(0 0 0 / 0.12), transparent 40%);\n box-shadow: var(--inset-shadow), 4px 0 18px rgb(0 0 0 / 0.2);\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n\n [data-rg-chrome=\"activity-bottom\"] {\n border-top-color: hsl(var(--border));\n box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.06);\n }\n\n /* Brand plate at the top of the rail */\n [data-rg-chrome=\"activity-brand\"] {\n margin: 0.35rem 0.35rem 0.15rem;\n width: calc(3rem - 0.7rem) !important;\n height: 2.75rem !important;\n border-radius: var(--radius-md);\n border: 1px solid hsl(var(--border));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.1), transparent 55%),\n linear-gradient(0deg, rgb(0 0 0 / 0.2), transparent 40%);\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n }\n\n [data-rg-chrome=\"activity-brand\"]:hover {\n background-color: hsl(var(--muted));\n }\n\n /* Icon wells - physical buttons sitting in the channel */\n [data-rg-chrome=\"activity-item\"],\n [data-rg-chrome=\"activity-collapse\"] {\n margin: 0.15rem 0.35rem;\n width: calc(3rem - 0.7rem) !important;\n height: calc(3rem - 0.55rem) !important;\n border-radius: var(--radius-md);\n border: 1px solid transparent;\n background-image: linear-gradient(180deg, rgb(255 255 255 / 0.03), transparent 60%);\n }\n\n [data-rg-chrome=\"activity-item\"]:hover,\n [data-rg-chrome=\"activity-collapse\"]:hover {\n border-color: hsl(var(--border));\n background-color: hsl(var(--muted));\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.1), transparent 50%),\n linear-gradient(0deg, rgb(0 0 0 / 0.15), transparent 40%);\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n color: hsl(var(--foreground));\n }\n\n /* Active tool - pressed / latched into the rail */\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"] {\n border-color: hsl(var(--primary) / 0.45);\n background-color: hsl(var(--primary) / 0.16);\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 45%),\n linear-gradient(0deg, rgb(0 0 0 / 0.28), transparent 50%);\n box-shadow:\n var(--inset-shadow),\n 0 0 0 1px hsl(var(--primary) / 0.2),\n inset 0 0 10px hsl(var(--primary) / 0.12);\n color: hsl(var(--primary));\n }\n\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"]:hover {\n background-color: hsl(var(--primary) / 0.2);\n }\n\n /* Inlaid active indicator - brass/LED strip instead of a flat bar */\n [data-rg-chrome=\"activity-indicator\"] {\n left: 0.1rem !important;\n width: 3px !important;\n border-radius: 999px;\n box-shadow:\n 0 0 6px hsl(var(--primary) / 0.55),\n inset 0 1px 0 rgb(255 255 255 / 0.35);\n }\n\n [data-rg-chrome=\"activity-item\"][data-rg-active=\"true\"] [data-rg-chrome=\"activity-indicator\"] {\n opacity: 1 !important;\n background: linear-gradient(\n 180deg,\n hsl(var(--primary)),\n hsl(var(--primary) / 0.65)\n ) !important;\n }\n`;\nvar SHARED_CHROME = `\n ${ACTIVITY_BAR_CHROME}\n\n /* Recessed trays (inspector / misc side rails) */\n aside,\n [data-sidebar],\n nav[aria-label] {\n box-shadow: var(--inset-shadow);\n }\n\n /* Embossed cards / popovers */\n .bg-card,\n .bg-card\\\\/40,\n .bg-card\\\\/50,\n .bg-card\\\\/60,\n .bg-card\\\\/70,\n .bg-card\\\\/75,\n .bg-card\\\\/80,\n .bg-card\\\\/85,\n .bg-popover,\n .bg-popover\\\\/95 {\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.08), transparent 42%),\n linear-gradient(0deg, rgb(0 0 0 / 0.14), transparent 38%);\n box-shadow: var(--inset-highlight), var(--shadow-md);\n border-color: hsl(var(--border));\n }\n\n /* Raised actuators - skip activity-bar items (styled above) */\n button:not([data-rg-chrome^=\"activity\"]),\n [role=\"button\"]:not([data-rg-chrome^=\"activity\"]),\n .bg-primary {\n box-shadow: var(--inset-highlight), var(--shadow-sm);\n }\n\n button:not([data-rg-chrome^=\"activity\"]):active,\n [role=\"button\"]:not([data-rg-chrome^=\"activity\"]):active {\n box-shadow: var(--inset-shadow);\n transform: translateY(1px);\n }\n\n /* Recessed fields */\n input,\n textarea,\n select,\n [data-slot=\"input\"] {\n box-shadow: var(--inset-shadow);\n background-image: linear-gradient(180deg, rgb(0 0 0 / 0.1), transparent 55%);\n }\n\n /* Hairline metal/leather edge on focus */\n button:focus-visible,\n [role=\"button\"]:focus-visible,\n a:focus-visible,\n input:focus-visible,\n textarea:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n }\n\n /* Kill glass - materials already zero blur; keep surfaces opaque */\n .backdrop-blur-sm,\n .backdrop-blur,\n .backdrop-blur-md,\n .backdrop-blur-lg,\n .backdrop-blur-xl,\n .backdrop-blur-2xl,\n .backdrop-blur-3xl {\n -webkit-backdrop-filter: none !important;\n backdrop-filter: none !important;\n }\n`;\nvar LEATHER_GRAIN = `\n background-image:\n radial-gradient(ellipse at 18% 8%, rgb(140 80 45 / 0.22), transparent 42%),\n radial-gradient(ellipse at 82% 92%, rgb(30 14 8 / 0.35), transparent 48%),\n repeating-linear-gradient(\n 118deg,\n rgb(255 230 180 / 0.025) 0 1px,\n transparent 1px 4px\n ),\n repeating-linear-gradient(\n 28deg,\n rgb(0 0 0 / 0.04) 0 2px,\n transparent 2px 5px\n );\n`;\nvar STEEL_BRUSH = `\n background-image:\n linear-gradient(180deg, rgb(255 255 255 / 0.06), transparent 35%),\n repeating-linear-gradient(\n 90deg,\n rgb(255 255 255 / 0.035) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 0deg,\n rgb(0 0 0 / 0.04) 0 1px,\n transparent 1px 2px\n );\n`;\nvar JOURNAL_FIBER = `\n background-image:\n radial-gradient(ellipse at 50% 0%, rgb(255 255 255 / 0.55), transparent 55%),\n repeating-linear-gradient(\n 0deg,\n rgb(40 30 20 / 0.03) 0 1px,\n transparent 1px 3px\n ),\n repeating-linear-gradient(\n 90deg,\n rgb(40 30 20 / 0.02) 0 1px,\n transparent 1px 4px\n );\n`;\nvar WALNUT_GRAIN = `\n background-image:\n radial-gradient(ellipse at 30% 20%, rgb(160 100 50 / 0.15), transparent 50%),\n repeating-linear-gradient(\n 95deg,\n rgb(255 210 150 / 0.03) 0 2px,\n transparent 2px 7px\n ),\n repeating-linear-gradient(\n 5deg,\n rgb(0 0 0 / 0.06) 0 1px,\n transparent 1px 6px\n );\n`;\nvar PORCELAIN_GLOSS = `\n background-image:\n radial-gradient(ellipse at 20% 0%, rgb(255 255 255 / 0.9), transparent 45%),\n radial-gradient(ellipse at 80% 100%, rgb(180 200 220 / 0.18), transparent 50%),\n linear-gradient(180deg, rgb(255 255 255 / 0.35), transparent 40%);\n`;\nvar LACQUER_SHEEN = `\n background-image:\n radial-gradient(ellipse at 15% 10%, rgb(180 40 40 / 0.22), transparent 40%),\n radial-gradient(ellipse at 85% 90%, rgb(0 0 0 / 0.45), transparent 45%),\n linear-gradient(135deg, rgb(255 200 160 / 0.05), transparent 40%),\n repeating-linear-gradient(\n 120deg,\n rgb(255 255 255 / 0.02) 0 1px,\n transparent 1px 5px\n );\n`;\nvar DENIM_TWILL = `\n background-image:\n repeating-linear-gradient(\n 45deg,\n rgb(255 255 255 / 0.03) 0 1px,\n transparent 1px 4px\n ),\n repeating-linear-gradient(\n -45deg,\n rgb(0 0 0 / 0.05) 0 1px,\n transparent 1px 4px\n ),\n radial-gradient(ellipse at 50% 0%, rgb(100 140 200 / 0.12), transparent 55%);\n`;\nvar BRASS_PATINA = `\n background-image:\n radial-gradient(ellipse at 25% 15%, rgb(220 170 80 / 0.14), transparent 45%),\n radial-gradient(ellipse at 75% 85%, rgb(40 25 10 / 0.35), transparent 50%),\n repeating-linear-gradient(\n 92deg,\n rgb(255 210 120 / 0.04) 0 1px,\n transparent 1px 3px\n );\n`;\n\n// plugins/theme-skeuomorph/src/themes.ts\nvar FRAUNCES = {\n id: \"fraunces-display\",\n name: \"Fraunces\",\n family: \"'Fraunces', 'Georgia', serif\",\n category: \"display\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-3\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\", \"all\"]\n};\nvar IBM_PLEX_MONO = {\n id: \"ibm-plex-mono-steel\",\n name: \"IBM Plex Mono\",\n family: \"'IBM Plex Mono', ui-monospace, monospace\",\n category: \"mono\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap\",\n targets: [\"mono\"]\n};\nvar LITERATA = {\n id: \"literata-journal\",\n name: \"Literata\",\n family: \"'Literata', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;0,7..72,700;1,7..72,400&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SKEUO_FONTS = [FRAUNCES, SOURCE_SANS, IBM_PLEX_MONO, LITERATA];\nvar PHYSICAL_MATERIALS_BASE = {\n surfaceBlur: \"0px\",\n borderWidth: \"1px\"\n};\nvar LEATHER_DESK_THEME = {\n id: \"leather-desk\",\n name: \"Leather Desk\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Walnut blotter and brass actuators - embossed cards, recessed trays, leather grain.\",\n colors: {\n background: \"25 28% 12%\",\n foreground: \"36 40% 88%\",\n card: \"25 24% 16%\",\n cardForeground: \"36 40% 88%\",\n border: \"30 22% 28%\",\n primary: \"36 55% 48%\",\n primaryForeground: \"25 40% 10%\",\n secondary: \"25 18% 20%\",\n secondaryForeground: \"36 30% 82%\",\n muted: \"25 16% 18%\",\n mutedForeground: \"30 14% 58%\",\n accent: \"36 55% 48%\",\n accentForeground: \"25 40% 10%\",\n destructive: \"6 70% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"142 40% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 48%\",\n warningForeground: \"25 40% 10%\",\n info: \"200 40% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"25 22% 14%\",\n ring: \"36 55% 52%\",\n heading1: \"36 60% 72%\",\n heading2: \"34 45% 66%\",\n heading3: \"32 35% 60%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: SOURCE_SANS\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.65rem\",\n radiusSm: \"0.4rem\",\n radiusMd: \"0.5rem\",\n radiusLg: \"0.65rem\",\n radiusXl: \"0.85rem\",\n radius2xl: \"1rem\",\n shadowSm: \"0 1px 0 rgb(255 220 160 / 0.12), 0 1px 2px rgb(0 0 0 / 0.45)\",\n shadowMd: \"0 1px 0 rgb(255 220 160 / 0.1), 0 4px 10px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 1px 0 rgb(255 220 160 / 0.08), 0 12px 28px rgb(0 0 0 / 0.5), 0 4px 10px rgb(0 0 0 / 0.35)\",\n shadowXl: \"0 22px 40px rgb(0 0 0 / 0.55), 0 8px 16px rgb(0 0 0 / 0.4)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 230 180 / 0.22)\",\n insetShadow: \"inset 0 2px 4px rgb(0 0 0 / 0.45), inset 0 1px 0 rgb(0 0 0 / 0.25)\"\n },\n stylesheet: `${LEATHER_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BRUSHED_STEEL_THEME = {\n id: \"brushed-steel\",\n name: \"Brushed Steel\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Cold instrument panel - machined aluminum grain, tight radii, cyan status LEDs.\",\n colors: {\n background: \"210 12% 14%\",\n foreground: \"210 20% 92%\",\n card: \"210 10% 18%\",\n cardForeground: \"210 20% 92%\",\n border: \"210 8% 32%\",\n primary: \"198 72% 48%\",\n primaryForeground: \"210 30% 8%\",\n secondary: \"210 10% 22%\",\n secondaryForeground: \"210 15% 85%\",\n muted: \"210 8% 20%\",\n mutedForeground: \"210 8% 58%\",\n accent: \"198 72% 48%\",\n accentForeground: \"210 30% 8%\",\n destructive: \"0 65% 50%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 45% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 85% 50%\",\n warningForeground: \"210 30% 8%\",\n info: \"198 72% 52%\",\n infoForeground: \"210 30% 8%\",\n input: \"210 12% 16%\",\n ring: \"198 72% 52%\",\n heading1: \"198 70% 72%\",\n heading2: \"200 45% 68%\",\n heading3: \"205 30% 64%\"\n },\n fonts: {\n display: SOURCE_SANS,\n body: SOURCE_SANS,\n editor: SOURCE_SANS,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.35rem\",\n radiusSm: \"0.2rem\",\n radiusMd: \"0.28rem\",\n radiusLg: \"0.35rem\",\n radiusXl: \"0.45rem\",\n radius2xl: \"0.55rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.14), 0 1px 2px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.1), 0 3px 8px rgb(0 0 0 / 0.45), inset 0 -1px 0 rgb(0 0 0 / 0.25)\",\n shadowLg: \"0 10px 24px rgb(0 0 0 / 0.5), 0 1px 0 rgb(255 255 255 / 0.08)\",\n shadowXl: \"0 18px 36px rgb(0 0 0 / 0.55)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.28)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.55), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${STEEL_BRUSH}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BOUND_JOURNAL_THEME = {\n id: \"bound-journal\",\n name: \"Bound Journal\",\n type: \"light\",\n author: \"ReaderGo Materials\",\n description: \"Cloth-bound notebook - inked linen fiber, soft pressed pages, midnight ink accents.\",\n colors: {\n background: \"40 18% 93%\",\n foreground: \"220 25% 16%\",\n card: \"40 22% 97%\",\n cardForeground: \"220 25% 16%\",\n border: \"35 12% 78%\",\n primary: \"222 35% 28%\",\n primaryForeground: \"40 30% 96%\",\n secondary: \"38 14% 88%\",\n secondaryForeground: \"220 20% 22%\",\n muted: \"38 12% 90%\",\n mutedForeground: \"220 10% 42%\",\n accent: \"160 28% 32%\",\n accentForeground: \"40 30% 96%\",\n destructive: \"4 65% 42%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 35% 32%\",\n successForeground: \"0 0% 100%\",\n warning: \"32 70% 38%\",\n warningForeground: \"0 0% 100%\",\n info: \"210 40% 38%\",\n infoForeground: \"0 0% 100%\",\n input: \"40 20% 95%\",\n ring: \"222 35% 32%\",\n heading1: \"222 40% 22%\",\n heading2: \"220 28% 28%\",\n heading3: \"218 20% 34%\"\n },\n fonts: {\n display: LITERATA,\n body: SOURCE_SANS,\n editor: LITERATA,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.55rem\",\n radiusSm: \"0.35rem\",\n radiusMd: \"0.45rem\",\n radiusLg: \"0.55rem\",\n radiusXl: \"0.7rem\",\n radius2xl: \"0.85rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.85), 0 1px 2px rgb(40 30 20 / 0.12)\",\n shadowMd: \"0 1px 0 rgb(255 255 255 / 0.9), 0 4px 12px rgb(40 30 20 / 0.12), 0 1px 3px rgb(40 30 20 / 0.08)\",\n shadowLg: \"0 12px 28px rgb(40 30 20 / 0.14), 0 2px 6px rgb(40 30 20 / 0.08)\",\n shadowXl: \"0 20px 40px rgb(40 30 20 / 0.16)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.95)\",\n insetShadow: \"inset 0 2px 4px rgb(40 30 20 / 0.12), inset 0 1px 0 rgb(40 30 20 / 0.06)\"\n },\n stylesheet: `${JOURNAL_FIBER}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar WALNUT_LIBRARY_THEME = {\n id: \"walnut-library\",\n name: \"Walnut Library\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Deep library shelves - warm wood grain, amber lamps, wide embossed panels.\",\n colors: {\n background: \"28 32% 10%\",\n foreground: \"38 35% 86%\",\n card: \"28 28% 14%\",\n cardForeground: \"38 35% 86%\",\n border: \"32 24% 24%\",\n primary: \"32 70% 46%\",\n primaryForeground: \"28 40% 8%\",\n secondary: \"28 22% 18%\",\n secondaryForeground: \"38 28% 80%\",\n muted: \"28 20% 15%\",\n mutedForeground: \"32 16% 52%\",\n accent: \"150 35% 40%\",\n accentForeground: \"28 40% 8%\",\n destructive: \"8 68% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"150 35% 40%\",\n successForeground: \"0 0% 100%\",\n warning: \"36 78% 48%\",\n warningForeground: \"28 40% 8%\",\n info: \"200 35% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"28 26% 12%\",\n ring: \"32 70% 50%\",\n heading1: \"38 55% 70%\",\n heading2: \"34 42% 64%\",\n heading3: \"30 32% 58%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.75rem\",\n radiusSm: \"0.45rem\",\n radiusMd: \"0.55rem\",\n radiusLg: \"0.75rem\",\n radiusXl: \"1rem\",\n radius2xl: \"1.15rem\",\n shadowSm: \"0 1px 0 rgb(255 200 120 / 0.1), 0 1px 3px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 200 120 / 0.08), 0 6px 14px rgb(0 0 0 / 0.45), 0 2px 4px rgb(0 0 0 / 0.35)\",\n shadowLg: \"0 14px 32px rgb(0 0 0 / 0.55), 0 4px 10px rgb(0 0 0 / 0.4)\",\n shadowXl: \"0 24px 48px rgb(0 0 0 / 0.6)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 210 140 / 0.18)\",\n insetShadow: \"inset 0 3px 6px rgb(0 0 0 / 0.5), inset 0 1px 0 rgb(0 0 0 / 0.3)\"\n },\n stylesheet: `${WALNUT_GRAIN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar SOFT_PORCELAIN_THEME = {\n id: \"soft-porcelain\",\n name: \"Soft Porcelain\",\n type: \"light\",\n author: \"ReaderGo Materials\",\n description: \"Glazed ceramic workspace - soft gloss plates, cool slate ink, pillowy radius.\",\n colors: {\n background: \"210 25% 96%\",\n foreground: \"220 28% 18%\",\n card: \"0 0% 100%\",\n cardForeground: \"220 28% 18%\",\n border: \"210 16% 84%\",\n primary: \"205 55% 42%\",\n primaryForeground: \"0 0% 100%\",\n secondary: \"210 18% 92%\",\n secondaryForeground: \"220 22% 24%\",\n muted: \"210 16% 93%\",\n mutedForeground: \"215 12% 46%\",\n accent: \"340 45% 48%\",\n accentForeground: \"0 0% 100%\",\n destructive: \"4 70% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 40% 36%\",\n successForeground: \"0 0% 100%\",\n warning: \"32 75% 42%\",\n warningForeground: \"0 0% 100%\",\n info: \"205 55% 44%\",\n infoForeground: \"0 0% 100%\",\n input: \"210 20% 97%\",\n ring: \"205 55% 44%\",\n heading1: \"220 35% 22%\",\n heading2: \"215 28% 28%\",\n heading3: \"210 22% 34%\"\n },\n fonts: {\n display: SOURCE_SANS,\n body: SOURCE_SANS,\n editor: SOURCE_SANS,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.9rem\",\n radiusSm: \"0.5rem\",\n radiusMd: \"0.7rem\",\n radiusLg: \"0.9rem\",\n radiusXl: \"1.1rem\",\n radius2xl: \"1.35rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.95), 0 1px 3px rgb(40 60 90 / 0.08)\",\n shadowMd: \"0 1px 0 rgb(255 255 255), 0 6px 16px rgb(40 60 90 / 0.1), 0 2px 4px rgb(40 60 90 / 0.06)\",\n shadowLg: \"0 14px 32px rgb(40 60 90 / 0.12)\",\n shadowXl: \"0 22px 44px rgb(40 60 90 / 0.14)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255)\",\n insetShadow: \"inset 0 2px 4px rgb(40 60 90 / 0.08)\"\n },\n stylesheet: `${PORCELAIN_GLOSS}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar CINNABAR_LACQUER_THEME = {\n id: \"cinnabar-lacquer\",\n name: \"Cinnabar Lacquer\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Deep lacquer trays with cinnabar accents - glossy sheen, tight metal radius, gold edge light.\",\n colors: {\n background: \"0 35% 8%\",\n foreground: \"30 30% 90%\",\n card: \"0 28% 12%\",\n cardForeground: \"30 30% 90%\",\n border: \"8 30% 22%\",\n primary: \"6 72% 46%\",\n primaryForeground: \"30 40% 96%\",\n secondary: \"0 20% 16%\",\n secondaryForeground: \"30 25% 82%\",\n muted: \"0 18% 14%\",\n mutedForeground: \"20 12% 55%\",\n accent: \"38 70% 48%\",\n accentForeground: \"0 40% 8%\",\n destructive: \"0 75% 48%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"145 35% 40%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 48%\",\n warningForeground: \"0 40% 8%\",\n info: \"200 40% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"0 24% 10%\",\n ring: \"6 72% 50%\",\n heading1: \"38 65% 68%\",\n heading2: \"20 50% 64%\",\n heading3: \"8 40% 60%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: FRAUNCES,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.4rem\",\n radiusSm: \"0.25rem\",\n radiusMd: \"0.35rem\",\n radiusLg: \"0.4rem\",\n radiusXl: \"0.55rem\",\n radius2xl: \"0.7rem\",\n shadowSm: \"0 1px 0 rgb(255 180 120 / 0.12), 0 1px 3px rgb(0 0 0 / 0.55)\",\n shadowMd: \"0 1px 0 rgb(255 180 120 / 0.1), 0 5px 14px rgb(0 0 0 / 0.5), 0 2px 4px rgb(80 0 0 / 0.25)\",\n shadowLg: \"0 14px 30px rgb(0 0 0 / 0.55)\",\n shadowXl: \"0 22px 44px rgb(0 0 0 / 0.6)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 200 160 / 0.2)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.55)\"\n },\n stylesheet: `${LACQUER_SHEEN}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar DENIM_BENCH_THEME = {\n id: \"denim-bench\",\n name: \"Denim Bench\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Indigo workbench with twill texture - copper rivets, stitched borders, utility chrome.\",\n colors: {\n background: \"218 28% 14%\",\n foreground: \"210 25% 92%\",\n card: \"218 24% 18%\",\n cardForeground: \"210 25% 92%\",\n border: \"214 20% 30%\",\n primary: \"28 65% 52%\",\n primaryForeground: \"218 40% 10%\",\n secondary: \"218 20% 22%\",\n secondaryForeground: \"210 20% 85%\",\n muted: \"218 18% 20%\",\n mutedForeground: \"214 14% 58%\",\n accent: \"28 65% 52%\",\n accentForeground: \"218 40% 10%\",\n destructive: \"4 70% 50%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"152 40% 42%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 80% 50%\",\n warningForeground: \"218 40% 10%\",\n info: \"200 55% 52%\",\n infoForeground: \"218 40% 10%\",\n input: \"218 22% 16%\",\n ring: \"28 65% 54%\",\n heading1: \"28 70% 68%\",\n heading2: \"210 40% 78%\",\n heading3: \"214 30% 70%\"\n },\n fonts: {\n display: SOURCE_SANS,\n body: SOURCE_SANS,\n editor: SOURCE_SANS,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.5rem\",\n radiusSm: \"0.3rem\",\n radiusMd: \"0.4rem\",\n radiusLg: \"0.5rem\",\n radiusXl: \"0.65rem\",\n radius2xl: \"0.8rem\",\n shadowSm: \"0 1px 0 rgb(255 255 255 / 0.08), 0 1px 3px rgb(0 0 0 / 0.45)\",\n shadowMd: \"0 1px 0 rgb(255 200 140 / 0.08), 0 5px 12px rgb(0 0 0 / 0.4), 0 2px 4px rgb(0 20 60 / 0.3)\",\n shadowLg: \"0 12px 28px rgb(0 0 0 / 0.5)\",\n shadowXl: \"0 20px 40px rgb(0 0 0 / 0.55)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 255 255 / 0.14)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.5)\"\n },\n stylesheet: `${DENIM_TWILL}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar BRASS_CONSOLE_THEME = {\n id: \"brass-console\",\n name: \"Brass Console\",\n type: \"dark\",\n author: \"ReaderGo Materials\",\n description: \"Warm instrument console - oxidized brass bezels, olive panels, engraved mono telemetry.\",\n colors: {\n background: \"40 18% 11%\",\n foreground: \"42 35% 86%\",\n card: \"40 16% 15%\",\n cardForeground: \"42 35% 86%\",\n border: \"38 22% 26%\",\n primary: \"42 62% 48%\",\n primaryForeground: \"40 40% 8%\",\n secondary: \"80 12% 18%\",\n secondaryForeground: \"42 28% 80%\",\n muted: \"40 12% 16%\",\n mutedForeground: \"40 12% 54%\",\n accent: \"80 30% 40%\",\n accentForeground: \"42 40% 92%\",\n destructive: \"8 68% 46%\",\n destructiveForeground: \"0 0% 100%\",\n success: \"80 35% 40%\",\n successForeground: \"0 0% 100%\",\n warning: \"38 75% 48%\",\n warningForeground: \"40 40% 8%\",\n info: \"195 35% 48%\",\n infoForeground: \"0 0% 100%\",\n input: \"40 14% 13%\",\n ring: \"42 62% 50%\",\n heading1: \"42 60% 68%\",\n heading2: \"80 25% 62%\",\n heading3: \"40 30% 58%\"\n },\n fonts: {\n display: FRAUNCES,\n body: SOURCE_SANS,\n editor: IBM_PLEX_MONO,\n mono: IBM_PLEX_MONO\n },\n materials: {\n ...PHYSICAL_MATERIALS_BASE,\n radius: \"0.45rem\",\n radiusSm: \"0.25rem\",\n radiusMd: \"0.35rem\",\n radiusLg: \"0.45rem\",\n radiusXl: \"0.6rem\",\n radius2xl: \"0.75rem\",\n shadowSm: \"0 1px 0 rgb(255 210 120 / 0.14), 0 1px 3px rgb(0 0 0 / 0.5)\",\n shadowMd: \"0 1px 0 rgb(255 210 120 / 0.12), 0 5px 12px rgb(0 0 0 / 0.45), inset 0 -1px 0 rgb(0 0 0 / 0.3)\",\n shadowLg: \"0 12px 28px rgb(0 0 0 / 0.55)\",\n shadowXl: \"0 20px 40px rgb(0 0 0 / 0.6)\",\n insetHighlight: \"inset 0 1px 0 rgb(255 220 140 / 0.22)\",\n insetShadow: \"inset 0 2px 5px rgb(0 0 0 / 0.55)\"\n },\n stylesheet: `${BRASS_PATINA}\n${SHARED_CHROME}`,\n stylesheetScoped: true\n};\nvar SKEUO_THEMES = [\n LEATHER_DESK_THEME,\n BRUSHED_STEEL_THEME,\n BOUND_JOURNAL_THEME,\n WALNUT_LIBRARY_THEME,\n SOFT_PORCELAIN_THEME,\n CINNABAR_LACQUER_THEME,\n DENIM_BENCH_THEME,\n BRASS_CONSOLE_THEME\n];\nvar SKEUO_THEME_IDS = SKEUO_THEMES.map((t) => t.id);\n\n// plugins/theme-skeuomorph/src/index.ts\nvar SkeuomorphThemePlugin = {\n manifest: {\n id: \"readergo.theme.skeuomorph\",\n name: \"Skeuomorph Suite\",\n version: \"1.2.0\",\n description: \"Eight physical chrome themes: Leather Desk, Brushed Steel, Bound Journal, Walnut Library, Soft Porcelain, Cinnabar Lacquer, Denim Bench, and Brass Console.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n context.log.info(`Skeuomorph Suite activating (${SKEUO_THEMES.length} physical atmospheres)...`);\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => SKEUO_THEMES\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => SKEUO_FONTS\n });\n const enable = async (themeId) => {\n await context.executeCommand(\"readergo.theme.setTheme\", { themeId });\n return { activeTheme: themeId };\n };\n const commands = [\n { id: \"readergo.theme.skeuomorph.enableLeather\", title: \"Theme: Leather Desk\", themeId: LEATHER_DESK_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableSteel\", title: \"Theme: Brushed Steel\", themeId: BRUSHED_STEEL_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableJournal\", title: \"Theme: Bound Journal\", themeId: BOUND_JOURNAL_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableWalnut\", title: \"Theme: Walnut Library\", themeId: WALNUT_LIBRARY_THEME.id },\n { id: \"readergo.theme.skeuomorph.enablePorcelain\", title: \"Theme: Soft Porcelain\", themeId: SOFT_PORCELAIN_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableLacquer\", title: \"Theme: Cinnabar Lacquer\", themeId: CINNABAR_LACQUER_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableDenim\", title: \"Theme: Denim Bench\", themeId: DENIM_BENCH_THEME.id },\n { id: \"readergo.theme.skeuomorph.enableBrass\", title: \"Theme: Brass Console\", themeId: BRASS_CONSOLE_THEME.id }\n ];\n for (const cmd of commands) {\n await context.registerCommand({\n id: cmd.id,\n title: cmd.title,\n handler: async () => enable(cmd.themeId)\n });\n }\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.cycle\",\n title: \"Theme: Cycle Skeuomorph Atmosphere\",\n handler: async () => {\n const active = await context.executeCommand(\"readergo.theme.getActiveTheme\");\n const currentId = active?.id || LEATHER_DESK_THEME.id;\n const idx = SKEUO_THEME_IDS.indexOf(currentId);\n const next = SKEUO_THEME_IDS[idx >= 0 ? (idx + 1) % SKEUO_THEME_IDS.length : 0];\n return enable(next);\n }\n });\n await context.registerCommand({\n id: \"readergo.theme.skeuomorph.getModes\",\n title: \"Theme: List Skeuomorph Atmospheres\",\n handler: async () => SKEUO_THEMES.map((t) => ({\n id: t.id,\n name: t.name,\n type: t.type,\n description: t.description\n }))\n });\n },\n deactivate(context) {\n context.log.info(\"Skeuomorph Suite deactivated.\");\n }\n};\nvar index_default = SkeuomorphThemePlugin;\n\n\n return { ACTIVITY_BAR_CHROME: ACTIVITY_BAR_CHROME, BOUND_JOURNAL_THEME: BOUND_JOURNAL_THEME, BRASS_CONSOLE_THEME: BRASS_CONSOLE_THEME, BRASS_PATINA: BRASS_PATINA, BRUSHED_STEEL_THEME: BRUSHED_STEEL_THEME, CINNABAR_LACQUER_THEME: CINNABAR_LACQUER_THEME, DENIM_BENCH_THEME: DENIM_BENCH_THEME, DENIM_TWILL: DENIM_TWILL, FRAUNCES: FRAUNCES, IBM_PLEX_MONO: IBM_PLEX_MONO, JOURNAL_FIBER: JOURNAL_FIBER, LACQUER_SHEEN: LACQUER_SHEEN, LEATHER_DESK_THEME: LEATHER_DESK_THEME, LEATHER_GRAIN: LEATHER_GRAIN, LITERATA: LITERATA, PORCELAIN_GLOSS: PORCELAIN_GLOSS, SHARED_CHROME: SHARED_CHROME, SKEUO_FONTS: SKEUO_FONTS, SKEUO_THEMES: SKEUO_THEMES, SKEUO_THEME_IDS: SKEUO_THEME_IDS, SOFT_PORCELAIN_THEME: SOFT_PORCELAIN_THEME, SOURCE_SANS: SOURCE_SANS, STEEL_BRUSH: STEEL_BRUSH, SkeuomorphThemePlugin: SkeuomorphThemePlugin, WALNUT_GRAIN: WALNUT_GRAIN, WALNUT_LIBRARY_THEME: WALNUT_LIBRARY_THEME, default: index_default };\n}\n" diff --git a/public/theme-solarized.bundle.json b/public/theme-solarized.bundle.json index 70fb49f..0c55726 100644 --- a/public/theme-solarized.bundle.json +++ b/public/theme-solarized.bundle.json @@ -4,7 +4,7 @@ "name": "Solarized Light", "version": "1.0.0", "description": "Ethan Schoonover's Solarized Light palette with Source Serif reading type.", - "category": "feature", + "category": "theme", "provides": [ "theme-provider", "font-provider" @@ -18,6 +18,24 @@ "autoActivate": true, "compile": { "ui": "./src/index.ts" + }, + "style": "Solarized · Dark · Precision reading", + "tags": [ + "dark", + "solarized", + "classic", + "serif" + ], + "longDescription": "Solarized Dark precision palette with Source Serif for reading and Source Sans for UI. A classic low-contrast scientific look that ages well.", + "preview": { + "background": "192 100% 11%", + "foreground": "44 87% 94%", + "card": "192 81% 14%", + "primary": "45 100% 35%", + "accent": "68 100% 30%", + "border": "192 20% 25%", + "muted": "192 40% 16%", + "type": "dark" } }, "entryCode": "export function __readergoStart(host) {\n const __readergoModule = (id) => {\n if (!host || typeof host.module !== \"function\") {\n throw new Error(\"ReaderGo plugin host is not installed\");\n }\n return host.module(id);\n };\n const require = (id) => __readergoModule(id);\n// plugins/theme-solarized/src/index.ts\nvar SOURCE_SERIF = {\n id: \"source-serif-4\",\n name: \"Source Serif 4\",\n family: \"'Source Serif 4', 'Georgia', serif\",\n category: \"serif\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Serif+4:opsz,wght@8..60,400;8..60,600;8..60,700&display=swap\",\n targets: [\"display\", \"editor\"]\n};\nvar SOURCE_SANS = {\n id: \"source-sans-3\",\n name: \"Source Sans 3\",\n family: \"'Source Sans 3', system-ui, sans-serif\",\n category: \"sans\",\n cssUrl: \"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&display=swap\",\n targets: [\"body\"]\n};\nvar THEME = {\n id: \"solarized-light\",\n name: \"Solarized Light\",\n type: \"light\",\n author: \"Ethan Schoonover\",\n description: \"Precision-tuned cream reading palette with cyan accents and serif prose.\",\n colors: {\n background: \"44 87% 94%\",\n foreground: \"192 81% 14%\",\n card: \"46 42% 88%\",\n cardForeground: \"192 81% 14%\",\n border: \"45 23% 77%\",\n primary: \"175 59% 40%\",\n primaryForeground: \"44 87% 94%\",\n secondary: \"46 42% 88%\",\n secondaryForeground: \"192 81% 14%\",\n muted: \"45 23% 77%\",\n mutedForeground: \"186 8% 45%\",\n accent: \"205 69% 49%\",\n accentForeground: \"44 87% 94%\",\n destructive: \"1 71% 52%\",\n destructiveForeground: \"44 87% 94%\",\n success: \"68 100% 30%\",\n successForeground: \"44 87% 94%\",\n warning: \"45 100% 35%\",\n warningForeground: \"44 87% 94%\",\n info: \"205 69% 49%\",\n infoForeground: \"44 87% 94%\",\n input: \"46 42% 88%\",\n ring: \"175 59% 40%\",\n heading1: \"192 81% 14%\",\n heading2: \"175 59% 33%\",\n heading3: \"205 69% 40%\"\n },\n fonts: {\n display: SOURCE_SERIF,\n body: SOURCE_SANS,\n editor: SOURCE_SERIF\n }\n};\nvar SolarizedThemePlugin = {\n manifest: {\n id: \"readergo.theme.solarized\",\n name: \"Solarized Light\",\n version: \"1.0.0\",\n description: \"Ethan Schoonover's Solarized Light palette with Source Serif reading type.\",\n category: \"feature\",\n provides: [\"theme-provider\", \"font-provider\"],\n permissions: []\n },\n async activate(context) {\n await context.registerCapability(\"theme-provider\", {\n getThemes: () => [THEME]\n });\n await context.registerCapability(\"font-provider\", {\n getFonts: () => [SOURCE_SERIF, SOURCE_SANS]\n });\n context.log.info(\"Solarized Light theme activated\");\n },\n deactivate(context) {\n context.log.info(\"Solarized Light theme deactivated\");\n }\n};\nvar index_default = SolarizedThemePlugin;\n\n\n return { SolarizedThemePlugin: SolarizedThemePlugin, default: index_default };\n}\n" diff --git a/scripts/build-catalog.mjs b/scripts/build-catalog.mjs index 58ab747..f52fcfd 100644 --- a/scripts/build-catalog.mjs +++ b/scripts/build-catalog.mjs @@ -4,12 +4,15 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; import crypto from "node:crypto"; +import { buildThemePreviewSvg } from "./theme-preview-svg.mjs"; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const pluginsDir = path.join(root, "plugins"); const catalogDir = path.join(root, "public"); +const screenshotsDir = path.join(catalogDir, "screenshots"); await fs.mkdir(catalogDir, { recursive: true }); +await fs.mkdir(screenshotsDir, { recursive: true }); const entries = await fs.readdir(pluginsDir, { withFileTypes: true }); const catalog = []; @@ -21,6 +24,12 @@ function runtimeBundleName(runtimeRel) { return path.basename(runtimeRel); } +function isThemeManifest(manifest) { + const category = String(manifest.category || "").toLowerCase(); + const provides = Array.isArray(manifest.provides) ? manifest.provides : []; + return category === "theme" || provides.includes("theme-provider"); +} + for (const entry of entries) { if (!entry.isDirectory()) continue; const pluginDir = path.join(pluginsDir, entry.name); @@ -32,14 +41,32 @@ for (const entry of entries) { continue; } + const provides = Array.isArray(manifest.provides) ? manifest.provides : []; + const category = + manifest.category || + (provides.includes("theme-provider") ? "theme" : "feature"); + const row = { id: manifest.id, name: manifest.name, description: manifest.description || "", - category: manifest.category, + category, version: manifest.version || "1.0.0", - provides: Array.isArray(manifest.provides) ? manifest.provides : [], + provides, }; + + if (manifest.longDescription) row.longDescription = manifest.longDescription; + if (manifest.style) row.style = manifest.style; + if (Array.isArray(manifest.tags) && manifest.tags.length > 0) { + row.tags = manifest.tags; + } + if (manifest.preview && typeof manifest.preview === "object") { + row.preview = manifest.preview; + } + if (typeof manifest.screenshot === "string" && manifest.screenshot.trim()) { + row.screenshot = manifest.screenshot.trim(); + } + let wrote = false; if (manifest.main && String(manifest.main).endsWith(".js")) { @@ -94,6 +121,35 @@ for (const entry of entries) { } } + // Auto-generate theme preview screenshots from palette metadata when missing. + if (wrote && row.id && isThemeManifest(manifest) && row.preview && !row.screenshot) { + const shotName = `${entry.name}.svg`; + const svg = buildThemePreviewSvg({ + ...row.preview, + label: row.name, + style: row.style, + name: row.name, + }); + await fs.writeFile(path.join(screenshotsDir, shotName), svg); + row.screenshot = `screenshots/${shotName}`; + } else if ( + wrote && + row.id && + typeof row.screenshot === "string" && + row.screenshot.endsWith(".svg") && + row.preview + ) { + // Keep generated SVG in sync when preview colors change. + const base = path.basename(row.screenshot); + const svg = buildThemePreviewSvg({ + ...row.preview, + label: row.name, + style: row.style, + name: row.name, + }); + await fs.writeFile(path.join(screenshotsDir, base), svg); + } + if (wrote && row.id) { catalog.push(row); } diff --git a/scripts/theme-preview-svg.mjs b/scripts/theme-preview-svg.mjs new file mode 100644 index 0000000..1ca542e --- /dev/null +++ b/scripts/theme-preview-svg.mjs @@ -0,0 +1,100 @@ +/** + * Build a compact SVG mock of a ReaderGo workspace painted with theme preview colors. + * Used by build-catalog.mjs so theme plugins ship a screenshot without hand-drawn assets. + */ + +function hsl(triplet, fallback = '0 0% 50%') { + const value = typeof triplet === 'string' && triplet.trim() ? triplet.trim() : fallback; + return `hsl(${value})`; +} + +export function buildThemePreviewSvg(preview = {}) { + const bg = hsl(preview.background, '231 29% 8%'); + const fg = hsl(preview.foreground, '210 40% 98%'); + const card = hsl(preview.card, preview.background || '223 48% 16%'); + const primary = hsl(preview.primary, '273 66% 62%'); + const accent = hsl(preview.accent, preview.primary || '109 100% 54%'); + const border = hsl(preview.border, '258 22% 26%'); + const muted = hsl(preview.muted, preview.card || '223 48% 16%'); + const label = String(preview.label || preview.name || 'Theme').slice(0, 28); + const style = String(preview.style || '').slice(0, 42); + const scheme = preview.type === 'light' ? 'light' : 'dark'; + + return ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${escapeXml(label)} + ${escapeXml(style || scheme)} + + + +`; +} + +function escapeXml(value) { + return String(value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}