docs: add Modern Fable visual identity design spec

This commit is contained in:
2026-04-08 10:04:55 -04:00
parent 93af4e6bab
commit 0afa2d8771
@@ -0,0 +1,249 @@
# Modern Fable — Visual Identity Design Spec
## Goal
Replace the generic "competent dark-mode Vue app" aesthetic with a distinctive visual identity that is unmistakably Fabled Assistant. The design language evolves from "Illuminated Transcript" to "Modern Fable" — keeping the scholarly DNA but adding personality through color, typography, interaction, and card design that no other app has.
## Color Palette
Shift from indigo (`#6366f1`) to deep violet + muted gold.
### Dark theme
| Role | Old | New | Usage |
|------|-----|-----|-------|
| Primary | `#818cf8` | `#a78bfa` | Text accents, active states, tags, links |
| Primary solid | `#6366f1` | `#7c3aed` | Buttons, gradients, accent strips |
| Primary deep | `#4f46e5` | `#5b21b6` | Gradient endpoints, hover states |
| Accent (warm) | — | `#d4a017` | Due dates, event times, counts, temporal data |
| Accent light | — | `#e8c45a` | Amber hover states |
| Background | `#111113` | `#0f0f14` | Slightly deeper, more dramatic |
| Surface | `#1a1b22` | `#16161f` | Cards, panels |
| Card bg | `#1e1e27` | `#1a1a24` | Card interiors |
| Border | `rgba(99,102,241,0.10)` | `rgba(124,58,237,0.12)` | Violet-tinted borders |
| Text | `#e4e4f0` | `#e4e4f0` | Unchanged |
| Text muted | `#52526a` | `#52526a` | Unchanged |
### Light theme
| Role | Old | New |
|------|-----|-----|
| Primary | `#6366f1` | `#7c3aed` |
| Primary text | `#4f46e5` | `#5b21b6` |
| Accent | — | `#b8860b` (darker gold for light bg) |
| Tag bg | `#ede9fe` | `#ede5ff` |
| Tag text | `#4f46e5` | `#6d28d9` |
### Semantic color rules
- **Violet = structural** — navigation, type badges, status indicators, card accents, CTA buttons
- **Amber/gold = temporal** — due dates, event times, countdown values, "overdue" states, calendar dot, relative timestamps
- This duality is a core brand principle: violet organizes, amber marks time
### Logo update
Update `AppLogo.vue` SVG fill to use the new violet gradient (`#7c3aed``#5b21b6`) instead of the current indigo values.
## Card Design — Type DNA
Each content type gets a distinct visual signature recognizable at a glance without reading the badge.
### Shared card structure
- Background: `var(--color-surface)`
- Border: `1px solid` with type-tinted color at low opacity
- Border-radius: `var(--radius-lg)` (14px)
- Padding: 14px
- Hover: translateY(-2px) + violet shadow bloom (`0 8px 24px rgba(124,58,237,0.15)`)
### Type-specific signatures
**Note** (`note`)
- Top edge: full-width 3px gradient bar (`#7c3aed``#a78bfa`)
- Border tint: `rgba(124,58,237,0.12)`
- Badge color: `#a78bfa`
**Task** (`task`)
- Top edge: half-width 3px gradient bar (`#d4a017` → transparent`), left-aligned — partial bar suggests "in progress"
- Border tint: `rgba(212,160,23,0.10)`
- Badge color: `#d4a017`
- Status badge inline with type badge row
- Due date in amber; overdue in `--color-overdue` (red)
**Person** (`person`)
- Top edge: none
- Corner accent: subtle 60px quarter-circle in top-right (`rgba(16,185,129,0.06)`)
- Border tint: `rgba(16,185,129,0.10)`
- Badge color: `#34d399`
**Place** (`place`)
- Top edge: none
- Corner accent: subtle 60px quarter-circle in top-right (`rgba(245,158,11,0.06)`)
- Border tint: `rgba(245,158,11,0.10)`
- Badge color: `#fbbf24`
**List** (`list`)
- Top edge: full-width 3px gradient bar (`#38bdf8``#7dd3fc`)
- Border tint: `rgba(56,189,248,0.10)`
- Badge color: `#7dd3fc`
- Progress bar beneath checkboxes
### Card hover state
All cards share the same hover treatment:
```css
.k-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(124,58,237,0.15), 0 2px 8px rgba(0,0,0,0.3);
border-color: rgba(124,58,237,0.2);
}
```
## Navigation — Signature Header
Replace the flat nav links with a pill-grouped tab bar.
### Structure
```
[Logo + "Fabled"] [ Knowledge | Chat | Briefing | Calendar | News | Projects ] [status · ? · ☀ · ⚙ · user]
```
### Brand in header
- Logo: `AppLogo` SVG at 28px with new violet gradient
- Text: "Fabled" only (not "Fabled Assistant") — Fraunces italic, `#c4b0f0`, 15px
- The full name "Fabled Assistant" appears on the login page and Settings; the header uses the short form
### Tab bar
- Container: `rgba(124,58,237,0.06)` background, `border-radius: 10px`, 3px padding
- Inactive tabs: transparent background, `color: var(--color-text-muted)`
- Active tab: `rgba(124,58,237,0.2)` background, `border-radius: 8px`, `color: #c4b5fd`, soft box-shadow glow `0 0 12px rgba(124,58,237,0.2)`
- Hover (inactive): `rgba(124,58,237,0.08)` background
- Transition: background 0.15s, color 0.15s
### Header background
Subtle gradient: `linear-gradient(180deg, var(--color-surface), var(--color-bg))` with a bottom border of `rgba(124,58,237,0.08)`. Creates depth without being heavy.
### Mobile
On mobile (< 768px), the pill bar collapses into the existing hamburger dropdown menu. The dropdown gets the same violet active styling.
## Typography — Fraunces as Narrator
Fraunces italic becomes the "narrator's voice" of the application — the assistant speaking through the UI. System UI font remains for body text and interactive elements.
### Where Fraunces is used
| Element | Style | Example |
|---------|-------|---------|
| View titles | Fraunces italic, 20-24px, `#c4b0f0` | *Knowledge*, *Chat*, *Briefing* |
| Sidebar section labels | Fraunces italic, 11px, `var(--color-primary)` | *Filter*, *Tags*, *Sort* |
| Empty states | Fraunces italic, 13-15px, `#d4a017` | *"Every story starts with a blank page."* |
| Card headings (h1/h2/h3) | Fraunces, non-italic, 600 weight | Existing behavior, unchanged |
| Briefing greeting | Fraunces italic, 16px | *"Good morning, Bryan"* |
### Where Fraunces is NOT used
- Navigation tab labels (system font, 12-13px)
- Buttons and form labels
- Card body text, snippets, metadata
- Toast messages, error text
### Empty state voice
Each major view gets a distinctive empty state message in Fraunces italic, amber color:
- Knowledge: *"Your story is unwritten. Create your first note to begin."*
- Chat: *"Start a conversation."*
- Calendar: *"No events ahead. A quiet chapter."*
- Briefing (no briefing yet): *"Your daily briefing will appear here each morning."*
## Living Details
Small touches that accumulate into a distinctive feel.
### Glow interactions
- **Buttons**: Primary buttons (`btn-send`, `btn-new-note`, CTAs) get a violet glow on hover: `box-shadow: 0 0 16px rgba(124,58,237,0.35)`
- **Focus ring**: Change from current `color-mix` to a violet glow: `0 0 0 2px rgba(124,58,237,0.4)`
- **Active nav tab**: Soft glow behind the active pill (see Navigation section)
### Amber for temporal data
Consistently use `#d4a017` (dark theme) for all time-related information:
- Due dates on task cards
- Event times on calendar chips
- "3d ago" timestamps on cards
- Overdue badge in the today bar
- Countdown/relative time in briefing
This creates a visual language: when you see amber, it's about *when*.
### Card hover bloom
Cards lift and emit a violet shadow on hover (see Card Design section). The shadow color matches the card's type accent at very low opacity for a subtle differentiation.
### Status dot pulse
The Ollama status indicator in the header gains a CSS pulse animation when the model is loaded:
```css
@keyframes status-pulse {
0%, 100% { box-shadow: 0 0 4px rgba(74,222,128,0.4); }
50% { box-shadow: 0 0 10px rgba(74,222,128,0.6); }
}
```
Pulse only when status is "loaded" (green). Offline (red) and loading (amber) are static.
### Scroll edge fades
Top and bottom edges of scrollable areas (card grid, chat messages, sidebar tag list) get a gradient mask that fades content into the background. 20px height, using `mask-image: linear-gradient(...)`.
### Sidebar section dividers
Replace flat `border-bottom` between filter sections with a centered ornamental divider:
```css
.filter-section + .filter-section::before {
content: '·';
display: block;
text-align: center;
color: rgba(124,58,237,0.3);
font-size: 1.2rem;
letter-spacing: 0.5em;
padding: 8px 0;
}
```
Three centered dots (` · · · `) in faint violet. Subtle but distinctive.
### Scrollbar
Keep the current thin scrollbar but update the color from indigo to violet:
```css
::-webkit-scrollbar-thumb {
background: rgba(124,58,237,0.25);
}
```
## Files Changed
| File | Change |
|------|--------|
| `frontend/src/assets/theme.css` | Full palette update (both light and dark), scrollbar color |
| `frontend/src/components/AppLogo.vue` | SVG fill gradient update |
| `frontend/src/components/AppHeader.vue` | Pill-grouped nav tabs, brand shortening, header gradient, status pulse |
| `frontend/src/views/KnowledgeView.vue` | Card type DNA (gradient bars, corner accents), hover bloom, section dividers, empty state text, scroll fades, Fraunces view title |
| `frontend/src/components/ChatPanel.vue` | Scroll fade on messages, empty state text |
| `frontend/src/views/CalendarView.vue` | Empty state text, amber event times |
| `frontend/src/views/BriefingView.vue` | Empty state text, Fraunces greeting |
| `frontend/src/views/ChatView.vue` | (uses ChatPanel — inherits changes) |
| `frontend/src/App.vue` | Update any global styles referencing old indigo values |
## What Does NOT Change
- Overall layout structure (sidebar + content + optional graph panel)
- Chat bubble design (user transparent, assistant border-left + shadow)
- TipTap editor styling
- Settings view layout
- Backend — zero changes
- Mobile layout patterns