From 73b8a7a4de519ab3bb1469d629c41133d183bfdd Mon Sep 17 00:00:00 2001 From: Mattsson <111893710+mattssonn@users.noreply.github.com> Date: Thu, 26 Mar 2026 21:40:56 +0100 Subject: [PATCH] feat: soften button system with refined primary color (GNU-6) (#142) * feat: soften button system with refined primary color (GNU-6) Replace near-black primary with a lighter dark charcoal (210 5% 25%), add subtle shadows to solid buttons, and unify border-radius across all button sizes. Co-Authored-By: Claude Opus 4.6 (1M context) * feat: add scout-design skill for design auditing and improvement tracking --------- Co-authored-by: Claude Opus 4.6 (1M context) --- .claude/skills/scout-design/SKILL.md | 135 +++++++++++++++++++++++++++ .gitignore | 1 + app/globals.css | 8 +- components/ui/button.tsx | 8 +- 4 files changed, 144 insertions(+), 8 deletions(-) create mode 100644 .claude/skills/scout-design/SKILL.md diff --git a/.claude/skills/scout-design/SKILL.md b/.claude/skills/scout-design/SKILL.md new file mode 100644 index 00000000..666215f6 --- /dev/null +++ b/.claude/skills/scout-design/SKILL.md @@ -0,0 +1,135 @@ +--- +name: scout-design +description: "Scan a specific area of the app for design issues and improvement opportunities, then create Linear tickets for approved findings. Usage: /scout-design (e.g., /scout-design settings, /scout-design bookkeeping). Evaluates against the gnubok design system for consistency, missing states, animation gaps, accessibility, and visual polish." +--- + +# Scout Design + +You are a design auditor for gnubok. Your job is to scan a scoped area of the application, identify design issues and improvement opportunities, and create Linear tickets for the ones the user approves. + +## Step 1: Resolve Scope + +The user provides an area name as an argument (e.g., "settings", "bookkeeping", "invoices"). + +Map the area to these file locations: +- **Pages**: `app/(dashboard)/{area}/` (all page.tsx, layout.tsx files recursively) +- **Components**: `components/{area}/` (all .tsx files recursively) + +If the area also has sub-routes (e.g., `invoices/new`, `invoices/[id]`), include those too. + +Valid areas based on the project structure: +`bookkeeping`, `customers`, `expenses`, `invoices`, `supplier-invoices`, `suppliers`, `transactions`, `receipts`, `reports`, `settings`, `kpi`, `deadlines`, `help`, `pending`, `import`, `extensions`, `onboarding`, `login`, `register` + +If the user provides an invalid area, list the valid areas and ask them to pick one. + +## Step 2: Read and Analyze + +Read ALL files in the resolved scope (pages + components). For each file, evaluate against the checklist below. + +### Design Audit Checklist + +**Consistency & Design System** +- Are spacing values consistent (using Tailwind scale, not arbitrary values)? +- Are colors from the design system palette (grayscale, sage green, terracotta, ochre) or are there off-palette colors? +- Are font sizes/weights consistent with the typography system (Fraunces for headings, Geist for body)? +- Are `tabular-nums` applied to all financial/numeric data? +- Are shadcn/ui components used where appropriate, or are there custom implementations that should use shadcn? +- Are icon sizes consistent (15px nav, larger for empty states)? +- Are border styles consistent (subtle, 60% opacity)? + +**Loading & Empty States** +- Does the page/component have a loading state? (skeleton, spinner, or shimmer) +- Is there an empty state when no data exists? (illustration, message, CTA) +- Are loading states using skeletons (preferred) rather than plain spinners? + +**Error Handling UI** +- Are there error boundaries or error states shown to the user? +- Do forms show inline validation errors? +- Are error messages helpful and in Swedish? + +**Animation & Motion** +- Are list items stagger-animated on entry? +- Do interactive elements have hover/active transitions? +- Are transitions using appropriate easing (spring for feedback, ease for reveals)? +- Is `prefers-reduced-motion` respected? +- Are there abrupt state changes that would benefit from a transition? + +**Accessibility** +- Do interactive elements have visible focus rings? +- Is color contrast WCAG AA compliant (4.5:1 text, 3:1 UI)? +- Is color never the sole indicator of state (paired with icons/text/shape)? +- Are form inputs labeled (via label element or aria-label)? +- Are clickable areas large enough for touch targets? + +**Layout & Responsiveness** +- Does the layout work on mobile widths? +- Are tables horizontally scrollable on small screens? +- Is whitespace generous but not wasteful? +- Does dense data (tables, ledgers) use tighter but non-cramped spacing? + +**Polish & Details** +- Are numbers right-aligned in tables? +- Are monetary values formatted consistently (Swedish format with kr)? +- Are dates formatted consistently? +- Are positive/negative amounts visually distinct? +- Are interactive elements obviously interactive (cursor, hover state)? +- Are disabled states visually clear? + +## Step 3: Present Findings + +After scanning, present findings as a numbered list. For each finding: + +``` +### #{number}: {Short title} + +**Area**: {area name} +**File(s)**: {file path(s) with line numbers if relevant} +**Category**: {Consistency | Loading State | Error Handling | Animation | Accessibility | Layout | Polish} +**Severity**: {High | Medium | Low} + +**What's wrong**: {1-2 sentences describing the current state} +**What it should be**: {1-2 sentences describing the desired state} +**Implementation notes**: {Brief technical guidance on how to fix it} +``` + +Sort findings by severity (High first). + +After listing all findings, ask the user: +> "Found {N} design improvements. Create Linear tickets for: all, none, or specific numbers? (e.g., '1,3,5')" + +## Step 4: Create Linear Tickets + +For each approved finding, create a Linear issue using the `mcp__claude_ai_Linear__save_issue` tool with: + +- **team**: `Gnubok` +- **title**: Short, actionable title prefixed with area. Example: `[Invoices] Add loading skeleton to invoice list` +- **description**: Markdown formatted: + ```markdown + ## Problem + {What's wrong — current state} + + ## Proposed Change + {What it should be — desired state} + + ## Implementation + **File(s):** {file paths} + **Category:** {category} + + {Implementation notes} + + --- + *Generated by /scout-design* + ``` +- **labels**: `Improvement` +- **priority**: Map severity: High → 2, Medium → 3, Low → 4 + +After creating tickets, list them with their Linear identifiers so the user can reference them. + +## Important Notes + +- Be specific. "The button looks off" is not actionable. "The primary button in InvoiceForm uses `rounded-lg` while all other forms use `rounded-md`" is. +- Reference exact Tailwind classes, component names, and line numbers. +- Don't flag things that are intentional design choices documented in CLAUDE.md. +- Don't suggest adding features — only flag design/UX issues with what already exists. +- Keep findings focused on visual design, interaction design, and frontend polish. Not code quality or architecture. +- If a component is very small or trivial (e.g., a simple redirect page), skip it. diff --git a/.gitignore b/.gitignore index eb5ec90d..8a7cee29 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ supabase/.temp/ # claude local settings .claude/settings.local.json +.claude/scheduled_tasks.lock # dev docs (internal reference, not published) /dev_docs diff --git a/app/globals.css b/app/globals.css index 47b38e34..a3e6c6d9 100644 --- a/app/globals.css +++ b/app/globals.css @@ -15,7 +15,7 @@ --popover: 0 0% 99%; --popover-foreground: 0 0% 9%; - --primary: 0 0% 15%; + --primary: 210 5% 25%; --primary-foreground: 0 0% 100%; --secondary: 0 0% 94%; @@ -32,7 +32,7 @@ --border: 0 0% 90%; --input: 0 0% 90%; - --ring: 0 0% 15%; + --ring: 210 5% 25%; /* Radius */ --radius: 0.5rem; @@ -82,7 +82,7 @@ --popover: 0 0% 10%; --popover-foreground: 0 0% 87%; - --primary: 0 0% 85%; + --primary: 210 4% 82%; --primary-foreground: 0 0% 7%; --secondary: 0 0% 14%; @@ -99,7 +99,7 @@ --border: 0 0% 18%; --input: 0 0% 18%; - --ring: 0 0% 85%; + --ring: 210 4% 82%; --success: 155 22% 48%; --success-foreground: 0 0% 100%; diff --git a/components/ui/button.tsx b/components/ui/button.tsx index 471b4818..bfc1cc44 100644 --- a/components/ui/button.tsx +++ b/components/ui/button.tsx @@ -9,9 +9,9 @@ const buttonVariants = cva( variants: { variant: { default: - "bg-primary text-primary-foreground hover:bg-primary/90 active:scale-[0.98]", + "bg-primary text-primary-foreground shadow-sm hover:bg-primary/80 active:scale-[0.98]", destructive: - "bg-destructive text-destructive-foreground hover:bg-destructive/90 active:scale-[0.98]", + "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/80 active:scale-[0.98]", outline: "border border-input bg-transparent hover:bg-secondary hover:border-secondary-foreground/20", secondary: @@ -21,11 +21,11 @@ const buttonVariants = cva( link: "text-primary underline-offset-4 hover:underline", success: - "bg-success text-success-foreground hover:bg-success/90 active:scale-[0.98]", + "bg-success text-success-foreground shadow-sm hover:bg-success/80 active:scale-[0.98]", }, size: { default: "h-10 px-5 py-2 rounded-lg", - sm: "h-9 px-4 text-xs rounded-md", + sm: "h-9 px-4 text-xs rounded-lg", lg: "h-11 px-8 text-base rounded-lg", icon: "h-10 w-10 rounded-lg", },