feat: scaffold Vue 3 + Vuetify + Pinia frontend themed to FabledDesignSystem
Curator signature accent (#A87338, aged amber) is baked into fabled-tokens.js. Vuetify theme consumes the same tokens module the rest of the SPA does, so updating design system tokens propagates throughout. Vite dev server proxies /api and /ws to the Quart backend. App.vue references AppShell (lands in Task 9) and main.js references router.js (lands in Task 9) — these are intentionally split so Task 8 is the framework scaffold and Task 9 is the navigation/shell content. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<AppShell>
|
||||
<RouterView />
|
||||
</AppShell>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import AppShell from './components/AppShell.vue'
|
||||
</script>
|
||||
@@ -0,0 +1,26 @@
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import { createVuetify } from 'vuetify'
|
||||
import 'vuetify/styles'
|
||||
import '@mdi/font/css/materialdesignicons.css'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router.js'
|
||||
import { fabledCuratorTheme } from './theme/vuetify-theme.js'
|
||||
|
||||
const vuetify = createVuetify({
|
||||
theme: {
|
||||
defaultTheme: 'fabledCurator',
|
||||
themes: { fabledCurator: fabledCuratorTheme }
|
||||
},
|
||||
defaults: {
|
||||
// FabledDesignSystem: pill shape for buttons
|
||||
VBtn: { rounded: 'pill' }
|
||||
}
|
||||
})
|
||||
|
||||
createApp(App)
|
||||
.use(createPinia())
|
||||
.use(router)
|
||||
.use(vuetify)
|
||||
.mount('#app')
|
||||
@@ -0,0 +1,41 @@
|
||||
// FabledDesignSystem tokens — mirrored from FabledDesignSystem-new/design-system.md.
|
||||
// Do not hand-edit hexes; update the source-of-truth doc and re-mirror here.
|
||||
|
||||
export const surfaces = {
|
||||
obsidian: '#14171A', // page background
|
||||
iron: '#1E2228', // cards
|
||||
slate: '#2C313A', // hovered surfaces
|
||||
pewter: '#3F4651' // borders, ghost outlines
|
||||
}
|
||||
|
||||
export const text = {
|
||||
parchment: '#E8E4D8', // primary on dark
|
||||
vellum: '#C2BFB4', // secondary
|
||||
ash: '#9C9A92' // tertiary
|
||||
}
|
||||
|
||||
export const action = {
|
||||
moss: '#4A5D3F', // primary action
|
||||
bronze: '#8B7355', // secondary action
|
||||
pewter: '#3F4651', // tertiary/ghost
|
||||
destructive: '#6B2118' // delete/irreversible
|
||||
}
|
||||
|
||||
export const semantic = {
|
||||
success: '#4A5D3F',
|
||||
warning: '#8B6F1E',
|
||||
error: '#C04A1F',
|
||||
info: '#3D5A6E'
|
||||
}
|
||||
|
||||
// Per-app signature accent. Curator's accent was added to FabledDesignSystem
|
||||
// during FC-1 (2026-05-14). Aged amber — manuscript ink, curated archive.
|
||||
export const accent = {
|
||||
curator: '#A87338'
|
||||
}
|
||||
|
||||
export const typography = {
|
||||
display: 'Fraunces, Georgia, serif',
|
||||
body: 'Inter, system-ui, sans-serif',
|
||||
mono: '"JetBrains Mono", monospace'
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { surfaces, text, action, semantic, accent } from './fabled-tokens.js'
|
||||
|
||||
export const fabledCuratorTheme = {
|
||||
dark: true,
|
||||
colors: {
|
||||
background: surfaces.obsidian,
|
||||
surface: surfaces.iron,
|
||||
'surface-bright': surfaces.slate,
|
||||
'surface-light': surfaces.pewter,
|
||||
|
||||
primary: action.moss,
|
||||
secondary: action.bronze,
|
||||
tertiary: action.pewter,
|
||||
|
||||
'on-background': text.parchment,
|
||||
'on-surface': text.parchment,
|
||||
'on-primary': text.parchment,
|
||||
'on-secondary': text.parchment,
|
||||
|
||||
success: semantic.success,
|
||||
warning: semantic.warning,
|
||||
error: semantic.error,
|
||||
info: semantic.info,
|
||||
|
||||
// Curator signature accent — used for nav-active state, wordmark, selection.
|
||||
// Not on action buttons (see design-system.md "Accent usage rules").
|
||||
accent: accent.curator
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user