# Theming, Templating & Vue Component Standards
Frontend design system for the Go No Go questionnaire application. Built with Vue 3, Inertia.js v2, and Tailwind CSS.
## Design Tokens
### Color Palette
| Token | Hex | RGB | Tailwind Class | Usage |
|-------------|-----------|------------------|-----------------|---------------------------------------------|
| Primary | `#d1ec51` | 209, 236, 81 | `bg-primary`, `text-primary` | Buttons (default), accents, highlights |
| Primary Dark | `#b5d136` | 181, 209, 54 | `bg-primary-dark`, `text-primary-dark` | Selected/hover state for pill buttons, ~15% darker primary |
| Secondary | `#00b7b3` | 0, 183, 179 | `bg-secondary`, `text-secondary` | Button hover states, secondary accents |
| Background | `#2b303a` | 43, 48, 58 | `bg-surface` | Page background, card backgrounds |
| Text | `#ffffff` | 255, 255, 255 | `text-white` | Primary body text on dark background |
| Text Muted | `#9ca3af` | 156, 163, 175 | `text-gray-400` | Secondary/muted text, labels, placeholders |
Dark background means all primary text is white. Use `text-gray-400` for de-emphasized text.
## Tailwind Configuration
Register design tokens in `tailwind.config.js` so they are available as utility classes:
```js
// tailwind.config.js
export default {
theme: {
extend: {
colors: {
primary: '#d1ec51',
secondary: '#00b7b3',
surface: '#2b303a',
},
},
},
};
```
This enables `bg-primary`, `text-secondary`, `bg-surface`, `border-primary`, etc.
## Layout
`resources/js/Layouts/AppLayout.vue` is the persistent layout wrapping all authenticated pages.
Structure:
- **Header bar:** `PageHeader` component -- Piccadilly logo (top-left) with the current page title to its right
- **Main content area:** below the header, renders the page slot
Applied via Inertia persistent layouts on each page component:
```js
import AppLayout from '@/Layouts/AppLayout.vue';
defineOptions({ layout: AppLayout });
```
Pages: Dashboard (`/`), Session/Show (questionnaire flow), Session/Result (final result).
## Components
All shared components live in `resources/js/Components/`.
### AppButton
Central button component. All buttons in the app use this -- no one-off button styling.
| Prop | Type | Default | Description |
|------------|-----------|-------------|----------------------------------------------------------|
| `variant` | `String` | `'primary'` | `'primary'` / `'danger'` / `'ghost'` |
| `size` | `String` | `'md'` | `'sm'` / `'md'` / `'lg'` |
| `href` | `String` | `undefined` | When set, renders as Inertia `Link` instead of `button` |
| `disabled` | `Boolean` | `false` | Disables interaction and applies muted styling |
| `loading` | `Boolean` | `false` | Shows spinner and disables interaction |
Default state: `bg-primary` background, dark text (`text-surface` or `text-gray-900`).
Hover state: `bg-secondary` background.
Danger variant: red background/text for destructive actions.
Ghost variant: transparent background, text-only.
### AppLogo
Renders the Piccadilly logo (SVG or image). No props beyond optional size overrides. Used inside `PageHeader`.
### PageHeader
Contains `AppLogo` (left) and the page title (right of logo). Used inside `AppLayout`. Accepts a `title` prop (String).
### ScoreIndicator
Displays the running score during a session with color coding based on thresholds. See [Scoring Colors](#scoring-colors) for the color rules.
### QuestionCard
Renders a single question in the questionnaire flow. Adapts its UI based on the question's field configuration:
- `has_yes` -- show Yes button
- `has_no` -- show No button
- `has_na` -- show N/A button
- `details` -- show a text input for additional notes
### RadioButtonGroup
Pill-shaped button group that replaces native radio buttons. Options appear as connected segments with rounded outer edges.
| Prop | Type | Default | Description |
|--------------|-------------------------------|---------|--------------------------------|
| `modelValue` | `String \| null` | `null` | Selected value (v-model) |
| `options` | `Array<{value, label}>` | required | Options to render |
| `name` | `String` | required | HTML radio group name |
| `disabled` | `Boolean` | `false` | Disables all options |
Default state: `bg-primary` with `text-gray-900`.
Selected & hover state: `bg-primary-dark`.
Keyboard focus: visible ring using `ring-primary-dark`.
Used in `QuestionCard` (3-option: Yes/No/N/A) and `Screening/Show` (2-option: Yes/No).
## Icons
Heroicons is the only icon library. No other icon packages.
```bash
npm install @heroicons/vue
```
Default: **outline** variant (24x24):
```vue
```
Small/inline contexts: **solid** variant (20x20):
```vue
```
## Scoring Colors
Result-specific colors, separate from brand colors. Used only in `ScoreIndicator` and the result page.
| Result | Color | Tailwind Class |
|---------------------|--------------|-------------------------|
| GO | Green | `text-green-500` / `bg-green-500` |
| Consult Leadership | Yellow/Amber | `text-amber-500` / `bg-amber-500` |
| NO GO | Red | `text-red-500` / `bg-red-500` |
These are standard Tailwind palette colors, not custom tokens.