fix: replace all remaining old brand tokens (text-brand-dark, border-brand-border, bg-white opacity)

30 references to removed CSS variables: border-brand-border → border-[#1e2130],
text-brand-text-muted → text-[#4f5666], text-brand-dark → text-white,
bg-white/[0.04] → bg-[#191c25], hover:border-white/[0.12] → hover:border-[#2a2f3d].

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-03-22 04:27:46 -04:00
parent 4c5649d620
commit 123fc50af9
32 changed files with 578 additions and 72 deletions

View File

@@ -0,0 +1,128 @@
# How To Make Claude Code Follow The New Design System
## The Problem
Your project currently has MULTIPLE contradicting design documents:
- CLAUDE.md references purple gradients, glass-morphism, AND cyan accents
- Old docs like DESIGN_SYSTEM_GUIDE.md describe monochrome glass-card patterns
- UI-DESIGN-SYSTEM.md describes a purple gradient workspace system
- REBRAND-IMPLEMENTATION-GUIDE.md has the old Patherly → ResolutionFlow rebrand
- Your actual CSS has Tailwind v4 with OKLCH cyan tokens
Claude Code sees ALL of these and gets confused about which to follow.
## The Fix — 4 Steps
### Step 1: Place the new DESIGN-SYSTEM.md in your project root
Copy `DESIGN-SYSTEM.md` (the file I created alongside this one) to:
```
C:\Dev\Projects\patherly\DESIGN-SYSTEM.md
```
This is the SINGLE SOURCE OF TRUTH for all design decisions going forward.
---
### Step 2: Update CLAUDE.md — Branding Section
Find the `### Branding` section and REPLACE EVERYTHING between `**Brand details:**`
and the next `---` separator with this:
```markdown
**Brand details:**
- **Design system:** [DESIGN-SYSTEM.md](DESIGN-SYSTEM.md) — THE source of truth for all design decisions
- **Design aesthetic:** Flat, high-contrast dark theme (Sentry/PostHog-inspired). No glass morphism, no gradients on surfaces, no ambient effects.
- **Accent color:** Cyan (#22d3ee / #06b6d4). Used sparingly — ≤5% of the UI.
- **Fonts:** IBM Plex Sans (body), Bricolage Grotesque (headings), JetBrains Mono (code) — loaded via Google Fonts
- **Logo:** 30px gradient square (cyan) + "ResolutionFlow" in Bricolage Grotesque 700
- **Layout:** Icon rail sidebar (72px, default) with hover flyout panels. Pinnable to full 260px sidebar.
- **Brand assets:** `brand-assets/` (source SVGs), `frontend/src/assets/brand/` (app assets), `frontend/public/icons/` (favicon)
- **Landing page:** Shares color system and typography. Full-width marketing layout at `/` route.
- **Reference mockups:** `docs/mockups/` (HTML files, open in browser)
**Component rules:**
- Primary buttons: solid `accent` background (#22d3ee), white text
- Cards: `bg-card` with 1px `border-default`, 8px radius. NO shadows, NO blur, NO gradients.
- Badges: pill-shaped (20px radius), semantic dim background + matching text color
- Active nav: `accent-dim` background + `accent-text` color + 3px left accent bar
- Stat cards: 3px colored left border (accent/success/warning by position)
- Code blocks: `bg-code` with JetBrains Mono, material-inspired syntax highlighting
- Status colors: green (success), amber (warning), red (danger) — ONLY for semantic meaning
When adding new pages/components: reference DESIGN-SYSTEM.md. Use flat dark surfaces, 1px borders, no decorative effects. All colors via CSS variables.
```
---
### Step 3: Update CLAUDE.md — Tech Stack Line
Find the styling line under Tech Stack → Frontend and change it to:
```markdown
- **Styling:** Tailwind CSS v4 — flat dark theme with cyan accent (see DESIGN-SYSTEM.md)
```
Remove any references to "monochrome glass-morphism" or "dark-only" limitations.
---
### Step 4: Archive Old Design Docs
Move these files into an `archive/` folder (don't delete — you might want to reference them later):
```
mkdir archive
mkdir archive\design-docs
move DESIGN_SYSTEM_GUIDE.md archive\design-docs\
move UI-DESIGN-SYSTEM.md archive\design-docs\
move REBRAND-IMPLEMENTATION-GUIDE.md archive\design-docs\
move COMPONENT_EXAMPLES.md archive\design-docs\ (if it exists in root)
move docs\plans\Frontend\DESIGN_SYSTEM_GUIDE.md archive\design-docs\ (if it exists here)
```
If any of these files are referenced elsewhere in CLAUDE.md, remove those references.
---
## Why This Works
Claude Code prioritizes files in this order:
1. **CLAUDE.md** — reads this first, every time
2. **Files referenced in CLAUDE.md** — follows links to read referenced docs
3. **Files in the project root** — scans these for context
4. **Files deeper in the tree** — only reads if specifically asked
By putting DESIGN-SYSTEM.md in the root AND linking it from CLAUDE.md's branding section,
Claude Code will find it immediately and treat it as authoritative. By archiving the old
docs, Claude Code won't stumble on contradicting information.
---
## Verification
After making these changes, test by asking Claude Code:
1. "What color system does this project use?" — Should say cyan/teal flat dark theme, NOT purple gradients or monochrome
2. "Create a new card component" — Should use bg-card with 1px border, NOT glass-card with backdrop-blur
3. "What fonts does this project use?" — Should say IBM Plex Sans + Bricolage Grotesque, NOT Inter + Plus Jakarta Sans
4. "Add a sidebar nav item" — Should follow the icon rail pattern, NOT a traditional full sidebar
If any of these come back wrong, check that the old docs are actually archived and not still being found.
---
## Place These Mockup Files in docs/mockups/
Also copy the HTML mockups we created into your project so Claude Code has visual references:
```
mkdir docs\mockups
copy resolutionflow-redesign.html docs\mockups\
copy resolutionflow-sidebar-final.html docs\mockups\
copy resolutionflow-landing.html docs\mockups\
```
Then Claude Code can open these in a browser to see exactly what the target looks like.

378
Design/DESIGN-SYSTEM.md Normal file
View File

@@ -0,0 +1,378 @@
# ResolutionFlow Design System v4
> **Status:** ACTIVE — This document is the single source of truth for all frontend design decisions.
> **Supersedes:** All previous design system docs including `DESIGN_SYSTEM_GUIDE.md`, `UI-DESIGN-SYSTEM.md`, `REBRAND-IMPLEMENTATION-GUIDE.md`, and any `COMPONENT_EXAMPLES.md` files.
> **Last Updated:** March 21, 2026
---
## Design Philosophy
ResolutionFlow uses a **flat, high-contrast dark theme** inspired by Sentry and PostHog. The aesthetic is premium, clean, and minimal — no glass morphism, no backdrop blur, no ambient orbs, no gradient backgrounds on surfaces. The accent color appears in ≤5% of the UI. Every design decision prioritizes **readability over decoration**.
**Light mode** is a planned addition (dark/light toggle). Design all components with CSS variables so theming is a variable swap, not a rewrite.
---
## Color System
All colors are defined as CSS custom properties in `index.css` inside the `@theme` block (Tailwind v4) or `:root` / `.dark` blocks (Tailwind v3).
### Dark Mode (Default)
```
Page background: #0c0d10
Sidebar background: #0f1118
Card background: #14161d
Card hover: #191c25
Input background: #191c25
Code background: #0e1017
Elevated surface: #1c1f2a
Text primary: #e2e5eb
Text heading: #f0f2f5
Text secondary: #848b9b
Text muted: #4f5666
Text rail label: #6b7280
Border default: #1e2130
Border hover: #2a2f3d
Accent (cyan): #22d3ee
Accent hover: #06b6d4
Accent dim (8-10%): rgba(34,211,238,0.10)
Accent text: #67e8f9
Success: #34d399
Success dim: rgba(52,211,153,0.10)
Warning: #fbbf24
Warning dim: rgba(251,191,36,0.10)
Danger: #f87171
Danger dim: rgba(248,113,113,0.10)
```
### Light Mode (Planned)
```
Page background: #f3f4f7
Sidebar background: #ffffff
Card background: #ffffff
Card hover: #f8f9fb
Input background: #eef0f4
Code background: #f5f6f9
Elevated surface: #e8eaef
Text primary: #1a1d24
Text heading: #0d0f13
Text secondary: #5a6274
Text muted: #8b92a1
Border default: #dde0e7
Border hover: #c5c9d3
Accent: #0891b2
Accent dim: rgba(8,145,178,0.07)
Accent text: #0e7490
```
### What NOT To Use
- No glass morphism (`backdrop-filter: blur`)
- No gradient backgrounds on cards or surfaces
- No ambient orbs or floating glow elements
- No `bg-white/[0.04]` opacity-based backgrounds
- No purple gradient accent (`#818cf8 → #a78bfa`) — this is deprecated
- No `text-gradient-brand` utility — replaced by solid `accent-text` color
- No `glass-card`, `glass-stat`, `glass-card-glow` CSS utilities
---
## Typography
### Font Stack
| Role | Font | Weights | CSS Variable |
|------|------|---------|-------------|
| Body text | IBM Plex Sans | 400, 500, 600, 700 | `--font-sans` / `font-sans` |
| Headings | Bricolage Grotesque | 600, 700, 800 | `--font-heading` / `font-heading` |
| Code / Monospace | JetBrains Mono | 400, 500 | `--font-mono` / `font-mono` |
### Typography Scale
| Element | Size | Weight | Color | Letter Spacing |
|---------|------|--------|-------|---------------|
| Page title (h1) | 22px | 700 (Bricolage) | text-heading | -0.03em |
| Section title | 15px | 600 (Bricolage) | text-heading | normal |
| Card title | 14px | 600 (IBM Plex) | text-heading | normal |
| Body text | 14px | 400 (IBM Plex) | text-primary | normal |
| Secondary text | 13px | 400 (IBM Plex) | text-secondary | normal |
| Label / hint | 12px | 500 (IBM Plex) | text-muted | normal |
| Nav section header | 10px | 600 (IBM Plex) | text-muted | 1.2px, uppercase |
| Rail icon label | 10px | 500 (IBM Plex) | text-rail-label | normal |
| Code | 12px | 400 (JetBrains) | text-primary | normal |
| Stat number | 28px | 700 (Bricolage) | text-heading | -0.03em |
| Badge | 11px | 550 (IBM Plex) | varies | normal |
### What NOT To Use
- No Inter, Plus Jakarta Sans, or Outfit — these are deprecated
- No `font-label` utility — use `font-mono` for monospace or `font-sans` at small size
- No font sizes below 10px
---
## Layout Architecture
### App Shell
The app uses a CSS Grid layout with two states:
**Icon Rail (Default):**
```
[icon-rail: 72px] [main-content: 1fr]
```
**Pinned Sidebar:**
```
[full-sidebar: 260px] [main-content: 1fr]
```
### Icon Rail Sidebar
The default navigation is a narrow icon rail (72px) with:
- Logo mark at top (30px square, gradient background, lightning bolt icon)
- Nav items as vertical column: icon (20px) + label text (10px) underneath
- Dividers between nav sections
- User avatar at bottom
- Pin/expand button below avatar
**Hover behavior:** Hovering a rail item opens a flyout panel (220px) to the right of the rail with sub-navigation items for that section. The flyout stays open while the cursor is on either the rail item or the flyout panel.
**Pinned state:** Clicking the pin button expands to a traditional 260px sidebar with full text labels, section headers, badges, and the active left-bar accent. An unpin button in the header returns to the icon rail.
### Active Nav Indicator
- **Icon rail:** `accent-dim` background on the item, `accent-text` color on icon and label
- **Pinned sidebar:** Same as above, plus a 3px left border (`border-radius: 0 3px 3px 0`) in `accent` color
### Main Content Area
- Padding: 28px top/bottom, 36px left/right
- Max content width: not constrained (fills available space)
- Page title: Bricolage Grotesque, 22px, weight 700
---
## Component Patterns
### Stat Cards
```
Background: bg-card
Border: 1px solid border-default
Border-left: 3px solid [varies by position - accent, success, warning, accent]
Border-radius: 8px
Padding: 18px 16px
```
- Label: 11px, uppercase, 600 weight, text-muted
- Value: 28px, Bricolage Grotesque 700, text-heading
- Delta: 12px, 500 weight, success/danger color with ↑/↓ prefix
### Cards
```
Background: bg-card
Border: 1px solid border-default
Border-radius: 8px
Padding: 20px
Hover: border-color transitions to border-hover
```
No shadows. No gradients. No glow effects.
### Flow List Items
```
Layout: flex row, 12px gap
Padding: 10px 8px
Border-bottom: 1px solid border-default (divider style, not bordered cards)
Hover: bg-card-hover
```
- Icon: 34px square, border-radius 5px, semantic dim background + colored stroke
- Name: 13px, 500 weight, text-heading
- Meta: 11.5px, text-muted
- Badge: right-aligned status badge
### Badges
```
Font: 11px, 550 weight
Padding: 3px 9px
Border-radius: 20px (pill)
```
| Type | Background | Text Color |
|------|-----------|------------|
| Info/Accent | accent-dim | accent-text |
| Success | success-dim | success |
| Warning | warning-dim | warning |
| Danger | danger-dim | danger |
### Form Inputs
```
Background: bg-input
Border: 1px solid border-default
Border-radius: 5px
Padding: 9px 12px
Font: 13px, IBM Plex Sans
Focus: border-color accent, box-shadow 0 0 0 2px accent-dim
Placeholder: text-muted
```
### Buttons
**Primary:**
```
Background: accent (#22d3ee)
Color: #fff
Border: none
Border-radius: 5px
Padding: 9px 16px
Font: 13px, 550 weight
Hover: brightness(1.1)
```
**Ghost:**
```
Background: transparent
Color: text-secondary
Border: 1px solid border-default
Hover: bg-elevated, text-primary, border-hover
```
### Code Blocks
```
Background: bg-code (#0e1017)
Border: 1px solid border-default
Border-radius: 8px
Padding: 18px 20px
Font: JetBrains Mono, 12px, line-height 1.7
```
**Syntax colors (dark mode):**
| Token | Color |
|-------|-------|
| Comment | #4a5568 |
| Keyword | #c792ea |
| Function/Cmdlet | #82aaff |
| String | #c3e88d |
| Variable | #89ddff |
| Parameter | #8c93a4 |
| Number | #f78c6c |
### Chips / Tags
```
Font: 11.5px, 500 weight
Padding: 4px 11px
Border-radius: 20px
Background: accent-dim
Color: accent-text
```
---
## Logo
- **Mark:** 30-32px square, border-radius 8px, `linear-gradient(135deg, #06b6d4, #22d3ee)`, white lightning bolt SVG
- **Wordmark:** "ResolutionFlow" in Bricolage Grotesque, 16-17px, weight 700, text-heading color
- **Combined:** Mark + wordmark horizontally, 10px gap
---
## Spacing System
- Component internal gaps: 6px, 8px, 12px, 14px, 16px
- Card padding: 20px
- Section gaps: 24px between major sections
- Page padding: 28px vertical, 36px horizontal
- Stat grid gap: 12px
- Two-column gap: 16px
- Nav item padding: 8px 10px (pinned), 8px 4px (rail)
---
## Border Radius
| Token | Value | Use |
|-------|-------|-----|
| radius-sm | 5px | Inputs, buttons, small elements |
| radius | 8px | Cards, stat cards, code blocks |
| radius-lg | 12px | Large cards, modals |
| radius-xl | 16px | Hero elements, CTA boxes |
| radius-pill | 100px | Badges, chips, toggle tracks |
---
## Shadows
Minimal to none. No decorative shadows.
- Cards: none (border only)
- Dropdowns/flyouts: `0 4px 12px rgba(0,0,0,0.3)` if needed
- Logo mark: `0 2px 8px rgba(14,165,233,0.25)` (subtle brand glow on logo only)
---
## Icons
All icons use Lucide React (`lucide-react` package).
- Default size: 16-18px
- Stroke width: 1.6-1.8
- Color: `currentColor` (inherits from parent text color)
- Nav icons: 20px at stroke-width 1.6
- Rail icon opacity: 0.6 default, 0.85 on hover, 1.0 when active
---
## Landing Page
The marketing landing page at `/` shares the same color system and typography but has its own layout (no sidebar, full-width sections). Key differences:
- Navigation: fixed top bar with logo, links, and CTAs
- Hero: centered layout with glow effect (radial gradient, accent at 15% opacity)
- Sections: 100px vertical padding, max-width 1120px container
- Section labels: JetBrains Mono, 12px, uppercase, accent-text color
- Section titles: Bricolage Grotesque, clamp(28px, 4vw, 42px), weight 800
- Pricing cards: same card pattern but with featured state (accent border + subtle glow)
- Product mockup: embedded in hero, shows the actual app UI with browser chrome
---
## Files That Define The Design System
These are the source-of-truth files in the codebase:
| File | What It Controls |
|------|-----------------|
| `frontend/src/index.css` | CSS variables, `@theme` block, base styles |
| `frontend/tailwind.config.js` (v3) or inline in index.css (v4) | Color tokens, font families, spacing extensions |
| `frontend/index.html` | Google Font imports |
| `DESIGN-SYSTEM.md` (this file) | Design decisions, component specs, rules |
---
## Deprecated Files — DO NOT Reference
These files contain outdated design information and should be ignored:
- `DESIGN_SYSTEM_GUIDE.md` — Old monochrome glass-morphism system
- `UI-DESIGN-SYSTEM.md` — Old workspace/purple gradient system
- `REBRAND-IMPLEMENTATION-GUIDE.md` — Old purple rebrand from Patherly
- `COMPONENT_EXAMPLES.md` — Old monochrome component patterns
- Any file referencing `glass-card`, `glass-stat`, `bg-gradient-brand`, or `text-gradient-brand`

View File

@@ -69,7 +69,7 @@ export function DeleteAccountModal({ onClose }: Props) {
onClick={onClose} onClick={onClose}
className={cn( className={cn(
'rounded-lg px-4 py-2 text-sm font-medium', 'rounded-lg px-4 py-2 text-sm font-medium',
'bg-white/[0.04] border border-brand-border text-[#e2e5eb]' 'bg-[#191c25] border border-[#1e2130] text-[#e2e5eb]'
)} )}
> >
Cancel Cancel

View File

@@ -45,7 +45,7 @@ export function LeaveAccountModal({ accountName, onClose }: Props) {
onClick={onClose} onClick={onClose}
className={cn( className={cn(
'rounded-lg px-4 py-2 text-sm font-medium', 'rounded-lg px-4 py-2 text-sm font-medium',
'bg-white/[0.04] border border-brand-border text-[#e2e5eb]' 'bg-[#191c25] border border-[#1e2130] text-[#e2e5eb]'
)} )}
> >
Cancel Cancel

View File

@@ -90,7 +90,7 @@ export function TransferOwnershipModal({ members, onClose, onTransferred }: Prop
onClick={onClose} onClick={onClose}
className={cn( className={cn(
'rounded-lg px-4 py-2 text-sm font-medium', 'rounded-lg px-4 py-2 text-sm font-medium',
'bg-white/[0.04] border border-brand-border text-[#e2e5eb]' 'bg-[#191c25] border border-[#1e2130] text-[#e2e5eb]'
)} )}
> >
Cancel Cancel
@@ -100,7 +100,7 @@ export function TransferOwnershipModal({ members, onClose, onTransferred }: Prop
disabled={isSubmitting || !password} disabled={isSubmitting || !password}
className={cn( className={cn(
'rounded-lg px-4 py-2 text-sm font-semibold', 'rounded-lg px-4 py-2 text-sm font-semibold',
'bg-amber-500 text-brand-dark hover:bg-amber-400', 'bg-amber-500 text-white hover:bg-amber-400',
'disabled:opacity-50' 'disabled:opacity-50'
)} )}
> >

View File

@@ -29,7 +29,7 @@ export function ChatMessage({ role, content, suggestedFlows }: ChatMessageProps)
className={`rounded-2xl px-4 py-3 text-[0.875rem] leading-relaxed ${ className={`rounded-2xl px-4 py-3 text-[0.875rem] leading-relaxed ${
role === 'user' role === 'user'
? 'bg-primary/15 text-[#e2e5eb]' ? 'bg-primary/15 text-[#e2e5eb]'
: 'bg-white/[0.04] text-[#e2e5eb] border border-brand-border' : 'bg-[#191c25] text-[#e2e5eb] border border-[#1e2130]'
}`} }`}
> >
<MarkdownContent content={content} className="text-[0.875rem] leading-relaxed" /> <MarkdownContent content={content} className="text-[0.875rem] leading-relaxed" />

View File

@@ -31,7 +31,7 @@ export function ChatSidebar({
<div className="px-4 py-3 border-b shrink-0" style={{ borderColor: 'var(--glass-border)' }}> <div className="px-4 py-3 border-b shrink-0" style={{ borderColor: 'var(--glass-border)' }}>
<button <button
onClick={onNewChat} onClick={onNewChat}
className="w-full flex items-center justify-center gap-2 bg-[#22d3ee] text-brand-dark font-semibold text-sm rounded-lg px-4 py-2.5 hover:brightness-110 active:scale-[0.98] transition-all" className="w-full flex items-center justify-center gap-2 bg-[#22d3ee] text-white font-semibold text-sm rounded-lg px-4 py-2.5 hover:brightness-110 active:scale-[0.98] transition-all"
> >
<Plus size={16} /> <Plus size={16} />
New Chat New Chat
@@ -103,7 +103,7 @@ function ChatItem({
'group flex items-center gap-2 px-3 py-2.5 mx-1.5 rounded-lg cursor-pointer transition-colors', 'group flex items-center gap-2 px-3 py-2.5 mx-1.5 rounded-lg cursor-pointer transition-colors',
isActive isActive
? 'bg-[rgba(34,211,238,0.10)] text-[#e2e5eb]' ? 'bg-[rgba(34,211,238,0.10)] text-[#e2e5eb]'
: 'text-[#848b9b] hover:bg-white/[0.04] hover:text-[#e2e5eb]' : 'text-[#848b9b] hover:bg-[#191c25] hover:text-[#e2e5eb]'
)} )}
> >
<MessageSquare size={14} className="shrink-0" /> <MessageSquare size={14} className="shrink-0" />

View File

@@ -169,7 +169,7 @@ export function ConcludeSessionModal({
</div> </div>
<button <button
onClick={onClose} onClick={onClose}
className="p-2 rounded-lg hover:bg-brand-border text-[#848b9b] hover:text-[#e2e5eb] transition-colors" className="p-2 rounded-lg hover:bg-[#1e2130] text-[#848b9b] hover:text-[#e2e5eb] transition-colors"
> >
<X size={18} /> <X size={18} />
</button> </button>
@@ -196,7 +196,7 @@ export function ConcludeSessionModal({
className={cn( className={cn(
'w-6 h-6 rounded-full flex items-center justify-center text-[0.6875rem] font-sans text-xs font-medium transition-colors', 'w-6 h-6 rounded-full flex items-center justify-center text-[0.6875rem] font-sans text-xs font-medium transition-colors',
step === s step === s
? 'bg-[#22d3ee] text-brand-dark' ? 'bg-[#22d3ee] text-white'
: (i < ['select-outcome', 'add-notes', 'summary'].indexOf(step)) : (i < ['select-outcome', 'add-notes', 'summary'].indexOf(step))
? 'bg-primary/20 text-[#22d3ee]' ? 'bg-primary/20 text-[#22d3ee]'
: 'bg-brand-border text-[#848b9b]' : 'bg-brand-border text-[#848b9b]'
@@ -233,8 +233,8 @@ export function ConcludeSessionModal({
className={cn( className={cn(
'w-full flex items-center gap-4 p-4 rounded-xl border transition-all text-left', 'w-full flex items-center gap-4 p-4 rounded-xl border transition-all text-left',
'hover:scale-[1.01] active:scale-[0.99]', 'hover:scale-[1.01] active:scale-[0.99]',
'bg-white/[0.02] border-brand-border', 'bg-[#14161d] border-[#1e2130]',
'hover:border-white/[0.12] hover:bg-white/[0.04]' 'hover:border-[#2a2f3d] hover:bg-[#191c25]'
)} )}
> >
<div className={cn('w-10 h-10 rounded-xl flex items-center justify-center', o.bg)}> <div className={cn('w-10 h-10 rounded-xl flex items-center justify-center', o.bg)}>
@@ -308,7 +308,7 @@ export function ConcludeSessionModal({
{/* Generated summary */} {/* Generated summary */}
<div <div
className="rounded-xl border p-5 bg-white/[0.02]" className="rounded-xl border p-5 bg-[#14161d]"
style={{ borderColor: 'var(--glass-border)' }} style={{ borderColor: 'var(--glass-border)' }}
> >
<div className="flex items-center justify-between mb-3"> <div className="flex items-center justify-between mb-3">
@@ -335,7 +335,7 @@ export function ConcludeSessionModal({
<div /> <div />
<button <button
onClick={onClose} onClick={onClose}
className="px-4 py-2 rounded-lg text-sm text-[#848b9b] hover:text-[#e2e5eb] bg-white/[0.04] border border-brand-border hover:border-white/[0.12] transition-all" className="px-4 py-2 rounded-lg text-sm text-[#848b9b] hover:text-[#e2e5eb] bg-[#191c25] border border-[#1e2130] hover:border-[#2a2f3d] transition-all"
> >
Cancel Cancel
</button> </button>
@@ -346,14 +346,14 @@ export function ConcludeSessionModal({
<> <>
<button <button
onClick={() => setStep('select-outcome')} onClick={() => setStep('select-outcome')}
className="px-4 py-2 rounded-lg text-sm text-[#848b9b] hover:text-[#e2e5eb] bg-white/[0.04] border border-brand-border hover:border-white/[0.12] transition-all" className="px-4 py-2 rounded-lg text-sm text-[#848b9b] hover:text-[#e2e5eb] bg-[#191c25] border border-[#1e2130] hover:border-[#2a2f3d] transition-all"
> >
Back Back
</button> </button>
<button <button
onClick={handleGenerate} onClick={handleGenerate}
disabled={generating} disabled={generating}
className="flex items-center gap-2 bg-[#22d3ee] text-brand-dark font-semibold text-sm rounded-lg px-5 py-2.5 hover:brightness-110 active:scale-[0.98] transition-all disabled:opacity-50" className="flex items-center gap-2 bg-[#22d3ee] text-white font-semibold text-sm rounded-lg px-5 py-2.5 hover:brightness-110 active:scale-[0.98] transition-all disabled:opacity-50"
> >
{generating ? ( {generating ? (
<> <>
@@ -390,7 +390,7 @@ export function ConcludeSessionModal({
'flex items-center gap-2 px-4 py-2.5 rounded-lg text-sm font-semibold transition-all', 'flex items-center gap-2 px-4 py-2.5 rounded-lg text-sm font-semibold transition-all',
copied copied
? 'bg-emerald-400/15 text-emerald-400 border border-emerald-400/30' ? 'bg-emerald-400/15 text-emerald-400 border border-emerald-400/30'
: 'bg-[#22d3ee] text-brand-dark hover:brightness-110 active:scale-[0.98]' : 'bg-[#22d3ee] text-white hover:brightness-110 active:scale-[0.98]'
)} )}
> >
{copied ? ( {copied ? (
@@ -407,7 +407,7 @@ export function ConcludeSessionModal({
</button> </button>
<button <button
onClick={onClose} onClick={onClose}
className="px-4 py-2.5 rounded-lg text-sm text-[#848b9b] hover:text-[#e2e5eb] bg-white/[0.04] border border-brand-border hover:border-white/[0.12] transition-all" className="px-4 py-2.5 rounded-lg text-sm text-[#848b9b] hover:text-[#e2e5eb] bg-[#191c25] border border-[#1e2130] hover:border-[#2a2f3d] transition-all"
> >
Done Done
</button> </button>

View File

@@ -18,7 +18,7 @@ export function SuggestedFlowCard({ flow }: SuggestedFlowCardProps) {
return ( return (
<button <button
onClick={handleClick} onClick={handleClick}
className="w-full text-left card-flat p-3 rounded-xl hover:border-white/[0.12] transition-colors group" className="w-full text-left card-flat p-3 rounded-xl hover:border-[#2a2f3d] transition-colors group"
> >
<div className="flex items-start gap-2"> <div className="flex items-start gap-2">
<Box size={14} className="text-[#22d3ee] mt-0.5 shrink-0" /> <Box size={14} className="text-[#22d3ee] mt-0.5 shrink-0" />

View File

@@ -87,7 +87,7 @@ export function ContextMenu({ position, items, onClose }: ContextMenuProps) {
'flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm transition-colors', 'flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm transition-colors',
item.variant === 'danger' item.variant === 'danger'
? 'text-rose-400 hover:bg-rose-500/10' ? 'text-rose-400 hover:bg-rose-500/10'
: 'text-[#e2e5eb] hover:bg-brand-border' : 'text-[#e2e5eb] hover:bg-[#1e2130]'
)} )}
> >
{item.icon && ( {item.icon && (

View File

@@ -110,7 +110,7 @@ export function CopilotPanel({ isOpen, onClose, treeId, sessionId, currentNodeId
</div> </div>
<button <button
onClick={onClose} onClick={onClose}
className="p-1.5 rounded-lg hover:bg-brand-border text-[#848b9b] hover:text-[#e2e5eb] transition-colors" className="p-1.5 rounded-lg hover:bg-[#1e2130] text-[#848b9b] hover:text-[#e2e5eb] transition-colors"
> >
<X size={16} /> <X size={16} />
</button> </button>
@@ -124,7 +124,7 @@ export function CopilotPanel({ isOpen, onClose, treeId, sessionId, currentNodeId
className={`max-w-[85%] rounded-xl px-3.5 py-2.5 text-[0.8125rem] leading-relaxed ${ className={`max-w-[85%] rounded-xl px-3.5 py-2.5 text-[0.8125rem] leading-relaxed ${
msg.role === 'user' msg.role === 'user'
? 'bg-primary/15 text-[#e2e5eb]' ? 'bg-primary/15 text-[#e2e5eb]'
: 'bg-white/[0.04] text-[#e2e5eb] border border-brand-border' : 'bg-[#191c25] text-[#e2e5eb] border border-[#1e2130]'
}`} }`}
> >
<MarkdownContent content={msg.content} className="text-[0.8125rem] leading-relaxed" /> <MarkdownContent content={msg.content} className="text-[0.8125rem] leading-relaxed" />
@@ -133,7 +133,7 @@ export function CopilotPanel({ isOpen, onClose, treeId, sessionId, currentNodeId
))} ))}
{loading && ( {loading && (
<div className="flex justify-start"> <div className="flex justify-start">
<div className="bg-white/[0.04] border border-brand-border rounded-xl px-3.5 py-2.5"> <div className="bg-[#191c25] border border-[#1e2130] rounded-xl px-3.5 py-2.5">
<Loader2 size={16} className="animate-spin text-[#22d3ee]" /> <Loader2 size={16} className="animate-spin text-[#22d3ee]" />
</div> </div>
</div> </div>
@@ -171,7 +171,7 @@ export function CopilotPanel({ isOpen, onClose, treeId, sessionId, currentNodeId
<button <button
onClick={handleSend} onClick={handleSend}
disabled={!input.trim() || loading || initializing} disabled={!input.trim() || loading || initializing}
className="bg-[#22d3ee] text-brand-dark p-2.5 rounded-xl hover:brightness-110 active:scale-[0.98] transition-all disabled:opacity-40" className="bg-[#22d3ee] text-white p-2.5 rounded-xl hover:brightness-110 active:scale-[0.98] transition-all disabled:opacity-40"
> >
<Send size={16} /> <Send size={16} />
</button> </button>

View File

@@ -83,7 +83,7 @@ export function AIPromptDialog({
<button <button
onClick={onClose} onClick={onClose}
disabled={isGenerating} disabled={isGenerating}
className="rounded-[10px] bg-white/[0.04] border border-brand-border px-4 py-2 text-sm text-foreground hover:border-white/[0.12] transition-colors disabled:opacity-50" className="rounded-[10px] bg-[#191c25] border border-[#1e2130] px-4 py-2 text-sm text-foreground hover:border-[#2a2f3d] transition-colors disabled:opacity-50"
> >
Cancel Cancel
</button> </button>

View File

@@ -50,7 +50,7 @@ export function ChatTab({ messages, input, onInputChange, onSend, isLoading }: C
className={`max-w-[85%] rounded-xl px-3.5 py-2.5 text-[0.8125rem] leading-relaxed ${ className={`max-w-[85%] rounded-xl px-3.5 py-2.5 text-[0.8125rem] leading-relaxed ${
msg.role === 'user' msg.role === 'user'
? 'bg-primary/15 text-foreground' ? 'bg-primary/15 text-foreground'
: 'bg-white/[0.04] text-foreground border border-brand-border' : 'bg-[#191c25] text-foreground border border-[#1e2130]'
}`} }`}
> >
<MarkdownContent content={msg.content} className="text-[0.8125rem] leading-relaxed" /> <MarkdownContent content={msg.content} className="text-[0.8125rem] leading-relaxed" />
@@ -59,7 +59,7 @@ export function ChatTab({ messages, input, onInputChange, onSend, isLoading }: C
))} ))}
{isLoading && ( {isLoading && (
<div className="flex justify-start"> <div className="flex justify-start">
<div className="bg-white/[0.04] border border-brand-border rounded-xl px-3.5 py-2.5"> <div className="bg-[#191c25] border border-[#1e2130] rounded-xl px-3.5 py-2.5">
<Loader2 size={16} className="animate-spin text-primary" /> <Loader2 size={16} className="animate-spin text-primary" />
</div> </div>
</div> </div>

View File

@@ -65,7 +65,7 @@ export function EditorAIPanel({
</div> </div>
<button <button
onClick={onClose} onClick={onClose}
className="p-1.5 rounded-lg hover:bg-brand-border text-muted-foreground hover:text-foreground transition-colors" className="p-1.5 rounded-lg hover:bg-[#1e2130] text-muted-foreground hover:text-foreground transition-colors"
> >
<X size={16} /> <X size={16} />
</button> </button>

View File

@@ -26,7 +26,7 @@ export function SuggestionsTab({ suggestions }: SuggestionsTabProps) {
const config = STATUS_CONFIG[s.status] const config = STATUS_CONFIG[s.status]
const StatusIcon = config.icon const StatusIcon = config.icon
return ( return (
<div key={s.id} className="rounded-lg border border-border bg-white/[0.02] px-3 py-2"> <div key={s.id} className="rounded-lg border border-border bg-[#14161d] px-3 py-2">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<span className="font-label text-[0.625rem] uppercase tracking-widest text-muted-foreground"> <span className="font-label text-[0.625rem] uppercase tracking-widest text-muted-foreground">
{s.action_type.replace(/_/g, ' ')} {s.action_type.replace(/_/g, ' ')}
@@ -39,7 +39,7 @@ export function SuggestionsTab({ suggestions }: SuggestionsTabProps) {
{s.target_node_id && ( {s.target_node_id && (
<p className="mt-1 text-xs text-muted-foreground truncate">Node: {s.target_node_id}</p> <p className="mt-1 text-xs text-muted-foreground truncate">Node: {s.target_node_id}</p>
)} )}
<p className="mt-0.5 font-label text-[0.625rem] text-brand-text-muted"> <p className="mt-0.5 font-label text-[0.625rem] text-[#4f5666]">
{new Date(s.created_at).toLocaleDateString()} {new Date(s.created_at).toLocaleDateString()}
</p> </p>
</div> </div>

View File

@@ -122,7 +122,7 @@ export function ImportFlowModal({ onClose }: ImportFlowModalProps) {
'flex flex-col items-center justify-center rounded-lg border-2 border-dashed px-4 py-8 text-center transition-colors cursor-pointer', 'flex flex-col items-center justify-center rounded-lg border-2 border-dashed px-4 py-8 text-center transition-colors cursor-pointer',
isDragging isDragging
? 'border-primary/50 bg-primary/5' ? 'border-primary/50 bg-primary/5'
: 'border-[#1e2130] hover:border-white/[0.12]' : 'border-[#1e2130] hover:border-[#2a2f3d]'
)} )}
onClick={() => fileInputRef.current?.click()} onClick={() => fileInputRef.current?.click()}
onDragOver={(e) => { e.preventDefault(); setIsDragging(true) }} onDragOver={(e) => { e.preventDefault(); setIsDragging(true) }}

View File

@@ -64,7 +64,7 @@ export function FallbackSteps({
key={fbStep.id} key={fbStep.id}
className={cn( className={cn(
'rounded-lg border p-3 transition-colors', 'rounded-lg border p-3 transition-colors',
'bg-white/[0.02] border-[#1e2130]/50', 'bg-[#14161d] border-[#1e2130]/50',
isCompleted && 'border-emerald-500/30 bg-emerald-500/5' isCompleted && 'border-emerald-500/30 bg-emerald-500/5'
)} )}
> >

View File

@@ -60,7 +60,7 @@ export function ParameterCard({
<button <button
type="button" type="button"
onClick={() => setExpanded(v => !v)} onClick={() => setExpanded(v => !v)}
className="w-full flex items-center gap-2 px-3 py-2.5 bg-white/[0.02] hover:bg-white/[0.04] transition-colors" className="w-full flex items-center gap-2 px-3 py-2.5 bg-[#14161d] hover:bg-[#191c25] transition-colors"
> >
<GripVertical size={14} className="text-[#848b9b]/50 shrink-0" /> <GripVertical size={14} className="text-[#848b9b]/50 shrink-0" />
{expanded ? <ChevronDown size={14} className="text-[#848b9b]" /> : <ChevronRight size={14} className="text-[#848b9b]" />} {expanded ? <ChevronDown size={14} className="text-[#848b9b]" /> : <ChevronRight size={14} className="text-[#848b9b]" />}

View File

@@ -138,7 +138,7 @@ export function ScriptTemplateListView({ onEdit, onCreate }: Props) {
{templates.map(t => ( {templates.map(t => (
<tr <tr
key={t.id} key={t.id}
className="border-b border-[#1e2130] last:border-b-0 hover:bg-white/[0.02] transition-colors" className="border-b border-[#1e2130] last:border-b-0 hover:bg-[#14161d] transition-colors"
> >
<td className="px-4 py-3"> <td className="px-4 py-3">
<span className="text-[#e2e5eb] font-medium">{t.name}</span> <span className="text-[#e2e5eb] font-medium">{t.name}</span>

View File

@@ -43,7 +43,7 @@ export function ScriptParameterForm({ canGenerate }: Props) {
if (parameters.length === 0) { if (parameters.length === 0) {
return ( return (
<div className="flex items-center gap-2 rounded-lg border border-border bg-white/[0.02] px-3 py-3"> <div className="flex items-center gap-2 rounded-lg border border-border bg-[#14161d] px-3 py-3">
<Terminal size={14} className="text-muted-foreground shrink-0" /> <Terminal size={14} className="text-muted-foreground shrink-0" />
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
This template has no parameters click <span className="text-foreground font-medium">Generate</span> to produce the script. This template has no parameters click <span className="text-foreground font-medium">Generate</span> to produce the script.

View File

@@ -290,7 +290,7 @@ export function TicketPickerModal({ open, onClose, sessionId, onLinked, onSelect
disabled={isLooking} disabled={isLooking}
className={cn( className={cn(
'w-full rounded-lg border border-transparent px-3 py-2.5 text-left transition-all', 'w-full rounded-lg border border-transparent px-3 py-2.5 text-left transition-all',
'hover:border-[#1e2130] hover:bg-white/[0.04]', 'hover:border-[#1e2130] hover:bg-[#191c25]',
'disabled:opacity-50', 'disabled:opacity-50',
result.closed && 'opacity-60' result.closed && 'opacity-60'
)} )}

View File

@@ -8,9 +8,9 @@ const buttonVariants = cva(
variants: { variants: {
variant: { variant: {
primary: primary:
'bg-[#22d3ee] text-brand-dark font-semibold hover:brightness-110', 'bg-[#22d3ee] text-white font-semibold hover:brightness-110',
secondary: secondary:
'bg-white/[0.04] border border-brand-border text-[#e2e5eb] hover:border-white/[0.12] hover:bg-brand-border', 'bg-[#191c25] border border-[#1e2130] text-[#e2e5eb] hover:border-[#2a2f3d] hover:bg-[#1e2130]',
destructive: destructive:
'bg-red-400/10 text-red-400 border border-red-400/20 hover:bg-red-400/20', 'bg-red-400/10 text-red-400 border border-red-400/20 hover:bg-red-400/20',
ghost: ghost:

View File

@@ -47,7 +47,7 @@ export function ListSkeleton({ count = 5, className }: { count?: number; classNa
return ( return (
<div className={cn('space-y-3', className)}> <div className={cn('space-y-3', className)}>
{Array.from({ length: count }).map((_, i) => ( {Array.from({ length: count }).map((_, i) => (
<div key={i} className="flex items-center gap-3 px-4 py-3 rounded-lg bg-white/[0.02]"> <div key={i} className="flex items-center gap-3 px-4 py-3 rounded-lg bg-[#14161d]">
<Skeleton className="size-8 rounded-full shrink-0" /> <Skeleton className="size-8 rounded-full shrink-0" />
<div className="flex-1 space-y-2"> <div className="flex-1 space-y-2">
<Skeleton className="h-4 w-2/3" /> <Skeleton className="h-4 w-2/3" />

View File

@@ -275,7 +275,7 @@ export default function AssistantChatPage() {
<div className="w-8 h-8 rounded-full bg-primary/15 flex items-center justify-center"> <div className="w-8 h-8 rounded-full bg-primary/15 flex items-center justify-center">
<Sparkles size={14} className="text-[#22d3ee]" /> <Sparkles size={14} className="text-[#22d3ee]" />
</div> </div>
<div className="bg-white/[0.04] border border-brand-border rounded-2xl px-4 py-3"> <div className="bg-[#191c25] border border-[#1e2130] rounded-2xl px-4 py-3">
<Loader2 size={16} className="animate-spin text-[#22d3ee]" /> <Loader2 size={16} className="animate-spin text-[#22d3ee]" />
</div> </div>
</div> </div>
@@ -302,7 +302,7 @@ export default function AssistantChatPage() {
<button <button
onClick={handleSend} onClick={handleSend}
disabled={!input.trim() || loading} disabled={!input.trim() || loading}
className="bg-[#22d3ee] text-brand-dark p-3 rounded-xl hover:brightness-110 active:scale-[0.98] transition-all disabled:opacity-40" className="bg-[#22d3ee] text-white p-3 rounded-xl hover:brightness-110 active:scale-[0.98] transition-all disabled:opacity-40"
title="Send message" title="Send message"
> >
<Send size={18} /> <Send size={18} />
@@ -338,7 +338,7 @@ export default function AssistantChatPage() {
</p> </p>
<button <button
onClick={handleNewChat} onClick={handleNewChat}
className="bg-[#22d3ee] text-brand-dark font-semibold text-sm rounded-lg px-6 py-2.5 hover:brightness-110 active:scale-[0.98] transition-all" className="bg-[#22d3ee] text-white font-semibold text-sm rounded-lg px-6 py-2.5 hover:brightness-110 active:scale-[0.98] transition-all"
> >
Start a Conversation Start a Conversation
</button> </button>

View File

@@ -14,7 +14,7 @@ export default function GuideDetailPage() {
<p className="text-sm text-[#848b9b] mb-4">The guide you're looking for doesn't exist.</p> <p className="text-sm text-[#848b9b] mb-4">The guide you're looking for doesn't exist.</p>
<Link <Link
to="/guides" to="/guides"
className="bg-[#22d3ee] text-brand-dark font-semibold text-sm rounded-lg px-5 py-2 hover:brightness-110 active:scale-[0.98] transition-all" className="bg-[#22d3ee] text-white font-semibold text-sm rounded-lg px-5 py-2 hover:brightness-110 active:scale-[0.98] transition-all"
> >
Back to Guides Back to Guides
</Link> </Link>

View File

@@ -149,7 +149,7 @@ export function LoginPage() {
data-testid="login-submit" data-testid="login-submit"
className={cn( className={cn(
'w-full rounded-lg px-4 py-2.5 text-sm font-semibold', 'w-full rounded-lg px-4 py-2.5 text-sm font-semibold',
'bg-[#22d3ee] text-brand-dark hover:brightness-110 active:scale-[0.98]', 'bg-[#22d3ee] text-white hover:brightness-110 active:scale-[0.98]',
'focus:outline-hidden focus:ring-2 focus:ring-primary/30 focus:ring-offset-2 focus:ring-offset-background', 'focus:outline-hidden focus:ring-2 focus:ring-primary/30 focus:ring-offset-2 focus:ring-offset-background',
'disabled:cursor-not-allowed disabled:opacity-50', 'disabled:cursor-not-allowed disabled:opacity-50',
'transition-all' 'transition-all'

View File

@@ -399,12 +399,12 @@ export default function SurveyPage() {
</button> </button>
) : <div />} ) : <div />}
{si < SLIDES.length - 1 ? ( {si < SLIDES.length - 1 ? (
<button onClick={() => goSlide(si + 1)} className="inline-flex items-center gap-2 px-5 py-2.5 sm:px-6 sm:py-3 rounded-lg text-sm font-semibold bg-[#22d3ee] text-brand-dark transition-all duration-150 hover:brightness-110 active:scale-[0.98]"> <button onClick={() => goSlide(si + 1)} className="inline-flex items-center gap-2 px-5 py-2.5 sm:px-6 sm:py-3 rounded-lg text-sm font-semibold bg-[#22d3ee] text-white transition-all duration-150 hover:brightness-110 active:scale-[0.98]">
Next Next
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14"/><path d="M12 5l7 7-7 7"/></svg> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14"/><path d="M12 5l7 7-7 7"/></svg>
</button> </button>
) : ( ) : (
<button onClick={handleSubmit} disabled={isSubmitting} className="inline-flex items-center gap-2 px-5 py-2.5 sm:px-6 sm:py-3 rounded-lg text-sm font-semibold bg-[#22d3ee] text-brand-dark transition-all duration-150 hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed"> <button onClick={handleSubmit} disabled={isSubmitting} className="inline-flex items-center gap-2 px-5 py-2.5 sm:px-6 sm:py-3 rounded-lg text-sm font-semibold bg-[#22d3ee] text-white transition-all duration-150 hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed">
{isSubmitting ? 'Submitting...' : 'Submit'} {isSubmitting ? 'Submitting...' : 'Submit'}
{!isSubmitting && <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M20 6L9 17l-5-5"/></svg>} {!isSubmitting && <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M20 6L9 17l-5-5"/></svg>}
</button> </button>
@@ -443,7 +443,7 @@ export default function SurveyPage() {
value={emailInput} value={emailInput}
onChange={e => setEmailInput(e.target.value)} onChange={e => setEmailInput(e.target.value)}
placeholder="your@email.com" placeholder="your@email.com"
className="flex-1 rounded-[9px] px-3.5 py-2.5 text-sm text-[#e2e5eb] placeholder:text-brand-text-muted focus:outline-hidden" className="flex-1 rounded-[9px] px-3.5 py-2.5 text-sm text-[#e2e5eb] placeholder:text-[#4f5666] focus:outline-hidden"
style={{ background: 'rgba(16, 17, 20, 0.6)', border: '1px solid var(--glass-border)' }} style={{ background: 'rgba(16, 17, 20, 0.6)', border: '1px solid var(--glass-border)' }}
onFocus={e => { e.currentTarget.style.borderColor = 'var(--color-primary)' }} onFocus={e => { e.currentTarget.style.borderColor = 'var(--color-primary)' }}
onBlur={e => { e.currentTarget.style.borderColor = 'var(--glass-border)' }} onBlur={e => { e.currentTarget.style.borderColor = 'var(--glass-border)' }}
@@ -473,7 +473,7 @@ export default function SurveyPage() {
} }
}} }}
disabled={!emailInput.trim() || emailSending} disabled={!emailInput.trim() || emailSending}
className="inline-flex items-center justify-center gap-2 px-5 py-2.5 rounded-[9px] text-sm font-semibold bg-[#22d3ee] text-brand-dark transition-all duration-150 hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed whitespace-nowrap" className="inline-flex items-center justify-center gap-2 px-5 py-2.5 rounded-[9px] text-sm font-semibold bg-[#22d3ee] text-white transition-all duration-150 hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed whitespace-nowrap"
> >
{emailSending ? ( {emailSending ? (
<> <>
@@ -502,7 +502,7 @@ export default function SurveyPage() {
</button> </button>
<button <button
onClick={() => navigate('/survey/thank-you')} onClick={() => navigate('/survey/thank-you')}
className="inline-flex items-center gap-2 px-5 py-2.5 sm:px-6 rounded-lg text-sm font-semibold bg-[#22d3ee] text-brand-dark transition-all duration-150 hover:brightness-110 active:scale-[0.98]" className="inline-flex items-center gap-2 px-5 py-2.5 sm:px-6 rounded-lg text-sm font-semibold bg-[#22d3ee] text-white transition-all duration-150 hover:brightness-110 active:scale-[0.98]"
> >
Finish Finish
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14"/><path d="M12 5l7 7-7 7"/></svg> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M5 12h14"/><path d="M12 5l7 7-7 7"/></svg>
@@ -600,7 +600,7 @@ function QuestionCard({ question: q, answer, setAnswer }: { question: SurveyQues
value={(answer as string) || ''} value={(answer as string) || ''}
onChange={e => setAnswer(q.id, e.target.value)} onChange={e => setAnswer(q.id, e.target.value)}
placeholder="Type your answer here..." placeholder="Type your answer here..."
className="w-full min-h-[100px] rounded-[9px] p-3 sm:p-3.5 text-[13px] sm:text-sm text-[#e2e5eb] leading-relaxed resize-y transition-all duration-200 placeholder:text-brand-text-muted focus:outline-hidden" className="w-full min-h-[100px] rounded-[9px] p-3 sm:p-3.5 text-[13px] sm:text-sm text-[#e2e5eb] leading-relaxed resize-y transition-all duration-200 placeholder:text-[#4f5666] focus:outline-hidden"
style={{ style={{
background: 'rgba(16, 17, 20, 0.6)', background: 'rgba(16, 17, 20, 0.6)',
border: '1px solid var(--glass-border)', border: '1px solid var(--glass-border)',
@@ -736,7 +736,7 @@ function DragRank({ items, onChange }: { items: string[]; onChange: (items: stri
color: 'var(--color-muted-foreground)', color: 'var(--color-muted-foreground)',
}} }}
> >
<div className="shrink-0 text-brand-text-muted"> <div className="shrink-0 text-[#4f5666]">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="9" cy="6" r="1"/><circle cx="15" cy="6" r="1"/><circle cx="9" cy="12" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="9" cy="18" r="1"/><circle cx="15" cy="18" r="1"/></svg> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="9" cy="6" r="1"/><circle cx="15" cy="6" r="1"/><circle cx="9" cy="12" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="9" cy="18" r="1"/><circle cx="15" cy="18" r="1"/></svg>
</div> </div>
<div className="font-sans text-xs text-[11px] font-semibold w-5 text-center shrink-0" style={{ color: 'var(--color-primary)' }}>{idx + 1}</div> <div className="font-sans text-xs text-[11px] font-semibold w-5 text-center shrink-0" style={{ color: 'var(--color-primary)' }}>{idx + 1}</div>

View File

@@ -42,7 +42,7 @@ export function VerifyEmailPage() {
<Link <Link
to="/" to="/"
className={cn( className={cn(
'mt-6 inline-flex items-center rounded-lg bg-[#22d3ee] px-6 py-2 text-sm font-semibold text-brand-dark', 'mt-6 inline-flex items-center rounded-lg bg-[#22d3ee] px-6 py-2 text-sm font-semibold text-white',
'hover:brightness-110' 'hover:brightness-110'
)} )}
> >
@@ -58,8 +58,8 @@ export function VerifyEmailPage() {
<Link <Link
to="/" to="/"
className={cn( className={cn(
'mt-6 inline-flex items-center rounded-lg bg-white/[0.04] border border-brand-border px-6 py-2 text-sm font-medium text-[#e2e5eb]', 'mt-6 inline-flex items-center rounded-lg bg-[#191c25] border border-[#1e2130] px-6 py-2 text-sm font-medium text-[#e2e5eb]',
'hover:border-white/[0.12]' 'hover:border-[#2a2f3d]'
)} )}
> >
Go to Dashboard Go to Dashboard

View File

@@ -104,7 +104,7 @@ export default function ChatRetentionSettingsPage() {
<button <button
onClick={handleSave} onClick={handleSave}
disabled={saving} disabled={saving}
className="bg-[#22d3ee] text-brand-dark font-semibold text-sm rounded-lg px-5 py-2.5 hover:brightness-110 active:scale-[0.98] transition-all disabled:opacity-40 flex items-center gap-2" className="bg-[#22d3ee] text-white font-semibold text-sm rounded-lg px-5 py-2.5 hover:brightness-110 active:scale-[0.98] transition-all disabled:opacity-40 flex items-center gap-2"
> >
{saving ? <Loader2 size={14} className="animate-spin" /> : <Save size={14} />} {saving ? <Loader2 size={14} className="animate-spin" /> : <Save size={14} />}
Save Settings Save Settings

View File

@@ -132,7 +132,7 @@ export function ProfileSettingsPage() {
type="submit" type="submit"
disabled={isSaving || !hasChanges} disabled={isSaving || !hasChanges}
className={cn( className={cn(
'inline-flex items-center gap-2 rounded-lg bg-[#22d3ee] px-4 py-2 text-sm font-semibold text-brand-dark', 'inline-flex items-center gap-2 rounded-lg bg-[#22d3ee] px-4 py-2 text-sm font-semibold text-white',
'hover:brightness-110 active:scale-[0.98]', 'hover:brightness-110 active:scale-[0.98]',
'disabled:opacity-50 disabled:cursor-not-allowed' 'disabled:opacity-50 disabled:cursor-not-allowed'
)} )}
@@ -145,8 +145,8 @@ export function ProfileSettingsPage() {
to="/change-password" to="/change-password"
className={cn( className={cn(
'inline-flex items-center rounded-lg px-4 py-2 text-sm font-medium', 'inline-flex items-center rounded-lg px-4 py-2 text-sm font-medium',
'bg-white/[0.04] border border-brand-border text-[#e2e5eb]', 'bg-[#191c25] border border-[#1e2130] text-[#e2e5eb]',
'hover:border-white/[0.12]' 'hover:border-[#2a2f3d]'
)} )}
> >
Change Password Change Password

View File

@@ -101,7 +101,7 @@ export default function SurveyInvitesPage() {
<button <button
onClick={() => handleCreate(false)} onClick={() => handleCreate(false)}
disabled={creating || !name.trim()} disabled={creating || !name.trim()}
className="inline-flex items-center gap-2 rounded-lg bg-[#22d3ee] px-4 py-2 text-sm font-semibold text-brand-dark hover:brightness-110 active:scale-[0.98] disabled:opacity-50 disabled:cursor-not-allowed transition-all" className="inline-flex items-center gap-2 rounded-lg bg-[#22d3ee] px-4 py-2 text-sm font-semibold text-white hover:brightness-110 active:scale-[0.98] disabled:opacity-50 disabled:cursor-not-allowed transition-all"
> >
{creating ? <Loader2 className="h-4 w-4 animate-spin" /> : <Link2 className="h-4 w-4" />} {creating ? <Loader2 className="h-4 w-4 animate-spin" /> : <Link2 className="h-4 w-4" />}
Generate Link Generate Link
@@ -109,7 +109,7 @@ export default function SurveyInvitesPage() {
<button <button
onClick={() => handleCreate(true)} onClick={() => handleCreate(true)}
disabled={creating || !name.trim() || !email.trim()} disabled={creating || !name.trim() || !email.trim()}
className="inline-flex items-center gap-2 rounded-lg bg-white/[0.04] border border-brand-border px-4 py-2 text-sm font-medium text-[#e2e5eb] hover:border-white/[0.12] active:scale-[0.98] disabled:opacity-50 disabled:cursor-not-allowed transition-all" className="inline-flex items-center gap-2 rounded-lg bg-[#191c25] border border-[#1e2130] px-4 py-2 text-sm font-medium text-[#e2e5eb] hover:border-[#2a2f3d] active:scale-[0.98] disabled:opacity-50 disabled:cursor-not-allowed transition-all"
> >
{creating ? <Loader2 className="h-4 w-4 animate-spin" /> : <Send className="h-4 w-4" />} {creating ? <Loader2 className="h-4 w-4 animate-spin" /> : <Send className="h-4 w-4" />}
Send Email Send Email
@@ -132,7 +132,7 @@ export default function SurveyInvitesPage() {
</div> </div>
<button <button
onClick={() => handleCopy(lastCreated.survey_url)} onClick={() => handleCopy(lastCreated.survey_url)}
className="shrink-0 rounded-lg p-2 text-[#848b9b] hover:bg-brand-border hover:text-[#e2e5eb] transition-colors" className="shrink-0 rounded-lg p-2 text-[#848b9b] hover:bg-[#1e2130] hover:text-[#e2e5eb] transition-colors"
> >
{copied ? <Check className="h-4 w-4 text-emerald-400" /> : <Copy className="h-4 w-4" />} {copied ? <Check className="h-4 w-4 text-emerald-400" /> : <Copy className="h-4 w-4" />}
</button> </button>
@@ -163,7 +163,7 @@ export default function SurveyInvitesPage() {
<tr><td colSpan={7} className="px-4 py-8 text-center text-sm text-[#848b9b]">No invites yet</td></tr> <tr><td colSpan={7} className="px-4 py-8 text-center text-sm text-[#848b9b]">No invites yet</td></tr>
) : ( ) : (
invites.map(invite => ( invites.map(invite => (
<tr key={invite.id} className="border-b border-[#1e2130]/50 hover:bg-white/[0.02] transition-colors"> <tr key={invite.id} className="border-b border-[#1e2130]/50 hover:bg-[#14161d] transition-colors">
<td className="px-4 py-3 text-sm text-[#e2e5eb]">{invite.recipient_name}</td> <td className="px-4 py-3 text-sm text-[#e2e5eb]">{invite.recipient_name}</td>
<td className="px-4 py-3 text-sm text-[#848b9b]">{invite.recipient_email || '—'}</td> <td className="px-4 py-3 text-sm text-[#848b9b]">{invite.recipient_email || '—'}</td>
<td className="px-4 py-3"> <td className="px-4 py-3">
@@ -188,7 +188,7 @@ export default function SurveyInvitesPage() {
<td className="px-4 py-3 text-center"> <td className="px-4 py-3 text-center">
<button <button
onClick={() => handleCopy(invite.survey_url)} onClick={() => handleCopy(invite.survey_url)}
className="rounded-lg p-1.5 text-[#848b9b] hover:bg-brand-border hover:text-[#e2e5eb] transition-colors" className="rounded-lg p-1.5 text-[#848b9b] hover:bg-[#1e2130] hover:text-[#e2e5eb] transition-colors"
title="Copy survey link" title="Copy survey link"
> >
<Copy className="h-3.5 w-3.5" /> <Copy className="h-3.5 w-3.5" />

View File

@@ -152,7 +152,7 @@ function ResponseRow({
className={cn( className={cn(
'border-b border-[#1e2130]/50 transition-colors cursor-pointer', 'border-b border-[#1e2130]/50 transition-colors cursor-pointer',
!response.is_read && 'bg-primary/3', !response.is_read && 'bg-primary/3',
'hover:bg-white/[0.02]' 'hover:bg-[#14161d]'
)} )}
> >
{/* Checkbox */} {/* Checkbox */}
@@ -214,7 +214,7 @@ function ResponseRow({
<td className="px-3 py-3 w-10 relative"> <td className="px-3 py-3 w-10 relative">
<button <button
onClick={e => { e.stopPropagation(); setShowMenu(!showMenu) }} onClick={e => { e.stopPropagation(); setShowMenu(!showMenu) }}
className="p-1.5 rounded-lg hover:bg-brand-border text-[#848b9b] hover:text-[#e2e5eb] transition-colors" className="p-1.5 rounded-lg hover:bg-[#1e2130] text-[#848b9b] hover:text-[#e2e5eb] transition-colors"
> >
<MoreHorizontal className="h-4 w-4" /> <MoreHorizontal className="h-4 w-4" />
</button> </button>
@@ -227,14 +227,14 @@ function ResponseRow({
> >
<button <button
onClick={() => { onMarkRead(); setShowMenu(false) }} onClick={() => { onMarkRead(); setShowMenu(false) }}
className="flex w-full items-center gap-2.5 px-3 py-2 text-xs text-[#848b9b] hover:text-[#e2e5eb] hover:bg-white/[0.04] transition-colors" className="flex w-full items-center gap-2.5 px-3 py-2 text-xs text-[#848b9b] hover:text-[#e2e5eb] hover:bg-[#191c25] transition-colors"
> >
{response.is_read ? <EyeOff className="h-3.5 w-3.5" /> : <Eye className="h-3.5 w-3.5" />} {response.is_read ? <EyeOff className="h-3.5 w-3.5" /> : <Eye className="h-3.5 w-3.5" />}
{response.is_read ? 'Mark Unread' : 'Mark Read'} {response.is_read ? 'Mark Unread' : 'Mark Read'}
</button> </button>
<button <button
onClick={() => { onArchive(); setShowMenu(false) }} onClick={() => { onArchive(); setShowMenu(false) }}
className="flex w-full items-center gap-2.5 px-3 py-2 text-xs text-[#848b9b] hover:text-[#e2e5eb] hover:bg-white/[0.04] transition-colors" className="flex w-full items-center gap-2.5 px-3 py-2 text-xs text-[#848b9b] hover:text-[#e2e5eb] hover:bg-[#191c25] transition-colors"
> >
{response.archived_at ? <ArchiveRestore className="h-3.5 w-3.5" /> : <Archive className="h-3.5 w-3.5" />} {response.archived_at ? <ArchiveRestore className="h-3.5 w-3.5" /> : <Archive className="h-3.5 w-3.5" />}
{response.archived_at ? 'Unarchive' : 'Archive'} {response.archived_at ? 'Unarchive' : 'Archive'}
@@ -437,7 +437,7 @@ export default function SurveyResponsesPage() {
'inline-flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-medium transition-colors border', 'inline-flex items-center gap-2 rounded-lg px-3 py-2 text-xs font-medium transition-colors border',
showArchived showArchived
? 'bg-[rgba(34,211,238,0.10)] text-[#22d3ee] border-primary/20' ? 'bg-[rgba(34,211,238,0.10)] text-[#22d3ee] border-primary/20'
: 'bg-white/[0.04] text-[#848b9b] border-brand-border hover:border-white/[0.12]' : 'bg-[#191c25] text-[#848b9b] border-[#1e2130] hover:border-[#2a2f3d]'
)} )}
> >
<Archive className="h-3.5 w-3.5" /> <Archive className="h-3.5 w-3.5" />
@@ -446,7 +446,7 @@ export default function SurveyResponsesPage() {
<button <button
onClick={handleExport} onClick={handleExport}
disabled={exporting || responses.length === 0} disabled={exporting || responses.length === 0}
className="inline-flex items-center gap-2 rounded-lg bg-white/[0.04] border border-brand-border px-4 py-2 text-sm font-medium text-[#e2e5eb] transition-colors hover:border-white/[0.12] disabled:opacity-50" className="inline-flex items-center gap-2 rounded-lg bg-[#191c25] border border-[#1e2130] px-4 py-2 text-sm font-medium text-[#e2e5eb] transition-colors hover:border-[#2a2f3d] disabled:opacity-50"
> >
{exporting ? ( {exporting ? (
<Loader2 className="h-4 w-4 animate-spin" /> <Loader2 className="h-4 w-4 animate-spin" />
@@ -508,21 +508,21 @@ export default function SurveyResponsesPage() {
<div className="flex-1" /> <div className="flex-1" />
<button <button
onClick={() => handleBulkAction('mark_read')} onClick={() => handleBulkAction('mark_read')}
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium text-[#848b9b] hover:text-[#e2e5eb] hover:bg-brand-border transition-colors" className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium text-[#848b9b] hover:text-[#e2e5eb] hover:bg-[#1e2130] transition-colors"
> >
<Eye className="h-3.5 w-3.5" /> <Eye className="h-3.5 w-3.5" />
Mark Read Mark Read
</button> </button>
<button <button
onClick={() => handleBulkAction('mark_unread')} onClick={() => handleBulkAction('mark_unread')}
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium text-[#848b9b] hover:text-[#e2e5eb] hover:bg-brand-border transition-colors" className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium text-[#848b9b] hover:text-[#e2e5eb] hover:bg-[#1e2130] transition-colors"
> >
<EyeOff className="h-3.5 w-3.5" /> <EyeOff className="h-3.5 w-3.5" />
Mark Unread Mark Unread
</button> </button>
<button <button
onClick={() => handleBulkAction('archive')} onClick={() => handleBulkAction('archive')}
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium text-[#848b9b] hover:text-[#e2e5eb] hover:bg-brand-border transition-colors" className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium text-[#848b9b] hover:text-[#e2e5eb] hover:bg-[#1e2130] transition-colors"
> >
<Archive className="h-3.5 w-3.5" /> <Archive className="h-3.5 w-3.5" />
Archive Archive
@@ -536,7 +536,7 @@ export default function SurveyResponsesPage() {
</button> </button>
<button <button
onClick={() => setSelectedIds(new Set())} onClick={() => setSelectedIds(new Set())}
className="px-3 py-1.5 rounded-lg text-xs font-medium text-[#848b9b] hover:text-[#e2e5eb] hover:bg-brand-border transition-colors" className="px-3 py-1.5 rounded-lg text-xs font-medium text-[#848b9b] hover:text-[#e2e5eb] hover:bg-[#1e2130] transition-colors"
> >
Clear Clear
</button> </button>