7.5 KiB
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
# 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
mainbranch. - Pull before every session:
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.cssdirectly — always rebuild fromsrc/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:
[
{
"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.
# 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:
git pull origin main- Identify the exact files to change — nothing else.
- Apply minimal edits.
- If
src/input.cssortailwind.config.jswere changed → rebuild CSS. - Validate:
jq empty blog.jsonfor JSON; visual check for HTML. - Commit with a descriptive message.
git push origin main
Success Criteria
- Changes are minimal, validated, and committed.
blog.jsonis a valid array with exactly five fields per post.assets/site.cssreflects 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.cssby 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
mainis 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
mainvia PR immediately after the task is complete. - Be deleted after merge — never abandoned.