# Claude Code Instructions

## Development Workflow

Follow these steps for every feature addition or task:

1. **Implement the feature or task** as requested.

2. **Check for breaking changes** — before finishing, consider whether the change could break existing installations (e.g., database schema changes, renamed config keys, removed columns, changed file structures). If a breaking change exists, include a migration (database migration, config upgrade script, or data transformation) to bring existing installations up to the new structure.

3. **Update documentation** — add or update the relevant documentation for the feature or change (changelog, inline docs, README, or any docs/ files that describe the affected area).

   > **Docs repo:** Documentation lives at `F:\html\ChargePanda-docs` (GitHub: `https://github.com/ChargePanda/docs`). It is a standalone VitePress project — `cd F:\html\ChargePanda-docs && npm run dev` to preview. Do **not** add a `docs/` folder to this repo.

   > **Changelog dates:** Never write a real date in `changelog.md`. New entries must use `TBD` as the release date (e.g. `## v1.x.x — TBD`). Dates are filled in by the team at release time.

---

## Styling Conventions

### Admin Panel (backend views — `resources/views/admin/` and module `admin/` views)

The admin panel uses Bootstrap 5 with a **heavily customised utility layer**. Do NOT use `btn-outline-*` variants — they render with invisible text against the custom background. Use solid button variants only.

**Buttons:**
```html
<button class="btn btn-primary">Primary action</button>
<button class="btn btn-secondary btn-sm">Secondary / back / cancel</button>
<button class="btn btn-success btn-sm">Confirm / activate</button>
<button class="btn btn-danger btn-sm">Delete / destructive</button>
<button class="btn btn-warning btn-sm">Deactivate / caution</button>
<button class="btn btn-info btn-sm">Filter / search</button>
<button class="btn btn-link">Inline link action</button>
<!-- NEVER use btn-outline-* — invisible text in the custom theme -->
```

**Badges (Bootstrap 5 syntax — always `bg-*`, never `badge-*`):**
```html
<span class="badge bg-success">Active</span>
<span class="badge bg-secondary">Inactive</span>
<span class="badge bg-danger">Error</span>
<span class="badge bg-warning text-dark">Warning</span>  <!-- text-dark required on warning -->
<span class="badge bg-info">Info</span>
<span class="badge bg-primary">Primary</span>
<!-- NEVER use badge-success, badge-secondary etc. — that is Bootstrap 4 syntax -->
```

**Card / panel container:**
```html
<div class="bgc-white bd bdrs-3 p-20 mB-20">
    <!-- content -->
</div>
```

**Spacing utilities** (custom, not Bootstrap):
- Margin: `mB-20`, `mT-10`, `mR-5`, `mL-5`, `mY-20`
- Padding: `p-20`, `pY-40`, `pX-20`, `pT-10`, `pB-10`

**Text colour utilities** (custom):
- `c-grey-900` — headings / primary text
- `c-grey-600` — secondary / muted text
- `c-blue-500`, `c-green-500`, `c-red-500`, `c-orange-500` — accent colours

**Flexbox helpers** (custom):
- `peers` — flex container, `peer` — flex child
- `ai-c` — align-items: center

**Icons:** Themify Icons (`ti-*`) — e.g. `ti-pencil`, `ti-trash`, `ti-check`, `ti-arrow-left`

---

### Frontend / Account pages (Tailwind theme — `resources/themes/tailwind/` and module `account/` views)

The frontend uses **Tailwind CSS v4** with a custom design token layer. Always follow these patterns when writing account-facing views.

**Layout wrapper** (every account page):
```html
@extends('theme::layouts.app', ['title' => $title])
@section('content')
<main class="flex-grow w-full max-w-[1440px] mx-auto px-6 lg:px-10 py-10">
    <div class="flex flex-col lg:flex-row gap-10">
        @include('theme::partials.account.nav')
        <section class="flex-grow">
            <!-- content -->
        </section>
    </div>
</main>
@endsection
```

**Page header:**
```html
<div class="mb-8">
    <h1 class="text-2xl font-bold text-text-main dark:text-white">Title</h1>
    <p class="text-text-muted dark:text-gray-400 mt-1">Subtitle</p>
</div>
```

**Card (section container):**
```html
<section class="bg-white dark:bg-surface-dark border border-border-light dark:border-border-dark rounded-2xl shadow-sm overflow-hidden">
    <div class="p-6 border-b border-border-light dark:border-border-dark">
        <h2 class="text-lg font-bold text-text-main dark:text-white">Section title</h2>
    </div>
    <div class="p-6 space-y-5">
        <!-- content -->
    </div>
</section>
```

**Buttons:**
```html
<!-- Primary -->
<button class="flex items-center gap-2 px-5 py-2.5 bg-primary hover:bg-primary-dark text-white rounded-xl font-semibold text-sm transition-all shadow-sm shadow-primary/20">
    <span class="material-symbols-outlined text-[18px]">add</span> Label
</button>
<!-- Secondary / outline -->
<button class="flex items-center gap-2 px-4 py-2.5 border border-gray-200 dark:border-gray-700 text-text-main dark:text-white rounded-xl font-medium text-sm hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors">
    Label
</button>
<!-- Danger icon button -->
<button class="size-7 flex items-center justify-center text-text-muted hover:text-red-500 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors">
    <span class="material-symbols-outlined text-[16px]">delete</span>
</button>
```

**Form inputs:**
```html
<div class="space-y-1.5">
    <label class="block text-xs font-bold text-text-muted uppercase tracking-wider" for="field_id">Label</label>
    <input type="text" id="field_id" name="field"
           class="w-full px-4 py-2.5 bg-gray-50 dark:bg-background-dark border border-gray-200 dark:border-gray-700 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-primary/10 focus:border-primary transition-all" />
    <!-- Validation error -->
    <p class="text-[11px] text-red-500">{{ $message }}</p>
    <!-- Help text -->
    <p class="text-xs text-text-muted dark:text-gray-500">Help text here.</p>
</div>
```

**Status / tag badges:**
```html
<!-- Green -->
<span class="px-2 py-0.5 bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-green-400 text-[11px] font-bold rounded uppercase tracking-wider">Active</span>
<!-- Red -->
<span class="px-2 py-0.5 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 text-[11px] font-bold rounded uppercase tracking-wider">Failed</span>
<!-- Amber -->
<span class="px-2 py-0.5 bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 text-[11px] font-bold rounded uppercase tracking-wider">Pending</span>
<!-- Gray / neutral -->
<span class="px-2 py-0.5 bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 text-[11px] font-bold rounded uppercase tracking-wider">Inactive</span>
```

**Alert / flash messages:**
```html
<!-- Error -->
<div class="px-4 py-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-xl text-sm text-red-600 dark:text-red-400">
    Message here.
</div>
<!-- Success -->
<div class="px-4 py-3 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-xl text-sm text-green-600 dark:text-green-400">
    Message here.
</div>
```

**Icons:** Material Symbols Outlined — `<span class="material-symbols-outlined text-[20px]">icon_name</span>`
- Common sizes: `text-[14px]` (xs), `text-[18px]` (sm), `text-[20px]` (base), `text-[24px]` (lg), `text-[64px]` (empty-state hero)
- Do **not** use `ti-*` (Themify) or `fa-*` (Font Awesome) in frontend views — those are admin-panel only

**Empty state:**
```html
<div class="bg-white dark:bg-surface-dark border border-border-light dark:border-border-dark rounded-2xl shadow-sm p-12 text-center">
    <span class="material-symbols-outlined text-[64px] text-gray-300 dark:text-gray-700 mb-4">icon_name</span>
    <h3 class="text-lg font-bold text-text-main dark:text-white mb-2">Nothing here yet</h3>
    <p class="text-text-muted dark:text-gray-400">Descriptive message.</p>
</div>
```

**Custom design tokens** (defined in Tailwind config):
- `text-text-main` / `dark:text-white` — primary text
- `text-text-muted` / `dark:text-gray-400` — secondary text
- `bg-surface-dark` — dark mode card background
- `border-border-light` / `dark:border-border-dark` — card borders
- `bg-primary`, `hover:bg-primary-dark` — brand colour
- `shadow-soft`, `shadow-soft-hover` — custom soft shadows
