# Lovelii — Agent Guide

Laravel 13 + Inertia 3 + Vue 3.5 + Tailwind CSS 4 application built from the design
handoff in `docs/` and `design/`. Laravel Boost is installed; `CLAUDE.md` contains the
full framework guidelines and skill list (PHP, testing, Tailwind, cloud deployment).

## Setup

```bash
composer install
npm install
cp .env.example .env
php artisan key:generate
lerd db:create              # creates lovelii and lovelii_testing
php artisan migrate --seed
```

MySQL is the app database; `.env.example` targets Lerd's `lerd-mysql` container. The
feature suite runs against the `lovelii_testing` MySQL database configured in
`phpunit.xml`.

Preview account: `demo@lovelii.chat` / `password`.

Run in development with `php artisan serve` plus `npm run dev`. In this environment the
`php` binary is wrapped by Lerd (podman); if the dev-server port is not reachable from the
host, use `/usr/bin/php artisan serve` instead and point it at the published MySQL port:

```bash
DB_HOST=127.0.0.1 DB_PORT=3308 /usr/bin/php artisan serve
```

Use the Lerd wrapper for Artisan, tests, and other commands so `lerd-mysql` resolves.

## Commands

```bash
php artisan test                    # feature suite
npm run build                       # production assets
./vendor/bin/pint                   # format PHP
php artisan route:list --except-vendor
```

## Structure

- `app/Http/Controllers/` — `AuthController`, `ChatController`, `ProfileController`,
  `CallController`. Keep controllers thin; chat queries and persistence are handled in
  `app/Support/ChatService.php`.
- `routes/web.php` — guest routes (`/login`, `/register`) and auth routes. Route names:
  `login`, `register`, `logout`, `chat.index`, `chat.start`, `chat.show`,
  `chat.messages.store`, `profile.edit`, `profile.update`, `profile.show`, `users.show`,
  `users.media`, `call.audio`, `call.video`.
- `resources/js/Pages/` — Inertia pages. This directory is PascalCase; the published
  `config/inertia.php` points the page finder at `resources/js/Pages`. Do not move pages
  to lowercase `pages` without updating that config.
- `resources/js/Layouts/AppLayout.vue` — dashboard shell (sidebar + fixed header) used by
  chat and profile. `GuestLayout.vue` wraps auth screens. Calls are full-bleed pages.
- `resources/js/Components/` — shared UI (`UserAvatar`, `AppSidebar`, `AppHeader`,
  `Auth/AuthPanel`, `Chat/*`).
- `resources/css/app.css` — **single source of Tailwind theme tokens** (`@theme`), base
  styles, and motion keyframes. Do not reintroduce a `tailwind.config.js`; Tailwind 4 is
  configured from CSS.
- `docs/` — Markdown only (design system + handoff notes). `design/` — reference HTML and
  its preview image per screen. Keep those two concerns separate.

## Conventions

- Use Vue 3 `<script setup>` and Composition API. Inertia navigation via `<Link>` and
  `useForm`; no client-side router.
- Brand tokens: `primary #b70942`, surfaces `#f9f9ff` family, Plus Jakarta Sans, Material
  Symbols Outlined. Use token utilities (`bg-surface`, `text-on-surface`,
  `text-headline-md`, `space-md`) rather than raw hex values in components.
- Radius follows the prototypes: Tailwind defaults (`rounded-lg` = 0.5rem,
  `rounded-xl` = 0.75rem) — not the older YAML radius scale in `docs/DESIGN.md`.
- Avatars use uploaded private profile photos when present, with deterministic gradient
  initials as the fallback (`UserAvatar.vue`). Profile and cover photos are editable in
  the profile editor. The handoff's remote Google image URLs are dead placeholders; do not
  add remote image dependencies.
- Chat threads are between registered users. Conversation and message metadata are
  persisted to the `conversations` and `messages` tables; active threads refresh every few
  seconds. Voice, image, video, and document files use private storage, and view-once
  messages are consumed server-side by the recipient. Profile identity updates are persisted to the
  `users` table.
- Keep the design references in `design/` untouched when changing the app; update
  `docs/README.md` only if the implementation mapping changes.
