# Standard: Newsletter signup (MailerLite)

**Status:** established convention — follow it on every page that should collect email subscribers.
**Audience:** anyone (human or AI agent) adding a newsletter signup to this site.

This documents the one and only way we add a "subscribe to our newsletter" form. It is already
wired to MailerLite through `main.js`; you do **not** write any JavaScript. You only paste HTML.

---

## 1. How it works (read this once)

- All subscribe forms are handled centrally by `setupNewsletter()` in **`main.js`** (section 7).
- On page load it finds every `form.subscribe-form` and `form.subscribe-form-bottom`, and:
  - forces the input to `type="email"`, `name="fields[email]"`, `required`,
  - inserts a live status message element after the form,
  - on submit: validates the email, then POSTs to MailerLite's JSONP endpoint,
  - shows a localized success / error / "sending" message (EN / SI / MK).
- MailerLite uses **double opt-in**: the subscriber gets a confirmation email. The success
  message intentionally says "check your inbox to confirm".

**MailerLite config** lives in one place — `main.js`, `setupNewsletter()`:

```js
const ML_ACCOUNT = '1253161';
const ML_FORM    = '194374752800868123';
```

To point the whole site at a different MailerLite audience/form, change those two values only.
(They come from MailerLite → Forms → Embedded forms → your form → the subscribe URL
`https://assets.mailerlite.com/jsonp/<ACCOUNT>/forms/<FORM>/subscribe`.)

---

## 2. Two non-negotiable requirements

1. **The page must load `main.js`.** Without it the form is dead. Check for:
   ```html
   <script src="{{PREFIX}}main.js"></script>
   ```
   just before `</body>`. If a page has its own script (e.g. `news-filter.js`), load `main.js`
   **as well**, before it. (This was the exact bug on the News hub page — it shipped without
   `main.js`, so its form — and its header dropdowns — didn't work.)

2. **Use the exact class names.** `subscribe-form-bottom` (full band, the default) or
   `subscribe-form` (compact hero). No other class is auto-wired.

---

## 3. The snippet (default — full "band" CTA)

This is the standard block shown above the footer on content pages (News, articles, projects,
get-to-know…). Paste it just before `</main>`.

```html
<section class="newsletter-cta">
    <div class="container">
        <div class="cta-content">
            <h2>{{HEADING}}</h2>
            <p>{{SUBTITLE}}</p>
            <form class="subscribe-form-bottom">
                 <div class="input-wrapper">
                    <input type="email" placeholder="{{PLACEHOLDER}}">
                 </div>
                <button type="submit" class="btn btn-primary-orange">{{BUTTON}}</button>
            </form>
            <p class="privacy-note">{{PRIVACY_TEXT}} <a href="{{PREFIX}}{{LANG}}/privacy-policy/">{{PRIVACY_LINK}}</a>{{PRIVACY_SUFFIX}}</p>
        </div>
    </div>
</section>
```

Styling is already defined in `css/pages/_article.css` (`.newsletter-cta`, `.subscribe-form-bottom`,
`.privacy-note`) and is globally available via `main.css`. Nothing to add.

### Compact variant (hero)
When you want it inline under a page hero (as on the get-to-know pages), use the smaller form —
same wiring, no band wrapper:

```html
<form class="subscribe-form">
    <input type="email" placeholder="{{PLACEHOLDER}}">
    <button type="submit" class="btn btn-primary-orange">{{BUTTON}}</button>
</form>
<p class="privacy-note">{{PRIVACY_TEXT}} <a href="{{PREFIX}}{{LANG}}/privacy-policy/">{{PRIVACY_LINK}}</a>{{PRIVACY_SUFFIX}}</p>
```

---

## 4. `{{PREFIX}}` — the relative path to the site root

Count the folders between the page and the repo root; that's how many `../` you need.

| Page location (example)                                  | `{{PREFIX}}` |
| -------------------------------------------------------- | ------------ |
| `en/index.html`                                          | `../`        |
| `en/news/index.html`                                     | `../../`     |
| `en/news/proof-of-means-updated-2026/index.html`         | `../../../`  |

So the privacy link on a depth‑3 article is `../../../en/privacy-policy/`, and the script tag is
`../../../main.js`. Get this wrong and the link/JS 404s.

---

## 5. Copy — fill the placeholders per language

Always ship all three languages (`en/`, `si/`, `mk/`) — the site is fully mirrored.

**Honest copy only.** Do **not** reuse the legacy `"Join 2,000+ subscribers"` heading that still
appears on some older pages — we don't have that many subscribers. Tailor the heading to the page.
The values below are the current News-section standard:

| Field              | EN                                                        | MK                                                                    | SI                                                            |
| ------------------ | --------------------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------ |
| `{{HEADING}}`      | Never miss an MSOS update                                 | Не пропуштајте ниту една новост од МСОС                               | Ne zamudite nobene novice MSOS                               |
| `{{SUBTITLE}}`     | News, announcements and open calls — straight to your inbox. | Вести, соопштенија и отворени повици — директно во вашето сандаче.  | Novice, obvestila in razpisi — naravnost v vaš e-poštni predal. |
| `{{PLACEHOLDER}}`  | Enter your email                                          | Внесете ја вашата е-пошта                                             | Vnesite svoj e-mail                                          |
| `{{BUTTON}}`       | Subscribe                                                 | Претплати се                                                          | Naroči se                                                    |
| `{{PRIVACY_TEXT}}` | We care about your data in our                            | Ние се грижиме за вашите податоци во нашата                           | Skrbimo za vaše podatke v naši                               |
| `{{PRIVACY_LINK}}` | privacy policy                                            | политика за приватност                                               | politiki zasebnosti                                          |
| `{{PRIVACY_SUFFIX}}` | *(empty)*                                               | *(empty)*                                                             | `.`                                                          |

Change `{{HEADING}}` / `{{SUBTITLE}}` to fit the page's purpose; keep the rest as-is for consistency.

---

## 6. Checklist before you call it done

- [ ] Block pasted before `</main>` (band) or under the hero (compact).
- [ ] `{{PREFIX}}` correct for the page depth (privacy link **and** the `main.js` script tag).
- [ ] Page loads `main.js` (added *before* any page-specific script).
- [ ] All three languages updated (`en/`, `si/`, `mk/`).
- [ ] Copy is honest (no fake subscriber counts).
- [ ] Tested locally: on load the input gets `name="fields[email]"` and a `.subscribe-status`
      element appears after the form; an invalid email shows the "valid email" error.
      **Do not** submit a real address while testing — it lands in the live MailerLite audience.
