# Aether Events — Onsite Badge Printing

**Last Updated:** 2026-06-12

Notes on setup, process, hardware, and browser behavior for onsite badge printing at events.

For cross-module onsite operations (SRR, launcher monitoring, exhibitor leads support), see:
`documentation/GUIDE__AE_Events_Onsite_Runbook.md`.

---

## Overview

Aether badge printing uses the browser's native `window.print()` — no special software or print
server needed. The badge render page (`/events/[event_id]/badges/print/[badge_id]`) outputs
print-ready HTML/CSS, and the browser sends it directly to the connected printer via CUPS (Linux)
or the OS print system (macOS/Windows).

Chrome (Chromium) is the recommended browser for onsite kiosk stations.
Firefox is a solid alternative, especially for Save-to-PDF workflows.

---

## Recommended Workflow — Onsite Kiosk

1. Open the event's badge printing page: `/events/[event_id]/badges`
2. Search for the attendee (name, badge ID, or QR scan)
3. Open the badge print page — review the rendered badge
4. Click **Print Badge** in the controls panel (or use keyboard shortcut)
5. In the browser print dialog:
   - Set Margins to **None** (Chrome) or leave defaults (Firefox)
   - Confirm paper/card size matches the stock loaded in the printer
   - Print
6. `print_count` increments automatically on each print via the Print Badge button

For high-volume events, consider the **rapid QR scan** mode in the Leads module or using a
dedicated kiosk session where the operator only handles physical card handoff.

---

## Browser Settings

### Chrome / Chromium (Recommended for kiosk use)

Chrome is recommended for onsite badge printing stations. Key print dialog settings:

| Setting | Correct value | Notes |
|---|---|---|
| Margins | **None** or **Minimum** | Default margins add URL/date headers — breaks badge centering |
| Paper size | Match card stock (e.g. 3.5" × 5.5") | Zebra driver may override this automatically |
| Background graphics | **On** | Required for colored header/footer stripe to print |
| Pages | 1 | PVC single-sided — only front should print |

**Important:** Chrome ignores CSS `@page { size }` for Save to PDF — it defaults to letter/A4.
For physical printer output, the printer driver controls paper size. This is expected behavior.

To lock Chrome settings for a kiosk, set Margins to "None" once and Chrome remembers per-printer.

### Firefox

Firefox honors CSS `@page { size }` which makes it ideal for PDF generation.
For physical printing, Firefox generally "just works" without margin adjustments.

| Setting | Notes |
|---|---|
| Paper size | Can be set in dialog, but CSS `@page { size }` is honored |
| Margins | Default is usually fine; remove headers/footers if they appear |
| Background graphics | Enable for colored stripes and header images to print |

### General Notes

- **Background graphics must be enabled** in any browser — otherwise header images, footer
  color stripes, and tonal backgrounds will not print.
- Private/incognito mode blocks PWA install prompts — use normal browser sessions for kiosk.
- For highest reliability, set the kiosk machine to auto-login and open Chrome to the event URL.

---

## Linux / CUPS Setup

For Linux workstations and dedicated kiosk machines running Linux:

1. Install CUPS if not already present: `sudo pacman -S cups` (Arch) or equivalent
2. Start the CUPS service: `sudo systemctl enable --now cups`
3. Open the CUPS web UI: `http://localhost:631`
4. Add the printer and install the appropriate driver (see per-printer sections below)
5. Print a test page from CUPS to confirm card feed and quality
6. In Chrome: select the CUPS printer name under Destination in the print dialog

On macOS and Windows, use the vendor-provided driver installer.

---

## Printers

---

### Zebra ZC10L — PVC Card Printer

**Card stock:** 3.5" × 5.5" PVC cards (CR80 extended)
**Tested:** 2026-03-17 (rental test day, Arch Linux)
**Status:** Working. Confirmed suitable for Axonius NYC (mid-April 2026).

#### Physical Setup

- Connect via USB (the ZC10L supports USB and Ethernet)
- Load PVC card stock per the Zebra loading instructions — cards face-up, landscape
- The ZC10L prints one side (single-sided dye-sub thermal); do not attempt duplex on PVC stock

#### Linux Driver

- Download the Zebra ZC10L CUPS driver from zebra.com (ZC Series Linux support)
- Install the `.deb` or extract the PPD file and add to CUPS manually
- In CUPS (`http://localhost:631`), add the printer and select the ZC10L PPD
- Set default paper size to **3.5" × 5.5"** (or CR80 Extended if listed)
- Print a blank test page from CUPS before using Chrome

> **Note:** Driver version tested: *(update here after confirming)*
> CUPS printer name used: *(update here after setup)*

#### Chrome Print Settings (ZC10L)

| Setting | Value |
|---|---|
| Destination | Zebra ZC10L (CUPS name) |
| Paper size | 3.5 × 5.5 in (or as set in CUPS) |
| Margins | **None** |
| Background graphics | On |
| Pages | 1 (front only) |

#### CSS Layout

The ZC10L uses the `badge_3.5x5.5_pvc` layout. The PVC layout CSS is at:
`src/routes/events/[event_id]/(badges)/badges/print/badge_layout_zebra_zc10l_pvc.css`

This layout hides `.badge_back` in `@media print` — only the front face prints.
`@page { size: 3.5in 5.5in; margin: 0; }` is set in the CSS.

#### Known Behaviors / Watch-outs

- Chrome with **Default** margins: inserts URL/date headers, offsets badge — use **None**
- Chrome with **None** or **Minimum** margins: correct output
- Firefox: works correctly out of the box with this layout
- Physical card alignment: if the badge appears offset on the card, a CSS margin tweak may
  be needed in the PVC layout file — note the offset and adjust `print_margin_cfg` once that
  field is wired to the UI
- Font sizes: if name/affiliation text appears too small at physical scale, adjust via the
  font size controls (+ / −) in the print controls panel; note the preferred values for this
  event's template

#### Test Results (2026-03-19)

- Card feeds and prints without jam: ✅
- Single-sided PVC confirmed (back does not print): ✅
- Chrome margins None/Minimum: correct output ✅
- Firefox: correct output ✅
- QR code scannable from printed card: ✅
- Print tracking (`print_count` increment): ✅
- Font sizes / visual quality: tested; specific calibration pending client design direction
- Driver version: *(record here)*
- Physical offset needed: *(record if any)*

---

### Epson ColorWorks C3500 — Fan-Fold Label Printer

**Card stock:** 4" × 6" fan-fold paper label stock
**Layout code:** `badge_4x6_fanfold`
**Status:** Configured. First live use: Axonius Adapt DC — June 9, 2026.

The C3500 is a color inkjet label printer — it prints continuous fan-fold paper stock,
not individual cards. Badges are separated along the perforation after printing.

#### Physical Setup

- Connect via USB or Ethernet
- Load 4" × 6" fan-fold stock per Epson instructions
- The C3500 is single-sided — only the front face prints. Back section is suppressed in CSS.
- The badge has a lanyard hole punch: 5/8" × 1/8", centered, 1/4" from the top.
  Most fan-fold stock for badge use includes a pre-punched lanyard slot — verify stock matches.

#### Driver

- Epson ColorWorks C3500 CUPS driver available from epson.com (ColorWorks section)
- On Linux/CUPS: install the provided PPD and add the printer at `http://localhost:631`
- Set default paper size to **4" × 6"** in CUPS
- Print a test page from CUPS before going live

#### Chrome Print Settings (C3500)

| Setting | Value |
|---|---|
| Destination | Epson C3500 (CUPS name) |
| Paper size | 4 × 6 in (set in CUPS driver) |
| Margins | **None** |
| Background graphics | On |
| Pages | 1 (single-sided) |

#### CSS Layout

The C3500 uses the `badge_4x6_fanfold` layout. CSS file:
`src/lib/ae_events/badges/css/badge_layout_epson_4x6_fanfold.css`

Created 2026-05-15 for Axonius Adapt DC. Key specs:
- `badge_front` 4" × 6", portrait orientation
- `badge_header` max-height 1.5in
- Lanyard hole: 5/8" × 1/8", centered, 1/4" from top
- `@page { size: 4in 6in; margin: 0; }` set in the print page dynamically
- `.badge_back` suppressed in `@media print` (single-sided)

#### Known Behaviors

- Same Chrome margin rules apply: **Margins → None** prevents URL/date header clipping
- Firefox honors `@page { size: 4in 6in }` for PDF proofing — use it to verify layout
- Fan-fold stock separates along the perforation — no cutting needed, but verify the
  perforation lands outside the badge content area

---

## Print Tracking

The badge print page tracks print counts per badge:

- `print_count` — increments on each **Print Badge** button click
- `print_first_datetime` — timestamp of first print
- An amber "Printed N×" chip appears in the print page header after the first print

The reprint shortcut (trusted access + edit mode) does **not** increment the count.
Only the **Print Badge** button path increments the count. This is intentional — reprints
for alignment or quality checks should not inflate the print count.

---

## Troubleshooting

| Symptom | Cause | Fix |
|---|---|---|
| White border around printed badge | Chrome Default margins | Change to None or Minimum |
| URL / date printed at top or bottom | Chrome Default margins | Change to None |
| Header image / stripe not printing | Background graphics disabled | Enable in print dialog |
| Badge appears on wrong-size output | Paper size mismatch | Set correct size in CUPS and/or print dialog |
| Card jams | Card stock misloaded | Re-seat cards per printer manual; check stock orientation |
| Badge content clipped | Layout overflow | Check font size — use − control to reduce if needed |
| Second blank card ejected | Duplex triggered on PVC | Confirm `.badge_back { display: none }` in print CSS for this layout |
