# Claude Code Guidelines ## Project Overview This is a SvelteKit 2.x application using Svelte 5 with Tailwind CSS v4. ## Code Style Rules ### SVG Attributes When using SVG elements, use `style` attribute instead of `fill` attribute to avoid IDE obsolete attribute warnings: ```svelte ``` ### Svelte 5 Runes - Use `$state()` for reactive state - Use `$derived()` for computed values - Use `$props()` for component props - Use `$effect()` for side effects ### Page Store Use `$app/state` instead of `$app/stores` for the page object: ```svelte import {page} from '$app/state'; const path = page.url.pathname; import {page} from '$app/stores'; const path = $page.url.pathname; ``` ### Theme Classes Use the custom theme utility classes defined in `layout.css`: - `text-theme`, `text-theme-secondary`, `text-theme-muted` - `bg-theme`, `bg-theme-card` - `border-theme` - `shadow-theme`, `shadow-theme-lg` ### Hover/Active States Use consistent hover/active patterns: ``` hover:bg-black/5 dark:hover:bg-white/10 active:bg-black/10 dark:active:bg-white/15 ``` ### Mobile Grid Layouts For card grids that should display single-column on mobile and multi-column on larger screens, always: 1. Explicitly set `grid-cols-1` (don't rely on CSS grid's implicit single column) 2. Add `min-w-0` on grid items with flex content to allow proper shrinking ```svelte
...
...
``` ### Button Element Content Button elements can only contain phrasing content (inline elements). Use `` instead of `
`, `

`, or `

`-`

` inside buttons: ```svelte ``` For multi-line button content, use `` to create line breaks: ```svelte ``` ### SvelteSet Reactivity `SvelteSet` from `svelte/reactivity` is already reactive and does NOT need to be wrapped in `$state()`: ```svelte import { SvelteSet } from 'svelte/reactivity'; let expandedItems = new SvelteSet(); let expandedItems = $state(new SvelteSet()); ``` ### Each Block Keys Always provide a key for `{#each}` blocks to avoid ESLint warnings: ```svelte {#each items as item (item.id)} {#each days as day (day)} {#each items as item} ``` ### Date Formatting Use the date utilities from `$lib/utils/date` which use `date-fns` to properly handle ISO date strings without timezone offset issues: ```svelte import {formatDate} from '$lib/utils/date'; {formatDate(startDate) || '—'} ``` ### File Organization - Place `.svelte.ts` files (stores, shared state) in `src/lib/stores/`, not in component folders - GraphQL mutations go in `src/lib/graphql/mutations/{entity}/` - GraphQL queries go in `src/lib/graphql/queries/{entity}/` ### Backend Integration Notes - The backend uses a unique constraint allowing only ONE active scope per address - The `isConditional` field on tasks is legacy and should always be set to `false` - GraphQL inputs use camelCase (e.g., `isActive`, `accountId`) which maps to snake_case in Django ### Task Frequency Values The backend `TaskFrequencyChoices` enum uses **lowercase** values. Handle frequency differently depending on the operation: **Individual mutations** (create/update task or task template) - use lowercase: ```typescript frequency: 'daily' | 'weekly' | 'monthly' | 'quarterly' | 'triannual' | 'annual' | 'as_needed'; ``` **JSON import** (`createScopeTemplateFromJson`) - uppercase is acceptable: ```json { "frequency": "DAILY" } ``` The backend's `build_scope_template` service normalizes uppercase to lowercase automatically. Valid frequency values: `daily`, `weekly`, `monthly`, `quarterly`, `triannual`, `annual`, `as_needed`