# Agent brief — CFS page reconcile/build (overnight 2026-06-17)

You are reconciling (or building) ONE CFS page to its Figma design. Read these FIRST:
1. `/home/mrwick/coding/fs/cfs/.claude/skills/reconcile-section/SKILL.md` — the LAW.
   Follow it exactly (coordinate measurement, never eyeball screenshots; verify hover
   FIRES; mobile is a separate structure; shared components must use canonical class+hooks).
2. `/home/mrwick/coding/fs/cfs/CLAUDE.md` — project conventions (Tailwind CDN only, bare
   `<p>` tags, dynamic tabs, font rules).
3. The figma-connect MCP is already prepared (file key R6EY4TpNCvVqUEikM7Lof9, "CFS (Copy)").
   Use `get_node` / `get_implementation_context` / `get_node_outline` / `get_screenshot_to_disk`
   / `get_variant_set` / `get_image_to_disk`. Tools are deferred — load via ToolSearch
   `select:mcp__figma-connect__get_node,...` before calling.

## Environment
- Preview server already running: `http://localhost:8778/html/<page>.html` (no-cache).

### Browser QUEUE — MANDATORY (3 engines run in parallel; you must mutex)
There are THREE single-instance Chromium browsers. Other agents may be running at the same
time. You MUST acquire a slot before any rendering/measurement and release it when done, or
you will corrupt another agent's page state. The lock is a race-free atomic `mkdir`.
```bash
Q=/home/mrwick/coding/fs/cfs/tools/browser-queue
SLOT=$(bash $Q/acquire.sh "<your-agent-name>")   # blocks until free; prints: browse|playwright|chrome
echo "got slot: $SLOT"
# ... do ALL your browser work on the engine named by $SLOT (cheat sheet below) ...
bash $Q/release.sh "$SLOT" "<your-agent-name>"   # release at the very end (and if you abort)
```
Hold ONE slot for your whole run. Use the engine that `$SLOT` names:

- **`browse`** (gstack CLI): `B="$HOME/.claude/skills/gstack/browse/dist/browse"`
  - viewport: `$B viewport 1440x2000` (mobile `$B viewport 393x852`)
  - navigate: `$B goto "http://localhost:8778/html/<page>.html"`
  - measure: `$B js "(()=>{ ...return JSON.stringify(...) })()"`  · hover: `$B hover "<sel>"`
- **`playwright`** (MCP): load tools via ToolSearch `select:mcp__plugin_playwright_playwright__browser_navigate,mcp__plugin_playwright_playwright__browser_resize,mcp__plugin_playwright_playwright__browser_evaluate,mcp__plugin_playwright_playwright__browser_hover`
  - viewport: `browser_resize(width,height)` · navigate: `browser_navigate(url)`
  - measure: `browser_evaluate({function:"() => { ... return JSON.stringify(...) }"})` · hover: `browser_hover`
- **`chrome`** (Chrome DevTools MCP): load via `select:mcp__plugin_chrome-devtools-mcp_chrome-devtools__navigate_page,mcp__plugin_chrome-devtools-mcp_chrome-devtools__emulate,mcp__plugin_chrome-devtools-mcp_chrome-devtools__evaluate_script,mcp__plugin_chrome-devtools-mcp_chrome-devtools__hover`
  - viewport: `emulate({viewport:"1440x2000x1"})` (mobile `emulate({viewport:"393x852x1,mobile,touch"})`) — do NOT use `resize_page` (errors on maximized window)
  - navigate: `navigate_page({type:"url",url})` · measure: `evaluate_script({function:"() => { ... return JSON.stringify(...) }"})` · hover: `hover`

All three are Chromium, so `getBoundingClientRect`/`getComputedStyle` numbers are equivalent.
- Git identity is already set to personal (Arjun KR <arjunkrishnaraj123@gmail.com>). COMMIT
  per section or per logical group; do NOT batch the whole page into one commit (checkpoints
  guard against the file-corruption risk noted in the skill). Commit messages end with the
  Co-Authored-By trailer the global CLAUDE.md specifies.

## Method (per section, desktop then mobile)
1. Pull section IR. Build a compact per-element table: bbox x/y/w/h, fill hex, stroke
   hex+weight, corner radius, and per-RUN text (fontFamily, size, weight, case, decoration,
   letterSpacing, color). READ fontFamily + textCase PER NODE — reused components keep their
   own typography (Lato vs Poppins; TITLE-case). Iterate ALL runs, never just runs[0].
2. Measure OUR render (getBoundingClientRect + getComputedStyle), normalize px→Figma px
   via scale = FIGMA_W / measured-section-width. Compare numbers.
3. Fix clear mismatches (size/weight/family/case/color/spacing/radius/dimensions/order).
   Position by Figma coordinates. `<p>` stays BARE — typography on the wrapper or a cms-* class.
4. Hover/interaction: find the component's hover variant via reactions → get_variant_set →
   diff default vs hover per element (per-run for text); wire each delta; then TRIGGER the
   hover in `$B hover <sel>` and read computed style to PROVE it fires. A shared hover class
   is not proof.
5. Mobile: pull the MOBILE frame IR separately. It is often a DIFFERENT structure (stacking,
   pills vs grid, colour flips, font-size flips) — build `lg:hidden` mobile + `hidden lg:…`
   desktop blocks where structure differs. Measure at 393px.

## Deliverables
- Edit `/home/mrwick/coding/fs/cfs/html/<page>.html` (and `css/custom.css` if a hover/clamp
  rule is needed). Keep `<p>` bare.
- Append a detailed section to `/home/mrwick/coding/fs/cfs/docs/2026-06-17-reconcile-accuracy.md`
  under the page's heading: per-section measured-vs-Figma deltas, what you fixed, residuals,
  and any deliberate deviation / client question (e.g. an occluded element, an ambiguous variant).
- Commit your work.
- Return a CONCISE summary (sections done, key fixes, open questions) — NOT a file dump.

## Hard rules (from global CLAUDE.md — non-negotiable)
- NEVER eyeball a screenshot to derive a measurement. Coordinates from IR + DOM only.
- State facts as facts, hypotheses as hypotheses.
- Don't claim done without measured proof. If something can't be verified, say so — don't fake it.
