Component Library
Objectuve uses Storybook to document and develop UI components in isolation. The full design system showcase lives at design.objectuve.com.
Browsing Components
- Design System — design.objectuve.com — curated gallery of brand, tokens, and patterns
- Storybook — storybook.objectuve.com — interactive component playground with prop controls
Running locally
cd ionic_frontend
npm run storybook
# → http://localhost:6006Story organization
Stories are co-located next to their components as ComponentName.stories.ts. The project currently includes 352 stories covering core UI elements, admin dashboard views, and design system tokens.
Example story structure
import type { Meta, StoryObj } from '@storybook/vue3'
import MyComponent from './MyComponent.vue'
const meta: Meta<typeof MyComponent> = {
component: MyComponent,
tags: ['autodocs'],
argTypes: {
// Define prop controls
},
}
export default meta
type Story = StoryObj<typeof MyComponent>
export const Default: Story = {
args: {
// Default prop values
},
}Conventions
- Tags: Always include
tags: ['autodocs']for automatic documentation generation - ArgTypes: Define
argTypesfor all public props to enable interactive controls - Decorators: Use Ionic and Apollo decorators from
.storybook/decorators/when components depend on those providers - Naming: Story files must match the component name:
GoalCard.vue→GoalCard.stories.ts
When to add a story
Add or update a story when:
- Creating a new component
- Adding new props or variants to an existing component
- Fixing a visual bug (add a story that reproduces the bug first)
Design philosophy
Objectuve is an anti-social app — designed for ~10 min/day sessions. Components should prioritize:
- Quick interactions — one-tap check-ins, immediate feedback (streak tick, XP pop, badge unlock)
- Clear progress signals — visible momentum so users feel accomplishment, not obligation
- No engagement hooks — no infinite scroll, no autoplay, no FOMO mechanics
See the Brand Guide for full tone, messaging, and visual identity details.
Design tokens
- Primary gradient:
#177bbb → #05cbfc - Accent orange:
#f28529 - Gold (achievements):
#fcc419 - Fonts: Outfit (headlines), Inter (body)
PageHeader ink contract (OBJ-2966)
design_system/src/components/layout/PageHeader.vue — the per-route header used across every design_system page — separates its decorative accent from its text ink. --page-accent (looked up per route from PAGE_ACCENTS[path], design_system/src/lib/pageAccents.ts) still drives the wash, icon-tile fill, inset ring, and header rule, but the eyebrow text and icon glyph read from a dedicated heroInkLight/heroInkDark pair instead of the decorative hue directly — each cleared against the worse of --background and the .page-hero wash (4.5:1 eyebrow text, 3:1 icon glyph). A new route added to PAGE_ACCENTS must register both ink values or its header silently falls back to --primary-accessible. Full rule and per-route value table: DESIGN.md § Palette intent § Accessibility hard rules — Page-Accent Ink Contract (OBJ-2966) and docs/ui-specs/obj-2966-page-accent-ink.md.
Last updated: 2026-09-11 — OBJ-3648: corrected the stale Storybook story count (189 → 352), matching the re-verified count from OBJ-3647