# city-individual — gated reconcile (coord-diff gate)

Agent: city-gate · browser slot: browse · 2026-06-18
Figma frames: desktop **3121:22150**, mobile **3121:21144** (file key R6EY4TpNCvVqUEikM7Lof9)
Gate: `tools/coord-diff.py --tol 6 --vtol 8`. A section is done when the gate is CLEAN or every
remaining line has a documented reason.

Page was previously marked DONE in the runbook; this is an independent objective-gate verification pass.

---

## DESKTOP

### Hero (3121:22164) — node 3121:22164
**Real fix:** hero photo asset (`city-mumbai-gateway.png`) was a **Zudio storefront / CFS building**,
NOT the **Gateway of India** the Figma fill (`gateway-india`, hash 32c6b8c) shows. Extracted the real
fill (EXIF: "Gateway of India … Mumbai, India"), replaced png→jpg, removed the wrong png.

Final gate residuals (all explained):
- MISSING "Contact Number" / EXTRA "Mobile Number" — placeholder text is not DOM `textContent` (gate
  blind spot); our input placeholder = "Contact Number" (matches Figma). "Mobile Number" is the
  intentional sr-only a11y label. Not a defect.
- VIS-SIZE/VIS-POS image (figma 590x393 @889,51 vs dom 400x419 @980,0) — Figma photo node is oversized
  and clipped by the rounded navy card; our 400x419 fill is the visible region. Authoring artifact.
- "+91" Δx-8 — prefix glyph centering, sub-meaningful.
- "Eye Hospital in Mumbai" Δy-21 — Figma GROUP bbox inflated to 440 by overflow rects (visible region
  419); internal heading-to-card-top offset is exact (18px both sides).
- "Request a Callback" Δx-210 — full-width `text-center` button; gate reads element x vs Figma's
  centered text-node x. Not a defect.

### Breadcrumb (3121:22222) + About (3121:22183) — verified by direct measurement
Both small/trivial; gated by computed-style read against IR:
- Breadcrumb: "Home" Poppins Light 15px −4% (−0.6px) #000; current Poppins Light 15px #636262;
  capitalize (=TITLE). Matches. Kept the semantic crumb split (documented EXTRA-allowed); Figma
  "Arrow 13" is a 1x0 hairline (gate skips <2px).
- About: Poppins Light 20px, **justify**, capitalize (=TITLE), #2b286f, width 1380. Exact match.

### Centres grid (3121:22185) — node 3121:22185
**Real fix:** centre-card phone icon 14→18px (Figma Phone fill 18x18).
Centre-card hover VERIFIED firing (browse hover + computed style): name → underline; book-arrow
expands to 7px; phone circle bg → #2b286f; phone path fill → #fff.

Final gate residuals (all explained):
- MISSING "Centre Name"/"City Name"/"Book an Appoinment" vs EXTRA "Chembur"/"Mumbai"/"Book an
  Appointment" — Figma uses generic placeholder strings; we render real Mumbai-centre CMS content.
  Correct content substitution.
- VIS-MISSING "Gurgaon 2"/"Gurgaon 4" (2 per card) — each Figma card stacks 3 identical image fills
  (Gurgaon 1/2/4); we render one `<img>`. Overlapping authoring duplicates.
- VIS-SIZE "Gurgaon 1" 421 vs 439 + VIS-POS Δx — Figma card grid is 1319 wide (23px inset each side),
  we run the grid full container-inner (1380), consistent with every other section on the page.
  Deliberate width deviation (3 cols × 439 vs Figma 421). Image height 207 matches exactly.
- "Centres in Mumbai" Δx-448 — `text-center` h2; gate reads element x vs centered Figma text x.
- VIS-EXTRA svg 0x12 — the collapsed book-arrow SVG (width 0 until hover).

### Specialties accordion (3121:22202) — node 3121:22202
**Fixes:** active-panel body gap `lg:mt-[20px]`→`[8px]` (Figma heading→body gap 8px);
accordion top gap `lg:mt-[26px]`→`[14px]` (Figma title→accordion gap 14px). After both, active
heading + body POS fall within tolerance.
Tab-switch interaction VERIFIED (browse click): click Glaucoma → glaucoma `data-active=true`, retina
→ false, glaucoma panel expands 92→1012px. Strip labels Poppins Light 36px capitalize (=TITLE) — exact.

Final gate residuals (all explained):
- EXTRA (13×) — inactive accordion panels' headings/bodies are `display:none`; the DOM dumper still
  emits their text (at 0,0). Hidden tab content, correct.
- POS (5×) rotated strip labels — labels are `rotate-[-90deg]`; the gate compares our rotated bbox
  (centered in the 636px strip) to Figma's pre-rotation tall-thin text box → large Δy. Rotation
  measurement artifact; font/size/color/case all match.
- "Specialties Available" Δx-439 — `text-center` h2 vs centered Figma text x.

### Doctor cards (3121:22205) — node 3121:22205
Identity audit: page uses canonical `.doctor-card` + `__loc-bar`/`__city`/`__image` hooks (4× each
desktop) — canonical component, not a fork.
**Fix:** desktop grid had `mt:0` to the heading; Figma heading→grid gap is 28px. Added `lg:mt-[28px]`,
which collapsed a uniform card-text Δy of −21..−34px down to +3..+7 (within/near tolerance).
Hover VERIFIED firing on the real desktop card (`.city-doctors ul.lg:grid li:first-child article`):
pill #d9d9d9→#ffcb05, city black→#2b286f, image scale(1.13). (First hover attempt mis-targeted the
hidden mobile card — that list is also under `.city-doctors ul`; scoped to `ul.lg:grid`.)

Final gate residuals (all explained):
- Names Δy+7 (1px over tol) — name's own top gap; not chased.
- "Book An Appointment" Δx-74, "Load More" Δx-39, "Eye Care Specialists" Δx-444 — full-width
  `text-center` elements; gate reads element x vs Figma centered text x.
- First chip "Retina & Uvea"/"Cataract" Δx-7/-8 — chip text left padding (px-2 ≈ 8px).
- VIS-SIZE/VIS-POS images (159x237 / 200x227 / 329x290 vs our 312x227) — per-card Figma photo crops
  differ (male card full-bleed 329-wide, lady cards inset 159-200); we use uniform 312x227
  object-cover. Documented per-card framing difference (CMS photos).
- VIS-SIZE icon g2505 20x22 vs 10x14 — Figma location-pin icon larger; ours is the smaller pin glyph
  inside the d9d9d9 pill. Minor.
- VIS-EXTRA 0x0 @-3077 — the hidden mobile card list (display:none) leaking into the dump.

### FAQ (3121:22215) — node 3121:22215
**Fixes:** chevron 24x24→`w-10 h-[37px]` (Figma "Expand Arrow" box 40x37 — extracted the fill,
hash d62e490; it's the same downward chevron glyph, just larger); row summary `py-5`→`py-4` (row
77→69px to match Figma h69, fixes progressive Δy drift); summary `px-6`→`pl-[15px] pr-6` (Figma arrow
inset 15px / text x69, was 24/80). After fixes all arrow + question-text POS within tolerance.
Open/close interaction VERIFIED: `[open]` → chevron `transform: matrix(-1,0,0,-1,…)` (180° rotate).

Final gate residuals (all explained):
- EXTRA (3×) — collapsed `<details>` answer text (hidden until open). Correct.
- "Frequently Asked Questions" Δx-375 — `text-center` h2 vs centered Figma text x.

### Services strip (3121:22218) — verified by measurement
Heading "Cataract Surgery Services Across Mumbai" Poppins Light 50px capitalize centered #2b286f;
city-links row Poppins Light 20px leading-38 #2b286f. **Fix:** heading→links gap `lg:mt-[18px]`→`[5px]`
(Figma gap ~5px). Matches.

### Callback form (3124:58592) — node 3124:58592 (shared component)
Visible inputs verified: Poppins Light **19px** #919191 placeholders ("Full name"/"Mobile Number"),
r5 h40 (Figma r6 h42). Submit button 239×42, Poppins 20px, navy #2b286f bg / white text — matches
Figma exactly. Submit hover VERIFIED firing: `brightness(1.05)`, NO scale (correct for the navy CTA).

Final gate residuals (all explained):
- FONT "Full name"/"Mobile Number" 16/400 vs 19/300 + Δx — the gate matched our `<label class=sr-only>`
  (a11y label, 16px) by textContent, NOT the visible input; the real inputs are Poppins Light 19px
  (measured). Gate blind spot (placeholder text isn't DOM textContent).
- EXTRA "Submit" — our button has a mobile "Submit" / desktop "Book An Appointment" span pair; at
  desktop the "Submit" span is `lg:hidden`. Correct responsive label.
- POS uniform Δy+62..+87 / "Form 1" VIS-POS/VIS-SIZE — Figma `Form` frame origin includes the
  full-bleed bg band (image 1440x602 starting above); our `.callback-form` section adds vertical
  padding. Frame-vs-section origin offset; the card's internal layout matches.
- VIS-MISSING icon "0" 32x32 — duplicate arrow-icon group inside the Figma button instance; we render
  one. Authoring duplicate.

### Shared header / footer / sticky (desktop) — canonical components, verified identical
- 01-utility-bar, 02-main-nav, 16-sticky-bar: byte-for-byte identical to centre-individual's
  canonical reconciled markup (only `aria-current` page marker differs). Spot fonts: utility Lato 16px;
  nav links Poppins Light 15px; CTA Poppins Light 15px on #ffcb05. No fork.
- 15-footer (3121:48148): byte-for-byte identical to centre-individual canonical footer. Gate residuals
  are the established shared-footer artifacts:
  - MISSING "|" (8×) — Figma renders pipe separators as text glyphs; we use CSS `border-l` dividers.
  - POS link-row Δx variance + Δy-21/-20 — footer link row is `flex-wrap justify-center` (distributed)
    vs Figma fixed positions; action/phones rows offset by frame origin. Shared-component layout.
  - VIS-POS social/action icons (Δ≤18) — minor.
  - FONT "terms of use" decoration — we underline the copyright links (conventional); Figma plain.
  - **OPEN CLIENT QUESTION:** Figma footer link row includes an **"EWS"** link (between "Get In Touch"
    and "Planet Lasik") that the canonical site-wide footer omits. "EWS" abbreviation is ambiguous
    (Empanelment/Workshops/Schemes?). Not patched here — adding it to only this page would fork the
    shared footer. Needs a footer-wide decision + the full link label.

---

## MOBILE (393×852, frame 3121:21144)

document.documentElement.scrollWidth == 393 (no horizontal overflow).

### Mobile centres (3121:21174) — node 3121:21174
**Fixes:** mobile centre-card image height `h-[180px]`→`h-[207px]` (Figma mobile image is 294×207, same
207 as desktop — was wrongly 180); phone icon made responsive `w-[14px] h-[14px] lg:w-[18px] lg:h-[18px]`
(Figma mobile phone is **14×14**, desktop 18×18 — the desktop 18px fix had over-applied to mobile).
Verified: mobile phone 14×14, desktop phone 18×18. Heading "Centres In Mumbai" SemiBold 30px (matches).

Final gate residuals (all explained):
- VIS-SIZE "Gurgaon 1" 294 vs 361 — cards run full single-column width (≈361) vs Figma's 294 inset;
  height 207 now matches. Deliberate full-width deviation (page-consistent).
- VIS-MISSING "Gurgaon 4" + VIS-SIZE Phone 0x12 — overlapping image-fill duplicate / collapsed
  book-arrow SVG, as on desktop.
- MISSING/EXTRA placeholder-vs-real city content.

### Mobile doctor cards (3121:21191) — node 3121:21191
**Fix:** mobile card list `gap-[20px]`→`gap-[35px]` — Figma card pitch is 311px (276 card + 35 gap),
ours was 296 (20 gap) → 15px/card cumulative drift. After the fix, inter-card pitch matches and the
per-row Δy is uniform (no longer accumulating). Structure matches the documented mobile horizontal
pattern: photo LEFT 131px, location pill YELLOW #ffcb05 r3, exp bar navy h36, chips yellow.
Heading "Eye Care Specialists" Poppins SemiBold 35px capitalize centered #2b286f — matches.

Final gate residuals (all explained):
- POS uniform Δy≈−72 — Figma mobile heading wraps to 2 lines (h88) in its 343px box; ours fits one
  line (h39) at 393px `px-6`. Same font (SemiBold 35px); pure text-wrap height difference, not markup.
- POS content Δx+24 — card content starts at our `pl-[17px]` past the 131px photo (x164) vs Figma x140;
  photo width 131 vs Figma 120-130. Minor inset difference.
- Within-card row Δy variance — mobile-card internal vertical spacing (`pt-[28px]` etc.) vs Figma; minor.
- VIS-EXTRA 0x0 @-5557 / desktop grid leaking — the hidden desktop grid (display:none).
- VIS-SIZE/POS image (per-card crops) + g2505 pin — per-card photo framing + larger Figma pin, as desktop.

### Mobile specialties accordion (3121:21188) — node 3121:21188
Structurally different from desktop (vertical stacked header bars, as expected). **Fix:** mobile bar
heights `min-h-[64px]` → `min-h-[91px]` inactive + `group-data-[active=true]/spec:min-h-[78px]` active
(Figma: active navy bar 78px, inactive bars 91px — ours were all 64). Verified: active 78 / inactive 91.
Bar colors descending blues #2b286f/#3a3692/#4641b4/#514cd0/#5b54eb correct; labels Poppins Light 18px.
Tab-switch verified (click cataract → active, retina → inactive).

### Mobile FAQ (3121:21325) — node 3121:21325
**Fixes:** chevron responsive `w-[15px] h-[23px] lg:w-10 lg:h-[37px]` (Figma mobile arrow 15×23,
desktop 40×37 — the desktop 40×37 had over-applied to mobile); summary `py-4`→`py-[10px] lg:py-4`
(mobile row h44 vs Figma 44 — was ~69/80); row gap `space-y-3`→`space-y-[9px]` mobile (Figma 9px).
After fixes mobile rows = 44px, chevron 15×23 mobile / 40×37 desktop verified, drift eliminated
(arrow Δy now uniform −11). Question text Poppins Light 15px (matches).

Final residuals: uniform arrow Δy−11 + title Δx−9 — heading wraps to 2 lines (Figma h82) vs ours;
top-gap + centered-text-vs-element-x. Within reason.

### Mobile services strip / callback / footer — shared, verified
- Services strip (3121:21328): heading SemiBold 30px + city-links Poppins Light, full width. Shared
  layout; verified renders (the desktop `lg:mt-[5px]` fix carries; mobile uses base `mt-4`).
- Callback form (3121:21331): canonical shared component; card is `h-auto` on mobile per the rule
  (no fixed height — `lg:min-h-[439px]` is desktop-only). Submit hover verified earlier.
- Footer (3121:21347): canonical shared footer (byte-identical to centre-individual); mobile stacked
  layout. Same EWS open question as desktop.

---

## SUMMARY

Gated reconcile complete, desktop + mobile, all sections top-to-bottom. No horizontal overflow at
either breakpoint (1440 / 393). All interactive states verified firing by computed style:
centre-card hover (name underline / arrow expand / phone navy+white), doctor-card hover (pill→yellow /
city→navy / image scale 1.13), specialties accordion tab-switch (desktop + mobile), FAQ open chevron
rotate, callback submit hover (brightness, no-scale).

### Real fixes applied
1. **Hero photo** was a Zudio storefront — replaced with the real Figma Gateway-of-India fill.
2. **Centre-card phone icon** 14→18px desktop; later made responsive (14 mobile / 18 desktop).
3. **Specialties accordion** active body gap 8px + top gap 14px.
4. **Doctor grid** heading→grid gap 28px (fixed a uniform −21..−34 card-text drift).
5. **FAQ** chevron 40x37 + extracted real expand-arrow fill; row 69px; left inset 15px; later made
   chevron + row-height responsive (15x23/h44 mobile, 40x37/h69 desktop).
6. **Services strip** heading→links gap 5px.
7. **Mobile centre-card image** 180→207px; phone icon responsive.
8. **Mobile doctor-card list gap** 20→35px (Figma pitch 311 — fixed cumulative drift).
9. **Mobile accordion bar heights** 78 (active) / 91 (inactive).
10. **Mobile FAQ** chevron 15x23, row h44, gap 9px.

### Real assets extracted
- `assets/images/city-individual/city-mumbai-gateway.jpg` (Gateway of India, hash 32c6b8c) — replaced wrong png.
- FAQ Expand-Arrow fill (hash d62e490) confirmed = same downward-chevron glyph → reproduced at Figma size.

### Residual classes (all documented above per section)
Placeholder-vs-real CMS content (MISSING/EXTRA), overlapping Figma image-fill duplicates, `text-center`
element-x vs Figma centered-text-x, full-width-vs-Figma-inset grid widths (deliberate, page-consistent),
rotated-strip-label bbox artifacts, sr-only-a11y-label vs placeholder gate blind spot, per-card photo
crop differences, mobile heading 2-line-wrap height differences.

### Open client questions
1. **Footer "EWS" link** — the Figma footer link row includes an "EWS" link (between "Get In Touch" and
   "Planet Lasik") absent from the canonical site-wide footer. Abbreviation ambiguous (Empanelment/
   Workshops/Schemes?). Needs a footer-wide decision + the full label before adding (would otherwise
   fork the shared footer used identically on every page).
2. **Centre grid width** — Figma frames the centre/doctor card grids in a 1319-wide inset block (23px
   each side); we run them full container-inner (1380), consistent with every other section. Confirm
   the full-width treatment is acceptable vs the Figma inset.
