17 · Data architectureThe cities hub composes from data/cities-tier-data.php (34 cities × 33 fields for the deep tier-1), data/cities-global.php (666 global-city graph), data/cities-expansion.php (top-N per country, 1,158 cities), data/cities-tier3.php (426 tier-3 additions, total 1,584). Helpers: ajg_cities_all(), ajg_cities_filter(), ajg_city_by_slug(). Single-file render via cities.php hub at root, individual city pages routed through city-template.php (Indian) or global-city-template.php (rest of world) under the front-controller pattern. Zero database, zero runtime API.
18 · Schema markupCollectionPage schema fires on the hub with ItemList of all cities; each city detail emits Place + AdministrativeArea + GeoCoordinates + ContainedInPlace (country) JSON-LD. BreadcrumbList walks Home → Cities → {Region} → {Country} → {City}. WebSite + SearchAction at the homepage cascades into the hub. The 32-point TOTALITY block emits TechArticle on top-20 cities. FAQPage on the hub answers 'how is the city directory built', 'how do I filter', 'what does each tier mean'.
19 · Internal linkingForward to /ftas/, /blocs/, /corridors/, /institutions/, /tools/landed-cost-calculator.php and /tools/living-cost-arbitrage.php. Outward from each city to adjacent cities (3-5 nearest by graph distance), to its country page, to its continent page. Cross-content injector pulls Library + ScopeScape matches on tokens 'city', 'urban', 'metro', 'cluster'. Link weaver hyperlinks all 1,584 city names automatically across the entire site.
20 · Page-speed postureThe hub renders <80ms server-side at p95. The grid uses CSS-grid with deferred image loading; no client-side framework, zero blocking JS. Critical CSS inlined; design-tokens.css deferred via media-swap pattern (per v149.4.6 PageSpeed-100-v6 fix). HTML payload <90KB pre-gzip for the full 1,584-city grid. Lighthouse Performance held at 95+ on mobile, 99+ on desktop as of v150.1.
21 · Mobile UXHub grid collapses to a single column at <640px with horizontal-scroll filter pills. Each city card is a 48-px tap target minimum (per SO #57); 16-px body type, 1.6 line-height. The 32-point TOTALITY block on city detail collapses to one cell per row on mobile with section-headers sticky. Footer factsheet cards reflow 2-up on phones, 4-up on tablets, 6-up on desktop.
22 · AccessibilityWCAG 2.1 AAA on body text contrast (per SO #11 strict palette: navy #0B2447 on white = 14.83:1). All filter controls have aria-label and aria-expanded. The 32-point TOTALITY block uses semantic article + section + heading hierarchy; cell tags are span with role="text". Skip-to-content link present. Focus rings honour the navy + gold combination at 3-px width per the unified-chrome accessibility-toolbar.
23 · SEO saturationEvery city URL emits unique title, meta-description, canonical, OG + Twitter card with city-specific image, JSON-LD per the schema_markup field, dateModified from the data file mtime, and a 1,200-word minimum body. Per SO #2 data-anchored SEO. The hub itself is canonical at /cities/ with rel=prev/next pagination across the four-tier grid views. Sitemap entries live in sitemap-cities.xml (1,584 URLs).
24 · ExtensibilityAdding a new city requires: append a row to data/cities-{tier}.php with 33 standard fields; the hub picks it up automatically on next request. Adding a new field across all cities requires touching the template (city-template.php or global-city-template.php) plus a data-migration helper script under admin/. Adding a new tier (say, Tier-4 micro-cities) is a 30-line change to the hub filter logic plus one new data file.