---
phase: 10-expanded-field-types-end-to-end
plan: 03
type: execute
wave: 2
depends_on:
  - 10-01
  - 10-02
files_modified:
  - teressa-copeland-homes/src/app/sign/[token]/_components/SigningPageClient.tsx
  - teressa-copeland-homes/src/app/sign/[token]/_components/SignatureModal.tsx
autonomous: false
requirements:
  - FIELD-01
  - FIELD-02
  - FIELD-03
  - FIELD-04

must_haves:
  truths:
    - "Client sees only interactive overlays (blue for signature, purple for initials) — no clickable overlays for text/checkbox/date fields"
    - "Clicking an initials overlay opens the signature modal with an 'Add Initials' title"
    - "Initials fields count toward the signing progress total (along with client-signature fields)"
    - "Submit button requires ALL initials AND signatures to be completed before enabling"
    - "Signed PDF embeds initials images at the correct field coordinates"
    - "Text/checkbox/date fields are already baked into the prepared PDF and require no client interaction"
    - "A full round-trip (place all 4 types + prepare + send + sign) succeeds without errors"
  artifacts:
    - path: "teressa-copeland-homes/src/app/sign/[token]/_components/SigningPageClient.tsx"
      provides: "Initials modal support; non-interactive field overlay suppression; updated progress counting"
      contains: "initials.*getFieldType"
    - path: "teressa-copeland-homes/src/app/sign/[token]/_components/SignatureModal.tsx"
      provides: "Optional title prop so initials modal shows 'Add Initials' instead of 'Add Signature'"
      contains: "title.*prop"
  key_links:
    - from: "handleFieldClick"
      to: "setModalOpen(true)"
      via: "getFieldType check allows both client-signature AND initials"
      pattern: "client-signature.*initials.*setModalOpen"
    - from: "SigningProgressBar total"
      to: "signatureFields.filter"
      via: "filter includes both client-signature and initials types"
      pattern: "client-signature.*initials.*length"
    - from: "handleSubmit completeness check"
      to: "requiredFields.length"
      via: "requiredFields filters to client-signature + initials"
      pattern: "requiredFields.*filter.*client-signature.*initials"
---

<objective>
Extend `SigningPageClient.tsx` to handle the initials field type in the signing flow: open the signature modal for initials fields, suppress non-interactive overlays for text/checkbox/date fields, and count initials fields in the signing progress. Add an optional `title` prop to `SignatureModal.tsx` so the initials modal displays "Add Initials" instead of "Add Signature". Close the phase with a human verification checkpoint covering all four new field types end-to-end.

Purpose: After Plans 01 and 02, all field types can be placed and embedded correctly. This plan makes the client-facing signing experience correct — initials are captured, non-interactive fields are invisible to the client, and the submit gate accounts for all required fields.
Output: Updated `SigningPageClient.tsx` and `SignatureModal.tsx`; human verification checkpoint confirming the full four-field-type round-trip.
</objective>

<execution_context>
@/Users/ccopeland/.claude/get-shit-done/workflows/execute-plan.md
@/Users/ccopeland/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/10-expanded-field-types-end-to-end/10-RESEARCH.md
@.planning/phases/10-expanded-field-types-end-to-end/10-01-SUMMARY.md
@.planning/phases/10-expanded-field-types-end-to-end/10-02-SUMMARY.md

<interfaces>
<!-- Key types and current state of files to be modified. -->

From teressa-copeland-homes/src/lib/db/schema.ts:
```typescript
export type SignatureFieldType =
  | 'client-signature' | 'initials' | 'text' | 'checkbox' | 'date' | 'agent-signature';

export function getFieldType(field: SignatureFieldData): SignatureFieldType {
  return field.type ?? 'client-signature';
}
export function isClientVisibleField(field: SignatureFieldData): boolean {
  return getFieldType(field) !== 'agent-signature';
}
```

Current SigningPageClient.tsx key behaviors (to be updated):
```typescript
// handleFieldClick — currently only allows client-signature:
if (getFieldType(field) !== 'client-signature') return;

// handleSubmit completeness check — currently only client-signature:
const clientSigFields = signatureFields.filter(
  (f) => getFieldType(f) === 'client-signature'
);
if (signedFields.size < clientSigFields.length || submitting) return;

// SigningProgressBar total — currently only client-signature:
total={signatureFields.filter((f) => getFieldType(f) === 'client-signature').length}

// Field overlay render — currently renders ALL fields from signatureFields as clickable overlays
// (server GET filter excludes agent-signature but includes text/checkbox/date)
// After Plan 02 these non-interactive fields are embedded in the prepared PDF
// but still come back from the server — the signing page must NOT render them as overlays
```

Current SignatureModal.tsx header (to add title prop):
```typescript
// Line 115:
<h2 style={{ color: '#1B2B4B', margin: 0, fontSize: '18px' }}>Add Signature</h2>
```

Current SignatureModal props:
```typescript
interface SignatureModalProps {
  isOpen: boolean;
  fieldId: string;
  onConfirm: (fieldId: string, dataURL: string, save: boolean) => void;
  onClose: () => void;
}
```
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: Add title prop to SignatureModal and extend signing page for initials + overlay filtering</name>
  <files>
    teressa-copeland-homes/src/app/sign/[token]/_components/SignatureModal.tsx
    teressa-copeland-homes/src/app/sign/[token]/_components/SigningPageClient.tsx
  </files>
  <action>
**SignatureModal.tsx — add optional title prop:**

Update `SignatureModalProps` to include an optional `title` prop:
```typescript
interface SignatureModalProps {
  isOpen: boolean;
  fieldId: string;
  onConfirm: (fieldId: string, dataURL: string, save: boolean) => void;
  onClose: () => void;
  title?: string;  // defaults to "Add Signature"
}
```

Update the function signature:
```typescript
export function SignatureModal({ isOpen, fieldId, onConfirm, onClose, title = 'Add Signature' }: SignatureModalProps) {
```

Update the hardcoded header text to use the prop:
```typescript
// Replace: <h2 ...>Add Signature</h2>
<h2 style={{ color: '#1B2B4B', margin: 0, fontSize: '18px' }}>{title}</h2>
```

Also update the "Apply Signature" confirm button text to be dynamic. When the title is "Add Initials", the button should say "Apply Initials". Add a derived `buttonLabel`:
```typescript
// Derive button label from title — "Add Initials" → "Apply Initials", otherwise "Apply Signature"
const buttonLabel = title.startsWith('Add ') ? title.replace('Add ', 'Apply ') : 'Apply Signature';
```
Replace the hardcoded "Apply Signature" button text with `{buttonLabel}`.

No other changes to SignatureModal — canvas, tabs, signature_pad wiring, save behavior all remain identical.

**SigningPageClient.tsx — three targeted changes:**

**Change 1: Track active field type for modal title.**
Add state for the active field type:
```typescript
const [activeFieldType, setActiveFieldType] = useState<'client-signature' | 'initials'>('client-signature');
```

**Change 2: Update `handleFieldClick` to open modal for both client-signature and initials:**
```typescript
const handleFieldClick = useCallback(
  (fieldId: string) => {
    const field = signatureFields.find((f) => f.id === fieldId);
    if (!field) return;
    const ft = getFieldType(field);
    // Only client-signature and initials require client action
    if (ft !== 'client-signature' && ft !== 'initials') return;
    if (signedFields.has(fieldId)) return;
    setActiveFieldId(fieldId);
    setActiveFieldType(ft as 'client-signature' | 'initials');
    setModalOpen(true);
  },
  [signatureFields, signedFields]
);
```

**Change 3: Update handleSubmit, handleJumpToNext, SigningProgressBar, and field overlay rendering.**

`handleSubmit` — replace `clientSigFields` filter with `requiredFields`:
```typescript
const requiredFields = signatureFields.filter(
  (f) => getFieldType(f) === 'client-signature' || getFieldType(f) === 'initials'
);
if (signedFields.size < requiredFields.length || submitting) return;
```

`handleJumpToNext` — update to jump to next unsigned REQUIRED field:
```typescript
const nextUnsigned = signatureFields.find(
  (f) => (getFieldType(f) === 'client-signature' || getFieldType(f) === 'initials') && !signedFields.has(f.id)
);
```

`SigningProgressBar total` — update to count both types:
```typescript
total={signatureFields.filter(
  (f) => getFieldType(f) === 'client-signature' || getFieldType(f) === 'initials'
).length}
```

**Field overlay rendering — suppress non-interactive fields:**
In the `fieldsOnPage.map((field) => {...})` section, add an early return for non-interactive field types. Text, checkbox, and date fields are already baked into the prepared PDF — they must NOT render as clickable overlays on the signing page.

Add this check at the top of the field map callback (before computing `isSigned` and `overlayStyle`):
```typescript
// Only render interactive overlays for client-signature and initials fields
// text/checkbox/date are embedded at prepare time — no client interaction needed
const ft = getFieldType(field);
const isInteractive = ft === 'client-signature' || ft === 'initials';
if (!isInteractive) return null;
```

**Update overlay visual distinction for initials vs signature:**
After the `isInteractive` check (and before the existing `isSigned` / `overlayStyle` computation), add a `fieldColor` variable and update the `aria-label`:
```typescript
const isSigned = signedFields.has(field.id);
const overlayStyle = {
  ...getFieldOverlayStyle(field, dims),
  // Initials: purple pulse; signature: blue pulse (uses CSS animation-name override)
};
```

For the initials color differentiation, add a `<style>` injection alongside the existing `pulse-border` keyframes for a purple variant:
```css
@keyframes pulse-border-purple {
  0%, 100% { box-shadow: 0 0 0 2px #7c3aed, 0 0 8px 2px rgba(124,58,237,0.4); }
  50% { box-shadow: 0 0 0 3px #7c3aed, 0 0 16px 4px rgba(124,58,237,0.6); }
}
```

Apply `animation: 'pulse-border-purple 2s infinite'` to initials field overlays and `animation: 'pulse-border 2s infinite'` to signature field overlays. Update `getFieldOverlayStyle` to accept a field type parameter, or add an `animation` property override after the call:
```typescript
const baseStyle = getFieldOverlayStyle(field, dims);
const animationStyle: React.CSSProperties = ft === 'initials'
  ? { animation: 'pulse-border-purple 2s infinite' }
  : { animation: 'pulse-border 2s infinite' };
const fieldOverlayStyle = { ...baseStyle, ...animationStyle };
```

Update the overlay div to use `fieldOverlayStyle` and update `aria-label`:
```typescript
aria-label={ft === 'initials'
  ? `Initials field${isSigned ? ' (initialed)' : ' — click to initial'}`
  : `Signature field${isSigned ? ' (signed)' : ' — click to sign'}`}
```

**Update SignatureModal usage** to pass the title prop:
```typescript
<SignatureModal
  isOpen={modalOpen}
  fieldId={activeFieldId ?? ''}
  title={activeFieldType === 'initials' ? 'Add Initials' : 'Add Signature'}
  onConfirm={handleModalConfirm}
  onClose={() => {
    setModalOpen(false);
    setActiveFieldId(null);
  }}
/>
```
  </action>
  <verify>TypeScript compiles: `cd /Users/ccopeland/temp/red/teressa-copeland-homes && npx tsc --noEmit 2>&1 | head -30`</verify>
  <done>TypeScript compiles clean; SignatureModal accepts optional title prop; SigningPageClient only renders interactive overlays for client-signature and initials; initials modal shows "Add Initials" title; progress bar counts both types; submit gate requires all required fields</done>
</task>

<task type="checkpoint:human-verify" gate="blocking">
  <name>Task 2: Human verification — all four field types end-to-end</name>
  <what-built>
Full Phase 10 implementation across all three plans:
- Plan 01: FieldPlacer palette extended with 5 typed tokens (Signature, Initials, Checkbox, Date, Text)
- Plan 02: preparePdf() renders each field type distinctly; POST handler filter + date stamp at sign time
- Plan 03: SigningPageClient initials capture; non-interactive overlay suppression; updated progress counting

The complete end-to-end flow for all four new field types is now implemented.
  </what-built>
  <how-to-verify>
Run `npm run dev` in `/Users/ccopeland/temp/red/teressa-copeland-homes` and verify:

**Step 1 — FieldPlacer palette:**
1. Open any document in the portal (e.g. /portal/documents/[docId])
2. Confirm the palette shows 5 tokens with distinct colors: Signature (blue), Initials (purple), Checkbox (green), Date (amber), Text (slate)
3. Drag each token — confirm the drag ghost shows the correct label and color
4. Drag a Checkbox token — confirm the ghost is small (square) with no text label
5. Drop all 5 token types onto the PDF — confirm each placed overlay shows the correct label and color

**Step 2 — Prepare pipeline (all 4 new types):**
1. With at least one each of Checkbox, Date, Initials, and Text fields placed, click "Prepare and Send"
2. Download the prepared PDF and open it in any PDF viewer
3. Verify: Checkbox field shows a bordered box with X diagonals
4. Verify: Date field shows an amber placeholder rectangle labeled "Date" (not the actual date yet — that stamps at sign time)
5. Verify: Initials field shows a purple bordered rectangle labeled "Initials"
6. Verify: Text field shows a light gray background rectangle
7. Verify: Signature field (if any placed) shows the blue "Sign Here" rectangle as before

**Step 3 — Signing page (initials + overlay suppression):**
1. Open the signing link (email or copy from prepare flow)
2. Confirm: Only Signature (blue pulse) and Initials (purple pulse) overlays are clickable — no overlay visible over checkbox/date/text areas
3. Click an Initials overlay — confirm the modal opens with "Add Initials" title and "Apply Initials" button
4. Draw initials and apply — confirm the initials overlay shows a preview image and turns green
5. Confirm the progress bar counts both signature and initials fields in the total
6. Complete all signature and initials fields — confirm the Submit button enables
7. Submit and confirm redirect to the confirmed page

**Step 4 — Post-signing PDF verification:**
1. Download the signed PDF from the agent portal
2. Open it and verify:
   - Initials image is embedded at the initials field position
   - Checkbox still shows the X mark (from prepare time)
   - Date field shows the actual signing date (e.g. 03/21/2026) — NOT the placeholder
   - Signature image is embedded at the signature field position
   - Text field shows the light background rectangle (text fill content from textFillData if any)
  </how-to-verify>
  <resume-signal>Type "approved" when all 4 steps pass, or describe which verification failed</resume-signal>
  <action>Run the dev server and execute the 4-step verification outlined in how-to-verify above.</action>
  <verify>All 4 steps pass and human types "approved"</verify>
  <done>Full end-to-end round-trip confirmed: all four field types place, prepare, and sign correctly</done>
</task>

</tasks>

<verification>
TypeScript: `cd /Users/ccopeland/temp/red/teressa-copeland-homes && npx tsc --noEmit`

Then proceed to the human verification checkpoint above.
</verification>

<success_criteria>
- SignatureModal renders with "Add Initials" title and "Apply Initials" button when mode is initials
- SigningPageClient.tsx renders zero overlays for text/checkbox/date fields
- Initials fields open the modal and produce an embeddable dataURL
- Progress bar total = count of (client-signature + initials) fields
- Submit gate requires all (client-signature + initials) fields completed
- Full round-trip test: place all 4 new field types + prepare + sign → produces correct PDF
- Human verification approved
- TypeScript compiles without errors
</success_criteria>

<output>
After completion, create `.planning/phases/10-expanded-field-types-end-to-end/10-03-SUMMARY.md` following the summary template.
</output>
