233 lines
7.5 KiB
Markdown
233 lines
7.5 KiB
Markdown
# AGENTS.md — NGO Landing Page
|
||
|
||
Read this file fully before taking any action.
|
||
|
||
---
|
||
|
||
## Project Context
|
||
|
||
Single-page static landing page for an NGO ERP product.
|
||
|
||
| Item | Detail |
|
||
|---|---|
|
||
| Pages | `index.html` — the only HTML file |
|
||
| Styling | Tailwind CSS v3 · source `src/input.css` → compiled `assets/site.css` |
|
||
| Data | `blog.json` — flat array of blog posts, loaded at runtime by inline JS |
|
||
| i18n | Inline `translations` object inside `index.html` (EN / ES / DE) |
|
||
| Blog renderer | Inline `<script>` in `index.html` — no external JS files |
|
||
| Dev server | `./start` (runs `live-server`) |
|
||
| Git remote | `git@git.odoo4projects.com:Oliver/NGO.git` |
|
||
|
||
### File map
|
||
|
||
```
|
||
index.html ← only HTML file — layout + all inline JS + i18n
|
||
src/input.css ← Tailwind source (edit here, then rebuild)
|
||
assets/site.css ← compiled output — DO NOT edit by hand
|
||
blog.json ← English blog posts (canonical + fallback)
|
||
blog.es.json ← Spanish blog posts
|
||
blog.de.json ← German blog posts
|
||
tailwind.config.js ← design tokens (colors, fonts, shadows)
|
||
```
|
||
|
||
### Design tokens (from `tailwind.config.js`)
|
||
|
||
| Token | Hex | Usage |
|
||
|---|---|---|
|
||
| `brand-ink` | `#201824` | default text / dark backgrounds |
|
||
| `brand-primary` | `#603F57` | section labels, bullet accents |
|
||
| `brand-accent` | `#F762B4` | CTA buttons, links |
|
||
| `brand-sunrise` | `#F8B84A` | hero highlights, hover states |
|
||
| `brand-emerald` | `#39B982` | positive indicators |
|
||
| `brand-snow` | `#F5F2F7` | page background |
|
||
| `brand-smoke` | `#E5DCE8` | borders, subtle dividers |
|
||
|
||
NEVER use raw hex values in HTML — always use the token class names above.
|
||
|
||
---
|
||
|
||
## 🎯 Goal
|
||
|
||
- Deliver an **SEO-optimised, fast-loading, responsive** single-page site.
|
||
- Keep all edits **minimal and targeted** — preserve design, structure, and functionality.
|
||
- NEVER introduce new frameworks, libraries, or external dependencies.
|
||
|
||
### Quality bar for every change
|
||
|
||
| Concern | Rule |
|
||
|---|---|
|
||
| SEO | Keep all existing meta tags, `ld+json`, `alt` attributes, and heading hierarchy |
|
||
| Performance | No comments in production HTML, no unused CSS classes, no render-blocking additions |
|
||
| Responsive | Every element must work on mobile (375 px), tablet (768 px), and desktop (1280 px+) |
|
||
| Consistency | Use only brand token classes; match existing spacing and rounding patterns |
|
||
|
||
---
|
||
|
||
## Commands
|
||
|
||
```bash
|
||
# Build CSS after editing src/input.css or tailwind.config.js
|
||
npm run build:css
|
||
|
||
# Watch CSS during active development
|
||
npm run watch:css
|
||
|
||
# Validate blog.json
|
||
jq empty blog.json && echo "JSON valid"
|
||
|
||
# Start dev server
|
||
./start
|
||
```
|
||
|
||
---
|
||
|
||
## Git Rules
|
||
|
||
- ALWAYS work on **`main`** branch.
|
||
- Pull before every session:
|
||
```bash
|
||
git pull origin main
|
||
```
|
||
- Commit messages must follow the pattern:
|
||
- `blog: add post – <title>`
|
||
- `fix: <short description>`
|
||
- `content: <short description>`
|
||
- Push immediately after committing — never leave unpushed commits.
|
||
- Branch creation is permitted ONLY under the **Branch Handling Exception** (see bottom).
|
||
|
||
---
|
||
|
||
## File Safety Rules
|
||
|
||
- ONLY modify files required for the task.
|
||
- NEVER delete or restructure content unrelated to the task.
|
||
- NEVER remove existing blog posts from `blog.json`.
|
||
- NEVER edit `assets/site.css` directly — always rebuild from `src/input.css`.
|
||
|
||
---
|
||
|
||
## Blog Post Schema
|
||
|
||
### Language-to-file mapping
|
||
|
||
| Language | File loaded | Fallback |
|
||
|---|---|---|
|
||
| English (`en`) | `blog.json` | — |
|
||
| Spanish (`es`) | `blog.es.json` | `blog.json` |
|
||
| German (`de`) | `blog.de.json` | `blog.json` |
|
||
|
||
The loader in `index.html` fetches the language-specific file automatically when the visitor switches language. If a language file is missing or returns an error, it falls back to `blog.json` silently.
|
||
|
||
`blog.json` is always the **English source and fallback**. Keep all three files structurally identical — same number of posts, same order, translated content only.
|
||
|
||
---
|
||
|
||
`blog.json` (and every language variant) is a root-level JSON array. Every post object contains **exactly these five fields**:
|
||
|
||
```json
|
||
[
|
||
{
|
||
"area": "Automation",
|
||
"date": "2026-03-25",
|
||
"title": "Article title as plain text",
|
||
"teaser": "<p>One or two sentences visible before 'Read more'.</p>",
|
||
"content": "<h3>Section</h3><p>Full article as HTML.</p>"
|
||
}
|
||
]
|
||
```
|
||
|
||
| Field | Type | Constraint |
|
||
|---|---|---|
|
||
| `area` | plain string | Category label rendered above the title |
|
||
| `date` | ISO 8601 (`YYYY-MM-DD`) | Used by `Intl.DateTimeFormat` |
|
||
| `title` | plain string | Rendered as `<h3>` — no HTML |
|
||
| `teaser` | HTML string | Always visible — wrap in `<p>` tags |
|
||
| `content` | HTML string | Revealed by "Read more" toggle — use `<h3>`, `<p>`, `<ul>`, `<li>` |
|
||
|
||
NEVER add extra fields (`slug`, `author`, `tags`, `excerpt`, `hero_image`, etc.) — they are ignored by the renderer and pollute the file.
|
||
|
||
### Adding a new blog post (jq method)
|
||
|
||
> Add to **all three files** in the same session. A post that exists in English but not in Spanish/German will silently fall back to the English version for those visitors — which is acceptable temporarily but should be resolved promptly.
|
||
|
||
```bash
|
||
# 1. Pull latest
|
||
git pull origin main
|
||
|
||
# 2. Backup all blog files once per session
|
||
mkdir -p /backup
|
||
for f in blog.json blog.es.json blog.de.json; do
|
||
cp $f /backup/$f.$(date +%Y%m%d%H%M%S)
|
||
done
|
||
|
||
# 3. Prepend new post to each language file
|
||
# $NEW_EN, $NEW_ES, $NEW_DE must each be a valid single post object
|
||
jq --argjson new "$NEW_EN" '. = [$new] + .' blog.json > tmp.json && mv tmp.json blog.json
|
||
jq --argjson new "$NEW_ES" '. = [$new] + .' blog.es.json > tmp.json && mv tmp.json blog.es.json
|
||
jq --argjson new "$NEW_DE" '. = [$new] + .' blog.de.json > tmp.json && mv tmp.json blog.de.json
|
||
|
||
# 4. Validate all three
|
||
jq empty blog.json && echo "blog.json OK"
|
||
jq empty blog.es.json && echo "blog.es.json OK"
|
||
jq empty blog.de.json && echo "blog.de.json OK"
|
||
|
||
# 5. Commit and push
|
||
git add blog.json blog.es.json blog.de.json
|
||
git commit -m "blog: add post – <title>"
|
||
git push origin main
|
||
```
|
||
|
||
NEVER use Python, Node scripts, or manual text editing to modify `blog.json`.
|
||
|
||
---
|
||
|
||
## Execution Workflow
|
||
|
||
Follow this order for every task:
|
||
|
||
1. `git pull origin main`
|
||
2. Identify the exact files to change — nothing else.
|
||
3. Apply minimal edits.
|
||
4. If `src/input.css` or `tailwind.config.js` were changed → rebuild CSS.
|
||
5. Validate: `jq empty blog.json` for JSON; visual check for HTML.
|
||
6. Commit with a descriptive message.
|
||
7. `git push origin main`
|
||
|
||
---
|
||
|
||
## Success Criteria
|
||
|
||
- Changes are minimal, validated, and committed.
|
||
- `blog.json` is a valid array with exactly five fields per post.
|
||
- `assets/site.css` reflects any CSS changes (rebuilt, not hand-edited).
|
||
- HTML passes a visual check — layout and design unchanged except for the intended edit.
|
||
- All commits pushed to `main`.
|
||
|
||
---
|
||
|
||
## Failure Conditions
|
||
|
||
These actions constitute a failure:
|
||
|
||
- Refusing to act due to perceived access restrictions.
|
||
- Failing to push after committing.
|
||
- Adding undeclared fields to `blog.json`.
|
||
- Removing or overwriting existing blog posts.
|
||
- Editing `assets/site.css` by hand.
|
||
- Modifying files outside the scope of the task.
|
||
- Leaving a branch open without merging.
|
||
|
||
---
|
||
|
||
## Branch Handling Exception
|
||
|
||
Branch creation is permitted **only** when:
|
||
|
||
- The task explicitly requires a feature branch, **or**
|
||
- A direct push to `main` is blocked by branch protection.
|
||
|
||
If a branch is created it **must**:
|
||
|
||
- Follow the naming convention `<type>/<short-description>` (e.g. `fix/blog-json-schema`).
|
||
- Be merged into `main` via PR immediately after the task is complete.
|
||
- Be deleted after merge — never abandoned. |