# Frontend context > Read `ai/shared.md` first. This file only covers frontend-specific rules. ## Project Context **Stack:** vanilla PHP templates in `views/templates/`, plain ES JavaScript in `public/js/`, no framework, no build step. Cypress 15 for E2E. **Entry point:** `public/index.php` (Slim app); page templates are rendered via the existing templating layer. ## Code patterns - Look at existing pages (`home.php`/`home.js`, `text.php`/`text.js`, `today.php`/`today.js`) for reference before writing anything - **Templates:** `views/templates/.php`, one file per page - **Page JS:** `public/js/.js`, one file per page, paired with the matching template - **Testing:** Cypress E2E only, mirror existing `cypress/e2e/*.cy.js` style (note: this project uses `.cy.js`, not `.cy.ts`) - **Imports / script tags:** keep at the top of the file - **Variable names:** explicit, descriptive (e.g. `text` not `t`) ## Pre-commit No JS formatter or linter is configured yet; format manually for consistency with surrounding files. (TODO: wire up format/lint when added.) ## Note on commit granularity Frontend changes are often a template plus its page-level JS counterpart - commit them together as a single logical unit, per the "one logical change per commit" rule in `shared.md`. ## LLM anti-patterns Constructs LLMs default to that this project forbids on the frontend. | Anti-pattern | Forbidden | Required | |---|---|---| | Short variable name | `t`, `n`, `res`, `req`, `e`, `el`, `ev` | `text`, `node`, `response`, `request`, `submitEvent`, `element`, `clickEvent` | | Em dash in code/comments | `// loads texts — owner only` | `// loads texts - owner only` | | Inline `` in a `.php` template | put logic in `public/js/.js`, load via `