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,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>FabledCurator</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Fraunces:wght@400;500;600&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "fabledcurator-frontend",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "vue-tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.4.0",
|
||||
"vue-router": "^4.3.0",
|
||||
"pinia": "^2.1.0",
|
||||
"vuetify": "^3.5.0",
|
||||
"@mdi/font": "^7.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.0.0",
|
||||
"vite": "^5.2.0",
|
||||
"vue-tsc": "^2.0.0",
|
||||
"vite-plugin-vuetify": "^2.0.0",
|
||||
"sass": "^1.71.0"
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vuetify from 'vite-plugin-vuetify'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
vuetify({ autoImport: true })
|
||||
],
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
emptyOutDir: true,
|
||||
sourcemap: false
|
||||
},
|
||||
server: {
|
||||
port: 5173,
|
||||
proxy: {
|
||||
// Dev server proxies API to local Quart
|
||||
'/api': 'http://localhost:8080',
|
||||
'/ws': { target: 'ws://localhost:8080', ws: true }
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user