86 Commits

Author SHA1 Message Date
oliver d4c8760007 fix: add copy-link button and hash deep-linking for blog articles 2026-05-15 06:49:52 -03:00
Oliver b8fc96ea0a Add blog post: Make Smarter Decisions With Better Data 2026-05-14 12:34:04 -03:00
oliver 966441e6aa fix: wire Book Meeting (nav + hero) and Request scoped help to calendar modal 2026-05-05 18:04:37 -03:00
oliver 43d66fd295 content: add Schedule a Meeting button with calendar modal next to trial widget 2026-05-05 17:28:30 -03:00
oliver 5afda4e953 fix: article CTA panel scrolls with content, appears below last paragraph 2026-05-05 15:00:18 -03:00
oliver c6d3e2516e fix: remove Book a free demo button from 4 blog posts
content: add free trial CTA panel (email + location + submit) to article modal lower-right
2026-05-05 14:57:13 -03:00
Oliver 3ac4e9bb4a Add blog post: From Spreadsheet Chaos to Donor-Ready Insights 2026-05-05 14:30:50 -03:00
Oliver eb2f6802fd Fix: button always pinned to bottom of card regardless of content height 2026-05-05 14:27:55 -03:00
Oliver 8bb70a9af0 Add blog post: Never Lose a Donor Again: Track Every Relationship with Ease 2026-05-05 14:17:51 -03:00
Oliver 8755db3305 Add blog post: No One Owned It: How Small NGOs Close the Accountability Gap on Donor Follow-Ups 2026-05-05 14:08:58 -03:00
Oliver 2fa1a5eb3a Fix: pin 'How to implement this' button to card bottom 2026-05-05 14:06:39 -03:00
Oliver 75fc2ccc3b Add blog post: Never Forget a Donor Again 2026-05-05 14:02:24 -03:00
Oliver e44d99c7e7 Add blog post: Gather Feedback That Helps You Grow 2026-05-05 13:54:46 -03:00
Oliver dedec93e23 Add blog post: Keep Donors Informed Automatically 2026-05-05 13:45:36 -03:00
Oliver 9a120ab0d6 Add blog post: Building Donor Trust With Organized NGO Operations 2026-05-05 13:38:50 -03:00
Oliver 6079039f21 Automated landing-page update & add blog post 2026-05-04 19:25:25 -03:00
Oliver 2cf4dcbdae Automated landing-page update & add blog post: Stop Reconciling Spreadsheets. Start Showing Real Impact. 2026-05-04 18:42:57 -03:00
Oliver e9dc4a6a0d Automated landing-page update & add blog post 2026-05-04 18:41:27 -03:00
Oliver f488a103c8 Automated landing-page update & add blog post 2026-05-04 18:34:45 -03:00
Oliver df5eeeb00c blog: re-style iframe.article — position right next to first paragraph, double size 2026-05-03 20:29:37 +00:00
oliver b581601064 style 2026-05-03 16:48:25 -03:00
oliver 77bc63de24 post 2026-05-03 16:46:15 -03:00
Oliver a86684f6d1 p 2026-05-03 19:37:12 +00:00
oliver b82c04ce51 posts 2026-05-03 15:35:20 -03:00
Oliver df20b2fb51 Add blog post: How Donor Management Helps NGOs Build Lasting Relationships 2026-05-03 14:03:39 +00:00
oliver 77aaa9989e fix: strip existing extension from post.image before appending .webp 2026-05-03 07:43:25 -03:00
oliver c5a862f7ba Update posts.json 2026-05-03 07:35:50 -03:00
Oliver 3bf0060439 Add blog post: How Small NGOs Can Reclaim Their Time from Administrative Work 2026-05-03 10:26:57 +00:00
oliver a5b3b9d36f content: SEO optimisation for 'how to manage a non profit organization' 2026-05-03 06:41:30 -03:00
oliver 440cc084d3 fix: article-body scroll vertical only, remove column layout 2026-05-03 06:25:37 -03:00
oliver f9a263dd8c fix: modal scroll vertical only, hide horizontal overflow 2026-05-03 06:19:37 -03:00
oliver fdc1a1a215 content: article modal now scrolls horizontally with newspaper columns 2026-05-03 06:15:55 -03:00
oliver 10ac10a92a fix: remove overflow clip from article modal to ensure vertical scroll works 2026-05-03 06:15:03 -03:00
oliver a9ea122ac5 content: rename Solutions to Tutorials, link to blog section 2026-05-03 06:13:59 -03:00
oliver f865d549d1 content: remove NGO offer card, fix article modal vertical scroll 2026-05-03 06:01:58 -03:00
oliver 3215694f5c content: rework hero for NGO ICP with 50% offer, rework blog heading 2026-05-03 05:55:01 -03:00
oliver 8594393664 fix: hero image visibility and article modal vertical scrolling 2026-05-03 05:50:54 -03:00
oliver b0dde481cf content: blog card redesign with 4-line teaser, article modal, hero bg update 2026-05-03 05:45:06 -03:00
oliver 5172bfe62c Update posts.json 2026-05-03 05:11:49 -03:00
oliver d518ad2ae4 fix: align blog renderer field names with posts.json schema 2026-05-03 05:10:29 -03:00
Oliver 62c4aee24c Add blog post: How to Build Donor Trust with Transparent Impact Reporting 2026-05-02 23:23:30 +00:00
Oliver d92c72a6cd Automated landing-page text update and empty posts.json 2026-05-02 23:01:32 +00:00
Oliver 3005e53d6e Delete 'Pick the vertical' block and move 'Live from the field' up 2026-05-02 22:49:43 +00:00
oliver afb5a2ac20 migrate 2026-04-26 10:32:18 -03:00
Your Name 3afcf77a16 name 2026-04-15 10:00:44 -03:00
Dev e542bbd44a blog: add post – NGO ERP: Donor Management & Fundraising Software Guide 2026-04-08 19:47:42 +00:00
Dev a626defcfd content: update trial, meeting sections and remove broken CTAs 2026-04-08 19:37:41 +00:00
Dev b2cb2a1a8e content: update homepage value cards with new localized copy and CTAs 2026-04-08 19:32:34 +00:00
Dev 3549e8757e Update homepage SEO copy + OG tags + hero/value props (SEO keywords) 2026-04-08 19:17:05 +00:00
Your Name 2b2baf6851 fix 2026-04-07 17:11:56 -03:00
Your Name e649373118 f 2026-04-07 17:10:51 -03:00
Your Name f3cb8ca848 fix: show total hours right-aligned in Today's Todos headline 2026-04-07 05:50:00 -03:00
Your Name acec840d91 Add minutes 2026-04-07 05:48:45 -03:00
Your Name 0d5205ac94 fix: display meeting times from ISO offset string, not browser timezone 2026-03-31 09:58:12 -03:00
Your Name 1a4a9542f5 fix: Latest Signups full height, count badge, remove Current Test box, handle array/object JSON 2026-03-30 10:59:23 -03:00
Your Name bd319d05a5 del 2026-03-30 09:14:06 -03:00
Your Name 2a0af148c8 block 2026-03-30 08:21:13 -03:00
Your Name ad7a531ea0 typo 2026-03-30 08:02:42 -03:00
Your Name fd91306cb0 added Dash 2026-03-30 08:01:42 -03:00
Oliver 4ea7586a7f google verification 2026-03-27 18:40:05 -03:00
Oliver 671ddb2b75 content: update impact strip stats — 55% no-ERP, 32% admin reduction 2026-03-27 18:32:05 -03:00
Oliver 7d447bee93 fix: footer links align-bottom; send btn inside textarea bottom-right, border color 2026-03-27 18:23:24 -03:00
Oliver 5cc4486ab7 fix: 2× textarea height; footer copyright br + remove dash 2026-03-27 18:18:09 -03:00
Oliver 6e4b1c891c feat: append IP + geo (city, region, country, org) to feedback webhook via ipapi.co 2026-03-27 18:15:26 -03:00
Oliver f1f67b29dd fix: footer textarea 50% smaller; translate placeholder EN/ES/DE 2026-03-27 18:13:46 -03:00
Oliver d568a365df fix: footer textarea size+scrollbar+arrow; bundle i18n; meeting copy update 2026-03-27 18:09:42 -03:00
Oliver 4781e84ebc perf: remove Google Fonts — system font stack for body and headings; rebuild site.css -48% 2026-03-27 18:04:06 -03:00
Oliver be09564a25 feat: badge text, 6-item bundle card, footer textarea 2×wide 30%tall, SVG send icon 2026-03-27 17:59:40 -03:00
Oliver 0fc5b59d5f feat: footer feedback widget — textarea + send to webhook 2026-03-27 17:46:37 -03:00
Oliver 5526873a41 design: promote NGO warm design to index.html; AU Sydney; bundle card; india.webp hero 2026-03-27 17:40:57 -03:00
Oliver d111b55de0 feat: blog modal with animation, replace trial form with product/location/webhook widget 2026-03-27 16:56:52 -03:00
Oliver 5bd3c7b398 feat: multi-language blog posts — add blog.es.json, blog.de.json; load by locale with EN fallback 2026-03-27 16:40:03 -03:00
Oliver 3627c2c73d build: add .gitignore, npm scripts, fix font-brand token, clear audit warnings 2026-03-27 16:30:07 -03:00
Oliver 4d2f57c20c Checked AGENTS.md 2026-03-27 16:23:57 -03:00
Oliver 05719aae4e INIT Blogs 2026-03-27 13:37:03 -03:00
Web_Designer b2a41d1a7b Add blog post: ODOO has 1,000,000 NGOs online! 2026-03-27 16:29:07 +00:00
Web_Designer 4bdef11b3c Publish: localisation-in-practice-shifting-power-and-funding-to-local-partners-effectively 2026-03-27 16:25:10 +00:00
Web_Designer aafb99460c Update homepage title and H1 to 'OPENCODEis NOICE' 2026-03-27 15:10:00 +00:00
Oliver a74de43248 Update README.md 2026-03-25 18:21:03 -03:00
Web_Designer 819665225f Add blog post: Reduce NGO Admin by 20–40%: 7 Workflows You Can Automate This Month 2026-03-25 20:55:58 +00:00
Oliver 3dd49559ac 0 2026-03-25 16:14:17 -03:00
Oliver c81565749a 0 2026-03-25 16:12:40 -03:00
Oliver ecf4219897 blog 2026-03-24 19:11:05 -03:00
Oliver 84090fd562 posts update 2026-03-24 19:08:42 -03:00
Web_Designer 76a47cc730 Add rollback changelog (2026-03-24T22:06:43Z) 2026-03-24 22:06:43 +00:00
Oliver 6127867d51 Deleted Backups and changed readme 2026-03-24 14:14:47 -03:00
24 changed files with 7185 additions and 3046 deletions
+21
View File
@@ -0,0 +1,21 @@
# Dependencies
node_modules/
# Tailwind build temp
tmp.json
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# OS
.DS_Store
Thumbs.db
# Editor
.vscode/
.idea/
*.swp
*.swo
+233
View File
@@ -0,0 +1,233 @@
# 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.
-311
View File
@@ -1,311 +0,0 @@
# README
Important: Update this README with every commit.
Repository purpose
- Project: NGO public website using Odoo-focused messaging and Odoo4Projects hosting service.
- Goal: Fast, accessible marketing homepage and blog that ranks well, highlights transparency and minimal admin for NGOs, and promotes donor acquisition and retention.
Repository rules
- Blog posts are saved in blog.json (do not create separate backup files).
- Do not create backups in the repo.
CI:
- CI: run linting, Tailwind build, accessibility checks, basic SEO checks, performance budget (build must verify page size and critical render time). (Keep CI config outside this README; note these checks are required.)
Main Page Blocks (ordered)
1. Hero
- Headline: Transparent
giving.
Minimal
admin.
Big
impact.
- Subheadline: Manage
donors,
communicate
transparently,
and
focus
on
impact
Odoo
made
simple
for
NGOs.
- Primary CTA: Donate
/
Support and secondary CTA: See
donor
management
2. Trust & Numbers bar
- Donor count, funds raised, projects completed, partner logos
3. How it works (3 steps)
- Step 1: Set up in minutes (little admin)
- Step 2: Track donations & communicate (donor communication)
- Step 3: Report impact (transparent reporting)
4. Features (highlighted cards)
- Donor Management (CRM + gift history)
- Easy Communication (email, receipts, automated updates)
- Transparent Reporting (dashboards, exports for donors)
- Low Admin (templates, automation, minimal data entry)
- Security & Compliance
5. Impact Stories / Testimonials
- Short stories with photos and metrics
6. Blog highlights
- Link to blog page, featured posts
7. Call to Action block
- Repeat primary CTA with trust indicators
8. Footer
- Contact, legal, social links, languages
Languages:
- Default: English
- Additional: Spanish (es), French (fr) — prepare for translation-ready content
Technology Stack:
- Tailwind CSS. Static-first, optimized HTML, semantic markup.
SEO & Performance goals:
- Fast page that ranks well: semantic HTML, structured data (schema.org), descriptive meta titles and descriptions, sitemap, robots.txt, optimized images (modern formats), critical CSS inlined, defer non-critical JS.
- Focus keywords: NGO donor management, transparent donations, Odoo for NGOs, donor communication, minimal admin for charities
Suggested meta and headings (to include on homepage):
- Meta title (homepage): Odoo
for
NGOs
Transparent
donor
management
with
minimal
admin
- Meta description: Manage
donors,
communicate
transparently,
and
report
impact
with
minimal
admin.
Odoo
solutions
tailored
for
NGOs
fast,
secure,
and
donor-friendly.
- H1: Transparent
donor
management
with
minimal
admin
- H2 examples: How
Odoo
simplifies
donor
management, Features:
Donor
CRM,
automated
communication,
impact
reporting, Stories
from
our
partners
Suggested CTAs (text variations):
- Primary: Support
now / Donate
- Secondary: See
donor
management / Schedule
a
demo
- Micro CTA: Download
impact
report
Content & SEO guidance (short):
- Use clear, trust-building language. Highlight transparency, automated communications, and low admin burden.
- Include one donor-focused success story on the homepage and link to deeper case studies in the blog.
- Use structured snippets for stats (JSON-LD) for trust signals.
Initial Blog Posts (to be saved into blog.json):
- Filename: blog.json (root)
- Initial entry (one object in the posts array):
{
id: how-odoo-makes-donor-management-easy,
title: How
Odoo
makes
donor
management
easy,
date: 2026-03-24,
author: Odoo4Projects
-
NGO
team,
categories: [donor-management, transparency, productivity],
tags: [Odoo, donor
communication, automation, minimal
admin],
excerpt: Learn
how
Odoo
reduces
administrative
effort,
improves
donor
communication,
and
increases
transparency
for
NGOs.,
content: Odoo
makes
donor
management
easy
by
centralizing
donor
data,
automating
receipts
and
updates,
and
generating
transparent
reports
donors
trust.
With
minimal
admin
required,
NGOs
can
set
up
templates,
schedule
automated
communications,
and
track
gifts
and
commitments
in
one
place.
Donors
receive
timely
receipts
and
impact
updates
that
strengthen
trust
and
retention.
Odoos
dashboards
provide
simple,
exportable
reports
for
accountability.
The
result:
less
time
on
admin,
more
time
on
mission.,
featured: true
}
Social media snippets (short, use for cards):
- Tweet/LinkedIn (short): Reduce
admin,
increase
trust.
See
how
Odoo
helps
NGOs
manage
donors
and
report
impact
with
transparency.
Read:
/blog/how-odoo-makes-donor-management-easy
- Facebook/Instagram (longer): Spend
less
time
on
paperwork
and
more
on
impact.
Odoo
helps
NGOs
automate
donor
receipts,
keep
supporters
updated,
and
produce
clear
impact
reports
all
with
minimal
admin.
Learn
more:
/blog/how-odoo-makes-donor-management-easy
Notes for the designer (content only):
- Keep layout simple and fast; prefer server-side rendered HTML where possible for SEO.
- Provide components/placeholder content for each Main Page Block above.
- Prefill the blog.json with the initial blog entry above.
- Add README.md with this content and commit to repo root. Ensure README is updated on every future commit.
Deliverables (create and commit):
1. README.md (prefilled as above)
2. blog.json (prefilled with the initial entry)
If you need any copy adjustments (tone, length, languages), ask and we will provide final texts. Thank you.
-1
View File
File diff suppressed because one or more lines are too long
-555
View File
@@ -1,555 +0,0 @@
<!DOCTYPE html>
<html lang="en" class="scroll-smooth">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>🐻 NGO ERP Landingpage | ODOO4projects</title>
<meta name="description" content="Purpose-built ERP platform for NGOs. Centralize programs, automate donor and grant reporting, and launch in weeks with ODOO4projects." />
<meta name="keywords" content="NGO ERP system, nonprofit management software, ERP for NGOs, NGO operations platform, ODOO for nonprofits" />
<link rel="icon" href="https://odoo4projects.com/web/image/website/1/favicon?unique=725c3af" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"></noscript>
<link rel="preload" href="assets/site.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<noscript><link rel="stylesheet" href="assets/site.css"></noscript>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "NGO ERP Landing",
"about": "ERP for NGOs",
"publisher": {
"@type": "Organization",
"name": "ODOO4projects",
"logo": "https://odoo4projects.com/web/image/website/1/logo?unique=1be96c3"
},
"mainEntity": {
"@type": "SoftwareApplication",
"name": "ODOO4projects NGO ERP",
"applicationCategory": "BusinessApplication",
"operatingSystem": "Cloud",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD",
"description": "4-week free trial of NGO ERP workspace"
}
}
}
</script>
<script defer data-domain="ngo.odoo4projects.com" src="https://plausible.odoo4projects.com/js/script.tagged-events.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
<style id="emoji-style">
/* Emoji styling to match heading font and spacing */
.emoji{font-family:inherit;font-size:1em;vertical-align:middle;margin-right:0.5rem;display:inline-block}
</style>
</head>
<body class="bg-brand-snow text-brand-ink">
<header class="bg-hero-gradient text-white">
<div class="max-w-6xl mx-auto px-6 py-6 flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center gap-3">
<img src="https://odoo4projects.com/web/image/website/1/logo?unique=1be96c3" alt="ODOO4projects logo" class="h-10 w-auto" />
<span class="uppercase tracking-[0.3em] text-xs text-brand-smoke" data-i18n="hero-badge"></span>
</div>
<nav class="flex flex-wrap items-center gap-6 text-sm">
<a href="#blog" class="hover:text-brand-sunrise transition" data-i18n="nav-resources"></a>
<a href="#trial" class="hover:text-brand-sunrise transition" data-i18n="nav-trial"></a>
</nav>
<div class="flex items-center gap-3">
<label for="lang-selector" class="sr-only">Language</label>
<select id="lang-selector" class="bg-white/10 border border-white/30 text-sm rounded-full px-3 py-1.5 focus:outline-none focus:ring-2 focus:ring-brand-sunrise/70">
<option value="en">English</option>
<option value="es">Español</option>
<option value="de">Deutsch</option>
</select>
<a href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ3DDbaiHFlhNhWySszAQoPXE_H73QLqYT3w7H9IYWC76RA_TgNIhLESjb4N7ep_D2D_OyW9q4-c" target="_blank" rel="noopener" class="px-5 py-2 bg-brand-sunrise text-brand-ink font-semibold rounded-full text-sm shadow-brand hover:translate-y-0.5 transition plausible-event-name=meeting" data-i18n="cta-meeting"></a>
</div>
</div>
<div class="max-w-6xl mx-auto px-6 py-16 grid md:grid-cols-2 gap-12 items-center">
<div>
<p class="text-brand-sunrise font-semibold mb-4" data-i18n="hero-pill"></p>
<h1 class="text-4xl md:text-5xl font-semibold leading-tight mb-6"><span class=\"emoji\" role=\"img\" aria-label=\"bear\">🐻</span> <span data-i18n=\"hero-headline\"></span></h1>
<p class="text-lg text-white/80 mb-8" data-i18n="hero-subheadline"></p>
<div class="flex flex-wrap gap-4">
<a href="#trial" class="px-6 py-3 bg-brand-accent hover:bg-brand-sunrise text-brand-ink font-semibold rounded-full transition" data-i18n="cta-trial" data-event="cta:hero-trial"></a>
</div>
<div class="mt-10 grid grid-cols-2 gap-6 text-sm text-white/80">
<div>
<p class="text-3xl font-semibold text-white">38%</p>
<p data-i18n="hero-stat1"></p>
</div>
<div>
<p class="text-3xl font-semibold text-white">2x</p>
<p data-i18n="hero-stat2"></p>
</div>
</div>
</div>
<div class="bg-white/10 backdrop-blur-lg rounded-3xl p-8 shadow-brand">
<div class="relative">
<img src="https://images.unsplash.com/photo-1521737604893-d14cc237f11d?auto=format&fit=crop&w=900&q=80" alt="NGO team collaborating" class="rounded-2xl" />
<div class="absolute -bottom-8 left-8 bg-white/90 text-brand-ink px-4 py-3 rounded-2xl shadow-lg">
<p class="text-xs uppercase tracking-widest text-brand-primary mb-1" data-i18n="hero-card-title"></p>
<p class="text-lg font-semibold" data-i18n="hero-card-headline"></p>
<p class="text-sm text-brand-primary" data-i18n="hero-card-body"></p>
</div>
</div>
</div>
</div>
</header>
<section class="max-w-6xl mx-auto px-6 py-16 grid md:grid-cols-3 gap-8">
<article class="bg-white rounded-2xl p-6 shadow-brand border border-brand-smoke">
<h2 class="text-xl font-semibold mb-2" data-i18n="value1-title"></h2>
<p class="text-sm text-brand-ink/80" data-i18n="value1-body"></p>
</article>
<article class="bg-white rounded-2xl p-6 shadow-brand border border-brand-smoke">
<h2 class="text-xl font-semibold mb-2" data-i18n="value2-title"></h2>
<p class="text-sm text-brand-ink/80" data-i18n="value2-body"></p>
</article>
<article class="bg-white rounded-2xl p-6 shadow-brand border border-brand-smoke">
<h2 class="text-xl font-semibold mb-2" data-i18n="value3-title"></h2>
<p class="text-sm text-brand-ink/80" data-i18n="value3-body"></p>
</article>
</section>
<section id="blog" class="bg-white py-20">
<div class="max-w-6xl mx-auto px-6">
<div class="flex flex-col md:flex-row md:items-end md:justify-between gap-6 mb-12">
<div>
<p class="text-sm uppercase tracking-[0.3em] text-brand-primary mb-3" data-i18n="blog-tagline"></p>
<h2 class="text-3xl font-semibold" data-i18n="blog-title"></h2>
<p class="text-brand-ink/80" data-i18n="blog-subtitle"></p>
</div>
<button id="blog-toggle" type="button" class="text-brand-accent font-semibold hover:underline underline-offset-4">Browse all articles →</button>
</div>
<div id="blog-grid" class="grid gap-6 md:grid-cols-3"></div>
<p id="blog-error" class="text-sm text-brand-ink/70 mt-6 hidden"></p>
</div>
</section>
<section id="trial" class="bg-brand-ink text-white py-20">
<div class="max-w-5xl mx-auto px-6 grid md:grid-cols-2 gap-12">
<div>
<p class="text-brand-sunrise text-sm uppercase tracking-[0.3em] mb-4" data-i18n="trial-tagline"></p>
<h2 class="text-3xl font-semibold mb-4" data-i18n="trial-heading"></h2>
<p class="text-white/80 mb-6" data-i18n="trial-body"></p>
<ul class="space-y-4 text-sm text-white/80">
<li class="flex gap-3"><span class="text-brand-emerald">✔</span><span data-i18n="trial-bullet1"></span></li>
<li class="flex gap-3"><span class="text-brand-emerald">✔</span><span data-i18n="trial-bullet2"></span></li>
<li class="flex gap-3"><span class="text-brand-emerald">✔</span><span data-i18n="trial-bullet3"></span></li>
</ul>
</div>
<form class="bg-white text-brand-ink rounded-3xl p-8 shadow-brand space-y-5" data-event="form:trial">
<label class="block text-sm font-medium">
<span data-i18n="trial-label-email"></span>
<input type="email" required class="mt-2 w-full rounded-2xl border border-brand-smoke px-4 py-3 focus:outline-none focus:ring-2 focus:ring-brand-accent" data-i18n-placeholder="trial-placeholder-email" />
</label>
<label class="block text-sm font-medium">
<span data-i18n="trial-label-priority"></span>
<select class="mt-2 w-full rounded-2xl border border-brand-smoke px-4 py-3 focus:outline-none focus:ring-2 focus:ring-brand-accent">
<option data-i18n-option="priority-1"></option>
<option data-i18n-option="priority-2"></option>
<option data-i18n-option="priority-3"></option>
<option data-i18n-option="priority-4"></option>
</select>
</label>
<label class="block text-sm font-medium">
<span data-i18n="trial-label-region"></span>
<input type="text" class="mt-2 w-full rounded-2xl border border-brand-smoke px-4 py-3 focus:outline-none focus:ring-2 focus:ring-brand-accent" data-i18n-placeholder="trial-placeholder-region" />
</label>
<p class="text-xs text-brand-ink/70" data-i18n="trial-microcopy"></p>
<button type="submit" class="w-full py-3 rounded-2xl bg-brand-accent text-brand-ink font-semibold" data-i18n="cta-trial"></button>
<p class="text-xs text-brand-ink/60 text-center" data-i18n="trial-help"></p>
</form>
</div>
</section>
<section id="meeting" class="py-20 bg-white">
<div class="max-w-5xl mx-auto px-6 grid md:grid-cols-2 gap-12 items-center">
<div>
<p class="uppercase text-xs tracking-[0.3em] text-brand-primary mb-3" data-i18n="meeting-tagline"></p>
<h2 class="text-3xl font-semibold mb-4" data-i18n="meeting-heading"></h2>
<p class="text-brand-ink/80 mb-6" data-i18n="meeting-body"></p>
<ul class="space-y-4 text-sm text-brand-ink/80">
<li class="flex gap-3"><span class="text-brand-primary">◎</span><span data-i18n="meeting-bullet1"></span></li>
<li class="flex gap-3"><span class="text-brand-primary">◎</span><span data-i18n="meeting-bullet2"></span></li>
<li class="flex gap-3"><span class="text-brand-primary">◎</span><span data-i18n="meeting-bullet3"></span></li>
</ul>
</div>
<div class="bg-brand-snow border border-brand-smoke rounded-3xl p-8 shadow-brand">
<p class="text-sm text-brand-primary font-semibold mb-2" data-i18n="meeting-note-title"></p>
<p class="text-brand-ink font-semibold text-xl mb-4" data-i18n="meeting-note-body"></p>
<p class="text-sm text-brand-ink/70" data-i18n="meeting-note-hint"></p>
<a href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ3DDbaiHFlhNhWySszAQoPXE_H73QLqYT3w7H9IYWC76RA_TgNIhLESjb4N7ep_D2D_OyW9q4-c" target="_blank" rel="noopener" class="inline-flex items-center gap-2 mt-4 text-sm font-semibold text-brand-primary hover:text-brand-accent plausible-event-name=meeting" data-i18n="meeting-note-cta"></a>
</div>
</div>
</section>
<footer class="bg-brand-ink text-white py-10">
<div class="max-w-6xl mx-auto px-6 flex flex-col md:flex-row gap-6 items-center justify-between text-sm">
<p>© <span id="year"></span> <span data-i18n="footer-note"></span></p>
<div class="flex gap-4">
<a href="https://odoo4projects.com/support" class="hover:text-brand-sunrise" data-i18n="footer-support"></a>
<a href="https://odoo4projects.com/legal" class="hover:text-brand-sunrise" data-i18n="footer-legal"></a>
<a href="https://odoo4projects.com/contactus" class="hover:text-brand-sunrise" data-i18n="footer-contact"></a>
</div>
</div>
</footer>
<script>
const translations = {
en: {
'nav-resources': 'Resources',
'nav-trial': 'Free Trial',
'hero-badge': 'ERP FOR NGOs',
'hero-pill': 'Unified NGO ERP Platform',
'hero-headline': 'Simplify every mission workflow with an ERP built for NGOs',
'hero-subheadline': 'Consolidate programs, automate donor and grant reporting, and give every field office the same source of truth. Launch in weeks with templates tailored to humanitarian and community-impact teams.',
'cta-trial': 'Sign Up for Free Trial',
'cta-meeting': 'Schedule a Meeting',
'hero-stat1': 'Faster donor & grant reporting cycles',
'hero-stat2': 'Increase in volunteer onboarding speed',
'hero-card-title': 'Live KPI snapshot',
'hero-card-headline': 'Program Impact Dashboard',
'hero-card-body': 'Realtime budgets • Volunteer hours • Donor health',
'value1-title': 'Transparency for Donors',
'value1-body': 'Accounting-ready ledgers pair receipts with stories so donors see every peso without extra spreadsheets or calls.',
'value2-title': 'Donor Management & Communications',
'value2-body': 'Automation buddies queue thank-yous, newsletters, and SMS nudges so every supporter hears from you right on time.',
'value3-title': 'International Fund Raising',
'value3-body': 'Multilingual homepages, acquisition kanbans, and project trackers keep campaigns aligned across countries without rebuilding playbooks.',
'blog-tagline': 'Insights for NGO leaders',
'blog-title': 'Blog & resource hub',
'blog-subtitle': 'Get your impulses with our entertaining playbooks.',
'blog-link': 'Browse all articles →',
'blog-all-open': 'Show fewer articles',
'blog-read-more': 'Read more',
'blog-show-less': 'Show less',
'blog-error': 'Unable to load articles right now.',
'trial-tagline': 'Sign up free trial',
'trial-heading': 'Launch your NGO ERP sandbox in under 5 minutes',
'trial-body': 'Experience localized NGO templates, donor CRM, and automation recipes. No credit card required—just choose your focus area and invite teammates.',
'trial-bullet1': 'Pre-loaded NGO chart of accounts & grant tracking',
'trial-bullet2': 'Automated donor receipts + impact dashboards',
'trial-bullet3': 'Guided checklists for go-live within 30 days',
'trial-label-email': 'Work email',
'trial-placeholder-email': 'impact@yourngo.org',
'trial-label-priority': 'Primary priority',
'priority-1': 'Grant compliance reporting',
'priority-2': 'Volunteer management',
'priority-3': 'Donor CRM & fundraising',
'priority-4': 'Finance & procurement',
'trial-label-region': 'Country / region',
'trial-placeholder-region': 'e.g., Paraguay, LATAM',
'trial-microcopy': 'No credit card required. EU hosting & GDPR-ready.',
'trial-help': 'Need help? Use the Schedule a Meeting button in the header to book a guided call.',
'meeting-tagline': 'Have a meeting',
'meeting-heading': 'See how your NGO can streamline operations, save time, and reduce errors',
'meeting-body': 'A 30-minute live walkthrough tailored to your mission, covering localization, integrations, and governance. Walk away with a rollout roadmap.',
'meeting-bullet1': 'Baseline automation scoring',
'meeting-bullet2': 'Tech stack alignment & data migration plan',
'meeting-bullet3': 'Budget templates & total cost forecast',
'meeting-note-title': 'How scheduling works',
'meeting-note-body': 'You will meet with an NGO consultant from ODOO4projects.',
'meeting-note-hint': 'Use the Schedule a Meeting button in the header and tell us during booking which question we should prepare for.',
'meeting-note-cta': 'Open booking calendar',
'footer-note': 'ODOO4projects — Hosting for the AI generation',
'footer-support': 'Support',
'footer-legal': 'Legal',
'footer-contact': 'Contact'
},
es: {
'nav-resources': 'Recursos',
'nav-trial': 'Prueba gratuita',
'hero-badge': 'ERP PARA ONGs',
'hero-pill': 'Plataforma ERP unificada para ONGs',
'hero-headline': 'Simplifica cada misión con un ERP diseñado para ONGs',
'hero-subheadline': 'Centraliza programas, automatiza reportes de donantes y subvenciones y ofrece a cada sede la misma fuente de verdad. Implementa en semanas con plantillas creadas para equipos humanitarios.',
'cta-trial': 'Crear prueba gratuita',
'cta-meeting': 'Agendar una reunión',
'hero-stat1': 'Ciclos más rápidos de reportes a donantes y subvenciones',
'hero-stat2': 'Mayor velocidad en la incorporación de voluntarios',
'hero-card-title': 'Panel de KPIs en vivo',
'hero-card-headline': 'Tablero de impacto programático',
'hero-card-body': 'Presupuestos en tiempo real • Horas voluntarias • Salud de donantes',
'value1-title': 'Transparencia para donantes',
'value1-body': 'Libros contables listos unen recibos y relatos para que cada donante vea su aporte sin hojas extra.',
'value2-title': 'Gestión y comunicación con donantes',
'value2-body': 'Bots de automatización programan agradecimientos, boletines y SMS para que cada aliado reciba noticias a tiempo.',
'value3-title': 'Recaudación internacional',
'value3-body': 'Sitios multilingües, tableros de adquisición y proyectos coordinan campañas globales sin rehacer playbooks ni procesos.',
'blog-tagline': 'Ideas para líderes de ONG',
'blog-title': 'Blog y centro de recursos',
'blog-subtitle': 'Recibe impulsos con nuestros playbooks entretenidos.',
'blog-link': 'Ver todos los artículos →',
'blog-all-open': 'Mostrar menos artículos',
'blog-read-more': 'Leer más',
'blog-show-less': 'Mostrar menos',
'blog-error': 'No pudimos cargar los artículos en este momento.',
'trial-tagline': 'Activa tu prueba',
'trial-heading': 'Lanza tu sandbox ERP para ONG en menos de 5 minutos',
'trial-body': 'Explora plantillas localizadas, CRM de donantes y recetas de automatización. Sin tarjeta; solo elige tu prioridad e invita al equipo.',
'trial-bullet1': 'Plan contable para ONG y seguimiento de subvenciones precargado',
'trial-bullet2': 'Recibos automáticos más tableros de impacto',
'trial-bullet3': 'Checklists guiados para salir a producción en 30 días',
'trial-label-email': 'Correo laboral',
'trial-placeholder-email': 'impacto@tuong.org',
'trial-label-priority': 'Prioridad principal',
'priority-1': 'Reportes de subvenciones',
'priority-2': 'Gestión de voluntarios',
'priority-3': 'CRM y recaudación',
'priority-4': 'Finanzas y compras',
'trial-label-region': 'País / región',
'trial-placeholder-region': 'ej. Paraguay, LATAM',
'trial-microcopy': 'Sin tarjeta. Hosting en la UE y cumplimiento GDPR.',
'trial-help': '¿Dudas? Usa el botón “Agendar una reunión” en el encabezado para reservar una llamada guiada.',
'meeting-tagline': 'Agenda una reunión',
'meeting-heading': 'Descubre cómo optimizar operaciones, ahorrar tiempo y reducir errores',
'meeting-body': 'Sesión de 30 minutos adaptada a tu misión, con localización, integraciones y gobernanza. Sal con un plan de implementación.',
'meeting-bullet1': 'Diagnóstico de automatización',
'meeting-bullet2': 'Plan de migración y alineación tecnológica',
'meeting-bullet3': 'Plantillas presupuestarias y previsión de costes',
'meeting-note-title': 'Cómo reservar',
'meeting-note-body': 'Te reunirás con un consultor ONG de ODOO4projects.',
'meeting-note-hint': 'Usa el botón “Agendar una reunión” del encabezado y cuéntanos durante la reserva qué pregunta debemos preparar.',
'meeting-note-cta': 'Abrir calendario de reservas',
'footer-note': 'ODOO4projects — Hosting para la generación IA',
'footer-support': 'Soporte',
'footer-legal': 'Legal',
'footer-contact': 'Contacto'
},
de: {
'nav-resources': 'Ressourcen',
'nav-trial': 'Kostenlose Testphase',
'hero-badge': 'ERP FÜR NGOs',
'hero-pill': 'Vereintes NGO-ERP',
'hero-headline': 'Vereinfache jeden Einsatz mit einem ERP für NGOs',
'hero-subheadline': 'Bündele Programme, automatisiere Spender- und Förderberichte und gib allen Standorten dieselbe Datenbasis. Starte in wenigen Wochen mit maßgeschneiderten Templates.',
'cta-trial': 'Kostenlose Testphase starten',
'cta-meeting': 'Meeting planen',
'hero-stat1': 'Schnellere Förder- & Spenderberichte',
'hero-stat2': 'Doppelt so schnelle Ehrenamtlichen-Onboardings',
'hero-card-title': 'Live-KPI-Überblick',
'hero-card-headline': 'Impact-Dashboard für Programme',
'hero-card-body': 'Budgets in Echtzeit • Ehrenamtsstunden • Donor Health',
'value1-title': 'Transparenz für Spender',
'value1-body': 'Buchhaltungsbereite Ledger verbinden Belege mit Geschichten, damit Spender jeden Euro ohne Zusatz-Excel sofort klar sehen.',
'value2-title': 'Spenderverwaltung & Kommunikation',
'value2-body': 'Automations-Buddys planen Dankesnachrichten, Newsletter und SMS, damit jede Beziehung pünktlich gepflegt und dokumentiert bleibt.',
'value3-title': 'Internationale Fundraising',
'value3-body': 'Mehrsprachige Homepages, Akquise-Kanban und Projekttracker halten Kampagnen weltweit synchron ohne Playbooks ständig umzuschreiben.',
'blog-tagline': 'Insights für NGO-Führungskräfte',
'blog-title': 'Blog & Wissenshub',
'blog-subtitle': 'Hol dir Impulse mit unseren unterhaltsamen Playbooks.',
'blog-link': 'Alle Artikel ansehen →',
'blog-all-open': 'Weniger Artikel anzeigen',
'blog-read-more': 'Mehr lesen',
'blog-show-less': 'Weniger anzeigen',
'blog-error': 'Artikel konnten gerade nicht geladen werden.',
'trial-tagline': 'Kostenlos testen',
'trial-heading': 'Starte dein NGO-ERP-Sandbox in unter 5 Minuten',
'trial-body': 'Teste lokalisierte Templates, Donor-CRM und Automatisierungen. Keine Kreditkarte wähle den Fokus und lade dein Team ein.',
'trial-bullet1': 'Vorkonfigurierter Kontenplan & Fördertracking',
'trial-bullet2': 'Automatische Spendenbelege & Impact-Dashboards',
'trial-bullet3': 'Geführte Checklisten für Go-Live in 30 Tagen',
'trial-label-email': 'Arbeits-E-Mail',
'trial-placeholder-email': 'impact@deinengo.org',
'trial-label-priority': 'Höchste Priorität',
'priority-1': 'Förder-Reporting',
'priority-2': 'Ehrenamt-Management',
'priority-3': 'Spender-CRM & Fundraising',
'priority-4': 'Finanzen & Beschaffung',
'trial-label-region': 'Land / Region',
'trial-placeholder-region': 'z.B. Paraguay, LATAM',
'trial-microcopy': 'Keine Kreditkarte. EU-Hosting & DSGVO-konform.',
'trial-help': 'Brauchen Sie Hilfe? Nutzen Sie den Button „Meeting planen“ im Header für einen geführten Call.',
'meeting-tagline': 'Meeting vereinbaren',
'meeting-heading': 'Erleben Sie, wie Ihre NGO Zeit spart und Fehler reduziert',
'meeting-body': 'Ein 30-minütiger Walkthrough zu Lokalisierung, Integrationen und Governance inklusive Rollout-Fahrplan.',
'meeting-bullet1': 'Automation-Score als Ausgangspunkt',
'meeting-bullet2': 'Technologie- & Migrationsplan',
'meeting-bullet3': 'Budgetvorlagen & Kostenprognose',
'meeting-note-title': 'So buchen Sie',
'meeting-note-body': 'Sie sprechen mit einem NGO-Berater von ODOO4projects.',
'meeting-note-hint': 'Verwenden Sie den Button „Meeting planen“ im Header und nennen Sie bei der Buchung Ihre Frage, damit wir uns vorbereiten können.',
'meeting-note-cta': 'Buchungskalender öffnen',
'footer-note': 'ODOO4projects — Hosting für die KI-Generation',
'footer-support': 'Support',
'footer-legal': 'Rechtliches',
'footer-contact': 'Kontakt'
}
};
const BLOG_LIMIT = 3;
const blogGrid = document.getElementById('blog-grid');
const blogToggle = document.getElementById('blog-toggle');
const blogError = document.getElementById('blog-error');
let blogPosts = [];
let blogExpanded = false;
if (blogGrid) {
fetch('blog.json')
.then(response => response.json())
.then(data => {
blogPosts = Array.isArray(data) ? data : [];
renderBlogCards();
})
.catch(error => {
if (blogError) {
blogError.classList.remove('hidden');
blogError.textContent = getTranslation(document.documentElement.lang, 'blog-error', 'Unable to load articles right now.');
}
console.error('blog.json load failed', error);
});
}
if (blogToggle) {
blogToggle.addEventListener('click', () => {
if (blogPosts.length <= BLOG_LIMIT) return;
blogExpanded = !blogExpanded;
renderBlogCards();
});
}
function getTranslation(locale, key, fallback) {
return (translations[locale] && translations[locale][key]) ?? translations.en[key] ?? fallback;
}
function renderBlogCards() {
if (!blogGrid) {
return;
}
if (!blogPosts.length) {
blogGrid.innerHTML = '';
updateBlogToggleLabel();
return;
}
const limit = blogExpanded ? blogPosts.length : Math.min(BLOG_LIMIT, blogPosts.length);
blogGrid.innerHTML = '';
blogPosts.slice(0, limit).forEach(post => {
blogGrid.appendChild(createBlogCard(post));
});
updateBlogToggleLabel();
}
function createBlogCard(post) {
const card = document.createElement('article');
card.className = 'border border-brand-smoke rounded-3xl p-6 h-full flex flex-col';
const meta = document.createElement('div');
meta.className = 'flex items-center justify-between mb-3';
const area = document.createElement('p');
area.className = 'text-xs uppercase tracking-widest text-brand-primary';
area.textContent = post.area || '';
const dateEl = document.createElement('time');
dateEl.className = 'text-xs text-brand-ink/60';
if (post.date) {
dateEl.dateTime = post.date;
}
dateEl.textContent = formatBlogDate(post.date);
meta.append(area, dateEl);
card.appendChild(meta);
const title = document.createElement('h3');
title.className = 'text-xl font-semibold mb-3';
title.textContent = post.title || '';
card.appendChild(title);
const teaser = document.createElement('div');
teaser.className = 'text-sm text-brand-ink/80 space-y-3 mb-4';
teaser.innerHTML = post.teaser || '';
card.appendChild(teaser);
let contentBlock = null;
const hasMore = post.content && post.content.trim() !== (post.teaser || '').trim();
if (post.content) {
contentBlock = document.createElement('div');
contentBlock.className = 'text-sm text-brand-ink/80 space-y-3 mb-4 hidden';
contentBlock.innerHTML = post.content;
card.appendChild(contentBlock);
}
if (hasMore && contentBlock) {
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'text-sm font-semibold text-brand-accent underline-offset-4 hover:underline self-start';
btn.textContent = getTranslation(document.documentElement.lang, 'blog-read-more', 'Read more');
btn.addEventListener('click', () => {
const isHidden = contentBlock.classList.contains('hidden');
if (isHidden) {
contentBlock.classList.remove('hidden');
btn.textContent = getTranslation(document.documentElement.lang, 'blog-show-less', 'Show less');
} else {
contentBlock.classList.add('hidden');
btn.textContent = getTranslation(document.documentElement.lang, 'blog-read-more', 'Read more');
}
});
card.appendChild(btn);
}
return card;
}
function formatBlogDate(dateString) {
if (!dateString) return '';
try {
const locale = document.documentElement.lang || 'en';
return new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'short', day: 'numeric' }).format(new Date(dateString));
} catch (error) {
return dateString;
}
}
function updateBlogToggleLabel() {
if (!blogToggle) return;
if (blogPosts.length <= BLOG_LIMIT) {
blogToggle.classList.add('hidden');
blogExpanded = false;
return;
}
blogToggle.classList.remove('hidden');
blogToggle.disabled = false;
const locale = document.documentElement.lang || 'en';
blogToggle.textContent = blogExpanded
? getTranslation(locale, 'blog-all-open', 'Show fewer articles')
: getTranslation(locale, 'blog-link', 'Browse all articles →');
}
function setLanguage(lang) {
const locale = translations[lang] ? lang : 'en';
document.documentElement.lang = locale;
document.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.dataset.i18n;
const value = translations[locale][key] ?? translations.en[key] ?? '';
if (value !== undefined) el.innerHTML = value;
});
document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
const key = el.dataset.i18nPlaceholder;
const value = translations[locale][key] ?? translations.en[key] ?? '';
if (value !== undefined) el.setAttribute('placeholder', value);
});
document.querySelectorAll('[data-i18n-option]').forEach(el => {
const key = el.dataset.i18nOption;
const value = translations[locale][key] ?? translations.en[key] ?? '';
if (value !== undefined) el.textContent = value;
});
document.querySelectorAll('[data-i18n-aria]').forEach(el => {
const key = el.dataset.i18nAria;
const value = translations[locale][key] ?? translations.en[key] ?? '';
if (value !== undefined) el.setAttribute('aria-label', value);
});
renderBlogCards();
updateBlogToggleLabel();
}
document.getElementById('lang-selector').addEventListener('change', (event) => {
setLanguage(event.target.value);
});
setLanguage('en');
document.getElementById('year').textContent = new Date().getFullYear();
</script>
</body>
</html>
-550
View File
@@ -1,550 +0,0 @@
<!DOCTYPE html>
<html lang="en" class="scroll-smooth">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>NGO ERP Landingpage | ODOO4projects</title>
<meta name="description" content="Purpose-built ERP platform for NGOs. Centralize programs, automate donor and grant reporting, and launch in weeks with ODOO4projects." />
<meta name="keywords" content="NGO ERP system, nonprofit management software, ERP for NGOs, NGO operations platform, ODOO for nonprofits" />
<link rel="icon" href="https://odoo4projects.com/web/image/website/1/favicon?unique=725c3af" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"></noscript>
<link rel="preload" href="assets/site.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<noscript><link rel="stylesheet" href="assets/site.css"></noscript>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "NGO ERP Landing",
"about": "ERP for NGOs",
"publisher": {
"@type": "Organization",
"name": "ODOO4projects",
"logo": "https://odoo4projects.com/web/image/website/1/logo?unique=1be96c3"
},
"mainEntity": {
"@type": "SoftwareApplication",
"name": "ODOO4projects NGO ERP",
"applicationCategory": "BusinessApplication",
"operatingSystem": "Cloud",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD",
"description": "4-week free trial of NGO ERP workspace"
}
}
}
</script>
<script defer data-domain="ngo.odoo4projects.com" src="https://plausible.odoo4projects.com/js/script.tagged-events.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
</head>
<body class="bg-brand-snow text-brand-ink">
<header class="bg-hero-gradient text-white">
<div class="max-w-6xl mx-auto px-6 py-6 flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center gap-3">
<img src="https://odoo4projects.com/web/image/website/1/logo?unique=1be96c3" alt="ODOO4projects logo" class="h-10 w-auto" />
<span class="uppercase tracking-[0.3em] text-xs text-brand-smoke" data-i18n="hero-badge"></span>
</div>
<nav class="flex flex-wrap items-center gap-6 text-sm">
<a href="#blog" class="hover:text-brand-sunrise transition" data-i18n="nav-resources"></a>
<a href="#trial" class="hover:text-brand-sunrise transition" data-i18n="nav-trial"></a>
</nav>
<div class="flex items-center gap-3">
<label for="lang-selector" class="sr-only">Language</label>
<select id="lang-selector" class="bg-white/10 border border-white/30 text-sm rounded-full px-3 py-1.5 focus:outline-none focus:ring-2 focus:ring-brand-sunrise/70">
<option value="en">English</option>
<option value="es">Español</option>
<option value="de">Deutsch</option>
</select>
<a href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ3DDbaiHFlhNhWySszAQoPXE_H73QLqYT3w7H9IYWC76RA_TgNIhLESjb4N7ep_D2D_OyW9q4-c" target="_blank" rel="noopener" class="px-5 py-2 bg-brand-sunrise text-brand-ink font-semibold rounded-full text-sm shadow-brand hover:translate-y-0.5 transition plausible-event-name=meeting" data-i18n="cta-meeting"></a>
</div>
</div>
<div class="max-w-6xl mx-auto px-6 py-16 grid md:grid-cols-2 gap-12 items-center">
<div>
<p class="text-brand-sunrise font-semibold mb-4" data-i18n="hero-pill"></p>
<h1 class="text-4xl md:text-5xl font-semibold leading-tight mb-6" data-i18n="hero-headline"></h1>
<p class="text-lg text-white/80 mb-8" data-i18n="hero-subheadline"></p>
<div class="flex flex-wrap gap-4">
<a href="#trial" class="px-6 py-3 bg-brand-accent hover:bg-brand-sunrise text-brand-ink font-semibold rounded-full transition" data-i18n="cta-trial" data-event="cta:hero-trial"></a>
</div>
<div class="mt-10 grid grid-cols-2 gap-6 text-sm text-white/80">
<div>
<p class="text-3xl font-semibold text-white">38%</p>
<p data-i18n="hero-stat1"></p>
</div>
<div>
<p class="text-3xl font-semibold text-white">2x</p>
<p data-i18n="hero-stat2"></p>
</div>
</div>
</div>
<div class="bg-white/10 backdrop-blur-lg rounded-3xl p-8 shadow-brand">
<div class="relative">
<img src="https://images.unsplash.com/photo-1521737604893-d14cc237f11d?auto=format&fit=crop&w=900&q=80" alt="NGO team collaborating" class="rounded-2xl" />
<div class="absolute -bottom-8 left-8 bg-white/90 text-brand-ink px-4 py-3 rounded-2xl shadow-lg">
<p class="text-xs uppercase tracking-widest text-brand-primary mb-1" data-i18n="hero-card-title"></p>
<p class="text-lg font-semibold" data-i18n="hero-card-headline"></p>
<p class="text-sm text-brand-primary" data-i18n="hero-card-body"></p>
</div>
</div>
</div>
</div>
</header>
<section class="max-w-6xl mx-auto px-6 py-16 grid md:grid-cols-3 gap-8">
<article class="bg-white rounded-2xl p-6 shadow-brand border border-brand-smoke">
<h2 class="text-xl font-semibold mb-2" data-i18n="value1-title"></h2>
<p class="text-sm text-brand-ink/80" data-i18n="value1-body"></p>
</article>
<article class="bg-white rounded-2xl p-6 shadow-brand border border-brand-smoke">
<h2 class="text-xl font-semibold mb-2" data-i18n="value2-title"></h2>
<p class="text-sm text-brand-ink/80" data-i18n="value2-body"></p>
</article>
<article class="bg-white rounded-2xl p-6 shadow-brand border border-brand-smoke">
<h2 class="text-xl font-semibold mb-2" data-i18n="value3-title"></h2>
<p class="text-sm text-brand-ink/80" data-i18n="value3-body"></p>
</article>
</section>
<section id="blog" class="bg-white py-20">
<div class="max-w-6xl mx-auto px-6">
<div class="flex flex-col md:flex-row md:items-end md:justify-between gap-6 mb-12">
<div>
<p class="text-sm uppercase tracking-[0.3em] text-brand-primary mb-3" data-i18n="blog-tagline"></p>
<h2 class="text-3xl font-semibold" data-i18n="blog-title"></h2>
<p class="text-brand-ink/80" data-i18n="blog-subtitle"></p>
</div>
<button id="blog-toggle" type="button" class="text-brand-accent font-semibold hover:underline underline-offset-4">Browse all articles →</button>
</div>
<div id="blog-grid" class="grid gap-6 md:grid-cols-3"></div>
<p id="blog-error" class="text-sm text-brand-ink/70 mt-6 hidden"></p>
</div>
</section>
<section id="trial" class="bg-brand-ink text-white py-20">
<div class="max-w-5xl mx-auto px-6 grid md:grid-cols-2 gap-12">
<div>
<p class="text-brand-sunrise text-sm uppercase tracking-[0.3em] mb-4" data-i18n="trial-tagline"></p>
<h2 class="text-3xl font-semibold mb-4" data-i18n="trial-heading"></h2>
<p class="text-white/80 mb-6" data-i18n="trial-body"></p>
<ul class="space-y-4 text-sm text-white/80">
<li class="flex gap-3"><span class="text-brand-emerald">✔</span><span data-i18n="trial-bullet1"></span></li>
<li class="flex gap-3"><span class="text-brand-emerald">✔</span><span data-i18n="trial-bullet2"></span></li>
<li class="flex gap-3"><span class="text-brand-emerald">✔</span><span data-i18n="trial-bullet3"></span></li>
</ul>
</div>
<form class="bg-white text-brand-ink rounded-3xl p-8 shadow-brand space-y-5" data-event="form:trial">
<label class="block text-sm font-medium">
<span data-i18n="trial-label-email"></span>
<input type="email" required class="mt-2 w-full rounded-2xl border border-brand-smoke px-4 py-3 focus:outline-none focus:ring-2 focus:ring-brand-accent" data-i18n-placeholder="trial-placeholder-email" />
</label>
<label class="block text-sm font-medium">
<span data-i18n="trial-label-priority"></span>
<select class="mt-2 w-full rounded-2xl border border-brand-smoke px-4 py-3 focus:outline-none focus:ring-2 focus:ring-brand-accent">
<option data-i18n-option="priority-1"></option>
<option data-i18n-option="priority-2"></option>
<option data-i18n-option="priority-3"></option>
<option data-i18n-option="priority-4"></option>
</select>
</label>
<label class="block text-sm font-medium">
<span data-i18n="trial-label-region"></span>
<input type="text" class="mt-2 w-full rounded-2xl border border-brand-smoke px-4 py-3 focus:outline-none focus:ring-2 focus:ring-brand-accent" data-i18n-placeholder="trial-placeholder-region" />
</label>
<p class="text-xs text-brand-ink/70" data-i18n="trial-microcopy"></p>
<button type="submit" class="w-full py-3 rounded-2xl bg-brand-accent text-brand-ink font-semibold" data-i18n="cta-trial"></button>
<p class="text-xs text-brand-ink/60 text-center" data-i18n="trial-help"></p>
</form>
</div>
</section>
<section id="meeting" class="py-20 bg-white">
<div class="max-w-5xl mx-auto px-6 grid md:grid-cols-2 gap-12 items-center">
<div>
<p class="uppercase text-xs tracking-[0.3em] text-brand-primary mb-3" data-i18n="meeting-tagline"></p>
<h2 class="text-3xl font-semibold mb-4" data-i18n="meeting-heading"></h2>
<p class="text-brand-ink/80 mb-6" data-i18n="meeting-body"></p>
<ul class="space-y-4 text-sm text-brand-ink/80">
<li class="flex gap-3"><span class="text-brand-primary">◎</span><span data-i18n="meeting-bullet1"></span></li>
<li class="flex gap-3"><span class="text-brand-primary">◎</span><span data-i18n="meeting-bullet2"></span></li>
<li class="flex gap-3"><span class="text-brand-primary">◎</span><span data-i18n="meeting-bullet3"></span></li>
</ul>
</div>
<div class="bg-brand-snow border border-brand-smoke rounded-3xl p-8 shadow-brand">
<p class="text-sm text-brand-primary font-semibold mb-2" data-i18n="meeting-note-title"></p>
<p class="text-brand-ink font-semibold text-xl mb-4" data-i18n="meeting-note-body"></p>
<p class="text-sm text-brand-ink/70" data-i18n="meeting-note-hint"></p>
<a href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ3DDbaiHFlhNhWySszAQoPXE_H73QLqYT3w7H9IYWC76RA_TgNIhLESjb4N7ep_D2D_OyW9q4-c" target="_blank" rel="noopener" class="inline-flex items-center gap-2 mt-4 text-sm font-semibold text-brand-primary hover:text-brand-accent plausible-event-name=meeting" data-i18n="meeting-note-cta"></a>
</div>
</div>
</section>
<footer class="bg-brand-ink text-white py-10">
<div class="max-w-6xl mx-auto px-6 flex flex-col md:flex-row gap-6 items-center justify-between text-sm">
<p>© <span id="year"></span> <span data-i18n="footer-note"></span></p>
<div class="flex gap-4">
<a href="https://odoo4projects.com/support" class="hover:text-brand-sunrise" data-i18n="footer-support"></a>
<a href="https://odoo4projects.com/legal" class="hover:text-brand-sunrise" data-i18n="footer-legal"></a>
<a href="https://odoo4projects.com/contactus" class="hover:text-brand-sunrise" data-i18n="footer-contact"></a>
</div>
</div>
</footer>
<script>
const translations = {
en: {
'nav-resources': 'Resources',
'nav-trial': 'Free Trial',
'hero-badge': 'ERP FOR NGOs',
'hero-pill': 'Unified NGO ERP Platform',
'hero-headline': 'Simplify every mission workflow with an ERP built for NGOs',
'hero-subheadline': 'Consolidate programs, automate donor and grant reporting, and give every field office the same source of truth. Launch in weeks with templates tailored to humanitarian and community-impact teams.',
'cta-trial': 'Sign Up for Free Trial',
'cta-meeting': 'Schedule a Meeting',
'hero-stat1': 'Faster donor & grant reporting cycles',
'hero-stat2': 'Increase in volunteer onboarding speed',
'hero-card-title': 'Live KPI snapshot',
'hero-card-headline': 'Program Impact Dashboard',
'hero-card-body': 'Realtime budgets • Volunteer hours • Donor health',
'value1-title': 'Transparency for Donors',
'value1-body': 'Accounting-ready ledgers pair receipts with stories so donors see every peso without extra spreadsheets or calls.',
'value2-title': 'Donor Management & Communications',
'value2-body': 'Automation buddies queue thank-yous, newsletters, and SMS nudges so every supporter hears from you right on time.',
'value3-title': 'International Fund Raising',
'value3-body': 'Multilingual homepages, acquisition kanbans, and project trackers keep campaigns aligned across countries without rebuilding playbooks.',
'blog-tagline': 'Insights for NGO leaders',
'blog-title': 'Blog & resource hub',
'blog-subtitle': 'Get your impulses with our entertaining playbooks.',
'blog-link': 'Browse all articles →',
'blog-all-open': 'Show fewer articles',
'blog-read-more': 'Read more',
'blog-show-less': 'Show less',
'blog-error': 'Unable to load articles right now.',
'trial-tagline': 'Sign up free trial',
'trial-heading': 'Launch your NGO ERP sandbox in under 5 minutes',
'trial-body': 'Experience localized NGO templates, donor CRM, and automation recipes. No credit card required—just choose your focus area and invite teammates.',
'trial-bullet1': 'Pre-loaded NGO chart of accounts & grant tracking',
'trial-bullet2': 'Automated donor receipts + impact dashboards',
'trial-bullet3': 'Guided checklists for go-live within 30 days',
'trial-label-email': 'Work email',
'trial-placeholder-email': 'impact@yourngo.org',
'trial-label-priority': 'Primary priority',
'priority-1': 'Grant compliance reporting',
'priority-2': 'Volunteer management',
'priority-3': 'Donor CRM & fundraising',
'priority-4': 'Finance & procurement',
'trial-label-region': 'Country / region',
'trial-placeholder-region': 'e.g., Paraguay, LATAM',
'trial-microcopy': 'No credit card required. EU hosting & GDPR-ready.',
'trial-help': 'Need help? Use the Schedule a Meeting button in the header to book a guided call.',
'meeting-tagline': 'Have a meeting',
'meeting-heading': 'See how your NGO can streamline operations, save time, and reduce errors',
'meeting-body': 'A 30-minute live walkthrough tailored to your mission, covering localization, integrations, and governance. Walk away with a rollout roadmap.',
'meeting-bullet1': 'Baseline automation scoring',
'meeting-bullet2': 'Tech stack alignment & data migration plan',
'meeting-bullet3': 'Budget templates & total cost forecast',
'meeting-note-title': 'How scheduling works',
'meeting-note-body': 'You will meet with an NGO consultant from ODOO4projects.',
'meeting-note-hint': 'Use the Schedule a Meeting button in the header and tell us during booking which question we should prepare for.',
'meeting-note-cta': 'Open booking calendar',
'footer-note': 'ODOO4projects — Hosting for the AI generation',
'footer-support': 'Support',
'footer-legal': 'Legal',
'footer-contact': 'Contact'
},
es: {
'nav-resources': 'Recursos',
'nav-trial': 'Prueba gratuita',
'hero-badge': 'ERP PARA ONGs',
'hero-pill': 'Plataforma ERP unificada para ONGs',
'hero-headline': 'Simplifica cada misión con un ERP diseñado para ONGs',
'hero-subheadline': 'Centraliza programas, automatiza reportes de donantes y subvenciones y ofrece a cada sede la misma fuente de verdad. Implementa en semanas con plantillas creadas para equipos humanitarios.',
'cta-trial': 'Crear prueba gratuita',
'cta-meeting': 'Agendar una reunión',
'hero-stat1': 'Ciclos más rápidos de reportes a donantes y subvenciones',
'hero-stat2': 'Mayor velocidad en la incorporación de voluntarios',
'hero-card-title': 'Panel de KPIs en vivo',
'hero-card-headline': 'Tablero de impacto programático',
'hero-card-body': 'Presupuestos en tiempo real • Horas voluntarias • Salud de donantes',
'value1-title': 'Transparencia para donantes',
'value1-body': 'Libros contables listos unen recibos y relatos para que cada donante vea su aporte sin hojas extra.',
'value2-title': 'Gestión y comunicación con donantes',
'value2-body': 'Bots de automatización programan agradecimientos, boletines y SMS para que cada aliado reciba noticias a tiempo.',
'value3-title': 'Recaudación internacional',
'value3-body': 'Sitios multilingües, tableros de adquisición y proyectos coordinan campañas globales sin rehacer playbooks ni procesos.',
'blog-tagline': 'Ideas para líderes de ONG',
'blog-title': 'Blog y centro de recursos',
'blog-subtitle': 'Recibe impulsos con nuestros playbooks entretenidos.',
'blog-link': 'Ver todos los artículos →',
'blog-all-open': 'Mostrar menos artículos',
'blog-read-more': 'Leer más',
'blog-show-less': 'Mostrar menos',
'blog-error': 'No pudimos cargar los artículos en este momento.',
'trial-tagline': 'Activa tu prueba',
'trial-heading': 'Lanza tu sandbox ERP para ONG en menos de 5 minutos',
'trial-body': 'Explora plantillas localizadas, CRM de donantes y recetas de automatización. Sin tarjeta; solo elige tu prioridad e invita al equipo.',
'trial-bullet1': 'Plan contable para ONG y seguimiento de subvenciones precargado',
'trial-bullet2': 'Recibos automáticos más tableros de impacto',
'trial-bullet3': 'Checklists guiados para salir a producción en 30 días',
'trial-label-email': 'Correo laboral',
'trial-placeholder-email': 'impacto@tuong.org',
'trial-label-priority': 'Prioridad principal',
'priority-1': 'Reportes de subvenciones',
'priority-2': 'Gestión de voluntarios',
'priority-3': 'CRM y recaudación',
'priority-4': 'Finanzas y compras',
'trial-label-region': 'País / región',
'trial-placeholder-region': 'ej. Paraguay, LATAM',
'trial-microcopy': 'Sin tarjeta. Hosting en la UE y cumplimiento GDPR.',
'trial-help': '¿Dudas? Usa el botón “Agendar una reunión” en el encabezado para reservar una llamada guiada.',
'meeting-tagline': 'Agenda una reunión',
'meeting-heading': 'Descubre cómo optimizar operaciones, ahorrar tiempo y reducir errores',
'meeting-body': 'Sesión de 30 minutos adaptada a tu misión, con localización, integraciones y gobernanza. Sal con un plan de implementación.',
'meeting-bullet1': 'Diagnóstico de automatización',
'meeting-bullet2': 'Plan de migración y alineación tecnológica',
'meeting-bullet3': 'Plantillas presupuestarias y previsión de costes',
'meeting-note-title': 'Cómo reservar',
'meeting-note-body': 'Te reunirás con un consultor ONG de ODOO4projects.',
'meeting-note-hint': 'Usa el botón “Agendar una reunión” del encabezado y cuéntanos durante la reserva qué pregunta debemos preparar.',
'meeting-note-cta': 'Abrir calendario de reservas',
'footer-note': 'ODOO4projects — Hosting para la generación IA',
'footer-support': 'Soporte',
'footer-legal': 'Legal',
'footer-contact': 'Contacto'
},
de: {
'nav-resources': 'Ressourcen',
'nav-trial': 'Kostenlose Testphase',
'hero-badge': 'ERP FÜR NGOs',
'hero-pill': 'Vereintes NGO-ERP',
'hero-headline': 'Vereinfache jeden Einsatz mit einem ERP für NGOs',
'hero-subheadline': 'Bündele Programme, automatisiere Spender- und Förderberichte und gib allen Standorten dieselbe Datenbasis. Starte in wenigen Wochen mit maßgeschneiderten Templates.',
'cta-trial': 'Kostenlose Testphase starten',
'cta-meeting': 'Meeting planen',
'hero-stat1': 'Schnellere Förder- & Spenderberichte',
'hero-stat2': 'Doppelt so schnelle Ehrenamtlichen-Onboardings',
'hero-card-title': 'Live-KPI-Überblick',
'hero-card-headline': 'Impact-Dashboard für Programme',
'hero-card-body': 'Budgets in Echtzeit • Ehrenamtsstunden • Donor Health',
'value1-title': 'Transparenz für Spender',
'value1-body': 'Buchhaltungsbereite Ledger verbinden Belege mit Geschichten, damit Spender jeden Euro ohne Zusatz-Excel sofort klar sehen.',
'value2-title': 'Spenderverwaltung & Kommunikation',
'value2-body': 'Automations-Buddys planen Dankesnachrichten, Newsletter und SMS, damit jede Beziehung pünktlich gepflegt und dokumentiert bleibt.',
'value3-title': 'Internationale Fundraising',
'value3-body': 'Mehrsprachige Homepages, Akquise-Kanban und Projekttracker halten Kampagnen weltweit synchron ohne Playbooks ständig umzuschreiben.',
'blog-tagline': 'Insights für NGO-Führungskräfte',
'blog-title': 'Blog & Wissenshub',
'blog-subtitle': 'Hol dir Impulse mit unseren unterhaltsamen Playbooks.',
'blog-link': 'Alle Artikel ansehen →',
'blog-all-open': 'Weniger Artikel anzeigen',
'blog-read-more': 'Mehr lesen',
'blog-show-less': 'Weniger anzeigen',
'blog-error': 'Artikel konnten gerade nicht geladen werden.',
'trial-tagline': 'Kostenlos testen',
'trial-heading': 'Starte dein NGO-ERP-Sandbox in unter 5 Minuten',
'trial-body': 'Teste lokalisierte Templates, Donor-CRM und Automatisierungen. Keine Kreditkarte wähle den Fokus und lade dein Team ein.',
'trial-bullet1': 'Vorkonfigurierter Kontenplan & Fördertracking',
'trial-bullet2': 'Automatische Spendenbelege & Impact-Dashboards',
'trial-bullet3': 'Geführte Checklisten für Go-Live in 30 Tagen',
'trial-label-email': 'Arbeits-E-Mail',
'trial-placeholder-email': 'impact@deinengo.org',
'trial-label-priority': 'Höchste Priorität',
'priority-1': 'Förder-Reporting',
'priority-2': 'Ehrenamt-Management',
'priority-3': 'Spender-CRM & Fundraising',
'priority-4': 'Finanzen & Beschaffung',
'trial-label-region': 'Land / Region',
'trial-placeholder-region': 'z.B. Paraguay, LATAM',
'trial-microcopy': 'Keine Kreditkarte. EU-Hosting & DSGVO-konform.',
'trial-help': 'Brauchen Sie Hilfe? Nutzen Sie den Button „Meeting planen“ im Header für einen geführten Call.',
'meeting-tagline': 'Meeting vereinbaren',
'meeting-heading': 'Erleben Sie, wie Ihre NGO Zeit spart und Fehler reduziert',
'meeting-body': 'Ein 30-minütiger Walkthrough zu Lokalisierung, Integrationen und Governance inklusive Rollout-Fahrplan.',
'meeting-bullet1': 'Automation-Score als Ausgangspunkt',
'meeting-bullet2': 'Technologie- & Migrationsplan',
'meeting-bullet3': 'Budgetvorlagen & Kostenprognose',
'meeting-note-title': 'So buchen Sie',
'meeting-note-body': 'Sie sprechen mit einem NGO-Berater von ODOO4projects.',
'meeting-note-hint': 'Verwenden Sie den Button „Meeting planen“ im Header und nennen Sie bei der Buchung Ihre Frage, damit wir uns vorbereiten können.',
'meeting-note-cta': 'Buchungskalender öffnen',
'footer-note': 'ODOO4projects — Hosting für die KI-Generation',
'footer-support': 'Support',
'footer-legal': 'Rechtliches',
'footer-contact': 'Kontakt'
}
};
const BLOG_LIMIT = 3;
const blogGrid = document.getElementById('blog-grid');
const blogToggle = document.getElementById('blog-toggle');
const blogError = document.getElementById('blog-error');
let blogPosts = [];
let blogExpanded = false;
if (blogGrid) {
fetch('blog.json')
.then(response => response.json())
.then(data => {
blogPosts = Array.isArray(data) ? data : [];
renderBlogCards();
})
.catch(error => {
if (blogError) {
blogError.classList.remove('hidden');
blogError.textContent = getTranslation(document.documentElement.lang, 'blog-error', 'Unable to load articles right now.');
}
console.error('blog.json load failed', error);
});
}
if (blogToggle) {
blogToggle.addEventListener('click', () => {
if (blogPosts.length <= BLOG_LIMIT) return;
blogExpanded = !blogExpanded;
renderBlogCards();
});
}
function getTranslation(locale, key, fallback) {
return (translations[locale] && translations[locale][key]) ?? translations.en[key] ?? fallback;
}
function renderBlogCards() {
if (!blogGrid) {
return;
}
if (!blogPosts.length) {
blogGrid.innerHTML = '';
updateBlogToggleLabel();
return;
}
const limit = blogExpanded ? blogPosts.length : Math.min(BLOG_LIMIT, blogPosts.length);
blogGrid.innerHTML = '';
blogPosts.slice(0, limit).forEach(post => {
blogGrid.appendChild(createBlogCard(post));
});
updateBlogToggleLabel();
}
function createBlogCard(post) {
const card = document.createElement('article');
card.className = 'border border-brand-smoke rounded-3xl p-6 h-full flex flex-col';
const meta = document.createElement('div');
meta.className = 'flex items-center justify-between mb-3';
const area = document.createElement('p');
area.className = 'text-xs uppercase tracking-widest text-brand-primary';
area.textContent = post.area || '';
const dateEl = document.createElement('time');
dateEl.className = 'text-xs text-brand-ink/60';
if (post.date) {
dateEl.dateTime = post.date;
}
dateEl.textContent = formatBlogDate(post.date);
meta.append(area, dateEl);
card.appendChild(meta);
const title = document.createElement('h3');
title.className = 'text-xl font-semibold mb-3';
title.textContent = post.title || '';
card.appendChild(title);
const teaser = document.createElement('div');
teaser.className = 'text-sm text-brand-ink/80 space-y-3 mb-4';
teaser.innerHTML = post.teaser || '';
card.appendChild(teaser);
let contentBlock = null;
const hasMore = post.content && post.content.trim() !== (post.teaser || '').trim();
if (post.content) {
contentBlock = document.createElement('div');
contentBlock.className = 'text-sm text-brand-ink/80 space-y-3 mb-4 hidden';
contentBlock.innerHTML = post.content;
card.appendChild(contentBlock);
}
if (hasMore && contentBlock) {
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'text-sm font-semibold text-brand-accent underline-offset-4 hover:underline self-start';
btn.textContent = getTranslation(document.documentElement.lang, 'blog-read-more', 'Read more');
btn.addEventListener('click', () => {
const isHidden = contentBlock.classList.contains('hidden');
if (isHidden) {
contentBlock.classList.remove('hidden');
btn.textContent = getTranslation(document.documentElement.lang, 'blog-show-less', 'Show less');
} else {
contentBlock.classList.add('hidden');
btn.textContent = getTranslation(document.documentElement.lang, 'blog-read-more', 'Read more');
}
});
card.appendChild(btn);
}
return card;
}
function formatBlogDate(dateString) {
if (!dateString) return '';
try {
const locale = document.documentElement.lang || 'en';
return new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'short', day: 'numeric' }).format(new Date(dateString));
} catch (error) {
return dateString;
}
}
function updateBlogToggleLabel() {
if (!blogToggle) return;
if (blogPosts.length <= BLOG_LIMIT) {
blogToggle.classList.add('hidden');
blogExpanded = false;
return;
}
blogToggle.classList.remove('hidden');
blogToggle.disabled = false;
const locale = document.documentElement.lang || 'en';
blogToggle.textContent = blogExpanded
? getTranslation(locale, 'blog-all-open', 'Show fewer articles')
: getTranslation(locale, 'blog-link', 'Browse all articles →');
}
function setLanguage(lang) {
const locale = translations[lang] ? lang : 'en';
document.documentElement.lang = locale;
document.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.dataset.i18n;
const value = translations[locale][key] ?? translations.en[key] ?? '';
if (value !== undefined) el.innerHTML = value;
});
document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
const key = el.dataset.i18nPlaceholder;
const value = translations[locale][key] ?? translations.en[key] ?? '';
if (value !== undefined) el.setAttribute('placeholder', value);
});
document.querySelectorAll('[data-i18n-option]').forEach(el => {
const key = el.dataset.i18nOption;
const value = translations[locale][key] ?? translations.en[key] ?? '';
if (value !== undefined) el.textContent = value;
});
document.querySelectorAll('[data-i18n-aria]').forEach(el => {
const key = el.dataset.i18nAria;
const value = translations[locale][key] ?? translations.en[key] ?? '';
if (value !== undefined) el.setAttribute('aria-label', value);
});
renderBlogCards();
updateBlogToggleLabel();
}
document.getElementById('lang-selector').addEventListener('change', (event) => {
setLanguage(event.target.value);
});
setLanguage('en');
document.getElementById('year').textContent = new Date().getFullYear();
</script>
</body>
</html>
-15
View File
@@ -1,15 +0,0 @@
{
"posts": [
{
"id": "how-odoo-makes-donor-management-easy",
"title": "How Odoo makes donor management easy",
"date": "2026-03-24",
"author": "Odoo4Projects - NGO team",
"categories": ["donor-management", "transparency", "productivity"],
"tags": ["Odoo", "donor communication", "automation", "minimal admin"],
"excerpt": "Learn how Odoo reduces administrative effort, improves donor communication, and increases transparency for NGOs.",
"content": "Odoo makes donor management easy by centralizing donor data, automating receipts and updates, and generating transparent reports donors trust. With minimal admin required, NGOs can set up templates, schedule automated communications, and track gifts and commitments in one place. Donors receive timely receipts and impact updates that strengthen trust and retention. Odoos dashboards provide simple, exportable reports for accountability. The result: less time on admin, more time on mission.",
"featured": true
}
]
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

+1
View File
@@ -0,0 +1 @@
google-site-verification: google261cafffa78d8c3d.html
+114
View File
@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-1152,-256)">
<rect id="Icons" x="0" y="0" width="1280" height="800" style="fill:none;"/>
<g id="Icons1" serif:id="Icons">
<g id="Strike">
</g>
<g id="H1">
</g>
<g id="H2">
</g>
<g id="H3">
</g>
<g id="list-ul">
</g>
<g id="hamburger-1">
</g>
<g id="hamburger-2">
</g>
<g id="list-ol">
</g>
<g id="list-task">
</g>
<g id="trash">
</g>
<g id="vertical-menu">
</g>
<g id="horizontal-menu">
</g>
<g id="sidebar-2">
</g>
<g id="Pen">
</g>
<g id="Pen1" serif:id="Pen">
</g>
<g id="clock">
</g>
<g id="external-link">
</g>
<g id="hr">
</g>
<g id="info">
</g>
<g id="warning">
</g>
<g id="plus-circle">
</g>
<g id="minus-circle">
</g>
<g id="vue">
</g>
<g id="cog">
</g>
<g id="logo">
</g>
<g id="radio-check">
</g>
<g id="eye-slash">
</g>
<g id="eye">
</g>
<g id="toggle-off">
</g>
<g id="shredder">
</g>
<g id="spinner--loading--dots-" serif:id="spinner [loading, dots]">
</g>
<g id="react">
</g>
<g id="check-selected">
</g>
<g id="turn-off">
</g>
<g id="code-block">
</g>
<g id="user">
</g>
<g id="coffee-bean">
</g>
<g transform="matrix(0.638317,0.368532,-0.368532,0.638317,785.021,-208.975)">
<g id="coffee-beans">
<g id="coffee-bean1" serif:id="coffee-bean">
</g>
</g>
</g>
<g id="coffee-bean-filled" transform="matrix(0.866025,0.5,-0.5,0.866025,717.879,-387.292)">
<g transform="matrix(1,0,0,1,0,-0.699553)">
<path d="M737.673,328.231C738.494,328.056 739.334,328.427 739.757,329.152C739.955,329.463 740.106,329.722 740.106,329.722C740.106,329.722 745.206,338.581 739.429,352.782C737.079,358.559 736.492,366.083 738.435,371.679C738.697,372.426 738.482,373.258 737.89,373.784C737.298,374.31 736.447,374.426 735.735,374.077C730.192,371.375 722.028,365.058 722.021,352C722.015,340.226 728.812,330.279 737.673,328.231Z"/>
</g>
<g transform="matrix(-1,0,0,-1,1483.03,703.293)">
<path d="M737.609,328.246C738.465,328.06 739.344,328.446 739.785,329.203C739.97,329.49 740.106,329.722 740.106,329.722C740.106,329.722 745.206,338.581 739.429,352.782C737.1,358.507 736.503,365.948 738.383,371.527C738.646,372.304 738.415,373.164 737.796,373.703C737.177,374.243 736.294,374.356 735.56,373.989C730.02,371.241 722.028,364.92 722.021,352C722.016,340.255 728.779,330.328 737.609,328.246Z"/>
</g>
</g>
<g transform="matrix(0.638317,0.368532,-0.368532,0.638317,913.062,-208.975)">
<g id="coffee-beans-filled">
<g id="coffee-bean2" serif:id="coffee-bean">
</g>
</g>
</g>
<g id="clipboard">
</g>
<g transform="matrix(1,0,0,1,128.011,1.35415)">
<g id="clipboard-paste">
</g>
</g>
<g id="clipboard-copy">
</g>
<g id="Layer1">
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

+224
View File
@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#000000"
width="800px"
height="800px"
viewBox="0 0 64 64"
version="1.1"
xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
id="svg6"
sodipodi:docname="bean_dark_Roast.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:serif="http://www.serif.com/"><defs
id="defs6" /><sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="1.075"
inkscape:cx="400"
inkscape:cy="400"
inkscape:window-width="1920"
inkscape:window-height="1129"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<g
transform="matrix(1,0,0,1,-1152,-256)"
id="g6">
<rect
id="Icons"
x="0"
y="0"
width="1280"
height="800"
style="fill:none;" />
<g
id="Icons1"
serif:id="Icons">
<g
id="Strike">
</g>
<g
id="H1">
</g>
<g
id="H2">
</g>
<g
id="H3">
</g>
<g
id="list-ul">
</g>
<g
id="hamburger-1">
</g>
<g
id="hamburger-2">
</g>
<g
id="list-ol">
</g>
<g
id="list-task">
</g>
<g
id="trash">
</g>
<g
id="vertical-menu">
</g>
<g
id="horizontal-menu">
</g>
<g
id="sidebar-2">
</g>
<g
id="Pen">
</g>
<g
id="Pen1"
serif:id="Pen">
</g>
<g
id="clock">
</g>
<g
id="external-link">
</g>
<g
id="hr">
</g>
<g
id="info">
</g>
<g
id="warning">
</g>
<g
id="plus-circle">
</g>
<g
id="minus-circle">
</g>
<g
id="vue">
</g>
<g
id="cog">
</g>
<g
id="logo">
</g>
<g
id="radio-check">
</g>
<g
id="eye-slash">
</g>
<g
id="eye">
</g>
<g
id="toggle-off">
</g>
<g
id="shredder">
</g>
<g
id="spinner--loading--dots-"
serif:id="spinner [loading, dots]">
</g>
<g
id="react">
</g>
<g
id="check-selected">
</g>
<g
id="turn-off">
</g>
<g
id="code-block">
</g>
<g
id="user">
</g>
<g
id="coffee-bean">
</g>
<g
transform="matrix(0.638317,0.368532,-0.368532,0.638317,785.021,-208.975)"
id="g1">
<g
id="coffee-beans">
<g
id="coffee-bean1"
serif:id="coffee-bean">
</g>
</g>
</g>
<g
id="coffee-bean-filled"
transform="matrix(0.866025,0.5,-0.5,0.866025,717.879,-387.292)">
<g
transform="matrix(1,0,0,1,0,-0.699553)"
id="g2">
<path
d="M737.673,328.231C738.494,328.056 739.334,328.427 739.757,329.152C739.955,329.463 740.106,329.722 740.106,329.722C740.106,329.722 745.206,338.581 739.429,352.782C737.079,358.559 736.492,366.083 738.435,371.679C738.697,372.426 738.482,373.258 737.89,373.784C737.298,374.31 736.447,374.426 735.735,374.077C730.192,371.375 722.028,365.058 722.021,352C722.015,340.226 728.812,330.279 737.673,328.231Z"
id="path1"
style="fill:#3e2723;fill-opacity:1" />
</g>
<g
transform="matrix(-1,0,0,-1,1483.03,703.293)"
id="g3">
<path
d="M737.609,328.246C738.465,328.06 739.344,328.446 739.785,329.203C739.97,329.49 740.106,329.722 740.106,329.722C740.106,329.722 745.206,338.581 739.429,352.782C737.1,358.507 736.503,365.948 738.383,371.527C738.646,372.304 738.415,373.164 737.796,373.703C737.177,374.243 736.294,374.356 735.56,373.989C730.02,371.241 722.028,364.92 722.021,352C722.016,340.255 728.779,330.328 737.609,328.246Z"
id="path2"
style="stroke:#3e2723;stroke-opacity:1;fill:#3e2723;fill-opacity:1" />
</g>
</g>
<g
transform="matrix(0.638317,0.368532,-0.368532,0.638317,913.062,-208.975)"
id="g4">
<g
id="coffee-beans-filled">
<g
id="coffee-bean2"
serif:id="coffee-bean">
</g>
</g>
</g>
<g
id="clipboard">
</g>
<g
transform="matrix(1,0,0,1,128.011,1.35415)"
id="g5">
<g
id="clipboard-paste">
</g>
</g>
<g
id="clipboard-copy">
</g>
<g
id="Layer1">
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

+224
View File
@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#000000"
width="800px"
height="800px"
viewBox="0 0 64 64"
version="1.1"
xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
id="svg6"
sodipodi:docname="bean_light_brown.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:serif="http://www.serif.com/"><defs
id="defs6" /><sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="1.075"
inkscape:cx="400"
inkscape:cy="400"
inkscape:window-width="1920"
inkscape:window-height="1129"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<g
transform="matrix(1,0,0,1,-1152,-256)"
id="g6">
<rect
id="Icons"
x="0"
y="0"
width="1280"
height="800"
style="fill:none;" />
<g
id="Icons1"
serif:id="Icons">
<g
id="Strike">
</g>
<g
id="H1">
</g>
<g
id="H2">
</g>
<g
id="H3">
</g>
<g
id="list-ul">
</g>
<g
id="hamburger-1">
</g>
<g
id="hamburger-2">
</g>
<g
id="list-ol">
</g>
<g
id="list-task">
</g>
<g
id="trash">
</g>
<g
id="vertical-menu">
</g>
<g
id="horizontal-menu">
</g>
<g
id="sidebar-2">
</g>
<g
id="Pen">
</g>
<g
id="Pen1"
serif:id="Pen">
</g>
<g
id="clock">
</g>
<g
id="external-link">
</g>
<g
id="hr">
</g>
<g
id="info">
</g>
<g
id="warning">
</g>
<g
id="plus-circle">
</g>
<g
id="minus-circle">
</g>
<g
id="vue">
</g>
<g
id="cog">
</g>
<g
id="logo">
</g>
<g
id="radio-check">
</g>
<g
id="eye-slash">
</g>
<g
id="eye">
</g>
<g
id="toggle-off">
</g>
<g
id="shredder">
</g>
<g
id="spinner--loading--dots-"
serif:id="spinner [loading, dots]">
</g>
<g
id="react">
</g>
<g
id="check-selected">
</g>
<g
id="turn-off">
</g>
<g
id="code-block">
</g>
<g
id="user">
</g>
<g
id="coffee-bean">
</g>
<g
transform="matrix(0.638317,0.368532,-0.368532,0.638317,785.021,-208.975)"
id="g1">
<g
id="coffee-beans">
<g
id="coffee-bean1"
serif:id="coffee-bean">
</g>
</g>
</g>
<g
id="coffee-bean-filled"
transform="matrix(0.866025,0.5,-0.5,0.866025,717.879,-387.292)">
<g
transform="matrix(1,0,0,1,0,-0.699553)"
id="g2">
<path
d="M737.673,328.231C738.494,328.056 739.334,328.427 739.757,329.152C739.955,329.463 740.106,329.722 740.106,329.722C740.106,329.722 745.206,338.581 739.429,352.782C737.079,358.559 736.492,366.083 738.435,371.679C738.697,372.426 738.482,373.258 737.89,373.784C737.298,374.31 736.447,374.426 735.735,374.077C730.192,371.375 722.028,365.058 722.021,352C722.015,340.226 728.812,330.279 737.673,328.231Z"
id="path1"
style="fill:#5d4037;fill-opacity:1" />
</g>
<g
transform="matrix(-1,0,0,-1,1483.03,703.293)"
id="g3">
<path
d="M737.609,328.246C738.465,328.06 739.344,328.446 739.785,329.203C739.97,329.49 740.106,329.722 740.106,329.722C740.106,329.722 745.206,338.581 739.429,352.782C737.1,358.507 736.503,365.948 738.383,371.527C738.646,372.304 738.415,373.164 737.796,373.703C737.177,374.243 736.294,374.356 735.56,373.989C730.02,371.241 722.028,364.92 722.021,352C722.016,340.255 728.779,330.328 737.609,328.246Z"
id="path2"
style="stroke:#5d4037;stroke-opacity:1;fill:#5d4037;fill-opacity:1" />
</g>
</g>
<g
transform="matrix(0.638317,0.368532,-0.368532,0.638317,913.062,-208.975)"
id="g4">
<g
id="coffee-beans-filled">
<g
id="coffee-bean2"
serif:id="coffee-bean">
</g>
</g>
</g>
<g
id="clipboard">
</g>
<g
transform="matrix(1,0,0,1,128.011,1.35415)"
id="g5">
<g
id="clipboard-paste">
</g>
</g>
<g
id="clipboard-copy">
</g>
<g
id="Layer1">
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

+116
View File
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="124.8711mm"
height="31.440542mm"
viewBox="0 0 124.8711 31.440542"
version="1.1"
id="svg1"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
sodipodi:docname="logo.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.70021044"
inkscape:cx="329.90082"
inkscape:cy="345.61039"
inkscape:window-width="1920"
inkscape:window-height="1046"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-17.727083,-56.885417)">
<g
id="g5"
transform="matrix(0.26458333,0,0,0.26458333,-67.310852,25.675979)">
<text
id="text5"
xml:space="preserve"
transform="matrix(1.3333333,0,0,1.3333333,316.00667,186.29426)"><tspan
id="tspan5"
style="font-variant:normal;font-weight:700;font-size:65.991px;font-family:'Noto Sans';writing-mode:lr-tb;fill:#3e2723;fill-opacity:1;fill-rule:nonzero;stroke:#3e2723;stroke-width:2.19965;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
x="0"
y="0">my</tspan></text>
<text
id="text6"
xml:space="preserve"
transform="matrix(1.3333333,0,0,1.3333333,452.48533,186.29426)"><tspan
id="tspan6"
style="font-variant:normal;font-weight:700;font-size:65.991px;font-family:'Noto Sans';writing-mode:lr-tb;fill:#e65100;fill-opacity:1;fill-rule:nonzero;stroke:#e65100;stroke-width:2.19965;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
x="0"
y="0">-</tspan></text>
<text
id="text7"
xml:space="preserve"
transform="matrix(1.3333333,0,0,1.3333333,480.79333,186.29426)"><tspan
id="tspan7"
style="font-variant:normal;font-weight:700;font-size:65.991px;font-family:'Noto Sans';writing-mode:lr-tb;fill:#3e2723;fill-opacity:1;fill-rule:nonzero;stroke:#3e2723;stroke-width:2.19965;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
x="0"
y="0">biz</tspan></text>
<text
id="text8"
xml:space="preserve"
transform="matrix(1.3333333,0,0,1.3333333,606.236,186.29426)"><tspan
id="tspan8"
style="font-variant:normal;font-weight:700;font-size:65.991px;font-family:'Noto Sans';writing-mode:lr-tb;fill:#e65100;fill-opacity:1;fill-rule:nonzero;stroke:#e65100;stroke-width:2.19965;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
x="0"
y="0">.app</tspan></text>
</g>
<g
id="g8"
transform="matrix(0.26458333,0,0,0.26458333,-67.310852,25.675979)">
<path
id="path8"
d="M 249.449,279.212 H 391.181"
style="fill:none;stroke:#e65100;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(1.3333333,0,0,-1.3333333,0,595.27559)" />
</g>
<g
id="g9"
transform="matrix(0.26458333,0,0,0.26458333,-67.310852,25.675979)">
<path
id="path9"
d="M 442.205,279.212 H 583.937"
style="fill:none;stroke:#e65100;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(1.3333333,0,0,-1.3333333,0,595.27559)" />
</g>
<g
id="g10"
transform="matrix(0.26458333,0,0,0.26458333,-67.310852,25.675979)">
<path
id="path10"
d="m 420.661,289.332 c 0.369,-0.114 0.596,-0.454 0.596,-0.822 0.028,-0.171 0.028,-0.284 0.028,-0.284 0,0 -0.028,-4.535 -5.386,-8.702 -2.182,-1.701 -4.053,-4.451 -4.564,-7.03 -0.056,-0.34 -0.311,-0.624 -0.652,-0.681 -0.368,-0.085 -0.708,0.057 -0.907,0.369 -1.53,2.268 -3.259,6.491 -0.368,11.48 2.608,4.536 7.427,6.832 11.253,5.67 z"
style="fill:#3e2723;fill-opacity:1;fill-rule:evenodd;stroke:none"
transform="matrix(1.3333333,0,0,-1.3333333,0,595.27559)" />
<path
id="path11"
d="m 413.121,269.376 c -0.368,0.141 -0.623,0.482 -0.623,0.85 0,0.17 0,0.284 0,0.284 0,0 0,4.535 5.357,8.702 2.154,1.672 4.054,4.394 4.564,6.945 0.057,0.368 0.34,0.623 0.709,0.708 0.34,0.057 0.708,-0.085 0.907,-0.396 1.53,-2.268 3.174,-6.463 0.34,-11.424 -2.608,-4.507 -7.399,-6.803 -11.254,-5.669 z"
style="fill:#3e2723;fill-opacity:1;fill-rule:evenodd;stroke:none"
transform="matrix(1.3333333,0,0,-1.3333333,0,595.27559)" />
<path
id="path12"
d="m 413.121,269.376 c -0.368,0.141 -0.623,0.482 -0.623,0.85 0,0.17 0,0.284 0,0.284 0,0 0,4.535 5.357,8.702 2.154,1.672 4.054,4.394 4.564,6.945 0.057,0.368 0.34,0.623 0.709,0.708 0.34,0.057 0.708,-0.085 0.907,-0.396 1.53,-2.268 3.174,-6.463 0.34,-11.424 -2.608,-4.507 -7.399,-6.803 -11.254,-5.669 z"
style="fill:none;stroke:#3e2723;stroke-width:0.4428;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(1.3333333,0,0,-1.3333333,0,595.27559)" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

+4574 -523
View File
File diff suppressed because it is too large Load Diff
-1027
View File
File diff suppressed because it is too large Load Diff
-20
View File
@@ -1,20 +0,0 @@
{
"name": "ngo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git@git.odoo4projects.com:Oliver/NGO.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs",
"devDependencies": {
"tailwindcss": "^3.4.17"
}
}
+47
View File
File diff suppressed because one or more lines are too long
View File
+1
View File
@@ -0,0 +1 @@
{"area": "CRM", "Vertical": "NGO", "date": "2026-05-04", "title": "Impact Reporting in Minutes", "teaser": "Small NGOs waste countless hours turning donor data into reports—instead of serving those theyre meant to help.", "content": "<article>\n<h2>Impact Reporting in Minutes</h2>\n<p style=\"margin: 0; color: #374151;\">— \"Maria stared at her screen at 11 p.m., three days before the grant deadline. Her donor database had 872 entries. Excel had 14 tabs. She hadnt slept in 36 hours. Every email from a donor—How was the clean water project?—demanded a new report. She couldnt tell them. Not without weeks of work. <strong>Spreadsheets</strong> were drowning her. <strong>Manual reporting</strong> was stealing her purpose. And worst of all—she knew donors were slipping away, not because her work wasnt impactful, but because she couldnt prove it.\" —</p>\n\n<p style=\"margin: 0; color: #374151;\">Modern digital tools can transform how NGOs capture and communicate impact. Automated systems can pull data from donations, program logs, and field reports into unified dashboards. Reports once built by hand can now be generated with a single click, reducing errors, saving weeks of labor, and preserving the emotional integrity of the stories behind the numbers.</p>\n\n<h3>Stop drowning in spreadsheets. Start telling stories.</h3>\n<p style=\"margin: 0; color: #374151;\">When your team spends 20 hours a week just compiling donor data, youre not serving beneficiaries—youre serving Excel. Automated reporting tools reset that balance. They sync with your existing donation platforms, track program outcomes across locations, and turn fragmented inputs into cohesive, real-time narratives that donors actually read.</p>\n\n<h3>Trust isnt built with PDFs. Its built with clarity.</h3>\n<p style=\"margin: 0; color: #374151;\">Donors dont want line items. They want to know lives changed. A clean, automated dashboard shows a childs progress in school, not just the $50 spent on textbooks. When you can show, not tell, donors see their values reflected in real results. Thats how <strong>retention grows</strong>—not through emails begging for more, but through transparency that feels genuine.</p>\n\n<h3>Proof that matters. Without the panic.</h3>\n<p style=\"margin: 0; color: #374151;\">Grant applications and board reviews require compliance—not creativity. When audit season rolls around, having pre-built, audit-ready templates means your finance lead isnt working through the night. No more frantic last-minute data fixes. Just a few clicks, and your compliance is done. That peace of mind? Its priceless.</p>\n\n<div class=\"video-container\" style=\"display: flex; margin: 2rem 0; gap: 2rem;\">\n <div class=\"video-text\" style=\"flex: 1;\">\n <p style=\"margin: 0; color: #374151;\">This is how you generate an impact report for your donors—no more spreadsheets, no more stress. Just one click, and your story goes live.</p>\n </div>\n <div class=\"video-player\" style=\"flex: 1; min-width: 300px; height: 300px;\">\n <iframe width=\"100%\" height=\"100%\"\n src=\"https://www.youtube.com/embed/huVrXvkCAqg\"\n title=\"YouTube video player\"\n frameborder=\"0\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n allowfullscreen\n style=\"width: 100%; height: 100%; border-radius: 8px;\">\n </iframe>\n </div>\n</div>\n\n<p style=\"margin: 0; color: #374151;\"><em>Remember: Every hour you spend wrestling with data is an hour taken from the field, the classroom, the clinic.</em></p>\n\n<a class=\"cta\" href=\"https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ3DDbaiHFlhNhWySszAQoPXE_H73QLqYT3w7H9IYWC76RA_TgNIhLESjb4N7ep_D2D_OyW9q4-c\">When you want to explore how this could work for your organization, you can book a meeting here:</a>\n</article>", "image": "ngo_office3"}
View File
-17
View File
@@ -1,17 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
font-family: 'Inter', 'Segoe UI', system-ui, sans-serif;
}
#lang-selector {
color: #ffffff;
}
#lang-selector:focus,
#lang-selector:focus-visible {
color: #201824;
background-color: #ffffff;
}
+1630
View File
File diff suppressed because it is too large Load Diff
-27
View File
@@ -1,27 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./index.html'],
theme: {
extend: {
colors: {
'brand-ink': '#201824',
'brand-primary': '#603F57',
'brand-accent': '#F762B4',
'brand-sunrise': '#F8B84A',
'brand-emerald': '#39B982',
'brand-snow': '#F5F2F7',
'brand-smoke': '#E5DCE8'
},
fontFamily: {
brand: ['Inter', 'Segoe UI', 'system-ui', 'sans-serif']
},
boxShadow: {
brand: '0 20px 60px rgba(32, 24, 36, 0.15)'
},
backgroundImage: {
'hero-gradient': 'radial-gradient(circle at top left, rgba(247,98,180,0.35), rgba(32,24,36,0.95))'
}
}
},
plugins: []
};