# Malin Avatar — Control-Layer Expression Pack (`v1_control_layer`)
**Author: Calypso · 6/5 · For Hermes to render on the 5090 → composite into the FC renderer**

Goal: get her face **past blink**. The blink set already exists (`neutral_warm` / `eyes_half` / `eyes_closed`). This pack adds the **mouth** and **brow** layers so the renderer can show real expressions and mouth-move when she speaks.

**Breadth-first minimum — 4 layers, not the full matrix:** 2 mouth + 2 brow. Composited onto the base + eye layer, these already give warmth, talking, engagement, and focus. Don't render the whole 21-layer set before this proves she feels alive.

---

## Method — REGION-INPAINT from `neutral_warm.png` (the PROVEN recipe, same as the blink set)

Do **NOT** txt2img whole new faces (that drifts the head + breaks compositing — already disproven). Instead, for each layer:

1. Load `C:\malin\avatar_assets\v1\eyes\neutral_warm.png` as the inpaint base.
2. Mask **only the target region** (mouth OR brows — see per-layer mask below).
3. Inpaint with the base prompt + the region delta, denoise **inside the mask only**.
4. Composite the result back onto `neutral_warm.png` so **only the masked region changes** — everything else stays pixel-identical → the layer drops straight into the renderer aligned.

This is the exact method that gave clean blink layers (`eyes_closed` @ denoise 0.95, `eyes_half` @ 0.80, mask = eyes only, composite back onto base).

**Disjoint masks (critical for compositing):** the **brow** mask must NOT touch the eyes (the blink layer owns the eyes) and the **mouth** mask must not touch brows/eyes. Keep all three regions non-overlapping so `base + eye + brow + mouth` compose without fighting.

---

## Base positive (reuse — identity/framing locked; region delta drops into `[DELTA]`)
```
photorealistic photograph, head-and-shoulders portrait of a beautiful mature adult woman in her late twenties, facing camera straight on, head upright and centered, [DELTA], long flowing vibrant orange-red ginger hair with warm coppery highlights, voluminous soft loose waves, wispy face-framing strands, vivid green eyes, fair skin with subtle warm undertones and delicate freckles, defined feminine cheekbones, soft pink full lips, mature adult face age 25 to 30, natural eye makeup, even soft frontal studio lighting, plain solid neutral grey background, photorealistic detailed skin texture, raw photo, dslr quality
```

## Base negative (same for all 4)
```
head tilt, tilted head, looking away, profile, side view, three-quarter view, turned head, off-center, hands, fingers near face, (young face, child face, teen face, baby face, doll face:1.7), (anime face, cartoon, illustration, chibi, 2d, cel shaded:1.5), (plastic skin, doll-like skin, cgi, 3d render, fake looking:1.4), child, underage, deformed face, bad anatomy, blurry, lowres, worst quality, (multiple faces, two people:1.5), wrong eye color, brown eyes, blue eyes, harsh shadows, (increased freckles, heavy freckles, dense freckles, freckle clusters, more freckles, freckled forehead:1.3)
```

**🔴 FRECKLE GUARD (Jun, 6/5 — applies to every Malin re-render):** keep freckles at the *anchor's* delicate density — Jun likes where she sits aesthetically in the original photo; do NOT let the re-render amplify them. Because we inpaint a region and composite back, the base skin is untouched — the only risk is the inpainted **patch** rendering denser freckles than the surrounding base, which reads as a seam. Mitigate: (1) "delicate freckles" stays un-emphasized in the prompt (never weighted up); (2) the negative above suppresses density gain; (3) **feather the mask edges** so freckle density blends rather than steps; (4) favor the **low end of the denoise range** on the brow/forehead layer (most skin shows there). Match the patch to the base — don't reinvent the skin.

---

## The 4 layers

| layer file | region mask | `[DELTA]` (drop into base positive) | denoise | reject | renderer use |
|---|---|---|---|---|---|
| `mouths/soft_smile.png` | mouth only (lips + philtrum + chin-top, corner to corner) | `gentle warm closed-mouth smile, soft lifted lip corners, relaxed natural lips` | ~0.80 | toothy grin, laughing, open mouth, smirk (one-sided) | idle warmth, "amused/affectionate" |
| `mouths/talk_open.png` | mouth only (same mask) | `mouth open mid-speech, lips parted naturally as if mid-sentence, slight natural glimpse of teeth, relaxed jaw` | ~0.90 | wide-open, yawn, scream, tongue out, exaggerated, distorted lips | speech frames (alternate with neutral/soft_smile while she talks) |
| `brows/brow_lift.png` | both brows + forehead skin just above + glabella (NOT eyes) | `eyebrows raised, open engaged interested look, lifted brows` | ~0.70 | shock/surprise, one brow only, heavy forehead wrinkles | "engaged / warm / playful" |
| `brows/brow_furrow.png` | same brow mask | `brows drawn lightly together in focus, gentle concentration, subtle furrow between the brows` | ~0.70 | angry scowl, deep frown lines, aggression, sad | "thoughtful / focused" |

---

## Output
```
C:\malin\avatar_assets\v1\mouths\soft_smile.png
C:\malin\avatar_assets\v1\mouths\talk_open.png
C:\malin\avatar_assets\v1\brows\brow_lift.png
C:\malin\avatar_assets\v1\brows\brow_furrow.png
```
Keep `neutral_warm.png` as the canonical "mouth-neutral / brow-neutral" — i.e. the absence of a mouth/brow overlay = neutral. So the layer enums are: mouth ∈ {neutral, soft_smile, talk_open}, brow ∈ {neutral, lift, furrow}, eye ∈ {open, half, closed}.

## Composition → expression matrix (few layers, many faces)
The renderer composites `base + eye + brow + mouth`. Examples:
- **warm idle:** eye open · brow neutral · mouth soft_smile
- **speaking:** eye open · brow neutral · mouth alternating neutral↔talk_open
- **amused:** eye open · brow lift · mouth soft_smile
- **thinking:** eye open (slow) · brow furrow · mouth neutral
- **listening/blink:** eye half↔closed cycle · brow neutral · mouth neutral

That's already a believable "alive" range out of 3 mouth + 3 brow + 3 eye states. The performance router (Calypso, in malin.py) picks the {eye,brow,mouth} triple per turn from her `[PERFORM: emotion intensity]` tag and writes it to the state the renderer reads.

## QA bar (my gate)
On-model Malin every layer (copper waves, freckles, green eyes, late-20s). Region change ONLY — if the head shifts or anything outside the mask moves, the composite breaks; re-mask tighter and re-inpaint. `talk_open` must read as *speaking*, not a goofy/exaggerated cartoon mouth.
