# One-page abstract submission page — template

A self-contained conference abstract submission page with **live A4 preview**,
**LaTeX math** (KaTeX), **figure + PDF upload**, and a hard **one-page limit**
(submission is blocked with an error when the preview overflows the page).

Built for [Magnonics 2027](https://magnonics2027.univie.ac.at/), hosted on
[micromagnetism.com/abstracts](https://micromagnetism.com/abstracts).
Free to reuse and adapt for your own conference or workshop.

## What's in the template

| File | Purpose |
|------|---------|
| `abstracts.html` | The whole frontend: form, LaTeX helper toolbar, live A4 preview, overflow check, upload logic, AI LaTeX import. No build step, no framework. |
| `server-snippet.mjs` | The backend (plain Node.js, no dependencies): the submission endpoint plus the optional AI LaTeX-import endpoint. |
| `abstract_template.tex` | One-page LaTeX template for authors — compiles to exactly one A4 page with the same margins as the preview. Authors fill it in and drop it on the page; the AI import fills the form from it. |
| `README.md` | This file. |

## How it works

- **Live preview** — the right-hand column renders a real 210 × 297 mm sheet
  (scaled with a CSS transform). Every keystroke re-typesets title, authors,
  affiliations, abstract paragraphs, figure and caption onto the sheet.
- **One-page check** — the content height (`scrollHeight`) is compared with the
  printable page height (A4 minus 20 mm top / 18 mm bottom margins). If it
  overflows, a red error badge appears, the overflowing region is hatched in
  red, and the submit button refuses with an error message. The flag is also
  sent to the server, which rejects over-long submissions as well.
- **LaTeX math** — [KaTeX](https://katex.org) auto-render with `$…$` (inline)
  and `$$…$$` (display) delimiters, loaded from the jsDelivr CDN. A toolbar
  inserts common templates (fractions, derivatives, Greek letters, the LLG
  equation, …) at the cursor, and a collapsible cheat-sheet helps newcomers.
- **Uploads** — figure (PNG/JPG/WebP ≤ 8 MB, shown on the page) and PDF
  (≤ 15 MB, stored alongside) are read client-side with `FileReader` and sent
  base64-encoded inside one JSON POST — so the server needs **no multipart
  parser and no dependencies**.

- **AI LaTeX import (optional)** — authors can drop a complete `.tex` file
  (ideally `abstract_template.tex`), a **`.zip` with the `.tex` and the
  figures** (e.g. an Overleaf download), or paste the source; the server sends
  the LaTeX to the Claude API, which returns the form fields as JSON (title,
  authors, affiliations, e-mail, abstract with math preserved, figure caption),
  and the form + preview fill themselves. For a ZIP, the browser unpacks it
  client-side (fflate), picks the `.tex` containing `\begin{document}`, finds
  the first `\includegraphics` image in the archive, and places it on the page
  automatically — PDF figures are converted to PNG in the browser with pdf.js. Needs an `ANTHROPIC_API_KEY` on the server;
  without one, the endpoint politely reports that AI import is not configured
  and everything else keeps working. Rate-limited to 10 imports per IP per hour.

## Setup (5 minutes)

1. Serve `abstracts.html` from any web server.
2. Add the handler from `server-snippet.mjs` to a Node.js server
   (it is written for a plain `http.createServer` if-chain; with Express,
   wrap it as `app.post('/api/abstract', …)` — the body is ordinary JSON).
3. Create the storage directory (the snippet does this itself on first use).
4. Adjust branding: conference name, colors in the `:root` CSS variables,
   contact address in the footer.

Each submission lands in `abstracts/<id>/` as:

```
abstracts/a1b2c3/
├── meta.json      # title, authors, affiliations, email, abstract, caption, date, IP
├── figure.png     # if uploaded
└── paper.pdf      # if uploaded
```

## Adapting the page style

All colors live in the `:root` block at the top of `abstracts.html`
(`--primary`, `--darkest`, grays, …) — swap them for your university's palette.
The preview sheet's typography (Georgia 11 pt, margins) is in the `#sheet` /
`#sheetInner` rules; change margins there **and** in the `checkFit()` function
so the one-page check stays consistent.

## License

Public domain / CC0 — no attribution required.
Template by Dieter Suess, University of Vienna (dieter.suess@univie.ac.at),
built with Claude.
