Files
AOS/skills/design/design-templates/social-card-swiss/references/image-overlay.md
T
Z User e45b68bb8b feat: IMAP mail sync with thread-to-contact matching (PRD §6.1)
Real IMAP connection via imapflow library:
- Connects to IMAP server (IMAPFlow, TLS on port 993)
- Fetches recent messages (configurable limit, default 20)
- Extracts: from, fromEmail, subject, date, snippet (200 chars)
- Thread-to-contact matching (PRD §6.1):
  1. Match sender email against persons table
  2. If no person match, extract domain and match against company.website
  3. Returns matchedCompany + matchedPerson for each email
- Audit-logged (action: crm.mailsync:imap)
- Zod validated (host, port, user, password, folder, limit)
- 502 on IMAP connection failure with detail
- 400 on validation failure

Tested: invalid creds → 502 'IMAP connection failed', missing host → 400
2026-10-27 22:50:50 +00:00

153 lines
9.4 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Image Overlay & Subject Safety
Two rules that govern any poster where text sits on top of an image — full-bleed background, large photo well with title bar, or generated/AI image with text overlay.
A composition can pass HTML linting and still be unreadable. Both rules below must clear before you ship.
## Rule 1 — Selection first, mask only if selection fails
The default editorial-magazine answer is **no mask**. Real magazine covers (Kinfolk, Cereal, Apartamento, Monocle) almost never lay a uniform black gradient over a hero photo. They rely on **photo selection + composition** so text lands in a quiet zone naturally. If you cannot find such a photo, the answer is usually to swap the photo, not to caulk over a bad one with a 70%-black scrim.
Apply the steps in order. Stop at the first one that passes.
### Step 1 — Photo selection (the main lever)
Before picking a mask, verify the photo qualifies for full-bleed treatment. Both tests must pass:
**Quiet-zone test**: at least one band of ≥30% canvas (full width × ≥30% height, or full height × ≥30% width) is **low-detail / low-contrast / uniform**. Examples: out-of-focus background, deep shade, fog, calm water, plain sky, blurred grass. This band is where the title will land.
**Light test**: the photo carries **atmospheric / restrained light** — overcast, dawn fog, golden hour, forest understory, film softness, dusk silhouette. Reject high-saturation noon shots, on-camera flash, "tourist trap" selfies, generic stock cheerfulness.
If either test fails, **the photo is wrong for M16**. Fall back to M01 (split-layout cover with photo in a frame), or shoot/source again. Do not "fix it with a mask."
### Step 2 — Compose without a mask first
Place the title inside the qualified quiet zone. Run the thumbnail contrast check (Step 4). If it reads clean, ship as-is. Most well-selected editorial photos pass at this step.
A no-mask cover signals craft. A heavily masked cover signals "we couldn't find the right photo." Try Step 2 every time before reaching for Step 3.
### Step 3 — Localized, image-toned tint (fallback only)
Only when Step 2 fails the contrast check. Three rules:
1. **Localized, not full-canvas.** Tint only the title region. Use `radial-gradient` centered on the title block, or a one-sided linear gradient that fades to fully transparent past the title. Never `inset: 0` over the whole image with a uniform alpha curve.
2. **Image-toned, not black.** Sample a dark tone already in the photo and use it as the tint color. Forest → deep moss `#1a2818`. Dusk → tea-rose dusk `#4a2638`. Snow → cool grey-blue `#2a3438`. Pure black `#000` reads as "annotation layer," not "atmospheric depth."
3. **Soft, not opaque.** Peak alpha 0.15-0.30 in the title region, falling to 0 outside. If you need >0.40 to read, the photo failed Step 1 — go back.
```css
/* Example: title in lower-left, image-toned soft tint */
.hero-bleed::after {
content: "";
position: absolute; inset: 0;
background: radial-gradient(
60% 45% at 25% 80%, /* centered on title block */
rgba(26, 40, 24, 0.28) 0%, /* forest moss tone, soft peak */
rgba(26, 40, 24, 0.0) 100%);
pointer-events: none;
}
```
### Step 4 — Thumbnail contrast check (always)
Whether or not you applied a tint:
- Render the PNG, downscale to 360 px wide in Preview / a browser tab, and look.
- Title strokes must be legible without zoom.
- If title looks like it's "fighting" the photo → swap photo or shift title to a different quiet zone, **not** strengthen the mask.
- If photo looks dead grey under uniform dark → mask is way too heavy or covers wrong area; restart from Step 1.
### Banned
- **Uniform full-canvas vertical falloff** (the `rgba(0,0,0,.55) → .10 → .10 → .80` pattern from earlier versions of this skill). That is game-key-art treatment, not editorial.
- **Pure black mask color**. Always image-toned (forest, dusk, snow, ink-blue, sepia).
- Flat black/white rectangle behind text — reads like screenshot annotation.
- `mix-blend-mode: difference` for readability — wrecks skin tones, breaks on print.
- `img { opacity: .6 }` — kills the photo's depth, the whole point of full-bleed.
- Reaching for Step 3 before honestly attempting Step 1 with a better photo.
---
## Rule 2 — Place text away from subject / face zones
Posters in 旅行 / 游戏 / 影视 / 穿搭 / 美食 frequently use a real photo as the hero. The photo has a subject — a face, a hand, a product, a peak. Text that overlaps the subject reads as graffiti, not editorial.
### Subject zone discovery — multimodal first
Before designing the title position on a hero photo, look at the image. Open it with the Read tool and observe in plain language:
1. Where is the **primary subject's face / focal feature**? (e.g. "the climber's face is in the upper-right third around 70% x 30% y")
2. Where is the **edge of the subject's silhouette**? (e.g. "left edge ends at ~40% x; below that is sky")
3. Where is the **largest open / low-detail area**? (e.g. "the lower-left quadrant is uniform fog")
Record the answers as a comment in the HTML next to the hero block:
```html
<!-- subject map (Wukong cover hero):
face/skull centerpiece: 50% x 45% y, occupies ~30% of frame
left-side staff & weapons: 15-40% x, full height
safe text zone: top band (0-15% y) and bottom band (65-100% y)
-->
```
This is the input the layout uses. It's deterministic and reviewable.
### Safe-zone placement rules
Given the subject map, place text in this order of preference:
1. **Above + below** the subject (kicker top, title bottom). 90% of full-bleed covers should do this.
2. **One side** — if subject occupies one vertical column (e.g. portrait shot on right side), text fills the opposite column. Combine with side tint from Rule 1 Step 3 only if needed.
3. **Diagonal corner** — only when the subject is in one corner and the opposite corner is genuinely empty. Rare.
Never place display titles **across** the face. A 90 px Chinese title cutting through a person's eyes is destructive even with a mask.
### Composition discipline (editorial look)
These four rules are what separates an editorial poster from a generic image-with-text:
- **Asymmetric placement.** Titles offset to one side / one corner read more confident than dead-centered ones. The Kinfolk / Cereal habit.
- **Generous negative space.** Title should occupy ≤40% of the canvas. The photo and the empty quiet zone are doing the design work.
- **Title in one quiet zone, only one.** Splitting the title into two zones (top + bottom) is fine; splitting it into three or wrapping around the subject is busy.
- **Title never overlaps the subject silhouette.** If the only safe placement requires crossing the subject's edge, switch modes (move to a frame, diptych, or off-image title) — do not enlarge the mask.
### Crop guards
The face-avoidance rule should also drive `object-position`. If the subject is in the upper third, do not use `object-position: center top` (that pushes the face into the title band).
| Subject location in raw image | Recommended `object-position` for 3:4 crop |
| ----------------------------- | ------------------------------------------ |
| Face / focus in upper third | `center 25%` (lifts face higher, gives bottom room for title) |
| Face / focus in middle third | `center center` (default; text goes top + bottom) |
| Face / focus in lower third | `center 70%` (drops face down, top room for title) |
| Wide landscape, no single subject | `center 35%` (slight upward bias to retain horizon line) |
| Vertical portrait, full body | `center top` |
### When the photo cannot accommodate text
If running the subject map shows there is no safe zone wider than ~30% of the poster (subject fills the frame, e.g. tight portrait), do not retrofit. Options:
- Move the photo into a **smaller frame** (use `.frame-img.r-3x4` or `.r-1x1` inside the layout — give it a defined slot, surround it with whitespace and text).
- **Two-image diptych** with one tight subject + one negative-space image, run titles over the negative-space one.
- **Move text off the image entirely** — title above, photo below. The Yading cover already does this.
A photo that demands the full canvas is not a sign that text should fight it. It is a sign that text should sit elsewhere.
---
## Checklist before delivery
Run this for every poster that has text touching an image:
- [ ] Photo passes quiet-zone test (≥30% canvas low-detail band) AND light test (atmospheric, not high-saturation noon).
- [ ] Tried no-mask composition first. Tint only added if Step 4 contrast check failed.
- [ ] If tinted: localized (`radial-gradient` or one-sided), image-toned color (not pure black), peak alpha ≤ 0.30.
- [ ] No full-canvas vertical falloff present (`linear-gradient(180deg, rgba(0,0,0,.X) → ...)` over `inset:0`).
- [ ] Subject map documented as a comment near the hero block.
- [ ] No display title (≥ 72 px) overlaps a face / hand / key product feature / subject silhouette.
- [ ] Title occupies ≤40% of canvas. Asymmetric placement preferred over centered.
- [ ] `object-position` chosen from the table above, not left at default `center top` for face shots.
- [ ] Thumbnail test passed (downscale to 360 px wide; title still legible without strain).
- [ ] No flat black/white text plate behind the title.
If any item fails, fix it before exporting the final PNG. Do not deliver and "we can adjust later" — the QA window for social cards is the moment of upload.