# Business card — Direction B (modern, people-first)

**Status:** working spec; finalization in progress. The locked design lives in
`card-template.html` alongside this file. When the parent mark and card both
lock and ship, this graduates to an ADR in `decisions/`, and the cycle entry in
`DESIGN-LOG.md` flips to `landed`.

## Direction (locked 2026-05-27)

- **Layout:** Option B — modern / operator, people-first. Signature top-right,
  tagline under it (right-aligned), person lower-left, asymmetric.
- **Paper:** warm white `#F8F6F0` (v4 Capital paper).
- **Corners:** square.
- **Parent mark:** F / Outer Heavy, Inner Air — the canonical parent mark, light
  mode (6-circle ring; the `parentMark` light palette, [ADR-0007](../../../decisions/0007-parent-mark-f-and-per-mode-tokens.md)).
  Front signature only. Tokenization did **not** shift the card art — light mode is
  the locked card hexes verbatim — so the existing card proofs stay valid.
- **Back:** centered "Caldura" wordmark + `caldura.com`. No mark, no stripe,
  no tagline.
- **Stripe:** 27px (~0.09") bronze (`#765B12`), front only, left edge, full
  bleed height.

## Print target: MOO Standard 3.5"×2"

| Layer | inches | mm | px @300 DPI |
|---|---|---|---|
| Bleed (artboard) | 3.66 × 2.16 | 92.96 × 54.86 | 1098 × 648 |
| Trim | 3.50 × 2.00 | 88.9 × 50.8 | 1050 × 600 |
| Safe area | 3.34 × 1.84 | 84.84 × 46.74 | 1002 × 552 |

Bleed and safe margin: 0.08" / 2.03mm per edge. Background and the bronze stripe
must extend to the bleed edge; text, mark, and contact stay inside the safe
area.

### Bleed-edge elements

Any *bounded* element flush against the bleed edge (the bronze stripe, an edge
bar, a corner block, a full-edge color field) must extend an extra 24px (the
bleed inset) into the bleed area in the file, so the post-trim *visible* size
matches what's spec'd. The paper background fills 1098×648 naturally and needs
no per-element calculation; bounded bleed-edge elements do.

**Worked example — the bronze stripe.** Visible-after-trim width: 27px (~0.09").
File width: 27 + 24 = **51px**, positioned at `left: 0`. After MOO trims at
x=24, the visible stripe is x=24..51 = 27px on the printed card. Without the
cushion, only 3px (~0.25mm) of stripe would survive the trim — a hairline, not
the brand element. The viewer with guides on surfaces the geometry: the dashed
trim guide should land inside the stripe, not at its right edge.

Generalize: for a bleed-edge element with intended visible-after-trim
dimension *D* on the bleed-adjacent side, file dimension = *D* + 24 px.

## File specs (MOO)

- **PDF/X-1a:2001** preset.
- **CMYK** — Coated GRACoL 2006. Confirm the exact ICC profile name from MOO's
  downloadable template before final export.
- **300 DPI** for any raster. The mark and text remain vector. 96 DPI is MOO's
  floor; do not work near it.
- **No crop marks** — MOO adds them automatically.
- **≤ 50 MB.**
- **Text minimum 8pt; line weight minimum 0.5pt** (MOO recommendations).
- **100% K** for body text where possible.

## Type spec

Sizes are given in pt on the real 3.5" card, with the @300-DPI pixel equivalents
used by the template. Hierarchy: name > supporting (role / contact / URL) >
tagline. Confident-restrained — comparable to mature-fintech cards (Bridgewater,
Sequoia, Founders Fund-class restraint), not whispered.

| Element | Size | Family / weight | Color | Notes |
|---|---|---|---|---|
| Person name | **9.3pt** (39px) | sans 700, line 1.1, tracking -0.005em | ink `#1A1210` | Modest by intent — Option B is restrained, not a giant-hero card. |
| Role | **8pt** (33px) | sans 600 | bronze `#765B12` | At MOO's 8pt floor. |
| Phone / email | **8pt** (33px) | sans 400, line 1.4 | bronze | At MOO's floor — these get scanned and typed. Order: phone, then email. |
| Tagline (front) | **7pt** (29px) | sans 400, line 1.2, tracking 0.04em | muted `#6B5D52` | Slightly under MOO's 8pt rec; acceptable for one short line of secondary positioning text. Keeps hierarchy below contact. |
| Caldura signature (front) | **13pt** (54px) | serif 500 | bronze | Right for a corner signature, paired with an 82px mark. |
| Caldura wordmark (back) | **26pt** (109px) | serif 500 | bronze | The back's hero. |
| caldura.com (back) | **8pt** (33px) | sans 400, tracking 0.04em | bronze | At floor — the back's only CTA, should invite reading. |
| Bronze stripe | **27px visible after trim** (~0.09"); 51px file width | — | bronze `#765B12` | Front only, left edge, full bleed height. The 24px difference is the bleed cushion (see "Bleed-edge elements" under Print target). |

**Why bump from the comp's literal scale.** The original Option B screen comp
sized supporting text at 13px on a 540px card → ~6pt and tagline ~5.3pt on the
real card. Those land under MOO's 8pt recommendation and read small physically.
This spec preserves Option B's *composition and hierarchy* (modest name, lower
supporting text, even smaller tagline) while moving the small tiers to the
print-legible floor.

## Data model (generator-ready)

```js
const person = { name, role, phone, email };
const brand  = { wordmark: "Caldura", tagline: "AI-native private infrastructure platform", url: "caldura.com" };
```

The template renders front and back from those two objects. URL params give a
bare 1098×648 per-face render for screenshot / generator export:

- `?render=front&guides=off`
- `?render=back&guides=off`

Rendered via the project's existing headless-Chrome toolchain (same pattern as
`systems/v4/comp-sheets/render-comps.sh`).

## Export to MOO

Each card proof has a download icon button in its caption row (above the card,
not in the form chrome — so it's clearly attached to the face it acts on).
Clicking produces a ready-to-upload file named after the current `person.name`:

- `caldura-card-{name}-front-1098x648-300dpi.png`
- `caldura-card-{name}-back-1098x648-300dpi.png`

Output is **1098 × 648 px** (3.66" × 2.16" bleed at 300 DPI), **RGB**. MOO
accepts PNG and converts to CMYK on their end against the GRACoL profile —
this is sufficient to order today, with the known color-shift caveat on warm
bronze (see open question #1). The buttons clone the requested face at true
1:1 into a hidden offscreen container, force guides off, apply capture-time
hygiene (see below), and capture via
[html2canvas](https://html2canvas.hertzen.com/) bundled locally as
`html2canvas-1.4.1.min.js` (no third-party CDN; supply-chain isolated).

### Capture hygiene

html2canvas 1.4.x has a class of bug where **any visual-only effect on the
captured element bakes into the captured surface**, not just into the
surrounding box. Concretely, an outer `box-shadow` composites onto the
element's paper, dimming `#F8F6F0` to `#BAB7B1` (= paper × 0.72 + shadow ×
0.28). The export path neutralizes this with four layers of defense:

1. **Strip on the clone.** The cloned card's `style.cssText` sets
   `box-shadow: none` inline (along with explicit `background-color`).
2. **Override via injected `!important` rule.** A temporary `<style data-h2c-override>`
   forces `box-shadow: none` and `background-color: #F8F6F0` on `.card`,
   `html`, and `body` for the duration of the capture. html2canvas reads
   stylesheet rules when building its clone, so this lands where it reads.
3. **Tell html2canvas explicitly.** `backgroundColor: PAPER` in the
   `html2canvas({...})` options.
4. **Composite over a paper fill.** The captured canvas is drawn onto a
   fresh canvas pre-filled with `#F8F6F0`, then exported.

A four-pixel integrity check runs after each export (three paper, one
bronze stripe). It logs only on regression — silent when the paper
captures clean.

The same principle applies to any future capture-only visual effect
(`box-shadow`, `filter`, `backdrop-filter`, opacity layering, etc.) and
to the SVG mark colors, which are kept as literal hex (not CSS variables)
for the same reason — what html2canvas captures must be self-describing,
not dependent on cascade resolution or effect composition.

Vector **PDF/X-1a CMYK** (open question #2) remains the ideal-quality path
and the generator's eventual export endpoint.

## Ordering at MOO

Use this as the order-flow checklist on moo.com. The card is sized for MOO's
US **Standard 3.5" × 2.0"** product; smaller/larger MOO sizes will not match.

- **Product:** Standard Business Cards (3.5" × 2.0").
- **Corners:** **Square** (not rounded).
- **Sides:** **Double-sided** (front + back).
- **Orientation:** Landscape.
- **Quantity:** start with the minimum pack (typically 50) for a first proof
  print — confirms bronze fidelity on real coated stock before committing to
  a larger run.
- **Paper:** select a stock that holds the warm-white tone and a saturated
  bronze. MOO's "Original" is a neutral white; the Luxe lines are thicker and
  feel more premium. **Uncoated / matte papers tend to keep warm bronzes truer;
  high-gloss coated papers can flatten the bronze.** Order a sample pack first
  if unsure.
- **Special finishes:** **none** (no spot UV, foil, or rounded corners — the
  design is intentionally clean).
- **Files:** upload the two PNGs produced by the template's per-card download
  buttons:
  - `caldura-card-{name}-front-1098x648-300dpi.png`
  - `caldura-card-{name}-back-1098x648-300dpi.png`
  Both are full-bleed (1098 × 648 px = 3.66 × 2.16" at 300 DPI), RGB, no crop
  marks. MOO converts to CMYK on their end.
- **Expected uploader warnings:** MOO may flag the 7pt tagline as small text —
  this is intentional; accept and proceed. Resolution will pass cleanly at
  exactly 300 DPI.

Color caveat: warm gold (`#765B12`) is the brand element most likely to shift
on auto-CMYK conversion. If the first print's bronze reads materially different
from screen, escalate to PDF/X-1a output (see open question #2).

## Open questions (block `landed`)

1. **CMYK proof of the bronze.** `#765B12` is sRGB. Warm golds shift on coated
   stock. Convert and proof against GRACoL before a real print run.
2. **PDF/X-1a export path.** Browser print-to-PDF outputs RGB; MOO wants CMYK
   PDF/X-1a. This needs a real PDF step (headless render → CMYK conversion
   against GRACoL). It is the core of the card-generator build.
3. **Generator scope on the prototype.** The form here (name / role / phone /
   email) is the seed. Production should add any extra fields not yet exposed
   (LinkedIn? second contact line? alternate roles?) and the CMYK export
   endpoint above.

## File index

- `card-template.html` — the live data-driven template implementing this spec.
- `html2canvas-1.4.1.min.js` — vendored locally (the PNG-download path
  loads this rather than a third-party CDN).
- `proof-front.png`, `proof-back.png` — current rendered proofs at true
  1098×648 (300 DPI), guides off.
- `proof-front-with-guides.png` — same front with trim/safe guides shown,
  useful when checking the spec against the design.
- `VENDORING.md` — handoff notes for vendoring this folder into the `sites`
  repo as the prototype's card-generator seed.
