@rubytech/create-realagent-code 0.1.24 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (577) hide show
  1. package/dist/index.js +81 -17
  2. package/package.json +1 -1
  3. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -90
  4. package/payload/platform/plugins/admin/PLUGIN.md +46 -23
  5. package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +111 -126
  6. package/payload/platform/plugins/brochures/.claude-plugin/plugin.json +8 -0
  7. package/payload/platform/plugins/brochures/PLUGIN.md +36 -0
  8. package/payload/platform/plugins/brochures/commands/make-brochure.md +11 -0
  9. package/payload/platform/plugins/brochures/skills/a4-print-documents/SKILL.md +478 -0
  10. package/payload/platform/plugins/brochures/skills/brand-design/SKILL.md +192 -0
  11. package/payload/platform/plugins/brochures/skills/make-brochure/SKILL.md +354 -0
  12. package/payload/platform/plugins/brochures/skills/make-brochure/references/seller-brief-template.md +115 -0
  13. package/payload/platform/plugins/brochures/skills/property-brochure/SKILL.md +119 -0
  14. package/payload/platform/plugins/brochures/skills/property-brochure/references/build.md +270 -0
  15. package/payload/platform/plugins/brochures/skills/property-brochure/references/copy.md +211 -0
  16. package/payload/platform/plugins/brochures/skills/property-brochure/references/images.md +166 -0
  17. package/payload/platform/plugins/brochures/skills/property-brochure/references/index-landing.md +376 -0
  18. package/payload/platform/plugins/brochures/skills/property-brochure/references/index.html +1288 -0
  19. package/payload/platform/plugins/brochures/skills/property-brochure/references/placeholders.md +250 -0
  20. package/payload/platform/plugins/brochures/skills/property-brochure/references/registers.md +47 -0
  21. package/payload/platform/plugins/brochures/skills/property-brochure/references/seller-brief.md +56 -0
  22. package/payload/platform/plugins/brochures/skills/property-brochure/references/structure.md +249 -0
  23. package/payload/platform/plugins/brochures/skills/property-brochure/references/template.html +2370 -0
  24. package/payload/platform/plugins/brochures/skills/property-extract/SKILL.md +372 -0
  25. package/payload/platform/plugins/buyers/.claude-plugin/plugin.json +8 -0
  26. package/payload/platform/plugins/buyers/PLUGIN.md +35 -0
  27. package/payload/platform/plugins/buyers/skills/buyer-feedback/SKILL.md +109 -0
  28. package/payload/platform/plugins/buyers/skills/buyer-management/SKILL.md +42 -0
  29. package/payload/platform/plugins/buyers/skills/buyer-management/references/buyer-qualification-questions.md +16 -0
  30. package/payload/platform/plugins/buyers/skills/buyer-management/references/buyer-qualification.md +59 -0
  31. package/payload/platform/plugins/buyers/skills/buyer-management/references/buyer-scripts.md +63 -0
  32. package/payload/platform/plugins/buyers/skills/buyer-management/references/buyer-working-scripts.md +54 -0
  33. package/payload/platform/plugins/buyers/skills/buyer-management/references/feedback-collection.md +42 -0
  34. package/payload/platform/plugins/buyers/skills/buyer-management/references/offer-capture.md +38 -0
  35. package/payload/platform/plugins/buyers/skills/buyer-management/references/viewing-booking.md +32 -0
  36. package/payload/platform/plugins/buyers/skills/buyer-management/references/viewing-management.md +52 -0
  37. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/SKILL.md +407 -0
  38. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/care-fees-guide.md +68 -0
  39. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/divorce-sales-guide.md +61 -0
  40. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/downsizing-guide.md +45 -0
  41. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/first-time-buyers.md +92 -0
  42. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/first-time-sellers.md +78 -0
  43. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/probate-guide.md +53 -0
  44. package/payload/platform/plugins/buyers/skills/buyer-seller-guides/references/upsizing-guide.md +41 -0
  45. package/payload/platform/plugins/buyers/skills/property-enquiry/SKILL.md +126 -0
  46. package/payload/platform/plugins/buyers/skills/viewing-management/SKILL.md +111 -0
  47. package/payload/platform/plugins/cloudflare/references/dashboard-guide.md +37 -0
  48. package/payload/platform/plugins/cloudflare/references/manual-setup.md +81 -1
  49. package/payload/platform/plugins/cloudflare/scripts/__tests__/tunnel-ingress.test.ts +241 -0
  50. package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +267 -28
  51. package/payload/platform/plugins/cloudflare/scripts/tunnel-ingress.ts +291 -0
  52. package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +42 -0
  53. package/payload/platform/plugins/contacts/PLUGIN.md +18 -9
  54. package/payload/platform/plugins/docs/references/platform.md +2 -0
  55. package/payload/platform/plugins/docs/references/troubleshooting.md +12 -0
  56. package/payload/platform/plugins/email/PLUGIN.md +18 -9
  57. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.d.ts +17 -0
  58. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.d.ts.map +1 -0
  59. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js +185 -0
  60. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js.map +1 -0
  61. package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js +34 -111
  62. package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js.map +1 -1
  63. package/payload/platform/plugins/estate-business/.claude-plugin/plugin.json +8 -0
  64. package/payload/platform/plugins/estate-business/PLUGIN.md +65 -0
  65. package/payload/platform/plugins/estate-business/skills/business-growth/SKILL.md +133 -0
  66. package/payload/platform/plugins/estate-business/skills/business-growth/references/buy-back-your-time.md +37 -0
  67. package/payload/platform/plugins/estate-business/skills/business-growth/references/firewave-gost-scorecards.md +14 -0
  68. package/payload/platform/plugins/estate-business/skills/business-growth/references/keller-org-model.md +17 -0
  69. package/payload/platform/plugins/estate-business/skills/business-growth/references/lencioni-team-models.md +22 -0
  70. package/payload/platform/plugins/estate-business/skills/business-growth/references/listing-management-system.md +11 -0
  71. package/payload/platform/plugins/estate-business/skills/business-growth/references/net-figure-form.md +11 -0
  72. package/payload/platform/plugins/estate-business/skills/business-growth/references/serhant-bizinbox-notes.md +13 -0
  73. package/payload/platform/plugins/estate-business/skills/business-growth/references/team-roles-commission.md +14 -0
  74. package/payload/platform/plugins/estate-business/skills/business-growth/references/va-2026-ops.md +43 -0
  75. package/payload/platform/plugins/estate-business/skills/business-growth/references/wingman-structure.md +13 -0
  76. package/payload/platform/plugins/estate-business/skills/business-operations/SKILL.md +32 -0
  77. package/payload/platform/plugins/estate-business/skills/business-operations/references/crm-systems.md +57 -0
  78. package/payload/platform/plugins/estate-business/skills/business-operations/references/hiring-guide.md +59 -0
  79. package/payload/platform/plugins/estate-business/skills/business-operations/references/impact-framework.md +47 -0
  80. package/payload/platform/plugins/estate-business/skills/business-operations/references/minutes-equal-money.md +55 -0
  81. package/payload/platform/plugins/estate-business/skills/business-operations/references/team-management.md +48 -0
  82. package/payload/platform/plugins/estate-business/skills/commission-calculator/SKILL.md +40 -0
  83. package/payload/platform/plugins/estate-business/skills/exp-partnership/SKILL.md +52 -0
  84. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/12-reasons.md +39 -0
  85. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/95-5-system.md +66 -0
  86. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/agent-attraction-scripts.md +90 -0
  87. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/business-partnership.md +92 -0
  88. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/exp-model-overview.md +66 -0
  89. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/model-comparison.md +66 -0
  90. package/payload/platform/plugins/estate-business/skills/exp-partnership/references/revenue-share-explained.md +57 -0
  91. package/payload/platform/plugins/estate-business/skills/month-end-close/SKILL.md +69 -0
  92. package/payload/platform/plugins/estate-business/skills/payment-batch-stager/SKILL.md +42 -0
  93. package/payload/platform/plugins/estate-business/skills/period-reconciler/SKILL.md +42 -0
  94. package/payload/platform/plugins/estate-business/skills/personal-branding/SKILL.md +117 -0
  95. package/payload/platform/plugins/estate-business/skills/personal-branding/references/attraction-agent-notes.md +31 -0
  96. package/payload/platform/plugins/estate-business/skills/personal-branding/references/attraction-agent.md +58 -0
  97. package/payload/platform/plugins/estate-business/skills/personal-branding/references/authenticity-boundaries.md +28 -0
  98. package/payload/platform/plugins/estate-business/skills/personal-branding/references/become-a-brand-leader-notes.md +19 -0
  99. package/payload/platform/plugins/estate-business/skills/personal-branding/references/blast-formula.md +42 -0
  100. package/payload/platform/plugins/estate-business/skills/personal-branding/references/brand-leader.md +48 -0
  101. package/payload/platform/plugins/estate-business/skills/personal-branding/references/brand-strategy-system.md +59 -0
  102. package/payload/platform/plugins/estate-business/skills/personal-branding/references/content-engine.md +49 -0
  103. package/payload/platform/plugins/estate-business/skills/personal-branding/references/firewave-blast-and-blogging.md +23 -0
  104. package/payload/platform/plugins/estate-business/skills/personal-branding/references/gary-v-content.md +52 -0
  105. package/payload/platform/plugins/estate-business/skills/personal-branding/references/gary-v-principles.md +20 -0
  106. package/payload/platform/plugins/estate-business/skills/personal-branding/references/oversubscribed-positioning.md +18 -0
  107. package/payload/platform/plugins/estate-business/skills/personal-branding/references/platforms.md +41 -0
  108. package/payload/platform/plugins/estate-business/skills/personal-branding/references/priestley-oversubscribed.md +54 -0
  109. package/payload/platform/plugins/estate-business/skills/personal-branding/references/storeys-style-examples.md +25 -0
  110. package/payload/platform/plugins/estate-business/skills/personal-branding/references/visual-identity.md +27 -0
  111. package/payload/platform/plugins/estate-coaching/.claude-plugin/plugin.json +8 -0
  112. package/payload/platform/plugins/estate-coaching/PLUGIN.md +55 -0
  113. package/payload/platform/plugins/estate-coaching/skills/agent-performance/SKILL.md +371 -0
  114. package/payload/platform/plugins/estate-coaching/skills/agent-performance/references/atomic-habits.md +52 -0
  115. package/payload/platform/plugins/estate-coaching/skills/agent-performance/references/daily-routine-scorecard.md +104 -0
  116. package/payload/platform/plugins/estate-coaching/skills/agent-performance/references/hp6-model.md +63 -0
  117. package/payload/platform/plugins/estate-coaching/skills/agent-performance/references/twelve-week-year.md +71 -0
  118. package/payload/platform/plugins/estate-coaching/skills/bespoke-coaching/SKILL.md +36 -0
  119. package/payload/platform/plugins/estate-coaching/skills/bespoke-coaching/references/coaching-boundaries.md +56 -0
  120. package/payload/platform/plugins/estate-coaching/skills/bespoke-coaching/references/feedback-framework.md +61 -0
  121. package/payload/platform/plugins/estate-coaching/skills/bespoke-coaching/references/performance-framework.md +109 -0
  122. package/payload/platform/plugins/estate-coaching/skills/coaching-toolkit/SKILL.md +421 -0
  123. package/payload/platform/plugins/estate-coaching/skills/coaching-toolkit/references/coaching-exercises.md +86 -0
  124. package/payload/platform/plugins/estate-coaching/skills/coaching-toolkit/references/goal-setting.md +78 -0
  125. package/payload/platform/plugins/estate-coaching/skills/coaching-toolkit/references/one-to-one-framework.md +92 -0
  126. package/payload/platform/plugins/estate-coaching/skills/coaching-toolkit/references/soi-workbook.md +103 -0
  127. package/payload/platform/plugins/estate-coaching/skills/serhant-training/SKILL.md +410 -0
  128. package/payload/platform/plugins/estate-coaching/skills/serhant-training/references/agent-training-guide.md +70 -0
  129. package/payload/platform/plugins/estate-coaching/skills/serhant-training/references/business-in-a-box.md +72 -0
  130. package/payload/platform/plugins/estate-coaching/skills/serhant-training/references/buyers-guide.md +53 -0
  131. package/payload/platform/plugins/estate-coaching/skills/serhant-training/references/codo-method.md +72 -0
  132. package/payload/platform/plugins/estate-coaching/skills/serhant-training/references/website-planning-guide.md +79 -0
  133. package/payload/platform/plugins/estate-onboarding/.claude-plugin/plugin.json +8 -0
  134. package/payload/platform/plugins/estate-onboarding/PLUGIN.md +31 -0
  135. package/payload/platform/plugins/estate-onboarding/skills/bootstrap/SKILL.md +26 -0
  136. package/payload/platform/plugins/estate-onboarding/skills/bootstrap/references/onboarding-flow.md +63 -0
  137. package/payload/platform/plugins/estate-sales/.claude-plugin/plugin.json +8 -0
  138. package/payload/platform/plugins/estate-sales/PLUGIN.md +53 -0
  139. package/payload/platform/plugins/estate-sales/skills/chase-progression/SKILL.md +107 -0
  140. package/payload/platform/plugins/estate-sales/skills/negotiation/SKILL.md +35 -0
  141. package/payload/platform/plugins/estate-sales/skills/negotiation/references/deal-saving.md +47 -0
  142. package/payload/platform/plugins/estate-sales/skills/negotiation/references/negotiation-deep-guide.md +64 -0
  143. package/payload/platform/plugins/estate-sales/skills/negotiation/references/negotiation-prep-principles.md +29 -0
  144. package/payload/platform/plugins/estate-sales/skills/negotiation/references/negotiation-techniques.md +42 -0
  145. package/payload/platform/plugins/estate-sales/skills/negotiation/references/offer-presentation.md +43 -0
  146. package/payload/platform/plugins/estate-sales/skills/risk-scorer/SKILL.md +42 -0
  147. package/payload/platform/plugins/estate-sales/skills/sales-closer/SKILL.md +24 -0
  148. package/payload/platform/plugins/estate-sales/skills/sales-closer/references/serhant-emotion-stages.md +36 -0
  149. package/payload/platform/plugins/estate-sales/skills/sales-discovery/SKILL.md +30 -0
  150. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/chris-voss-discovery.md +88 -0
  151. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/firewave-gost-journey.md +68 -0
  152. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/phil-jones-openers.md +78 -0
  153. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/pre-listing-checklist.md +77 -0
  154. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/serhant-improv.md +22 -0
  155. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/tom-ferry-discovery.md +103 -0
  156. package/payload/platform/plugins/estate-sales/skills/sales-discovery/references/vendor-motivation-competitor.md +52 -0
  157. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/SKILL.md +29 -0
  158. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/references/chris-voss-negotiation.md +70 -0
  159. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/references/phil-jones-price-words.md +40 -0
  160. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/references/serhant-negotiation-plus.md +55 -0
  161. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/references/tom-panos-commission-pricing.md +57 -0
  162. package/payload/platform/plugins/estate-sales/skills/sales-negotiation/references/tony-morris-questioning.md +54 -0
  163. package/payload/platform/plugins/estate-sales/skills/sales-progression/SKILL.md +27 -0
  164. package/payload/platform/plugins/estate-sales/skills/sales-progression/references/conveyancing-guide.md +54 -0
  165. package/payload/platform/plugins/estate-sales/skills/sales-progression/references/transaction-tracking.md +66 -0
  166. package/payload/platform/plugins/estate-teaching/.claude-plugin/plugin.json +8 -0
  167. package/payload/platform/plugins/estate-teaching/PLUGIN.md +31 -0
  168. package/payload/platform/plugins/estate-teaching/skills/content-directory/SKILL.md +39 -0
  169. package/payload/platform/plugins/estate-teaching/skills/content-directory/references/module-delivery.md +65 -0
  170. package/payload/platform/plugins/estate-teaching/skills/content-directory/references/progress-tracking.md +47 -0
  171. package/payload/platform/plugins/leads/.claude-plugin/plugin.json +8 -0
  172. package/payload/platform/plugins/leads/PLUGIN.md +62 -0
  173. package/payload/platform/plugins/leads/skills/chain-progression-tracker/SKILL.md +51 -0
  174. package/payload/platform/plugins/leads/skills/diary-builder/SKILL.md +38 -0
  175. package/payload/platform/plugins/leads/skills/enquiry-triage/SKILL.md +36 -0
  176. package/payload/platform/plugins/leads/skills/lead-nurturing/SKILL.md +137 -0
  177. package/payload/platform/plugins/leads/skills/lead-nurturing/references/buyer-search-letter.md +28 -0
  178. package/payload/platform/plugins/leads/skills/lead-nurturing/references/buyer-search-letters.md +37 -0
  179. package/payload/platform/plugins/leads/skills/lead-nurturing/references/database-reactivation.md +30 -0
  180. package/payload/platform/plugins/leads/skills/lead-nurturing/references/email-nurture-sequences.md +45 -0
  181. package/payload/platform/plugins/leads/skills/lead-nurturing/references/facebook-referrals.md +30 -0
  182. package/payload/platform/plugins/leads/skills/lead-nurturing/references/firewave-email-nurture-sequences.md +41 -0
  183. package/payload/platform/plugins/leads/skills/lead-nurturing/references/keller-33-touch.md +34 -0
  184. package/payload/platform/plugins/leads/skills/lead-nurturing/references/neighbour-letters.md +31 -0
  185. package/payload/platform/plugins/leads/skills/lead-nurturing/references/neighbour-notification-letter.md +20 -0
  186. package/payload/platform/plugins/leads/skills/lead-nurturing/references/ofi-follow-up-dialogue.md +22 -0
  187. package/payload/platform/plugins/leads/skills/lead-nurturing/references/ofi-follow-up.md +26 -0
  188. package/payload/platform/plugins/leads/skills/lead-nurturing/references/serhant-three-fs-plus.md +21 -0
  189. package/payload/platform/plugins/leads/skills/lead-nurturing/references/sharran-10x10x10.md +18 -0
  190. package/payload/platform/plugins/leads/skills/lead-nurturing/references/sms-templates.md +40 -0
  191. package/payload/platform/plugins/leads/skills/lead-nurturing/references/sphere-of-influence-notes.md +34 -0
  192. package/payload/platform/plugins/leads/skills/lead-nurturing/references/sphere-of-influence.md +60 -0
  193. package/payload/platform/plugins/leads/skills/lead-nurturing/references/tom-panos-sms-templates.md +59 -0
  194. package/payload/platform/plugins/leads/skills/morning-round/SKILL.md +72 -0
  195. package/payload/platform/plugins/leads/skills/prospecting/SKILL.md +33 -0
  196. package/payload/platform/plugins/leads/skills/prospecting/references/database-matching.md +30 -0
  197. package/payload/platform/plugins/leads/skills/prospecting/references/database-value.md +53 -0
  198. package/payload/platform/plugins/leads/skills/prospecting/references/prospecting-dialogues.md +24 -0
  199. package/payload/platform/plugins/leads/skills/prospecting/references/reactivation.md +34 -0
  200. package/payload/platform/plugins/listings/.claude-plugin/plugin.json +8 -0
  201. package/payload/platform/plugins/listings/PLUGIN.md +103 -0
  202. package/payload/platform/plugins/listings/skills/comparable-finder/SKILL.md +52 -0
  203. package/payload/platform/plugins/listings/skills/epc-checker/SKILL.md +38 -0
  204. package/payload/platform/plugins/listings/skills/home-preparation/SKILL.md +28 -0
  205. package/payload/platform/plugins/listings/skills/home-preparation/references/kerb-appeal.md +38 -0
  206. package/payload/platform/plugins/listings/skills/home-preparation/references/photo-day.md +59 -0
  207. package/payload/platform/plugins/listings/skills/home-preparation/references/situational-tips.md +50 -0
  208. package/payload/platform/plugins/listings/skills/home-preparation/references/staging-guide.md +52 -0
  209. package/payload/platform/plugins/listings/skills/listing-copy-writer/SKILL.md +55 -0
  210. package/payload/platform/plugins/listings/skills/listing-presentation/SKILL.md +286 -0
  211. package/payload/platform/plugins/listings/skills/listing-presentation/references/booking-script.md +51 -0
  212. package/payload/platform/plugins/listings/skills/listing-presentation/references/objection-scripts.md +193 -0
  213. package/payload/platform/plugins/listings/skills/listing-presentation/references/penhaul-presentation.md +123 -0
  214. package/payload/platform/plugins/listings/skills/listing-presentation/references/pre-listing-kit.md +139 -0
  215. package/payload/platform/plugins/listings/skills/listing-presentation/references/set-to-sell.md +55 -0
  216. package/payload/platform/plugins/listings/skills/listing-presentation/references/sharran-frameworks.md +107 -0
  217. package/payload/platform/plugins/listings/skills/local-market-stats/SKILL.md +33 -0
  218. package/payload/platform/plugins/listings/skills/new-instruction/SKILL.md +78 -0
  219. package/payload/platform/plugins/listings/skills/particulars-builder/SKILL.md +48 -0
  220. package/payload/platform/plugins/listings/skills/portal-launch-scheduler/SKILL.md +49 -0
  221. package/payload/platform/plugins/listings/skills/pricing-scenario-builder/SKILL.md +35 -0
  222. package/payload/platform/plugins/listings/skills/property-marketing/SKILL.md +337 -0
  223. package/payload/platform/plugins/listings/skills/property-marketing/references/auction-report-template.md +41 -0
  224. package/payload/platform/plugins/listings/skills/property-marketing/references/coming-soon-campaign.md +43 -0
  225. package/payload/platform/plugins/listings/skills/property-marketing/references/direct-mail-templates.md +121 -0
  226. package/payload/platform/plugins/listings/skills/property-marketing/references/eoi-form-template.md +62 -0
  227. package/payload/platform/plugins/listings/skills/property-marketing/references/monthly-scorecard.md +63 -0
  228. package/payload/platform/plugins/listings/skills/supplier-booker/SKILL.md +39 -0
  229. package/payload/platform/plugins/listings/skills/talk-track-composer/SKILL.md +36 -0
  230. package/payload/platform/plugins/listings/skills/terms-of-business-drafter/SKILL.md +54 -0
  231. package/payload/platform/plugins/listings/skills/valuation-prep/SKILL.md +69 -0
  232. package/payload/platform/plugins/loop/.claude-plugin/plugin.json +17 -0
  233. package/payload/platform/plugins/loop/PLUGIN.md +108 -0
  234. package/payload/platform/plugins/loop/mcp/dist/index.d.ts +2 -0
  235. package/payload/platform/plugins/loop/mcp/dist/index.d.ts.map +1 -0
  236. package/payload/platform/plugins/loop/mcp/dist/index.js +293 -0
  237. package/payload/platform/plugins/loop/mcp/dist/index.js.map +1 -0
  238. package/payload/platform/plugins/loop/mcp/dist/lib/crypto.d.ts +10 -0
  239. package/payload/platform/plugins/loop/mcp/dist/lib/crypto.d.ts.map +1 -0
  240. package/payload/platform/plugins/loop/mcp/dist/lib/crypto.js +88 -0
  241. package/payload/platform/plugins/loop/mcp/dist/lib/crypto.js.map +1 -0
  242. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.d.ts +82 -0
  243. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.d.ts.map +1 -0
  244. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.js +427 -0
  245. package/payload/platform/plugins/loop/mcp/dist/lib/loop-api.js.map +1 -0
  246. package/payload/platform/plugins/loop/mcp/dist/lib/neo4j.d.ts +5 -0
  247. package/payload/platform/plugins/loop/mcp/dist/lib/neo4j.d.ts.map +1 -0
  248. package/payload/platform/plugins/loop/mcp/dist/lib/neo4j.js +40 -0
  249. package/payload/platform/plugins/loop/mcp/dist/lib/neo4j.js.map +1 -0
  250. package/payload/platform/plugins/loop/mcp/dist/tools/customer-preferences.d.ts +10 -0
  251. package/payload/platform/plugins/loop/mcp/dist/tools/customer-preferences.d.ts.map +1 -0
  252. package/payload/platform/plugins/loop/mcp/dist/tools/customer-preferences.js +24 -0
  253. package/payload/platform/plugins/loop/mcp/dist/tools/customer-preferences.js.map +1 -0
  254. package/payload/platform/plugins/loop/mcp/dist/tools/feedback.d.ts +16 -0
  255. package/payload/platform/plugins/loop/mcp/dist/tools/feedback.d.ts.map +1 -0
  256. package/payload/platform/plugins/loop/mcp/dist/tools/feedback.js +35 -0
  257. package/payload/platform/plugins/loop/mcp/dist/tools/feedback.js.map +1 -0
  258. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.d.ts +5 -0
  259. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.d.ts.map +1 -0
  260. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.js +19 -0
  261. package/payload/platform/plugins/loop/mcp/dist/tools/key-deregister.js.map +1 -0
  262. package/payload/platform/plugins/loop/mcp/dist/tools/key-list.d.ts +4 -0
  263. package/payload/platform/plugins/loop/mcp/dist/tools/key-list.d.ts.map +1 -0
  264. package/payload/platform/plugins/loop/mcp/dist/tools/key-list.js +14 -0
  265. package/payload/platform/plugins/loop/mcp/dist/tools/key-list.js.map +1 -0
  266. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.d.ts +9 -0
  267. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.d.ts.map +1 -0
  268. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.js +60 -0
  269. package/payload/platform/plugins/loop/mcp/dist/tools/key-register.js.map +1 -0
  270. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-enquiry.d.ts +13 -0
  271. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-enquiry.d.ts.map +1 -0
  272. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-enquiry.js +41 -0
  273. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-enquiry.js.map +1 -0
  274. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-batch.d.ts +9 -0
  275. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-batch.d.ts.map +1 -0
  276. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-batch.js +16 -0
  277. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-batch.js.map +1 -0
  278. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-request.d.ts +15 -0
  279. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-request.d.ts.map +1 -0
  280. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-request.js +11 -0
  281. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match-request.js.map +1 -0
  282. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match.d.ts +10 -0
  283. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match.d.ts.map +1 -0
  284. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match.js +39 -0
  285. package/payload/platform/plugins/loop/mcp/dist/tools/marketing-match.js.map +1 -0
  286. package/payload/platform/plugins/loop/mcp/dist/tools/people-detail.d.ts +9 -0
  287. package/payload/platform/plugins/loop/mcp/dist/tools/people-detail.d.ts.map +1 -0
  288. package/payload/platform/plugins/loop/mcp/dist/tools/people-detail.js +125 -0
  289. package/payload/platform/plugins/loop/mcp/dist/tools/people-detail.js.map +1 -0
  290. package/payload/platform/plugins/loop/mcp/dist/tools/people-search.d.ts +18 -0
  291. package/payload/platform/plugins/loop/mcp/dist/tools/people-search.d.ts.map +1 -0
  292. package/payload/platform/plugins/loop/mcp/dist/tools/people-search.js +87 -0
  293. package/payload/platform/plugins/loop/mcp/dist/tools/people-search.js.map +1 -0
  294. package/payload/platform/plugins/loop/mcp/dist/tools/property-detail.d.ts +10 -0
  295. package/payload/platform/plugins/loop/mcp/dist/tools/property-detail.d.ts.map +1 -0
  296. package/payload/platform/plugins/loop/mcp/dist/tools/property-detail.js +82 -0
  297. package/payload/platform/plugins/loop/mcp/dist/tools/property-detail.js.map +1 -0
  298. package/payload/platform/plugins/loop/mcp/dist/tools/property-listed.d.ts +12 -0
  299. package/payload/platform/plugins/loop/mcp/dist/tools/property-listed.d.ts.map +1 -0
  300. package/payload/platform/plugins/loop/mcp/dist/tools/property-listed.js +32 -0
  301. package/payload/platform/plugins/loop/mcp/dist/tools/property-listed.js.map +1 -0
  302. package/payload/platform/plugins/loop/mcp/dist/tools/property-request.d.ts +15 -0
  303. package/payload/platform/plugins/loop/mcp/dist/tools/property-request.d.ts.map +1 -0
  304. package/payload/platform/plugins/loop/mcp/dist/tools/property-request.js +11 -0
  305. package/payload/platform/plugins/loop/mcp/dist/tools/property-request.js.map +1 -0
  306. package/payload/platform/plugins/loop/mcp/dist/tools/property-search.d.ts +16 -0
  307. package/payload/platform/plugins/loop/mcp/dist/tools/property-search.d.ts.map +1 -0
  308. package/payload/platform/plugins/loop/mcp/dist/tools/property-search.js +41 -0
  309. package/payload/platform/plugins/loop/mcp/dist/tools/property-search.js.map +1 -0
  310. package/payload/platform/plugins/loop/mcp/dist/tools/supplier.d.ts +13 -0
  311. package/payload/platform/plugins/loop/mcp/dist/tools/supplier.d.ts.map +1 -0
  312. package/payload/platform/plugins/loop/mcp/dist/tools/supplier.js +49 -0
  313. package/payload/platform/plugins/loop/mcp/dist/tools/supplier.js.map +1 -0
  314. package/payload/platform/plugins/loop/mcp/dist/tools/team-availability.d.ts +7 -0
  315. package/payload/platform/plugins/loop/mcp/dist/tools/team-availability.d.ts.map +1 -0
  316. package/payload/platform/plugins/loop/mcp/dist/tools/team-availability.js +19 -0
  317. package/payload/platform/plugins/loop/mcp/dist/tools/team-availability.js.map +1 -0
  318. package/payload/platform/plugins/loop/mcp/dist/tools/team-info.d.ts +5 -0
  319. package/payload/platform/plugins/loop/mcp/dist/tools/team-info.d.ts.map +1 -0
  320. package/payload/platform/plugins/loop/mcp/dist/tools/team-info.js +32 -0
  321. package/payload/platform/plugins/loop/mcp/dist/tools/team-info.js.map +1 -0
  322. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-create.d.ts +14 -0
  323. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-create.d.ts.map +1 -0
  324. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-create.js +11 -0
  325. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-create.js.map +1 -0
  326. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-detail.d.ts +9 -0
  327. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-detail.d.ts.map +1 -0
  328. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-detail.js +85 -0
  329. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-detail.js.map +1 -0
  330. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-search.d.ts +13 -0
  331. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-search.d.ts.map +1 -0
  332. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-search.js +44 -0
  333. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-search.js.map +1 -0
  334. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-update.d.ts +14 -0
  335. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-update.d.ts.map +1 -0
  336. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-update.js +18 -0
  337. package/payload/platform/plugins/loop/mcp/dist/tools/viewing-update.js.map +1 -0
  338. package/payload/platform/plugins/loop/mcp/package-lock.json +2549 -0
  339. package/payload/platform/plugins/loop/mcp/package.json +21 -0
  340. package/payload/platform/plugins/loop/mcp/src/__tests__/loop-swagger.snapshot.json +26467 -0
  341. package/payload/platform/plugins/loop/mcp/src/__tests__/swagger-write-coverage.test.ts +153 -0
  342. package/payload/platform/plugins/loop/mcp/src/index.ts +444 -0
  343. package/payload/platform/plugins/loop/mcp/src/lib/crypto.ts +105 -0
  344. package/payload/platform/plugins/loop/mcp/src/lib/loop-api.ts +604 -0
  345. package/payload/platform/plugins/loop/mcp/src/lib/neo4j.ts +51 -0
  346. package/payload/platform/plugins/loop/mcp/src/tools/customer-preferences.ts +66 -0
  347. package/payload/platform/plugins/loop/mcp/src/tools/feedback.ts +86 -0
  348. package/payload/platform/plugins/loop/mcp/src/tools/key-deregister.ts +27 -0
  349. package/payload/platform/plugins/loop/mcp/src/tools/key-list.ts +19 -0
  350. package/payload/platform/plugins/loop/mcp/src/tools/key-register.ts +95 -0
  351. package/payload/platform/plugins/loop/mcp/src/tools/marketing-enquiry.ts +113 -0
  352. package/payload/platform/plugins/loop/mcp/src/tools/marketing-match-batch.ts +53 -0
  353. package/payload/platform/plugins/loop/mcp/src/tools/marketing-match-request.ts +42 -0
  354. package/payload/platform/plugins/loop/mcp/src/tools/marketing-match.ts +84 -0
  355. package/payload/platform/plugins/loop/mcp/src/tools/people-detail.ts +245 -0
  356. package/payload/platform/plugins/loop/mcp/src/tools/people-search.ts +180 -0
  357. package/payload/platform/plugins/loop/mcp/src/tools/property-detail.ts +145 -0
  358. package/payload/platform/plugins/loop/mcp/src/tools/property-listed.ts +88 -0
  359. package/payload/platform/plugins/loop/mcp/src/tools/property-request.ts +42 -0
  360. package/payload/platform/plugins/loop/mcp/src/tools/property-search.ts +92 -0
  361. package/payload/platform/plugins/loop/mcp/src/tools/supplier.ts +129 -0
  362. package/payload/platform/plugins/loop/mcp/src/tools/team-availability.ts +52 -0
  363. package/payload/platform/plugins/loop/mcp/src/tools/team-info.ts +95 -0
  364. package/payload/platform/plugins/loop/mcp/src/tools/viewing-create.ts +41 -0
  365. package/payload/platform/plugins/loop/mcp/src/tools/viewing-detail.ts +171 -0
  366. package/payload/platform/plugins/loop/mcp/src/tools/viewing-search.ts +92 -0
  367. package/payload/platform/plugins/loop/mcp/src/tools/viewing-update.ts +53 -0
  368. package/payload/platform/plugins/loop/mcp/tsconfig.json +20 -0
  369. package/payload/platform/plugins/loop/mcp/vitest.config.ts +9 -0
  370. package/payload/platform/plugins/loop/skills/compliance-flag-checker/SKILL.md +53 -0
  371. package/payload/platform/plugins/loop/skills/priority-ranker/SKILL.md +40 -0
  372. package/payload/platform/plugins/loop/skills/tone-matched-drafter/SKILL.md +53 -0
  373. package/payload/platform/plugins/loop/skills/variance-narrator/SKILL.md +50 -0
  374. package/payload/platform/plugins/loop/skills/vendor-research/SKILL.md +54 -0
  375. package/payload/platform/plugins/memory/PLUGIN.md +58 -29
  376. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts +3 -1
  377. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts.map +1 -1
  378. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js +105 -4
  379. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js.map +1 -1
  380. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
  381. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +16 -3
  382. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  383. package/payload/platform/plugins/outlook/PLUGIN.md +14 -7
  384. package/payload/platform/plugins/replicate/PLUGIN.md +6 -3
  385. package/payload/platform/plugins/scheduling/PLUGIN.md +16 -8
  386. package/payload/platform/plugins/tasks/PLUGIN.md +28 -14
  387. package/payload/platform/plugins/teaching/.claude-plugin/plugin.json +8 -0
  388. package/payload/platform/plugins/teaching/PLUGIN.md +57 -0
  389. package/payload/platform/plugins/teaching/skills/interactive-tutor/SKILL.md +59 -0
  390. package/payload/platform/plugins/teaching/skills/interactive-tutor/references/assessment.md +70 -0
  391. package/payload/platform/plugins/teaching/skills/interactive-tutor/references/classroom-conduct.md +43 -0
  392. package/payload/platform/plugins/teaching/skills/interactive-tutor/references/teaching-modes.md +83 -0
  393. package/payload/platform/plugins/teaching/skills/lesson-planner/SKILL.md +48 -0
  394. package/payload/platform/plugins/teaching/skills/lesson-planner/references/context-gathering.md +41 -0
  395. package/payload/platform/plugins/teaching/skills/lesson-planner/references/plan-structure.md +94 -0
  396. package/payload/platform/plugins/teaching/skills/study-pack-builder/SKILL.md +52 -0
  397. package/payload/platform/plugins/teaching/skills/study-pack-builder/references/disaggregation.md +49 -0
  398. package/payload/platform/plugins/teaching/skills/study-pack-builder/references/materials.md +116 -0
  399. package/payload/platform/plugins/vendors/.claude-plugin/plugin.json +8 -0
  400. package/payload/platform/plugins/vendors/PLUGIN.md +34 -0
  401. package/payload/platform/plugins/vendors/skills/vendor-communication/SKILL.md +42 -0
  402. package/payload/platform/plugins/vendors/skills/vendor-communication/references/fee-protection-and-agenda.md +28 -0
  403. package/payload/platform/plugins/vendors/skills/vendor-communication/references/listing-scripts.md +44 -0
  404. package/payload/platform/plugins/vendors/skills/vendor-communication/references/negotiation-deep-guide.md +70 -0
  405. package/payload/platform/plugins/vendors/skills/vendor-communication/references/price-alignment-scripts.md +33 -0
  406. package/payload/platform/plugins/vendors/skills/vendor-communication/references/price-alignment.md +34 -0
  407. package/payload/platform/plugins/vendors/skills/vendor-communication/references/scenario-scripts.md +38 -0
  408. package/payload/platform/plugins/vendors/skills/vendor-communication/references/seller-engagement.md +51 -0
  409. package/payload/platform/plugins/vendors/skills/vendor-communication/references/valuation-booking.md +76 -0
  410. package/payload/platform/plugins/vendors/skills/vendor-communication/references/vendor-scripts.md +63 -0
  411. package/payload/platform/plugins/vendors/skills/vendor-communication/references/vendor-updates.md +41 -0
  412. package/payload/platform/plugins/vendors/skills/vendor-updates/SKILL.md +153 -0
  413. package/payload/platform/plugins/waitlist/PLUGIN.md +12 -6
  414. package/payload/platform/plugins/whatsapp/PLUGIN.md +25 -13
  415. package/payload/platform/plugins/workflows/PLUGIN.md +16 -8
  416. package/payload/platform/plugins/writer-craft/.claude-plugin/plugin.json +8 -0
  417. package/payload/platform/plugins/writer-craft/PLUGIN.md +87 -0
  418. package/payload/platform/plugins/writer-craft/agents/writer-craft--manuscript-reviewer.md +92 -0
  419. package/payload/platform/plugins/writer-craft/skills/citation-style/SKILL.md +94 -0
  420. package/payload/platform/plugins/writer-craft/skills/citation-style/references/book-and-chapter-models.md +77 -0
  421. package/payload/platform/plugins/writer-craft/skills/citation-style/references/citation-rules.md +103 -0
  422. package/payload/platform/plugins/writer-craft/skills/citation-style/references/journal-article-models.md +74 -0
  423. package/payload/platform/plugins/writer-craft/skills/citation-style/references/other-source-models.md +146 -0
  424. package/payload/platform/plugins/writer-craft/skills/citation-style/references/reference-list-rules.md +70 -0
  425. package/payload/platform/plugins/writer-craft/skills/editorial-practice/SKILL.md +108 -0
  426. package/payload/platform/plugins/writer-craft/skills/editorial-practice/references/copyediting.md +73 -0
  427. package/payload/platform/plugins/writer-craft/skills/editorial-practice/references/developmental-editing.md +85 -0
  428. package/payload/platform/plugins/writer-craft/skills/editorial-practice/references/genre-specific-editing.md +78 -0
  429. package/payload/platform/plugins/writer-craft/skills/editorial-practice/references/line-editing.md +55 -0
  430. package/payload/platform/plugins/writer-craft/skills/editorial-practice/references/self-editing.md +89 -0
  431. package/payload/platform/plugins/writer-craft/skills/persuasive-storytelling/SKILL.md +114 -0
  432. package/payload/platform/plugins/writer-craft/skills/persuasive-storytelling/references/audience-analysis.md +73 -0
  433. package/payload/platform/plugins/writer-craft/skills/persuasive-storytelling/references/crafting-persuasive-story.md +76 -0
  434. package/payload/platform/plugins/writer-craft/skills/persuasive-storytelling/references/persuasion-case-studies.md +67 -0
  435. package/payload/platform/plugins/writer-craft/skills/persuasive-storytelling/references/transformation-framework.md +86 -0
  436. package/payload/platform/plugins/writer-craft/skills/point-of-view/SKILL.md +97 -0
  437. package/payload/platform/plugins/writer-craft/skills/point-of-view/references/indirect-narration.md +72 -0
  438. package/payload/platform/plugins/writer-craft/skills/point-of-view/references/pov-types-and-voice.md +91 -0
  439. package/payload/platform/plugins/writer-craft/skills/point-of-view/references/protagonist-filter.md +71 -0
  440. package/payload/platform/plugins/writer-craft/skills/point-of-view/references/tense-and-person.md +85 -0
  441. package/payload/platform/plugins/writer-craft/skills/prose-craft/SKILL.md +100 -0
  442. package/payload/platform/plugins/writer-craft/skills/prose-craft/references/punctuation-and-grammar.md +72 -0
  443. package/payload/platform/plugins/writer-craft/skills/prose-craft/references/repetition.md +71 -0
  444. package/payload/platform/plugins/writer-craft/skills/prose-craft/references/sound-and-rhythm.md +64 -0
  445. package/payload/platform/plugins/writer-craft/skills/prose-craft/references/word-economy.md +93 -0
  446. package/payload/platform/plugins/writer-craft/skills/reader-engagement/SKILL.md +100 -0
  447. package/payload/platform/plugins/writer-craft/skills/reader-engagement/references/cause-effect-setup-payoff.md +79 -0
  448. package/payload/platform/plugins/writer-craft/skills/reader-engagement/references/conflict-escalation.md +81 -0
  449. package/payload/platform/plugins/writer-craft/skills/reader-engagement/references/hooking-readers.md +67 -0
  450. package/payload/platform/plugins/writer-craft/skills/reader-engagement/references/neurochemistry-of-engagement.md +94 -0
  451. package/payload/platform/plugins/writer-craft/skills/review-manuscript/SKILL.md +111 -0
  452. package/payload/platform/plugins/writer-craft/skills/review-manuscript/references/review-manuscript-checklist.md +119 -0
  453. package/payload/platform/plugins/writer-craft/skills/review-prose/SKILL.md +99 -0
  454. package/payload/platform/plugins/writer-craft/skills/review-prose/references/prose-review-checklist.md +112 -0
  455. package/payload/platform/plugins/writer-craft/skills/review-scene/SKILL.md +99 -0
  456. package/payload/platform/plugins/writer-craft/skills/review-scene/references/scene-analysis-framework.md +95 -0
  457. package/payload/platform/plugins/writer-craft/skills/story-architecture/SKILL.md +106 -0
  458. package/payload/platform/plugins/writer-craft/skills/story-architecture/references/blueprinting-and-scene-cards.md +118 -0
  459. package/payload/platform/plugins/writer-craft/skills/story-architecture/references/inner-issue-and-protagonist-goal.md +66 -0
  460. package/payload/platform/plugins/writer-craft/skills/story-architecture/references/misbelief-desire-worldview.md +87 -0
  461. package/payload/platform/plugins/writer-craft/skills/story-architecture/references/origin-scenes-and-escalation.md +82 -0
  462. package/payload/platform/plugins/writer-craft/skills/story-blueprint/SKILL.md +133 -0
  463. package/payload/platform/plugins/writer-craft/skills/story-blueprint/references/blueprinting-exercises.md +118 -0
  464. package/payload/platform/plugins/writer-craft/skills/story-blueprint/references/blueprinting-process.md +128 -0
  465. package/payload/platform/scripts/conversation-id-allowlist.txt +0 -1
  466. package/payload/platform/services/claude-session-manager/dist/config.d.ts +6 -0
  467. package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
  468. package/payload/platform/services/claude-session-manager/dist/config.js +60 -1
  469. package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
  470. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +9 -0
  471. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  472. package/payload/platform/services/claude-session-manager/dist/http-server.js +48 -2
  473. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  474. package/payload/platform/services/claude-session-manager/dist/index.js +39 -0
  475. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  476. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +22 -0
  477. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  478. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +32 -1
  479. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  480. package/payload/platform/services/claude-session-manager/dist/public-tool-audit.d.ts +33 -0
  481. package/payload/platform/services/claude-session-manager/dist/public-tool-audit.d.ts.map +1 -0
  482. package/payload/platform/services/claude-session-manager/dist/public-tool-audit.js +149 -0
  483. package/payload/platform/services/claude-session-manager/dist/public-tool-audit.js.map +1 -0
  484. package/payload/platform/services/claude-session-manager/dist/spawn-rate-limiter.d.ts +28 -0
  485. package/payload/platform/services/claude-session-manager/dist/spawn-rate-limiter.d.ts.map +1 -0
  486. package/payload/platform/services/claude-session-manager/dist/spawn-rate-limiter.js +77 -0
  487. package/payload/platform/services/claude-session-manager/dist/spawn-rate-limiter.js.map +1 -0
  488. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts +25 -0
  489. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -0
  490. package/payload/platform/services/claude-session-manager/dist/tool-surface.js +149 -0
  491. package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -0
  492. package/payload/premium-plugins/real-agency/plugins/estate-business/PLUGIN.md +15 -0
  493. package/payload/premium-plugins/real-agency/plugins/estate-sales/PLUGIN.md +5 -0
  494. package/payload/premium-plugins/real-agency/plugins/leads/PLUGIN.md +16 -0
  495. package/payload/premium-plugins/real-agency/plugins/listings/PLUGIN.md +39 -0
  496. package/payload/premium-plugins/real-agency/plugins/loop/PLUGIN.md +15 -0
  497. package/payload/server/{chunk-2ZNKHCQB.js → chunk-2MRZBQMH.js} +1 -1
  498. package/payload/server/{chunk-GPUCA2RQ.js → chunk-NL7QLVAD.js} +0 -192
  499. package/payload/server/{chunk-IDKWGLM5.js → chunk-YPZFYTYP.js} +1 -247
  500. package/payload/server/{cloudflare-task-tracker-LYI5BTYI.js → cloudflare-task-tracker-QVOGHKWV.js} +2 -2
  501. package/payload/server/maxy-edge.js +2 -2
  502. package/payload/server/package.json +0 -2
  503. package/payload/server/public/assets/{Checkbox-D1OQD43b.js → Checkbox-YIF0payo.js} +1 -1
  504. package/payload/server/public/assets/{admin-czNBxWor.js → admin-DW8IJcLc.js} +1 -1
  505. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-BcwgT80u.js → architectureDiagram-Q4EWVU46-Bz8mlxZZ.js} +1 -1
  506. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-BMSyZUQA.js → blockDiagram-DXYQGD6D-DwV8Z8-i.js} +1 -1
  507. package/payload/server/public/assets/{brand-2cku8WFs.css → brand-DqiRNMlu.css} +1 -1
  508. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-DPRGY1jJ.js → c4Diagram-AHTNJAMY-DiUTejMp.js} +1 -1
  509. package/payload/server/public/assets/channel-PtVtoBEL.js +1 -0
  510. package/payload/server/public/assets/{chunk-336JU56O-B7oQ3g1c.js → chunk-336JU56O-4mHZpBXe.js} +2 -2
  511. package/payload/server/public/assets/{chunk-426QAEUC-C1P0yFXw.js → chunk-426QAEUC-Cbv0vrN9.js} +1 -1
  512. package/payload/server/public/assets/{chunk-4TB4RGXK-LI7kOJd0.js → chunk-4TB4RGXK-BvLhId_2.js} +1 -1
  513. package/payload/server/public/assets/{chunk-5FUZZQ4R-CXQRGTQE.js → chunk-5FUZZQ4R-bBafOTkw.js} +1 -1
  514. package/payload/server/public/assets/{chunk-5PVQY5BW-NSyzpXRy.js → chunk-5PVQY5BW-B0NqBKVy.js} +1 -1
  515. package/payload/server/public/assets/{chunk-EDXVE4YY-voNwxbDs.js → chunk-EDXVE4YY-CFd4SqI6.js} +1 -1
  516. package/payload/server/public/assets/{chunk-ENJZ2VHE-CMEMPzYY.js → chunk-ENJZ2VHE-ajf2sb6c.js} +1 -1
  517. package/payload/server/public/assets/{chunk-ICPOFSXX-hEbwu-pe.js → chunk-ICPOFSXX-pWg6bug7.js} +1 -1
  518. package/payload/server/public/assets/{chunk-OYMX7WX6-DxskDrLs.js → chunk-OYMX7WX6-OjEd-17c.js} +1 -1
  519. package/payload/server/public/assets/{chunk-U2HBQHQK-D7TKgUo0.js → chunk-U2HBQHQK-DbEFSPoh.js} +1 -1
  520. package/payload/server/public/assets/{chunk-X2U36JSP-BvPUQEPm.js → chunk-X2U36JSP-COdNwrBb.js} +1 -1
  521. package/payload/server/public/assets/{chunk-YZCP3GAM-BY-RWQUW.js → chunk-YZCP3GAM-CHMWuY9B.js} +1 -1
  522. package/payload/server/public/assets/{chunk-ZZ45TVLE-DZvOYDY6.js → chunk-ZZ45TVLE-B-uDLQOB.js} +1 -1
  523. package/payload/server/public/assets/classDiagram-6PBFFD2Q-RVH_SEhY.js +1 -0
  524. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Cm3rAb93.js +1 -0
  525. package/payload/server/public/assets/clone-BjY0Wzht.js +1 -0
  526. package/payload/server/public/assets/{dagre-KV5264BT-Cnj0mUZl.js → dagre-KV5264BT-CMEzmhIL.js} +1 -1
  527. package/payload/server/public/assets/{dagre-Bt-fpckL.js → dagre-bhIG_KnW.js} +1 -1
  528. package/payload/server/public/assets/data-K_kS__sL.js +1 -0
  529. package/payload/server/public/assets/{device-url-actions-Bjz3Xzbm.js → device-url-actions-AcOyLSeF.js} +1 -1
  530. package/payload/server/public/assets/{diagram-5BDNPKRD-DjLzvOlx.js → diagram-5BDNPKRD-6RIoQhIL.js} +1 -1
  531. package/payload/server/public/assets/{diagram-G4DWMVQ6-DTfuRd-T.js → diagram-G4DWMVQ6-BSp36TVv.js} +1 -1
  532. package/payload/server/public/assets/{diagram-MMDJMWI5-BaL2mCnx.js → diagram-MMDJMWI5-D54fo52D.js} +1 -1
  533. package/payload/server/public/assets/{diagram-TYMM5635-C5InWY5R.js → diagram-TYMM5635-CWL8z-Pq.js} +1 -1
  534. package/payload/server/public/assets/{erDiagram-SMLLAGMA-DO7BXTpn.js → erDiagram-SMLLAGMA-AnnHBo3z.js} +1 -1
  535. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-DDdAKfLf.js → flowDiagram-DWJPFMVM-laWmBl5o.js} +1 -1
  536. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-arJD8Utm.js → ganttDiagram-T4ZO3ILL-B94ko8ie.js} +1 -1
  537. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-C55GH-OS.js → gitGraphDiagram-UUTBAWPF-DxzL1fxZ.js} +1 -1
  538. package/payload/server/public/assets/graph-DeEigyO_.js +1 -0
  539. package/payload/server/public/assets/graph-labels-C7I5QvNv.js +1 -0
  540. package/payload/server/public/assets/{graphlib-DL9PM7Ex.js → graphlib-CY-zIElM.js} +1 -1
  541. package/payload/server/public/assets/{infoDiagram-42DDH7IO-BMSGqUbG.js → infoDiagram-42DDH7IO-BMTajIIr.js} +1 -1
  542. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-Dw6BZ6BG.js → ishikawaDiagram-UXIWVN3A-B_QauE5O.js} +1 -1
  543. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-DrywUGXw.js → journeyDiagram-VCZTEJTY-DmlqSIih.js} +1 -1
  544. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-DuwtVBBc.js → kanban-definition-6JOO6SKY-ZGDQT7xB.js} +1 -1
  545. package/payload/server/public/assets/{line-JAksyKHj.js → line-D13opgep.js} +1 -1
  546. package/payload/server/public/assets/{mermaid-parser.core-BMq-ApBW.js → mermaid-parser.core-C650Sual.js} +1 -1
  547. package/payload/server/public/assets/{mermaid.core-tH4oX0Kh.js → mermaid.core-BqnQoXTp.js} +3 -3
  548. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-D1OiiJga.js → mindmap-definition-QFDTVHPH-BS_8y-tY.js} +1 -1
  549. package/payload/server/public/assets/{page-BZpoS7iR.js → page-B_rpjIRr.js} +1 -1
  550. package/payload/server/public/assets/{page-CkvBvezS.js → page-qSH972X0.js} +1 -1
  551. package/payload/server/public/assets/{pieDiagram-DEJITSTG-Ckwm69PW.js → pieDiagram-DEJITSTG-B5OmNvBO.js} +1 -1
  552. package/payload/server/public/assets/{public-C-dTMgXu.js → public-DDsYgotk.js} +3 -3
  553. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-COw3yZ1j.js → quadrantDiagram-34T5L4WZ-DTYITdNo.js} +1 -1
  554. package/payload/server/public/assets/{requirementDiagram-MS252O5E-DqGzM4K-.js → requirementDiagram-MS252O5E-CRZWxH06.js} +1 -1
  555. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-D-l1c_Pl.js → sankeyDiagram-XADWPNL6-DazRENhe.js} +1 -1
  556. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-BeIi0DtJ.js → sequenceDiagram-FGHM5R23-BcHTxmPy.js} +1 -1
  557. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-C-jgegLk.js → stateDiagram-FHFEXIEX-DYU7nbqg.js} +1 -1
  558. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BgljVtlp.js +1 -0
  559. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-BGFKkYmi.js → timeline-definition-GMOUNBTQ-BKGmqkST.js} +1 -1
  560. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-5NuIhJLS.js → vennDiagram-DHZGUBPP-BXvLPmX7.js} +1 -1
  561. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-Be9ytVut.js → wardleyDiagram-NUSXRM2D-BCclUa3Z.js} +1 -1
  562. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DCyHg41R.js → xychartDiagram-5P7HB3ND-C-Xp-Eoc.js} +1 -1
  563. package/payload/server/public/data.html +5 -5
  564. package/payload/server/public/graph.html +6 -6
  565. package/payload/server/public/index.html +8 -8
  566. package/payload/server/public/public.html +5 -5
  567. package/payload/server/server.js +1024 -2347
  568. package/payload/platform/scripts/check-sdk-oauth.mjs +0 -185
  569. package/payload/server/public/assets/channel-fxEghWew.js +0 -1
  570. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BsWzGW0N.js +0 -1
  571. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BGVa3h90.js +0 -1
  572. package/payload/server/public/assets/clone-Khvocke2.js +0 -1
  573. package/payload/server/public/assets/data-DBd-Buhp.js +0 -1
  574. package/payload/server/public/assets/graph-DUtVdnZ6.js +0 -1
  575. package/payload/server/public/assets/graph-labels-Dxfue-fP.js +0 -1
  576. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BaMs8Znv.js +0 -1
  577. /package/payload/server/public/assets/{brand-CSQuxS9w.js → brand-Bm671owU.js} +0 -0
@@ -0,0 +1,2370 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en-GB">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Property Folio — Template</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400;1,500;1,600&family=Lora:ital,wght@0,400;0,500;0,600;1,400;1,500&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
10
+ <style>
11
+ /* ═══════════════════════════════════════════════════
12
+ EDITORIAL PROPERTY FOLIO — CANONICAL TEMPLATE
13
+ A4 landscape (297 × 210 mm) — 16-page super-premium folio.
14
+ Reference register: Knight Frank country-houses / Strutt & Parker.
15
+ Type: Cormorant Garamond (display, italic-default at hero)
16
+ Lora (humanist serif body)
17
+ Inter (numeric labels, particulars)
18
+ Palette: ivory paper · ink · bronze · antique gold · champagne
19
+
20
+ SUBSTITUTION CONTRACT
21
+ ─────────────────────
22
+ This file is the CANONICAL template. Every property-specific value
23
+ is a {{ token }} placeholder — there is no exemplar copy left to
24
+ accidentally inherit. Substitution is mechanical and verifiable:
25
+ after rendering, `grep "{{" output/brochure.html` must return ZERO
26
+ matches. Any remaining {{ x }} is a bug.
27
+
28
+ The full token list, with source field, expected format, length
29
+ and voice, lives at:
30
+ references/placeholders.md
31
+ Each <!-- REPLACE: ... --> inline comment in this file gives the
32
+ short version (what fills the token, how long, what voice). The
33
+ placeholders.md file gives the long version with worked examples
34
+ from the validated muvin Sparrows Farm reference brochure.
35
+
36
+ Re-skin: agents override the design tokens in :root from their
37
+ brand DESIGN.md per the property-brochure SKILL ("registers" — see
38
+ references/registers.md).
39
+
40
+ Image filenames follow the pattern {{ property_slug }}-NN.webp,
41
+ where {{ property_slug }} is the literal slug from the property
42
+ directory (e.g. "sparrows-farm" or "agincourt-house") and NN is
43
+ the zero-padded image index per references/images.md.
44
+ ═══════════════════════════════════════════════════ */
45
+ :root {
46
+ /* Super-premium tokens (palette, type) */
47
+ --teal-900: #0E1418; /* primary ink */
48
+ --teal-950: #06080A; /* deepest surface (cover/back bg) */
49
+ --teal-700: #2A3036; /* secondary ink */
50
+ --gold-500: #A4884C; /* antique gold rule */
51
+ --gold-700: #7A6235; /* bronze accent */
52
+ --gold-300: #C9B07A; /* champagne flourish */
53
+ --paper-0: #FFFFFF;
54
+ --paper-25: #F8F4ED; /* ivory page */
55
+ --paper-50: #F4EFE5;
56
+ --paper-100: #EFE7D8; /* warm cream surface */
57
+ --slate-600: #5C6470;
58
+ --slate-400: #8A8E96;
59
+ --rule: rgba(14,20,24,0.16);
60
+ --rule-soft: rgba(14,20,24,0.08);
61
+ --rule-fine: #E2D5BD; /* champagne sand */
62
+ --ink: #0E1418;
63
+
64
+ --serif: 'Cormorant Garamond', 'EB Garamond', 'Garamond', 'Times New Roman', serif;
65
+ --body-serif: 'Lora', 'Source Serif Pro', 'Georgia', serif;
66
+ --sans: 'Inter', 'Söhne', -apple-system, BlinkMacSystemFont, sans-serif;
67
+ }
68
+
69
+ * { margin: 0; padding: 0; box-sizing: border-box; }
70
+ html { font-size: 16px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
71
+ body {
72
+ font-family: var(--body-serif);
73
+ background: #c9c1b1;
74
+ color: var(--ink);
75
+ line-height: 1.62;
76
+ font-weight: 400;
77
+ }
78
+
79
+ img { display: block; }
80
+
81
+ /* Super-premium body-copy contract: ragged-right, no hyphenation, on warm ivory */
82
+ .ed-body, .ed-deck, .opener-body p, .feature-page .panel p,
83
+ .spread-6 .bottom .ed-body, .toc-credit, .mi-foot, .back-tagline {
84
+ text-align: left !important;
85
+ hyphens: none !important;
86
+ -webkit-hyphens: none !important;
87
+ word-break: normal !important;
88
+ overflow-wrap: normal !important;
89
+ }
90
+ .opener-meta-row, .ed-stat .v, .mi-section .mi-row, .spec-list,
91
+ .opener-spec, .epc-bars, .attr-grid {
92
+ font-variant-numeric: tabular-nums;
93
+ font-feature-settings: "tnum" 1;
94
+ }
95
+
96
+ /* Download bar (screen only) */
97
+ .download-bar { position: fixed; top: 18px; right: 18px; z-index: 1000; }
98
+ .download-btn {
99
+ font-family: var(--sans);
100
+ font-size: 11px; font-weight: 400;
101
+ letter-spacing: 0.18em; text-transform: uppercase;
102
+ color: var(--paper-0); background: var(--teal-900);
103
+ border: 1px solid rgba(255,255,255,0.16);
104
+ padding: 12px 22px;
105
+ cursor: pointer;
106
+ display: flex; align-items: center; gap: 10px;
107
+ transition: background 250ms ease;
108
+ }
109
+ .download-btn:hover { background: var(--gold-700); }
110
+ .download-btn svg { width: 13px; height: 13px; }
111
+
112
+ /* ═══════════════════════════════════════════════════
113
+ PAGE BOXES
114
+ ═══════════════════════════════════════════════════ */
115
+ .page {
116
+ width: 297mm;
117
+ height: 210mm;
118
+ margin: 18px auto 0;
119
+ position: relative;
120
+ overflow: hidden;
121
+ background: var(--paper-25);
122
+ box-shadow: 0 4px 28px rgba(0,0,0,0.14);
123
+ }
124
+ .page:last-of-type { margin-bottom: 22px; }
125
+
126
+ /* Folio (page-number) chrome — the bottom strip on a magazine page */
127
+ .folio {
128
+ position: absolute;
129
+ bottom: 8mm; left: 14mm; right: 14mm;
130
+ display: flex; justify-content: space-between; align-items: center;
131
+ font-family: var(--sans);
132
+ font-size: 9px; font-weight: 500;
133
+ letter-spacing: 0.32em; text-transform: uppercase;
134
+ color: var(--teal-900);
135
+ z-index: 5;
136
+ pointer-events: none;
137
+ }
138
+ .folio > span {
139
+ background: rgba(252, 251, 248, 0.92);
140
+ backdrop-filter: blur(10px) saturate(1.2);
141
+ -webkit-backdrop-filter: blur(10px) saturate(1.2);
142
+ padding: 5px 10px;
143
+ border-radius: 2px;
144
+ box-shadow: 0 1px 0 rgba(6,68,68,0.04);
145
+ white-space: nowrap;
146
+ }
147
+ .folio .folio-mid { letter-spacing: 0.4em; }
148
+ .folio em { font-style: normal; color: var(--gold-700); font-weight: 500; }
149
+
150
+ /* On dark/photo-heavy pages, swap to light text on dark pill */
151
+ .page.folio-dark .folio { color: var(--paper-25); }
152
+ .page.folio-dark .folio > span { background: rgba(6, 68, 68, 0.55); }
153
+ .page.folio-dark .folio em { color: var(--gold-300); }
154
+
155
+ /* ═══════════════════════════════════════════════════
156
+ COVER — split layout: paper title block on top, full-bleed photo below
157
+ Reference register: Knight Frank country-houses / Strutt & Parker folios
158
+ ═══════════════════════════════════════════════════ */
159
+ .cover {
160
+ background: var(--paper-25);
161
+ color: var(--ink);
162
+ display: grid;
163
+ grid-template-rows: 86mm 1fr;
164
+ }
165
+
166
+ .cover-paper {
167
+ position: relative;
168
+ padding: 14mm 22mm 10mm;
169
+ display: flex; flex-direction: column;
170
+ align-items: center; justify-content: center;
171
+ text-align: center;
172
+ }
173
+
174
+ .cover-mast {
175
+ position: absolute;
176
+ top: 12mm; left: 0; right: 0;
177
+ display: flex; align-items: center; justify-content: center; gap: 14px;
178
+ font-family: var(--sans);
179
+ font-size: 9px; font-weight: 500;
180
+ letter-spacing: 0.42em; text-transform: uppercase;
181
+ color: var(--gold-700);
182
+ }
183
+ .cover-mast .pipe { width: 1px; height: 12px; background: var(--gold-700); opacity: 0.5; }
184
+ .cover-mast .brand { color: var(--gold-700); }
185
+ .cover-mast .label { color: var(--gold-700); opacity: 0.86; }
186
+
187
+ .cover-title-line {
188
+ display: flex; align-items: center; justify-content: center; gap: 28px;
189
+ margin-top: 6mm;
190
+ width: 100%;
191
+ }
192
+ .cover-title-line .flank {
193
+ flex: 1;
194
+ height: 1px;
195
+ background: var(--gold-500);
196
+ opacity: 0.55;
197
+ max-width: 70mm;
198
+ }
199
+
200
+ .cover-title {
201
+ font-family: var(--serif);
202
+ font-style: normal;
203
+ font-weight: 400;
204
+ font-size: 64px;
205
+ line-height: 1;
206
+ letter-spacing: 0.18em;
207
+ text-indent: 0.18em; /* compensate for trailing letter-spacing */
208
+ text-transform: uppercase;
209
+ color: var(--ink);
210
+ white-space: nowrap;
211
+ }
212
+
213
+ .cover-subtitle {
214
+ margin-top: 16px;
215
+ font-family: var(--sans);
216
+ font-size: 11px; font-weight: 500;
217
+ letter-spacing: 0.42em; text-transform: uppercase;
218
+ color: var(--teal-700);
219
+ }
220
+ .cover-subtitle em {
221
+ font-style: normal;
222
+ color: var(--gold-700);
223
+ font-weight: 500;
224
+ }
225
+
226
+ .cover-image {
227
+ position: relative;
228
+ overflow: hidden;
229
+ }
230
+ .cover-image > img {
231
+ width: 100%; height: 100%;
232
+ object-fit: cover;
233
+ object-position: 50% 50%;
234
+ }
235
+
236
+ /* ═══════════════════════════════════════════════════
237
+ CONTENTS PAGE
238
+ ═══════════════════════════════════════════════════ */
239
+ .toc-page {
240
+ display: grid;
241
+ grid-template-columns: 1.1fr 1fr;
242
+ height: 100%;
243
+ }
244
+ .toc-image {
245
+ position: relative;
246
+ overflow: hidden;
247
+ }
248
+ .toc-image img { width: 100%; height: 100%; object-fit: cover; }
249
+ .toc-image::after {
250
+ content: '';
251
+ position: absolute; inset: 0;
252
+ background: linear-gradient(180deg, transparent 60%, rgba(14,20,24,0.18) 100%);
253
+ }
254
+ .toc-image .caption {
255
+ position: absolute; bottom: 12mm; left: 12mm; right: 12mm;
256
+ padding: 14px 18px 16px;
257
+ background: rgba(14,20,24,0.78);
258
+ border-left: 1px solid var(--gold-300);
259
+ font-family: var(--serif);
260
+ font-style: italic;
261
+ font-weight: 400;
262
+ font-size: 16px;
263
+ color: var(--paper-0);
264
+ letter-spacing: 0.01em;
265
+ line-height: 1.45;
266
+ }
267
+ .toc-image .caption::before { display: none; }
268
+
269
+ .toc-content {
270
+ padding: 18mm 16mm 16mm;
271
+ display: flex; flex-direction: column;
272
+ justify-content: space-between;
273
+ }
274
+ .toc-eyebrow {
275
+ font-family: var(--sans);
276
+ font-size: 10px; font-weight: 500;
277
+ letter-spacing: 0.42em; text-transform: uppercase;
278
+ color: var(--gold-700);
279
+ }
280
+ .toc-rule { width: 32px; height: 1px; background: var(--gold-500); margin: 7px 0 14px; }
281
+ .toc-title.compact {
282
+ font-size: 38px !important;
283
+ line-height: 0.95 !important;
284
+ margin-bottom: 16px !important;
285
+ }
286
+ .toc-title {
287
+ font-family: var(--serif);
288
+ font-weight: 400;
289
+ font-size: 56px;
290
+ line-height: 1;
291
+ color: var(--teal-900);
292
+ letter-spacing: -0.01em;
293
+ margin-bottom: 24px;
294
+ }
295
+ .toc-title em { font-style: italic; color: var(--gold-700); }
296
+
297
+ .toc-list {
298
+ list-style: none;
299
+ border-top: 1px solid var(--rule);
300
+ }
301
+ .toc-list li {
302
+ display: grid;
303
+ grid-template-columns: 26px 1fr 34px;
304
+ align-items: baseline;
305
+ column-gap: 12px;
306
+ padding: 6.5px 0;
307
+ border-bottom: 1px solid var(--rule);
308
+ }
309
+ .toc-num {
310
+ font-family: var(--serif);
311
+ font-style: italic;
312
+ font-size: 13px;
313
+ color: var(--gold-700);
314
+ }
315
+ .toc-name {
316
+ font-family: var(--serif);
317
+ font-size: 15.5px;
318
+ font-weight: 400;
319
+ color: var(--teal-900);
320
+ letter-spacing: 0.005em;
321
+ line-height: 1.25;
322
+ }
323
+ .toc-name span {
324
+ font-family: var(--sans);
325
+ font-size: 8.5px; font-weight: 400;
326
+ letter-spacing: 0.18em; text-transform: uppercase;
327
+ color: var(--slate-600);
328
+ display: block;
329
+ margin-top: 2px;
330
+ }
331
+ .toc-page-num {
332
+ font-family: var(--sans);
333
+ font-size: 10px; font-weight: 500;
334
+ letter-spacing: 0.2em;
335
+ color: var(--gold-700);
336
+ text-align: right;
337
+ }
338
+
339
+ .toc-credit {
340
+ margin-top: auto;
341
+ font-family: var(--body-serif);
342
+ font-style: italic;
343
+ font-size: 11px;
344
+ color: var(--slate-600);
345
+ line-height: 1.55;
346
+ }
347
+ .toc-credit strong { font-style: normal; color: var(--teal-900); font-weight: 600; }
348
+ .toc-credit .brand-mark {
349
+ display: block;
350
+ font-family: var(--sans);
351
+ font-style: normal;
352
+ font-size: 10px; font-weight: 500;
353
+ letter-spacing: 0.32em; text-transform: uppercase;
354
+ color: var(--gold-700);
355
+ margin-bottom: 10px;
356
+ }
357
+
358
+ /* ═══════════════════════════════════════════════════
359
+ SHARED EDITORIAL STYLES
360
+ ═══════════════════════════════════════════════════ */
361
+ .ed-eyebrow {
362
+ font-family: var(--sans);
363
+ font-size: 9.5px; font-weight: 500;
364
+ letter-spacing: 0.42em; text-transform: uppercase;
365
+ color: var(--gold-700);
366
+ margin-bottom: 8px;
367
+ }
368
+ .ed-rule { width: 32px; height: 1px; background: var(--gold-500); margin: 8px 0 14px; }
369
+
370
+ .ed-headline {
371
+ font-family: var(--serif);
372
+ font-weight: 400;
373
+ font-size: 50px;
374
+ line-height: 0.98;
375
+ letter-spacing: -0.012em;
376
+ color: var(--teal-900);
377
+ }
378
+ .ed-headline em { font-style: italic; font-weight: 400; color: var(--gold-700); }
379
+ .ed-headline.smaller { font-size: 38px; }
380
+
381
+ .ed-deck {
382
+ font-family: var(--serif);
383
+ font-style: italic;
384
+ font-weight: 400;
385
+ font-size: 17px;
386
+ line-height: 1.42;
387
+ color: var(--teal-700);
388
+ margin-top: 16px;
389
+ letter-spacing: 0.005em;
390
+ }
391
+
392
+ .ed-body {
393
+ font-family: var(--body-serif);
394
+ font-size: 10.5px; font-weight: 400;
395
+ line-height: 1.62;
396
+ color: #1a2026;
397
+ text-align: left;
398
+ hyphens: none;
399
+ letter-spacing: 0.005em;
400
+ }
401
+ .ed-body + .ed-body { margin-top: 9px; }
402
+ .ed-body strong { color: var(--teal-900); font-weight: 600; }
403
+ .ed-body em { color: var(--gold-700); font-style: italic; }
404
+
405
+ .ed-body.dropcap::first-letter {
406
+ font-family: var(--serif);
407
+ font-style: italic;
408
+ font-weight: 400;
409
+ font-size: 68px;
410
+ line-height: 0.85;
411
+ float: left;
412
+ color: var(--gold-700);
413
+ padding: 6px 10px 0 0;
414
+ margin-top: 4px;
415
+ }
416
+
417
+ .ed-caption {
418
+ font-family: var(--serif);
419
+ font-style: italic;
420
+ font-size: 11px;
421
+ color: var(--slate-600);
422
+ line-height: 1.5;
423
+ letter-spacing: 0.01em;
424
+ margin-top: 6px;
425
+ }
426
+ .ed-caption strong { font-style: normal; color: var(--teal-900); font-weight: 500; }
427
+
428
+ .ed-pullquote {
429
+ font-family: var(--serif);
430
+ font-style: italic;
431
+ font-weight: 400;
432
+ font-size: 26px;
433
+ line-height: 1.22;
434
+ color: var(--teal-900);
435
+ letter-spacing: -0.005em;
436
+ padding: 12px 0 14px;
437
+ border-top: 1px solid var(--rule);
438
+ border-bottom: 1px solid var(--rule);
439
+ }
440
+ .ed-pullquote::before {
441
+ content: '“';
442
+ display: block;
443
+ font-size: 50px;
444
+ line-height: 0.6;
445
+ color: var(--gold-500);
446
+ margin-bottom: 8px;
447
+ }
448
+ .ed-pullquote .attrib {
449
+ display: block;
450
+ font-family: var(--sans);
451
+ font-style: normal;
452
+ font-size: 9px; font-weight: 500;
453
+ letter-spacing: 0.32em; text-transform: uppercase;
454
+ color: var(--slate-600);
455
+ margin-top: 12px;
456
+ }
457
+
458
+ .ed-stat {
459
+ border-top: 1px solid var(--rule);
460
+ padding-top: 8px;
461
+ }
462
+ .ed-stat .v {
463
+ font-family: var(--serif);
464
+ font-size: 36px; font-weight: 400;
465
+ line-height: 1;
466
+ color: var(--teal-900);
467
+ letter-spacing: -0.01em;
468
+ }
469
+ .ed-stat .v em { font-style: italic; color: var(--gold-700); }
470
+ .ed-stat .l {
471
+ font-family: var(--sans);
472
+ font-size: 8.5px; font-weight: 400;
473
+ letter-spacing: 0.28em; text-transform: uppercase;
474
+ color: var(--slate-600);
475
+ margin-top: 8px;
476
+ }
477
+
478
+ /* ═══════════════════════════════════════════════════
479
+ SPREAD 01 — OPENER (Pont Street-style two-page editorial)
480
+ Big serif title left, hero photo right
481
+ ═══════════════════════════════════════════════════ */
482
+ .opener {
483
+ display: grid;
484
+ grid-template-columns: 1fr 1.35fr;
485
+ height: 100%;
486
+ }
487
+ .opener-text {
488
+ padding: 18mm 14mm 14mm 18mm;
489
+ display: flex; flex-direction: column;
490
+ }
491
+ .opener-spec {
492
+ margin-top: 10px;
493
+ font-family: var(--serif);
494
+ font-style: italic;
495
+ font-size: 16px;
496
+ color: var(--gold-700);
497
+ letter-spacing: 0.01em;
498
+ }
499
+ .opener-spec strong { font-style: normal; font-weight: 500; color: var(--teal-900); }
500
+
501
+ .opener-title {
502
+ font-family: var(--serif);
503
+ font-style: italic;
504
+ font-weight: 400;
505
+ font-size: 72px;
506
+ line-height: 0.96;
507
+ letter-spacing: -0.016em;
508
+ color: var(--teal-900);
509
+ margin: 14px 0 0;
510
+ }
511
+ .opener-title em {
512
+ display: block;
513
+ font-style: italic;
514
+ font-weight: 400;
515
+ color: var(--gold-700);
516
+ font-size: 0.36em;
517
+ line-height: 1.2;
518
+ margin-top: 8px;
519
+ letter-spacing: 0.18em;
520
+ text-transform: uppercase;
521
+ font-family: var(--sans);
522
+ }
523
+
524
+ .opener-meta-row {
525
+ display: flex; flex-wrap: nowrap; gap: 14px;
526
+ margin: 18px 0 16px;
527
+ padding: 12px 0;
528
+ border-top: 1px solid var(--rule);
529
+ border-bottom: 1px solid var(--rule);
530
+ font-variant-numeric: tabular-nums;
531
+ }
532
+ .opener-meta-row .item {
533
+ flex: 0 1 auto;
534
+ min-width: 0;
535
+ white-space: nowrap;
536
+ font-family: var(--serif);
537
+ }
538
+ .opener-meta-row .item .k {
539
+ font-family: var(--sans);
540
+ font-size: 8.5px; font-weight: 500;
541
+ letter-spacing: 0.22em; text-transform: uppercase;
542
+ color: var(--slate-600);
543
+ display: block; margin-bottom: 4px;
544
+ white-space: nowrap;
545
+ }
546
+ .opener-meta-row .item .v {
547
+ font-family: var(--serif);
548
+ font-size: 17px; font-weight: 400;
549
+ color: var(--teal-900);
550
+ letter-spacing: 0;
551
+ white-space: nowrap;
552
+ }
553
+ .opener-meta-row .item .v em { font-style: italic; color: var(--gold-700); white-space: nowrap; }
554
+
555
+ .opener-body { margin-top: auto; }
556
+ .opener-body .ed-body { font-size: 10.5px; line-height: 1.58; }
557
+
558
+ .opener-image {
559
+ position: relative;
560
+ overflow: hidden;
561
+ }
562
+ .opener-image img { width: 100%; height: 100%; object-fit: cover; }
563
+ .opener-image::after {
564
+ content: '';
565
+ position: absolute; inset: 0;
566
+ background: linear-gradient(180deg, transparent 60%, rgba(14,20,24,0.18) 100%);
567
+ }
568
+ .opener-image .img-caption {
569
+ position: absolute;
570
+ bottom: 12mm; right: 12mm;
571
+ padding: 12px 16px 14px;
572
+ background: rgba(14,20,24,0.78);
573
+ border-right: 1px solid var(--gold-300);
574
+ font-family: var(--serif);
575
+ font-style: italic;
576
+ font-weight: 400;
577
+ font-size: 14px;
578
+ color: var(--paper-0);
579
+ text-align: right;
580
+ line-height: 1.5;
581
+ max-width: 320px;
582
+ }
583
+ .opener-image .img-caption::before { display: none; }
584
+
585
+ /* ═══════════════════════════════════════════════════
586
+ SPREAD 02 — STORY: ground floor / living
587
+ Mosaic with narrative column
588
+ ═══════════════════════════════════════════════════ */
589
+ .spread {
590
+ padding: 14mm 14mm 16mm;
591
+ height: 100%;
592
+ display: grid;
593
+ gap: 10px;
594
+ }
595
+
596
+ .spread-2 {
597
+ grid-template-columns: 1.1fr 1fr 1.1fr;
598
+ grid-template-rows: 1fr 56mm;
599
+ min-height: 0;
600
+ }
601
+ .spread-2 .hero-img {
602
+ grid-column: 1 / 3;
603
+ grid-row: 1;
604
+ overflow: hidden;
605
+ position: relative;
606
+ min-height: 0;
607
+ }
608
+ .spread-2 .hero-img img { width: 100%; height: 100%; object-fit: cover; }
609
+
610
+ .spread-2 .text-col {
611
+ grid-column: 3;
612
+ grid-row: 1;
613
+ padding: 2mm 0 0 4mm;
614
+ display: flex; flex-direction: column;
615
+ min-height: 0;
616
+ overflow: hidden;
617
+ }
618
+
619
+ .spread-2 .strip {
620
+ grid-column: 1 / 4;
621
+ grid-row: 2;
622
+ margin-top: 2mm;
623
+ display: grid;
624
+ grid-template-columns: 1fr 1fr 1fr;
625
+ gap: 14px;
626
+ }
627
+ .spread-2 .strip-cell { display: flex; flex-direction: column; gap: 6px; }
628
+ .spread-2 .strip-cell img {
629
+ width: 100%; height: 42mm; object-fit: cover;
630
+ }
631
+
632
+ /* ═══════════════════════════════════════════════════
633
+ SPREAD 03 — RECEPTION ROOMS / HALL
634
+ Asymmetric: left big text, right offset photo column
635
+ ═══════════════════════════════════════════════════ */
636
+ .spread-3 {
637
+ grid-template-columns: 1fr 1fr;
638
+ grid-template-rows: 60mm 1fr;
639
+ column-gap: 18px;
640
+ row-gap: 8px;
641
+ min-height: 0;
642
+ }
643
+ .spread-3 .head {
644
+ grid-column: 1 / 3;
645
+ grid-row: 1;
646
+ display: grid;
647
+ grid-template-columns: 1fr 1fr;
648
+ column-gap: 22px;
649
+ align-items: end;
650
+ overflow: hidden;
651
+ }
652
+ .spread-3 .head .right { padding-left: 0; }
653
+
654
+ .spread-3 .left-img {
655
+ grid-column: 1;
656
+ grid-row: 2;
657
+ position: relative;
658
+ overflow: hidden;
659
+ }
660
+ .spread-3 .left-img img { width: 100%; height: 100%; object-fit: cover; }
661
+
662
+ .spread-3 .right-stack {
663
+ grid-column: 2;
664
+ grid-row: 2;
665
+ display: grid;
666
+ grid-template-rows: 1fr 1fr;
667
+ row-gap: 10px;
668
+ min-height: 0;
669
+ }
670
+ .spread-3 .right-stack .cell { position: relative; overflow: hidden; min-height: 0; }
671
+ .spread-3 .right-stack img { width: 100%; height: 100%; object-fit: cover; }
672
+ .spread-3 .right-stack img { width: 100%; height: 100%; object-fit: cover; }
673
+
674
+ /* ═══════════════════════════════════════════════════
675
+ SPREAD 04 — BEDROOMS GALLERY (Savills-style)
676
+ Tile grid + sidebar text
677
+ ═══════════════════════════════════════════════════ */
678
+ .spread-4 {
679
+ grid-template-columns: 1fr 2.1fr;
680
+ grid-template-rows: auto 1fr;
681
+ column-gap: 18px;
682
+ row-gap: 12px;
683
+ }
684
+ .spread-4 .text-side {
685
+ grid-column: 1;
686
+ grid-row: 1 / 3;
687
+ padding-right: 6mm;
688
+ display: flex; flex-direction: column;
689
+ }
690
+ .spread-4 .gallery {
691
+ grid-column: 2;
692
+ grid-row: 1 / 3;
693
+ display: grid;
694
+ grid-template-columns: 1.4fr 1fr 1fr;
695
+ grid-template-rows: 1fr 1fr;
696
+ gap: 10px;
697
+ }
698
+ .spread-4 .gallery .cell { position: relative; overflow: hidden; }
699
+ .spread-4 .gallery .cell img { width: 100%; height: 100%; object-fit: cover; }
700
+ .spread-4 .gallery .cell.tall { grid-row: 1 / 3; }
701
+
702
+ /* ═══════════════════════════════════════════════════
703
+ SPREAD 05 — ANNEXE FEATURE: full-bleed photo + side panel
704
+ ═══════════════════════════════════════════════════ */
705
+ .feature-page {
706
+ display: grid;
707
+ grid-template-columns: 1.45fr 1fr;
708
+ height: 100%;
709
+ }
710
+ .feature-page .photo {
711
+ position: relative; overflow: hidden;
712
+ }
713
+ .feature-page .photo img { width: 100%; height: 100%; object-fit: cover; }
714
+ .feature-page .photo::after {
715
+ content: '';
716
+ position: absolute; inset: 0;
717
+ background: linear-gradient(180deg, transparent 60%, rgba(14,20,24,0.18) 100%);
718
+ }
719
+ .feature-page .photo .photo-caption {
720
+ position: absolute;
721
+ bottom: 12mm; left: 12mm; right: 12mm;
722
+ padding: 12px 16px 14px;
723
+ background: rgba(14,20,24,0.78);
724
+ border-left: 1px solid var(--gold-300);
725
+ font-family: var(--serif);
726
+ font-style: italic;
727
+ font-weight: 400;
728
+ font-size: 14px;
729
+ color: var(--paper-0);
730
+ line-height: 1.5;
731
+ max-width: 75%;
732
+ }
733
+ .feature-page .photo .photo-caption::before { display: none; }
734
+
735
+ .feature-page .panel {
736
+ background: var(--paper-100);
737
+ padding: 22mm 14mm 18mm 16mm;
738
+ display: flex; flex-direction: column;
739
+ position: relative;
740
+ }
741
+ .feature-page .panel::before {
742
+ content: '';
743
+ position: absolute;
744
+ top: 14mm; left: 16mm; right: 14mm;
745
+ height: 1px;
746
+ background: var(--gold-500);
747
+ }
748
+
749
+ /* Annexe attribute cards */
750
+ .attr-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; margin-top: 14px; }
751
+ .attr {
752
+ border-top: 1px solid var(--rule);
753
+ padding: 8px 0 4px;
754
+ }
755
+ .attr .k {
756
+ font-family: var(--sans);
757
+ font-size: 8px; font-weight: 500;
758
+ letter-spacing: 0.28em; text-transform: uppercase;
759
+ color: var(--gold-700);
760
+ margin-bottom: 4px;
761
+ }
762
+ .attr .v {
763
+ font-family: var(--serif);
764
+ font-size: 14px;
765
+ color: var(--teal-900);
766
+ line-height: 1.3;
767
+ letter-spacing: 0.005em;
768
+ }
769
+
770
+ /* ═══════════════════════════════════════════════════
771
+ SPREAD 06 — GROUNDS & DEVELOPMENT
772
+ Big landscape image top, two-column text under
773
+ ═══════════════════════════════════════════════════ */
774
+ .spread-6 {
775
+ grid-template-columns: 1fr 1fr 1fr 1fr;
776
+ grid-template-rows: 1.1fr auto;
777
+ row-gap: 14px;
778
+ column-gap: 14px;
779
+ }
780
+ .spread-6 .top-image {
781
+ grid-column: 1 / 5;
782
+ grid-row: 1;
783
+ position: relative; overflow: hidden;
784
+ }
785
+ .spread-6 .top-image img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 60%; }
786
+ .spread-6 .top-image::after {
787
+ content: '';
788
+ position: absolute; inset: 0;
789
+ background: linear-gradient(180deg, rgba(14,20,24,0.32) 0%, rgba(14,20,24,0.10) 30%, rgba(14,20,24,0) 55%, rgba(14,20,24,0) 75%, rgba(14,20,24,0.45) 100%);
790
+ }
791
+ .spread-6 .top-image .overlay {
792
+ position: absolute;
793
+ top: 12mm; left: 12mm;
794
+ max-width: 60%;
795
+ padding: 14px 18px 16px;
796
+ background: rgba(14,20,24,0.78);
797
+ color: var(--paper-0);
798
+ border-left: 1px solid var(--gold-300);
799
+ }
800
+ .spread-6 .top-image .overlay .ed-eyebrow { color: var(--gold-300); margin-bottom: 6px; }
801
+ .spread-6 .top-image .overlay .ed-rule { background: var(--gold-300); margin: 6px 0 12px; }
802
+ .spread-6 .top-image .overlay .ed-headline { color: var(--paper-0); font-size: 38px; line-height: 1.0; }
803
+ .spread-6 .top-image .overlay .ed-headline em { color: var(--gold-300); }
804
+ .spread-6 .top-image .overlay .ed-eyebrow { color: var(--gold-300); }
805
+ .spread-6 .top-image .overlay .ed-rule { background: var(--gold-300); }
806
+ .spread-6 .top-image .overlay .ed-headline { color: var(--paper-0); font-size: 44px; }
807
+ .spread-6 .top-image .overlay .ed-headline em { color: var(--gold-300); }
808
+
809
+ .spread-6 .bottom { grid-row: 2; grid-column: span 1; }
810
+ .spread-6 .bottom h4 {
811
+ font-family: var(--serif);
812
+ font-size: 19px; font-weight: 500;
813
+ color: var(--teal-900);
814
+ margin-bottom: 6px;
815
+ letter-spacing: 0.005em;
816
+ }
817
+ .spread-6 .bottom h4 em { font-style: italic; font-weight: 400; color: var(--gold-700); }
818
+ .spread-6 .bottom .ed-body { font-size: 10px; }
819
+
820
+ /* ═══════════════════════════════════════════════════
821
+ SPREAD 07 — FLOORPLAN & SPECIFICATION
822
+ ═══════════════════════════════════════════════════ */
823
+ .spread-7 {
824
+ grid-template-columns: 1.4fr 1fr;
825
+ grid-template-rows: auto 1fr;
826
+ column-gap: 22px;
827
+ row-gap: 10px;
828
+ }
829
+ .spread-7 .header {
830
+ grid-column: 1 / 3;
831
+ }
832
+ .spread-7 .plan-area {
833
+ grid-column: 1;
834
+ grid-row: 2;
835
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
836
+ }
837
+ .spread-7 .plan-area img {
838
+ max-width: 100%;
839
+ max-height: 130mm;
840
+ width: auto; height: auto;
841
+ object-fit: contain;
842
+ }
843
+ .spread-7 .plan-area .meta {
844
+ margin-top: 10px;
845
+ text-align: center;
846
+ }
847
+ .spread-7 .plan-area .meta .lead {
848
+ font-family: var(--serif);
849
+ font-size: 16px; font-weight: 400;
850
+ color: var(--teal-900);
851
+ letter-spacing: 0.005em;
852
+ }
853
+ .spread-7 .plan-area .meta .lead em { font-style: italic; color: var(--gold-700); }
854
+ .spread-7 .plan-area .meta .sub {
855
+ font-family: var(--sans);
856
+ font-size: 9px; font-weight: 300;
857
+ color: var(--slate-600);
858
+ letter-spacing: 0.16em; text-transform: uppercase;
859
+ margin-top: 4px;
860
+ }
861
+
862
+ .spec-side {
863
+ grid-column: 2;
864
+ grid-row: 2;
865
+ border-left: 1px solid var(--rule);
866
+ padding-left: 18px;
867
+ display: flex; flex-direction: column;
868
+ }
869
+ .spec-list {
870
+ list-style: none;
871
+ margin-top: 8px;
872
+ }
873
+ .spec-list li {
874
+ display: grid;
875
+ grid-template-columns: 24px 1fr;
876
+ column-gap: 12px;
877
+ padding: 7px 0;
878
+ border-bottom: 1px solid var(--rule-soft);
879
+ font-family: var(--sans);
880
+ font-size: 9.5px; font-weight: 300;
881
+ line-height: 1.5;
882
+ color: #2c3535;
883
+ }
884
+ .spec-list li:last-child { border-bottom: none; }
885
+ .spec-list li .num {
886
+ font-family: var(--serif);
887
+ font-style: italic;
888
+ font-size: 11px;
889
+ color: var(--gold-700);
890
+ }
891
+ .spec-list li strong { color: var(--teal-900); font-weight: 500; }
892
+
893
+ /* Location map — conditional. The slot lives between BROCHURE_MAP_SLOT_START / END
894
+ markers in the page-9 .spec-side block. property-extract screenshots whatever map
895
+ element the listing exposes (Google iframe, Mapbox/Leaflet div, static-map image,
896
+ etc.) — provider-agnostic — and saves the bytes as images/map.webp. When the slot
897
+ is non-null in property.json, the brochure agent leaves the block in place.
898
+ When the listing has no map, the agent deletes everything between the markers
899
+ (inclusive). Extract or omit — never synthesise. */
900
+ .location-map {
901
+ margin: 14px 0 0 0;
902
+ padding: 0;
903
+ border: 1px solid var(--rule);
904
+ background: var(--paper-100, #f6f1ea);
905
+ aspect-ratio: 16 / 10;
906
+ overflow: hidden;
907
+ position: relative;
908
+ display: flex; flex-direction: column;
909
+ }
910
+ .location-map img {
911
+ width: 100%; height: 100%;
912
+ object-fit: cover;
913
+ display: block;
914
+ }
915
+ .location-map figcaption {
916
+ position: absolute;
917
+ left: 0; right: 0; bottom: 0;
918
+ padding: 4px 8px;
919
+ background: rgba(252, 251, 248, 0.92);
920
+ font-family: var(--serif);
921
+ font-style: italic;
922
+ font-size: 8.5px;
923
+ line-height: 1.4;
924
+ color: var(--ink);
925
+ letter-spacing: 0.005em;
926
+ text-align: right;
927
+ border-top: 1px solid var(--rule);
928
+ }
929
+
930
+ /* EPC bars */
931
+ .epc-block { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rule); }
932
+ .epc-title {
933
+ font-family: var(--serif);
934
+ font-size: 14px; font-weight: 500;
935
+ color: var(--teal-900);
936
+ margin-bottom: 8px;
937
+ letter-spacing: 0.005em;
938
+ }
939
+ .epc-title em { font-style: italic; color: var(--gold-700); }
940
+ .epc-bars { display: flex; gap: 2px; }
941
+ .epc-bar {
942
+ flex: 1;
943
+ height: 18px;
944
+ display: flex; align-items: center; justify-content: center;
945
+ font-family: var(--sans);
946
+ font-size: 9px; font-weight: 600;
947
+ color: white;
948
+ }
949
+ .epc-bar.a { background: #008054; }
950
+ .epc-bar.b { background: #19b459; }
951
+ .epc-bar.c { background: #8dce46; color: #1c2222; }
952
+ .epc-bar.d { background: #ffd500; color: #1c2222; }
953
+ .epc-bar.e { background: #fcaa65; color: #1c2222; }
954
+ .epc-bar.f { background: #ef8023; }
955
+ .epc-bar.g { background: #e9153b; }
956
+ .epc-bar.current {
957
+ outline: 2px solid var(--ink);
958
+ outline-offset: 2px;
959
+ z-index: 2;
960
+ position: relative;
961
+ }
962
+
963
+ /* ═══════════════════════════════════════════════════
964
+ SPREAD 08 — MATERIAL INFORMATION
965
+ Editorial directory style
966
+ ═══════════════════════════════════════════════════ */
967
+ .mi-page { padding: 18mm 14mm; height: 100%; display: flex; flex-direction: column; }
968
+ .mi-head { display: grid; grid-template-columns: 2fr 3fr; column-gap: 24px; align-items: end; margin-bottom: 14px; }
969
+ .mi-intro {
970
+ font-family: var(--serif);
971
+ font-style: italic;
972
+ font-size: 13px;
973
+ line-height: 1.55;
974
+ color: var(--teal-700);
975
+ border-left: 1px solid var(--gold-500);
976
+ padding-left: 14px;
977
+ }
978
+ .mi-grid {
979
+ display: grid;
980
+ grid-template-columns: 1fr 1fr 1fr;
981
+ column-gap: 24px;
982
+ row-gap: 18px;
983
+ margin-top: 6px;
984
+ }
985
+ .mi-section .mi-label {
986
+ font-family: var(--sans);
987
+ font-size: 9px; font-weight: 500;
988
+ letter-spacing: 0.36em; text-transform: uppercase;
989
+ color: var(--gold-700);
990
+ border-bottom: 1px solid var(--gold-500);
991
+ padding-bottom: 6px;
992
+ margin-bottom: 8px;
993
+ }
994
+ .mi-section .mi-row {
995
+ display: flex; justify-content: space-between; align-items: baseline;
996
+ padding: 6px 0;
997
+ border-bottom: 1px solid var(--rule-soft);
998
+ font-family: var(--sans);
999
+ font-size: 9.5px;
1000
+ column-gap: 10px;
1001
+ }
1002
+ .mi-section .mi-row:last-child { border-bottom: none; }
1003
+ .mi-section .mi-row .k {
1004
+ color: var(--slate-600); font-weight: 300;
1005
+ }
1006
+ .mi-section .mi-row .v {
1007
+ color: var(--teal-900); font-weight: 400;
1008
+ text-align: right;
1009
+ font-family: var(--serif);
1010
+ font-size: 11.5px;
1011
+ letter-spacing: 0.01em;
1012
+ }
1013
+ .mi-foot {
1014
+ margin-top: auto;
1015
+ padding-top: 14px;
1016
+ border-top: 1px solid var(--rule);
1017
+ font-family: var(--serif);
1018
+ font-style: italic;
1019
+ font-size: 11px;
1020
+ color: var(--slate-600);
1021
+ line-height: 1.55;
1022
+ }
1023
+
1024
+ /* ═══════════════════════════════════════════════════
1025
+ BACK PAGE
1026
+ ═══════════════════════════════════════════════════ */
1027
+ .backpage {
1028
+ background: var(--teal-950);
1029
+ color: var(--paper-25);
1030
+ }
1031
+ .backpage .bg { position: absolute; inset: 0; }
1032
+ .backpage .bg img { width: 100%; height: 100%; object-fit: cover; opacity: 0.32; }
1033
+ .backpage .bg::after {
1034
+ content: '';
1035
+ position: absolute; inset: 0;
1036
+ background:
1037
+ radial-gradient(ellipse 60% 60% at 50% 40%, rgba(201,176,122,0.12) 0%, transparent 70%),
1038
+ linear-gradient(180deg, rgba(14,20,24,0.62) 0%, rgba(14,20,24,0.50) 50%, rgba(14,20,24,0.92) 100%);
1039
+ }
1040
+
1041
+ .backpage-frame {
1042
+ position: absolute;
1043
+ top: 14mm; left: 14mm; right: 14mm; bottom: 14mm;
1044
+ border: 1px solid rgba(229, 210, 168, 0.32);
1045
+ z-index: 1;
1046
+ pointer-events: none;
1047
+ }
1048
+
1049
+ .backpage-inner {
1050
+ position: relative; z-index: 2;
1051
+ height: 100%;
1052
+ padding: 22mm 28mm 18mm;
1053
+ display: flex; flex-direction: column;
1054
+ align-items: center; justify-content: center;
1055
+ text-align: center;
1056
+ }
1057
+ .backpage-inner .back-mast { margin-bottom: 18px; }
1058
+ .back-mast {
1059
+ display: flex; align-items: center; justify-content: center; gap: 16px;
1060
+ font-family: var(--sans);
1061
+ font-size: 10px; font-weight: 400;
1062
+ letter-spacing: 0.55em; text-transform: uppercase;
1063
+ color: rgba(229, 210, 168, 0.82);
1064
+ margin-bottom: 22px;
1065
+ }
1066
+ .back-mast img.back-mast-logo {
1067
+ height: 36px; width: auto; display: block;
1068
+ filter: drop-shadow(0 2px 12px rgba(0,0,0,0.45));
1069
+ }
1070
+ .back-mast .pipe { width: 1px; height: 18px; background: rgba(229, 210, 168, 0.55); }
1071
+ .back-mast .brand { font-family: var(--sans); font-size: 11px; font-weight: 500; letter-spacing: 0.42em; text-transform: uppercase; color: rgba(229, 210, 168, 0.95); }
1072
+ .back-mast .label { letter-spacing: 0.45em; text-transform: uppercase; color: rgba(229, 210, 168, 0.88); }
1073
+
1074
+ /* QR strip on the back page */
1075
+ .back-qr-strip {
1076
+ display: flex; gap: 28px; justify-content: center; align-items: flex-start;
1077
+ margin-top: 22px;
1078
+ }
1079
+ .back-qr-strip a.qr {
1080
+ display: flex; flex-direction: column; align-items: center; gap: 6px;
1081
+ text-decoration: none;
1082
+ color: inherit;
1083
+ transition: opacity 200ms ease;
1084
+ }
1085
+ .back-qr-strip a.qr:hover { opacity: 0.85; }
1086
+ .back-qr-strip .qr img {
1087
+ width: 72px; height: 72px;
1088
+ background: var(--paper-0);
1089
+ padding: 6px;
1090
+ border: 1px solid rgba(229, 210, 168, 0.32);
1091
+ }
1092
+ .back-qr-strip .qr-label {
1093
+ font-family: var(--sans);
1094
+ font-size: 8px; font-weight: 500;
1095
+ letter-spacing: 0.28em; text-transform: uppercase;
1096
+ color: rgba(229, 210, 168, 0.78);
1097
+ text-align: center;
1098
+ }
1099
+ .back-qr-strip .qr-label em { font-style: italic; color: var(--gold-300); text-transform: none; letter-spacing: 0.04em; font-family: var(--body-serif); font-size: 11px; font-weight: 400; display: block; margin-top: 3px; }
1100
+ .back-qr-strip .qr-link {
1101
+ font-family: var(--sans);
1102
+ font-size: 9px; font-weight: 400;
1103
+ letter-spacing: 0.04em; text-transform: none;
1104
+ color: var(--gold-300);
1105
+ text-align: center;
1106
+ text-decoration: underline;
1107
+ text-decoration-color: rgba(201, 176, 122, 0.45);
1108
+ text-underline-offset: 3px;
1109
+ margin-top: 4px;
1110
+ font-variant-numeric: tabular-nums;
1111
+ }
1112
+ .back-contact-grid .cell .name .dot { color: rgba(229,210,168,0.6); font-style: normal; }
1113
+
1114
+ .back-headline {
1115
+ font-family: var(--serif);
1116
+ font-style: italic;
1117
+ font-weight: 400;
1118
+ font-size: 60px;
1119
+ line-height: 1.04;
1120
+ letter-spacing: -0.012em;
1121
+ color: var(--paper-0);
1122
+ margin-bottom: 12px;
1123
+ }
1124
+ .back-headline em { font-style: italic; color: var(--gold-300); }
1125
+
1126
+ .back-tagline {
1127
+ font-family: var(--serif);
1128
+ font-style: italic;
1129
+ font-size: 17px;
1130
+ color: rgba(252,251,248,0.82);
1131
+ line-height: 1.5;
1132
+ max-width: 540px;
1133
+ margin: 0 auto 28px;
1134
+ }
1135
+ .back-rule {
1136
+ width: 56px; height: 1px;
1137
+ background: var(--gold-500);
1138
+ margin: 0 auto 20px;
1139
+ }
1140
+
1141
+ .back-contact-grid {
1142
+ display: grid;
1143
+ grid-template-columns: 1fr 1fr;
1144
+ gap: 36px;
1145
+ max-width: 540px;
1146
+ margin: 0 auto;
1147
+ text-align: left;
1148
+ }
1149
+ .back-contact-grid .cell .k {
1150
+ font-family: var(--sans);
1151
+ font-size: 9px; font-weight: 500;
1152
+ letter-spacing: 0.32em; text-transform: uppercase;
1153
+ color: rgba(229, 210, 168, 0.7);
1154
+ margin-bottom: 8px;
1155
+ border-bottom: 1px solid rgba(229,210,168,0.25);
1156
+ padding-bottom: 6px;
1157
+ }
1158
+ .back-contact-grid .cell .name {
1159
+ font-family: var(--serif);
1160
+ font-size: 19px;
1161
+ color: var(--paper-0);
1162
+ margin-bottom: 6px;
1163
+ letter-spacing: 0.005em;
1164
+ }
1165
+ .back-contact-grid .cell .name em { font-style: italic; color: var(--gold-300); }
1166
+ .back-contact-grid .cell .line {
1167
+ font-family: var(--sans);
1168
+ font-size: 11px; font-weight: 300;
1169
+ color: rgba(252,251,248,0.85);
1170
+ line-height: 1.7;
1171
+ }
1172
+
1173
+ .back-foot {
1174
+ position: absolute;
1175
+ bottom: 28mm; left: 28mm; right: 28mm;
1176
+ z-index: 2;
1177
+ display: flex; justify-content: space-between; align-items: flex-end;
1178
+ }
1179
+ .back-foot .left, .back-foot .right {
1180
+ font-family: var(--sans);
1181
+ font-size: 9px; font-weight: 400;
1182
+ letter-spacing: 0.28em; text-transform: uppercase;
1183
+ color: rgba(252,251,248,0.55);
1184
+ }
1185
+ .back-foot .right { text-align: right; }
1186
+ .back-foot em { font-style: normal; color: var(--gold-300); }
1187
+
1188
+ .back-disclaimer {
1189
+ position: absolute;
1190
+ bottom: 16mm; left: 28mm; right: 28mm;
1191
+ z-index: 2;
1192
+ font-family: var(--serif);
1193
+ font-style: italic;
1194
+ font-size: 9px;
1195
+ line-height: 1.55;
1196
+ color: rgba(252,251,248,0.45);
1197
+ text-align: center;
1198
+ }
1199
+
1200
+ /* ═══════════════════════════════════════════════════
1201
+ INTERMISSION / FULL-BLEED IMAGE PAGES
1202
+ Used between chapters; image is the page, with one
1203
+ small caption pill anchored bottom-left. The folio
1204
+ is the only other element. Lets the photography
1205
+ breathe between editorial spreads.
1206
+ ═══════════════════════════════════════════════════ */
1207
+ .page.intermission { padding: 0; background: var(--ink); }
1208
+ .full-bleed { position: relative; width: 100%; height: 100%; overflow: hidden; }
1209
+ .full-bleed > img { width: 100%; height: 100%; object-fit: cover; display: block; }
1210
+ .full-bleed::after {
1211
+ content: '';
1212
+ position: absolute; inset: 0;
1213
+ background: linear-gradient(180deg, transparent 50%, rgba(14,20,24,0.45) 100%);
1214
+ pointer-events: none;
1215
+ }
1216
+ .caption-pill {
1217
+ position: absolute;
1218
+ left: 14mm; bottom: 14mm;
1219
+ max-width: 60%;
1220
+ padding: 12px 16px 14px;
1221
+ background: rgba(14,20,24,0.72);
1222
+ color: var(--paper-0);
1223
+ border-left: 1px solid var(--gold-300);
1224
+ z-index: 2;
1225
+ }
1226
+ .caption-pill .ed-eyebrow-light {
1227
+ display: block;
1228
+ font-family: var(--sans);
1229
+ font-size: 9px; font-weight: 500;
1230
+ letter-spacing: 0.36em; text-transform: uppercase;
1231
+ color: var(--gold-300);
1232
+ margin-bottom: 7px;
1233
+ }
1234
+ .caption-pill .caption-text {
1235
+ display: block;
1236
+ font-family: var(--body-serif);
1237
+ font-size: 11.5px; font-weight: 400;
1238
+ line-height: 1.55;
1239
+ color: var(--paper-0);
1240
+ letter-spacing: 0.005em;
1241
+ }
1242
+ .caption-pill .caption-text em { font-style: italic; color: var(--gold-300); font-weight: 500; }
1243
+
1244
+ /* ═══════════════════════════════════════════════════
1245
+ IMAGE-LED GRID PAGE — additional internal coverage
1246
+ ═══════════════════════════════════════════════════ */
1247
+ .gallery-page {
1248
+ display: grid;
1249
+ grid-template-rows: 32mm 1fr;
1250
+ grid-template-columns: 1fr;
1251
+ height: 100%;
1252
+ padding: 14mm 14mm 16mm;
1253
+ gap: 10px;
1254
+ }
1255
+ .gallery-page .gallery-head { grid-row: 1; display: flex; flex-direction: column; justify-content: flex-end; }
1256
+ .gallery-page .gallery-grid {
1257
+ grid-row: 2;
1258
+ display: grid;
1259
+ grid-template-columns: 1fr 1fr 1fr;
1260
+ grid-template-rows: 1fr 1fr;
1261
+ gap: 10px;
1262
+ min-height: 0;
1263
+ }
1264
+ .gallery-page .gallery-cell { position: relative; overflow: hidden; min-height: 0; }
1265
+ .gallery-page .gallery-cell.tall { grid-row: 1 / 3; }
1266
+ .gallery-page .gallery-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
1267
+ .gallery-page .gallery-cell figcaption {
1268
+ position: absolute; left: 8px; right: 8px; bottom: 8px;
1269
+ padding: 6px 10px;
1270
+ background: rgba(14,20,24,0.72);
1271
+ color: var(--paper-0);
1272
+ font-family: var(--body-serif);
1273
+ font-style: italic;
1274
+ font-size: 9.5px; line-height: 1.4;
1275
+ border-left: 1px solid var(--gold-300);
1276
+ }
1277
+
1278
+ /* ═══════════════════════════════════════════════════
1279
+ SITE PLAN PAGE — dedicated page for plot plan
1280
+ ═══════════════════════════════════════════════════ */
1281
+ .siteplan-page {
1282
+ display: grid;
1283
+ grid-template-rows: 32mm 1fr 18mm;
1284
+ grid-template-columns: 1.4fr 1fr;
1285
+ height: 100%;
1286
+ padding: 14mm 14mm 16mm;
1287
+ gap: 12px 22px;
1288
+ }
1289
+ .siteplan-page .head { grid-column: 1 / 3; grid-row: 1; }
1290
+ .siteplan-page .plan-area {
1291
+ grid-column: 1; grid-row: 2;
1292
+ display: flex; align-items: center; justify-content: center;
1293
+ background: var(--paper-50);
1294
+ overflow: hidden;
1295
+ }
1296
+ .siteplan-page .plan-area img {
1297
+ max-width: 100%; max-height: 100%;
1298
+ width: auto; height: auto;
1299
+ object-fit: contain;
1300
+ }
1301
+ .siteplan-page .text-side {
1302
+ grid-column: 2; grid-row: 2;
1303
+ border-left: 1px solid var(--rule);
1304
+ padding-left: 18px;
1305
+ display: flex; flex-direction: column;
1306
+ gap: 12px;
1307
+ }
1308
+ .siteplan-page .text-side h4 {
1309
+ font-family: var(--body-serif);
1310
+ font-style: normal; font-weight: 500;
1311
+ font-size: 13px;
1312
+ color: var(--teal-900);
1313
+ letter-spacing: 0.005em;
1314
+ }
1315
+ .siteplan-page .text-side h4 em { font-style: italic; color: var(--gold-700); font-weight: 500; }
1316
+
1317
+ /* Strengthened text-on-image scrim for the feature page (page 7),
1318
+ per the user feedback that the body copy was hard to read against the photo */
1319
+ .feature-page .panel { background: var(--paper-100); }
1320
+
1321
+ /* ═══════════════════════════════════════════════════
1322
+ PRINT
1323
+ ═══════════════════════════════════════════════════ */
1324
+ .print-img {
1325
+ position: absolute;
1326
+ width: 1px;
1327
+ height: 1px;
1328
+ opacity: 0;
1329
+ pointer-events: none;
1330
+ z-index: -1;
1331
+ }
1332
+
1333
+ @page { size: A4 landscape; margin: 0; }
1334
+ @media print {
1335
+ html, body { background: white; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
1336
+ .download-bar { display: none !important; }
1337
+ .page { margin: 0; box-shadow: none; page-break-after: always; page-break-inside: avoid; overflow: hidden; }
1338
+ .page:last-of-type { page-break-after: auto; }
1339
+
1340
+ /* PRIMARY PATH — when print-img snapshots exist, hide everything else and show only the snapshot.
1341
+ The snapshot is a flat raster of the on-screen page (folio + all chrome baked in). */
1342
+ .page:has(.print-img[src]:not([src=""])) > *:not(.print-img) { display: none !important; }
1343
+ .print-img[src]:not([src=""]) {
1344
+ position: absolute !important;
1345
+ inset: 0 !important;
1346
+ width: 100% !important;
1347
+ height: 100% !important;
1348
+ opacity: 1 !important;
1349
+ object-fit: cover !important;
1350
+ z-index: 9999 !important;
1351
+ }
1352
+
1353
+ /* FALLBACK PATH — no snapshot present. Print the live DOM directly.
1354
+ Force folio reliability: drop backdrop-filter (Chrome's PDF engine strips it, pill goes invisible),
1355
+ lift z-index above any absolute imagery, and bring it 2mm inward of the printable edge. */
1356
+ .folio { z-index: 100 !important; bottom: 6mm !important; }
1357
+ .folio > span { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; background: rgba(252, 251, 248, 0.95) !important; }
1358
+ .page.folio-dark .folio > span { background: rgba(6, 68, 68, 0.78) !important; }
1359
+ .back-foot { z-index: 100 !important; }
1360
+
1361
+ * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
1362
+ }
1363
+ </style>
1364
+ </head>
1365
+ <body>
1366
+
1367
+ <div class="download-bar">
1368
+ <button class="download-btn" onclick="window.print()">
1369
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1370
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
1371
+ <polyline points="7 10 12 15 17 10"/>
1372
+ <line x1="12" y1="15" x2="12" y2="3"/>
1373
+ </svg>
1374
+ Download PDF
1375
+ </button>
1376
+ </div>
1377
+
1378
+
1379
+ <!-- ════════════════════════════════════════════════════
1380
+ COVER
1381
+ ════════════════════════════════════════════════════ -->
1382
+ <section class="page cover" data-screen-label="01 Cover">
1383
+ <img class="print-img" src="cover-print.png" alt="">
1384
+
1385
+ <div class="cover-paper">
1386
+ <div class="cover-title-line">
1387
+ <span class="flank"></span>
1388
+ <!-- REPLACE {{ property_name }}: the property's distinct house name
1389
+ (e.g. "Sparrows Farm", "Agincourt House") OR — if the property has
1390
+ no separate name — the street as a tracked-caps proper noun
1391
+ (e.g. "12 Henham Road"). All-caps display via CSS; the source
1392
+ should be Title Case. Capped at ~28 characters to fit between
1393
+ the gold flank rules. See placeholders.md for the picking rule. -->
1394
+ <h1 class="cover-title">{{ property_name }}</h1>
1395
+ <span class="flank"></span>
1396
+ </div>
1397
+
1398
+ <!-- REPLACE {{ address_subtitle }}: the postal address as four parts
1399
+ joined by " <em>·</em> " — typically "<street> · <locality> ·
1400
+ <county> · <postcode>". For a property without a separate house
1401
+ name the cover-title carries the street already; then the subtitle
1402
+ drops "<street>" and starts at "<locality>". Use a non-breaking
1403
+ space in the postcode (`NP7&nbsp;9TS`). Single line; will not wrap. -->
1404
+ <div class="cover-subtitle">{{ address_subtitle }}</div>
1405
+ </div>
1406
+
1407
+ <div class="cover-image">
1408
+ <!-- REPLACE {{ cover_hero_src }} / {{ cover_hero_alt }}: the strongest
1409
+ landscape exterior shot. By the images.md slot map this is
1410
+ {{ property_slug }}-01.webp (cover hero index). Alt text: property
1411
+ name + the moment captured (e.g. "...at golden hour", "...framed by
1412
+ the village green"). -->
1413
+ <img src="images/{{ cover_hero_src }}" alt="{{ cover_hero_alt }}">
1414
+ </div>
1415
+ </section>
1416
+
1417
+
1418
+ <!-- ════════════════════════════════════════════════════
1419
+ CONTENTS — page 2
1420
+ ════════════════════════════════════════════════════ -->
1421
+ <section class="page" data-screen-label="02 Contents">
1422
+ <img class="print-img" src="page2-print.png" alt="">
1423
+ <div class="toc-page">
1424
+ <div class="toc-image">
1425
+ <!-- REPLACE {{ toc_hero_src }} / {{ toc_hero_alt }}: an interior shot
1426
+ establishing character — typically the principal reception or the
1427
+ open-plan kitchen-dining. Slot index per images.md is normally
1428
+ {{ property_slug }}-07. Alt text: short factual description. -->
1429
+ <img src="images/{{ toc_hero_src }}" alt="{{ toc_hero_alt }}">
1430
+ <!-- REPLACE {{ toc_caption }}: ONE editorial sentence — the property's
1431
+ elevator pitch. 15-30 words. Italic register. Often distilled from
1432
+ seller brief Q5 ("the feeling on entry") + Q19 ("three words"). -->
1433
+ <div class="caption">{{ toc_caption }}</div>
1434
+ </div>
1435
+ <div class="toc-content">
1436
+ <div>
1437
+ <div class="toc-rule"></div>
1438
+ <h2 class="toc-title">Contents <em>&amp; itinerary</em></h2>
1439
+
1440
+ <!-- REPLACE {{ toc_chapter_N_title }} / {{ toc_chapter_N_sub }} /
1441
+ {{ toc_chapter_N_page }}: chapter titles, sub-lines and page
1442
+ numbers for chapters i–viii. The canonical eight-chapter arc
1443
+ is documented in references/structure.md (Of place & pedigree →
1444
+ A home at ease → Hall, hearth & sun → Bedrooms & baths →
1445
+ [feature page] → Garden & ground → Plan & particulars →
1446
+ Material information). Adapt the chapter titles to the property
1447
+ (e.g. "Pool, outdoor kitchen & summerhouse" becomes "Terrace
1448
+ & outdoor kitchen" when the property has no pool). PAGE NUMBERS
1449
+ MUST match the actual rendered pages (default: 03, 04, 06, 08,
1450
+ 10, 12, 14, 15 for the 16-page folio with intermissions). -->
1451
+ <ul class="toc-list">
1452
+ <li>
1453
+ <span class="toc-num">i.</span>
1454
+ <span class="toc-name">{{ toc_chapter_1_title }}<span>{{ toc_chapter_1_sub }}</span></span>
1455
+ <span class="toc-page-num">{{ toc_chapter_1_page }}</span>
1456
+ </li>
1457
+ <li>
1458
+ <span class="toc-num">ii.</span>
1459
+ <span class="toc-name">{{ toc_chapter_2_title }}<span>{{ toc_chapter_2_sub }}</span></span>
1460
+ <span class="toc-page-num">{{ toc_chapter_2_page }}</span>
1461
+ </li>
1462
+ <li>
1463
+ <span class="toc-num">iii.</span>
1464
+ <span class="toc-name">{{ toc_chapter_3_title }}<span>{{ toc_chapter_3_sub }}</span></span>
1465
+ <span class="toc-page-num">{{ toc_chapter_3_page }}</span>
1466
+ </li>
1467
+ <li>
1468
+ <span class="toc-num">iv.</span>
1469
+ <span class="toc-name">{{ toc_chapter_4_title }}<span>{{ toc_chapter_4_sub }}</span></span>
1470
+ <span class="toc-page-num">{{ toc_chapter_4_page }}</span>
1471
+ </li>
1472
+ <li>
1473
+ <span class="toc-num">v.</span>
1474
+ <span class="toc-name">{{ toc_chapter_5_title }}<span>{{ toc_chapter_5_sub }}</span></span>
1475
+ <span class="toc-page-num">{{ toc_chapter_5_page }}</span>
1476
+ </li>
1477
+ <li>
1478
+ <span class="toc-num">vi.</span>
1479
+ <span class="toc-name">{{ toc_chapter_6_title }}<span>{{ toc_chapter_6_sub }}</span></span>
1480
+ <span class="toc-page-num">{{ toc_chapter_6_page }}</span>
1481
+ </li>
1482
+ <li>
1483
+ <span class="toc-num">vii.</span>
1484
+ <span class="toc-name">{{ toc_chapter_7_title }}<span>{{ toc_chapter_7_sub }}</span></span>
1485
+ <span class="toc-page-num">{{ toc_chapter_7_page }}</span>
1486
+ </li>
1487
+ <li>
1488
+ <span class="toc-num">viii.</span>
1489
+ <span class="toc-name">{{ toc_chapter_8_title }}<span>{{ toc_chapter_8_sub }}</span></span>
1490
+ <span class="toc-page-num">{{ toc_chapter_8_page }}</span>
1491
+ </li>
1492
+ </ul>
1493
+ </div>
1494
+
1495
+ <!-- REPLACE {{ toc_credit }}: agent attribution. Two short lines:
1496
+ italic photo/floorplan note (boilerplate, see placeholders.md) then
1497
+ a <strong>Marketed by {{ brand_name }}</strong>, {{ brand_town }},
1498
+ {{ brand_county }}. line. -->
1499
+ <div class="toc-credit">
1500
+ Photographed in&#8209;situ. Floor plans drawn to indicative scale; areas in sq&nbsp;ft and m&sup2;.<br>
1501
+ <strong>Marketed by {{ brand_name }}</strong>, {{ brand_town }}, {{ brand_county }}.
1502
+ </div>
1503
+ </div>
1504
+ </div>
1505
+ <!-- REPLACE {{ folio_strip }}: "{{ property_name }} · {{ locality }}" —
1506
+ this exact pattern repeats on every interior page. The middle slot
1507
+ changes per page ({{ folio_mid_NN }}); the right slot is the page
1508
+ number (literal, matches the page index). -->
1509
+ <div class="folio">
1510
+ <span>{{ folio_strip }}</span>
1511
+ <span class="folio-mid">— <em>Contents</em> —</span>
1512
+ <span>02</span>
1513
+ </div>
1514
+ </section>
1515
+
1516
+
1517
+ <!-- ════════════════════════════════════════════════════
1518
+ OPENER — Spread 03 (Chapter I — Of place & pedigree)
1519
+ ════════════════════════════════════════════════════ -->
1520
+ <section class="page" data-screen-label="03 Opener">
1521
+ <img class="print-img" src="page3-print.png" alt="">
1522
+ <div class="opener">
1523
+ <div class="opener-text">
1524
+ <!-- REPLACE {{ chapter1_eyebrow }}: "Chapter I · <chapter1 title>".
1525
+ The chapter1 title is normally "Of place & pedigree" — adapt only
1526
+ if the property's narrative arc differs (rare). -->
1527
+ <div class="ed-eyebrow">{{ chapter1_eyebrow }}</div>
1528
+ <div class="ed-rule"></div>
1529
+ <!-- REPLACE {{ opener_title_main }} / {{ opener_title_sub }}: h2 with
1530
+ the property name as the main glyph and locality+county as the
1531
+ inline <em> sub-line. CSS renders the <em> as a smaller tracked-
1532
+ caps label. -->
1533
+ <h2 class="opener-title">{{ opener_title_main }}<em>{{ opener_title_sub }}</em></h2>
1534
+ <!-- REPLACE {{ opener_spec_line }}: "<strong><street></strong> ·
1535
+ <postcode> &nbsp;·&nbsp; <em>{{ price_line }}</em>" — keep the
1536
+ strong/em formatting; use the exact price qualifier from
1537
+ property.json (Offers Over / Guide Price / Asking Price). -->
1538
+ <div class="opener-spec">{{ opener_spec_line }}</div>
1539
+
1540
+ <!-- REPLACE {{ opener_meta_N_label }} / {{ opener_meta_N_value }}:
1541
+ five fixed slots — typically Bedrooms, Bathrooms, Receptions,
1542
+ Internal (sq ft), Plot (acres). Numbers come from property.json.
1543
+ If a slot is genuinely unknown (e.g. plot not surveyed, year
1544
+ unknown), drop that <div class="item"> rather than inventing
1545
+ a value — never synthesise. If the property has no acreage,
1546
+ substitute "Type" / "Detached <em>YYYY</em>" or similar. The
1547
+ row MUST NOT wrap — see copy.md "Stats rows". -->
1548
+ <div class="opener-meta-row">
1549
+ <div class="item">
1550
+ <span class="k">{{ opener_meta_1_label }}</span>
1551
+ <span class="v">{{ opener_meta_1_value }}</span>
1552
+ </div>
1553
+ <div class="item">
1554
+ <span class="k">{{ opener_meta_2_label }}</span>
1555
+ <span class="v">{{ opener_meta_2_value }}</span>
1556
+ </div>
1557
+ <div class="item">
1558
+ <span class="k">{{ opener_meta_3_label }}</span>
1559
+ <span class="v">{{ opener_meta_3_value }}</span>
1560
+ </div>
1561
+ <div class="item">
1562
+ <span class="k">{{ opener_meta_4_label }}</span>
1563
+ <span class="v">{{ opener_meta_4_value }}</span>
1564
+ </div>
1565
+ <div class="item">
1566
+ <span class="k">{{ opener_meta_5_label }}</span>
1567
+ <span class="v">{{ opener_meta_5_value }}</span>
1568
+ </div>
1569
+ </div>
1570
+
1571
+ <!-- REPLACE {{ opener_para_1 }} / {{ opener_para_2 }}: two editorial
1572
+ paragraphs introducing the home. Style guide in copy.md →
1573
+ "Opener paragraphs (page 3)".
1574
+ - Para 1 carries the dropcap. 4–6 sentences. Set place + age +
1575
+ tenure context. Distil from seller brief Q1 (why bought) +
1576
+ Q3 (love most) + Q11 (the area).
1577
+ - Para 2: pairs character + comfort or period + modern.
1578
+ 3–4 sentences. End on an italic phrase (single sentence
1579
+ wrapped in <em>) — the brochure's "voice signature" closer.
1580
+ Use <strong> sparingly for the two or three signature features.
1581
+ Em-dashes MUST stay rare — see copy.md "Reduce em-dash usage". -->
1582
+ <div class="opener-body">
1583
+ <p class="ed-body dropcap">
1584
+ {{ opener_para_1 }}
1585
+ </p>
1586
+ <p class="ed-body">
1587
+ {{ opener_para_2 }}
1588
+ </p>
1589
+ </div>
1590
+ </div>
1591
+
1592
+ <div class="opener-image">
1593
+ <!-- REPLACE {{ opener_image_src }} / {{ opener_image_alt }} /
1594
+ {{ opener_image_caption }}: the principal elevation OR a strong
1595
+ aerial. Slot {{ property_slug }}-02 per images.md. Caption is a
1596
+ single italic sentence below the image. -->
1597
+ <img src="images/{{ opener_image_src }}" alt="{{ opener_image_alt }}">
1598
+ <div class="img-caption">{{ opener_image_caption }}</div>
1599
+ </div>
1600
+ </div>
1601
+ <div class="folio">
1602
+ <span>{{ folio_strip }}</span>
1603
+ <span class="folio-mid">— <em>{{ folio_mid_03 }}</em> —</span>
1604
+ <span>03</span>
1605
+ </div>
1606
+ </section>
1607
+
1608
+
1609
+ <!-- ════════════════════════════════════════════════════
1610
+ SPREAD 04 — Chapter II — A home at ease
1611
+ ════════════════════════════════════════════════════ -->
1612
+ <section class="page" data-screen-label="04 House at ease">
1613
+ <img class="print-img" src="page4-print.png" alt="">
1614
+ <div class="spread spread-2">
1615
+ <div class="hero-img">
1616
+ <!-- REPLACE {{ chapter2_hero_src }} / {{ chapter2_hero_alt }}: the
1617
+ wide open-plan reception or kitchen-dining hero. Slot 04 or 07. -->
1618
+ <img src="images/{{ chapter2_hero_src }}" alt="{{ chapter2_hero_alt }}">
1619
+ </div>
1620
+ <div class="text-col">
1621
+ <!-- REPLACE {{ chapter2_eyebrow }}: "Chapter II" (Roman numeral). -->
1622
+ <div class="ed-eyebrow">{{ chapter2_eyebrow }}</div>
1623
+ <div class="ed-rule"></div>
1624
+ <!-- REPLACE {{ chapter2_heading }}: h3 with property's headline word(s)
1625
+ — "A home at ease", "A home built around the table", etc.
1626
+ Italic glyph at the end via <em>...</em>. Avoid "house" — use
1627
+ "home" per copy.md "Home vs house". -->
1628
+ <h3 class="ed-headline smaller">{{ chapter2_heading }}</h3>
1629
+ <!-- REPLACE {{ chapter2_deck }}: single italic sentence summarising
1630
+ the chapter — 12-25 words. Sourced from seller brief Q5
1631
+ (feeling on entry) + Q7 (lifestyle). -->
1632
+ <p class="ed-deck">{{ chapter2_deck }}</p>
1633
+ <!-- REPLACE {{ chapter2_para_1 }} / {{ chapter2_para_2 }}: two body
1634
+ paragraphs walking the reader through the ground-floor flow.
1635
+ - Para 1: from entrance through reception(s) to the central
1636
+ living space (kitchen-dining-living). 4–6 sentences.
1637
+ - Para 2: kitchen specifics (cabinetry, worksurfaces, appliances)
1638
+ and how the rooms connect to utility + outdoor. 3–5 sentences.
1639
+ Close with an italic phrase if the seller's brief offers one. -->
1640
+ <p class="ed-body" style="margin-top: 10px;">
1641
+ {{ chapter2_para_1 }}
1642
+ </p>
1643
+ <p class="ed-body">
1644
+ {{ chapter2_para_2 }}
1645
+ </p>
1646
+ </div>
1647
+
1648
+ <!-- REPLACE {{ chapter2_strip_N_src }} / {{ chapter2_strip_N_alt }} /
1649
+ {{ chapter2_strip_N_caption_label }} / {{ chapter2_strip_N_caption_text }}:
1650
+ three strip cells along the bottom. Each cell has a bold lead-in
1651
+ (e.g. "The kitchen.") then a one-sentence descriptive caption.
1652
+ Pick distinct moments — not three angles of the same room. -->
1653
+ <div class="strip">
1654
+ <div class="strip-cell">
1655
+ <img src="images/{{ chapter2_strip_1_src }}" alt="{{ chapter2_strip_1_alt }}">
1656
+ <div class="ed-caption"><strong>{{ chapter2_strip_1_caption_label }}</strong> {{ chapter2_strip_1_caption_text }}</div>
1657
+ </div>
1658
+ <div class="strip-cell">
1659
+ <img src="images/{{ chapter2_strip_2_src }}" alt="{{ chapter2_strip_2_alt }}">
1660
+ <div class="ed-caption"><strong>{{ chapter2_strip_2_caption_label }}</strong> {{ chapter2_strip_2_caption_text }}</div>
1661
+ </div>
1662
+ <div class="strip-cell">
1663
+ <img src="images/{{ chapter2_strip_3_src }}" alt="{{ chapter2_strip_3_alt }}">
1664
+ <div class="ed-caption"><strong>{{ chapter2_strip_3_caption_label }}</strong> {{ chapter2_strip_3_caption_text }}</div>
1665
+ </div>
1666
+ </div>
1667
+ </div>
1668
+ <div class="folio">
1669
+ <span>{{ folio_strip }}</span>
1670
+ <span class="folio-mid">— <em>{{ folio_mid_04 }}</em> —</span>
1671
+ <span>04</span>
1672
+ </div>
1673
+ </section>
1674
+
1675
+
1676
+ <!-- ════════════════════════════════════════════════════
1677
+ PAGE 5 — INTERMISSION (after Chapter II — visual breath)
1678
+ ════════════════════════════════════════════════════ -->
1679
+ <section class="page intermission" data-screen-label="05 Intermission interior">
1680
+ <img class="print-img" src="page5-print.png" alt="">
1681
+ <div class="full-bleed">
1682
+ <!-- REPLACE {{ intermission_05_src }} / {{ intermission_05_alt }}:
1683
+ one full-bleed interior shot — a dining table moment, a hearth, an
1684
+ orangery — that gives the eye a beat between chapters II and III.
1685
+ Use a slot with strong negative space; avoid busy/cluttered images
1686
+ because the caption pill sits on top of them. -->
1687
+ <img src="images/{{ intermission_05_src }}" alt="{{ intermission_05_alt }}">
1688
+ <div class="caption-pill">
1689
+ <span class="ed-eyebrow-light">Continued, Chapter II</span>
1690
+ <!-- REPLACE {{ intermission_05_caption }}: single italic sentence
1691
+ anchoring the image. Start with "<em>The [room]</em>," — the
1692
+ italic noun matches the visible feature. 10-20 words. -->
1693
+ <span class="caption-text">{{ intermission_05_caption }}</span>
1694
+ </div>
1695
+ </div>
1696
+ <div class="folio folio-dark">
1697
+ <span>{{ folio_strip }}</span>
1698
+ <span class="folio-mid">— <em>{{ folio_mid_04 }}</em> —</span>
1699
+ <span>05</span>
1700
+ </div>
1701
+ </section>
1702
+
1703
+
1704
+ <!-- ════════════════════════════════════════════════════
1705
+ SPREAD 06 — Chapter III (e.g. "Hall, hearth & sun" / "Hearth & hall")
1706
+ ════════════════════════════════════════════════════ -->
1707
+ <section class="page" data-screen-label="06 Chapter III">
1708
+ <img class="print-img" src="page6-print.png" alt="">
1709
+ <div class="spread spread-3">
1710
+ <div class="head">
1711
+ <div class="left">
1712
+ <!-- REPLACE {{ chapter3_eyebrow }}: "Chapter III". -->
1713
+ <div class="ed-eyebrow">{{ chapter3_eyebrow }}</div>
1714
+ <div class="ed-rule"></div>
1715
+ <!-- REPLACE {{ chapter3_heading }}: h3, two lines, italic glyph at
1716
+ the end. Default arc names this chapter for the home's quieter
1717
+ ground-floor moments — hearth, entry, sun-room, drawing room.
1718
+ Adapt to the property's actual features ("Hearth & hall" /
1719
+ "Hall, hearth & sun" / "Reception rooms"). -->
1720
+ <h3 class="ed-headline">{{ chapter3_heading }}</h3>
1721
+ </div>
1722
+ <div class="right">
1723
+ <!-- REPLACE {{ chapter3_deck }}: italic deck sentence. -->
1724
+ <p class="ed-deck" style="margin-top: 0;">{{ chapter3_deck }}</p>
1725
+ <!-- REPLACE {{ chapter3_para }}: ONE longer body paragraph (6–9
1726
+ sentences) walking through the secondary reception rooms.
1727
+ Lean on character features — beams, fireplaces, glazing,
1728
+ flooring — and connect them to how the rooms are used. -->
1729
+ <p class="ed-body" style="margin-top: 12px;">
1730
+ {{ chapter3_para }}
1731
+ </p>
1732
+ </div>
1733
+ </div>
1734
+
1735
+ <!-- REPLACE {{ chapter3_left_src }} / {{ chapter3_left_alt }}: the
1736
+ largest single image of the chapter — typically the hearth or the
1737
+ signature reception. -->
1738
+ <div class="left-img">
1739
+ <img src="images/{{ chapter3_left_src }}" alt="{{ chapter3_left_alt }}">
1740
+ </div>
1741
+
1742
+ <!-- REPLACE {{ chapter3_stack_N_src }} / _alt: two stacked images on the
1743
+ right. Use complementary rooms (e.g. hallway + drawing room, or
1744
+ orangery + study). -->
1745
+ <div class="right-stack">
1746
+ <div class="cell">
1747
+ <img src="images/{{ chapter3_stack_1_src }}" alt="{{ chapter3_stack_1_alt }}">
1748
+ </div>
1749
+ <div class="cell">
1750
+ <img src="images/{{ chapter3_stack_2_src }}" alt="{{ chapter3_stack_2_alt }}">
1751
+ </div>
1752
+ </div>
1753
+ </div>
1754
+ <div class="folio">
1755
+ <span>{{ folio_strip }}</span>
1756
+ <span class="folio-mid">— <em>{{ folio_mid_06 }}</em> —</span>
1757
+ <span>06</span>
1758
+ </div>
1759
+ </section>
1760
+
1761
+
1762
+ <!-- ════════════════════════════════════════════════════
1763
+ PAGE 7 — INTERMISSION (after Chapter III — visual breath)
1764
+ ════════════════════════════════════════════════════ -->
1765
+ <section class="page intermission" data-screen-label="07 Intermission Chapter III">
1766
+ <img class="print-img" src="page7-print.png" alt="">
1767
+ <div class="full-bleed">
1768
+ <!-- REPLACE {{ intermission_07_src }} / {{ intermission_07_alt }}: a
1769
+ second full-bleed interior moment — the orangery, a sun-flooded
1770
+ reception, the hearth from a wider angle. -->
1771
+ <img src="images/{{ intermission_07_src }}" alt="{{ intermission_07_alt }}">
1772
+ <div class="caption-pill">
1773
+ <span class="ed-eyebrow-light">Continued, Chapter III</span>
1774
+ <!-- REPLACE {{ intermission_07_caption }}: italic anchor sentence,
1775
+ same style as page 5. -->
1776
+ <span class="caption-text">{{ intermission_07_caption }}</span>
1777
+ </div>
1778
+ </div>
1779
+ <div class="folio folio-dark">
1780
+ <span>{{ folio_strip }}</span>
1781
+ <span class="folio-mid">— <em>{{ folio_mid_06 }}</em> —</span>
1782
+ <span>07</span>
1783
+ </div>
1784
+ </section>
1785
+
1786
+
1787
+ <!-- ════════════════════════════════════════════════════
1788
+ SPREAD 08 — Chapter IV — Bedrooms & baths
1789
+ ════════════════════════════════════════════════════ -->
1790
+ <section class="page" data-screen-label="08 Bedrooms baths">
1791
+ <img class="print-img" src="page8-print.png" alt="">
1792
+ <div class="spread spread-4">
1793
+ <div class="text-side">
1794
+ <!-- REPLACE {{ chapter4_eyebrow }}: "Chapter IV". -->
1795
+ <div class="ed-eyebrow">{{ chapter4_eyebrow }}</div>
1796
+ <div class="ed-rule"></div>
1797
+ <!-- REPLACE {{ chapter4_heading }}: "Bedrooms<br>&amp; <em>baths</em>"
1798
+ or similar — keep <br> for two-line setting. -->
1799
+ <h3 class="ed-headline smaller">{{ chapter4_heading }}</h3>
1800
+ <!-- REPLACE {{ chapter4_deck }}: italic deck. Mention the count (X
1801
+ bedrooms across Y floors) and the principal suite's signature. -->
1802
+ <p class="ed-deck">{{ chapter4_deck }}</p>
1803
+
1804
+ <!-- REPLACE {{ chapter4_para_1 }}: 3–5 sentences walking the sleeping
1805
+ floor — staircase, landing, second/third/fourth bedrooms in order.
1806
+ Lean on light, beam, glazing. -->
1807
+ <p class="ed-body" style="margin-top: 10px;">
1808
+ {{ chapter4_para_1 }}
1809
+ </p>
1810
+
1811
+ <!-- REPLACE three .ed-stat blocks. Each has a big number value (.v
1812
+ with optional <em> unit) and an all-caps slate label (.l).
1813
+ Typical content: bedroom count + character, bathroom count + en-
1814
+ suite split, upper-floor sq ft (or first-floor / principal floor).
1815
+ Drop the third stat if the property is small (apartment, terrace). -->
1816
+ <div style="margin-top: 10px; display: grid; gap: 8px;">
1817
+ <div class="ed-stat"><div class="v">{{ chapter4_stat_1_value }}</div><div class="l">{{ chapter4_stat_1_label }}</div></div>
1818
+ <div class="ed-stat"><div class="v">{{ chapter4_stat_2_value }}</div><div class="l">{{ chapter4_stat_2_label }}</div></div>
1819
+ <div class="ed-stat"><div class="v">{{ chapter4_stat_3_value }}</div><div class="l">{{ chapter4_stat_3_label }}</div></div>
1820
+ </div>
1821
+
1822
+ <!-- REPLACE {{ chapter4_para_2 }}: 2–3 sentence closer on the
1823
+ principal suite — dressing room, en-suite, view from the bed. -->
1824
+ <p class="ed-body" style="margin-top: 10px;">
1825
+ {{ chapter4_para_2 }}
1826
+ </p>
1827
+ </div>
1828
+
1829
+ <!-- REPLACE 5 gallery cells (1 tall feature + 4 standard). Mix bedrooms
1830
+ and bathrooms so the gallery reads as the floor as a whole. The
1831
+ tall cell is the principal-bedroom hero — verify pixel content
1832
+ matches the principal room (NOT a guest bedroom). -->
1833
+ <div class="gallery">
1834
+ <div class="cell tall">
1835
+ <img src="images/{{ chapter4_gallery_1_src }}" alt="{{ chapter4_gallery_1_alt }}">
1836
+ </div>
1837
+ <div class="cell">
1838
+ <img src="images/{{ chapter4_gallery_2_src }}" alt="{{ chapter4_gallery_2_alt }}">
1839
+ </div>
1840
+ <div class="cell">
1841
+ <img src="images/{{ chapter4_gallery_3_src }}" alt="{{ chapter4_gallery_3_alt }}">
1842
+ </div>
1843
+ <div class="cell">
1844
+ <img src="images/{{ chapter4_gallery_4_src }}" alt="{{ chapter4_gallery_4_alt }}">
1845
+ </div>
1846
+ <div class="cell">
1847
+ <img src="images/{{ chapter4_gallery_5_src }}" alt="{{ chapter4_gallery_5_alt }}">
1848
+ </div>
1849
+ </div>
1850
+ </div>
1851
+ <div class="folio">
1852
+ <span>{{ folio_strip }}</span>
1853
+ <span class="folio-mid">— <em>{{ folio_mid_08 }}</em> —</span>
1854
+ <span>08</span>
1855
+ </div>
1856
+ </section>
1857
+
1858
+
1859
+ <!-- ════════════════════════════════════════════════════
1860
+ PAGE 9 — IMAGE-LED additional internal coverage ("Rooms in passing")
1861
+ ════════════════════════════════════════════════════ -->
1862
+ <section class="page" data-screen-label="09 Image-led additional internal">
1863
+ <img class="print-img" src="page9-print.png" alt="">
1864
+ <div class="gallery-page">
1865
+ <div class="gallery-head">
1866
+ <!-- REPLACE {{ gallery_eyebrow }}: "Continued, Chapter II &amp; III"
1867
+ or similar — links the gallery to the chapters whose imagery
1868
+ it expands. -->
1869
+ <div class="ed-eyebrow">{{ gallery_eyebrow }}</div>
1870
+ <div class="ed-rule"></div>
1871
+ <!-- REPLACE {{ gallery_heading }} / {{ gallery_deck }}: h3 + deck for
1872
+ "Rooms in passing" — supplementary internal coverage. Keep
1873
+ heading short (2–4 words italic close). -->
1874
+ <h3 class="ed-headline smaller">{{ gallery_heading }}</h3>
1875
+ <p class="ed-deck" style="margin-top: 8px;">{{ gallery_deck }}</p>
1876
+ </div>
1877
+ <!-- REPLACE five gallery cells, each with src/alt + a one-line italic
1878
+ figcaption. The tall cell is the strongest single room. Captions
1879
+ are SHORT — "<em>The living room.</em>" + (optional) trailing
1880
+ clause. Don't repeat captions from the strip cells in Chapter II. -->
1881
+ <div class="gallery-grid">
1882
+ <div class="gallery-cell tall">
1883
+ <img src="images/{{ gallery_1_src }}" alt="{{ gallery_1_alt }}">
1884
+ <figcaption>{{ gallery_1_caption }}</figcaption>
1885
+ </div>
1886
+ <div class="gallery-cell">
1887
+ <img src="images/{{ gallery_2_src }}" alt="{{ gallery_2_alt }}">
1888
+ <figcaption>{{ gallery_2_caption }}</figcaption>
1889
+ </div>
1890
+ <div class="gallery-cell">
1891
+ <img src="images/{{ gallery_3_src }}" alt="{{ gallery_3_alt }}">
1892
+ <figcaption>{{ gallery_3_caption }}</figcaption>
1893
+ </div>
1894
+ <div class="gallery-cell">
1895
+ <img src="images/{{ gallery_4_src }}" alt="{{ gallery_4_alt }}">
1896
+ <figcaption>{{ gallery_4_caption }}</figcaption>
1897
+ </div>
1898
+ <div class="gallery-cell">
1899
+ <img src="images/{{ gallery_5_src }}" alt="{{ gallery_5_alt }}">
1900
+ <figcaption>{{ gallery_5_caption }}</figcaption>
1901
+ </div>
1902
+ </div>
1903
+ </div>
1904
+ <div class="folio">
1905
+ <span>{{ folio_strip }}</span>
1906
+ <span class="folio-mid">— <em>{{ folio_mid_09 }}</em> —</span>
1907
+ <span>09</span>
1908
+ </div>
1909
+ </section>
1910
+
1911
+
1912
+ <!-- ════════════════════════════════════════════════════
1913
+ SPREAD 10 — Chapter V — Feature page (pool / outdoor kitchen /
1914
+ summerhouse OR property-specific equivalent: terrace, annexe, studio,
1915
+ pavilion, etc.). Repurpose the chapter title to the actual feature.
1916
+ ════════════════════════════════════════════════════ -->
1917
+ <section class="page" data-screen-label="10 Feature page">
1918
+ <img class="print-img" src="page10-print.png" alt="">
1919
+ <div class="feature-page">
1920
+ <div class="photo">
1921
+ <!-- REPLACE {{ chapter5_photo_src }} / {{ chapter5_photo_alt }} /
1922
+ {{ chapter5_photo_caption }}: the strongest single shot of the
1923
+ feature, with a one-sentence caption beneath. -->
1924
+ <img src="images/{{ chapter5_photo_src }}" alt="{{ chapter5_photo_alt }}">
1925
+ <div class="photo-caption">{{ chapter5_photo_caption }}</div>
1926
+ </div>
1927
+ <div class="panel">
1928
+ <!-- REPLACE {{ chapter5_eyebrow }}: "Chapter V · <feature title>" —
1929
+ "Pool, outdoor kitchen & summerhouse", "Terrace & outdoor kitchen",
1930
+ "The annexe & studio", etc. Match the TOC entry. -->
1931
+ <div class="ed-eyebrow">{{ chapter5_eyebrow }}</div>
1932
+ <div class="ed-rule"></div>
1933
+ <!-- REPLACE {{ chapter5_heading }}: italic editorial headline summing
1934
+ the feature's appeal. Two-line layout (use <br>). -->
1935
+ <h3 class="ed-headline smaller">{{ chapter5_heading }}</h3>
1936
+ <!-- REPLACE {{ chapter5_deck }}: italic deck — 18-30 words. -->
1937
+ <p class="ed-deck" style="margin-top: 12px;">{{ chapter5_deck }}</p>
1938
+
1939
+ <!-- REPLACE {{ chapter5_para }}: ONE body paragraph (5–7 sentences)
1940
+ walking the feature in detail. Name each sub-element exactly —
1941
+ "outdoor kitchen" / "summerhouse" / "orangery" are NOT
1942
+ interchangeable; see structure.md "Distinguishing features
1943
+ clearly". -->
1944
+ <p class="ed-body" style="margin-top: 12px;">
1945
+ {{ chapter5_para }}
1946
+ </p>
1947
+
1948
+ <!-- REPLACE four .attr blocks. Each has a small all-caps label (.k)
1949
+ and a one-line value (.v). Pick four crisp facts — plot size,
1950
+ a single distinctive feature, a count, a material. Drop a row
1951
+ if the property has only three relevant facts. -->
1952
+ <div class="attr-grid">
1953
+ <div class="attr">
1954
+ <div class="k">{{ chapter5_attr_1_label }}</div>
1955
+ <div class="v">{{ chapter5_attr_1_value }}</div>
1956
+ </div>
1957
+ <div class="attr">
1958
+ <div class="k">{{ chapter5_attr_2_label }}</div>
1959
+ <div class="v">{{ chapter5_attr_2_value }}</div>
1960
+ </div>
1961
+ <div class="attr">
1962
+ <div class="k">{{ chapter5_attr_3_label }}</div>
1963
+ <div class="v">{{ chapter5_attr_3_value }}</div>
1964
+ </div>
1965
+ <div class="attr">
1966
+ <div class="k">{{ chapter5_attr_4_label }}</div>
1967
+ <div class="v">{{ chapter5_attr_4_value }}</div>
1968
+ </div>
1969
+ </div>
1970
+ </div>
1971
+ </div>
1972
+ <div class="folio">
1973
+ <span>{{ folio_strip }}</span>
1974
+ <span class="folio-mid">— <em>{{ folio_mid_10 }}</em> —</span>
1975
+ <span>10</span>
1976
+ </div>
1977
+ </section>
1978
+
1979
+
1980
+ <!-- ════════════════════════════════════════════════════
1981
+ PAGE 11 — INTERMISSION (after Chapter V — outdoor full-bleed)
1982
+ ════════════════════════════════════════════════════ -->
1983
+ <section class="page intermission" data-screen-label="11 Intermission outdoor">
1984
+ <img class="print-img" src="page11-print.png" alt="">
1985
+ <div class="full-bleed">
1986
+ <!-- REPLACE {{ intermission_11_src }} / {{ intermission_11_alt }}: the
1987
+ strongest single outdoor moment — pool at golden hour, terrace,
1988
+ pergola, garden-from-distance. Drone shots work well here. -->
1989
+ <img src="images/{{ intermission_11_src }}" alt="{{ intermission_11_alt }}">
1990
+ <div class="caption-pill">
1991
+ <span class="ed-eyebrow-light">Continued, Chapter V</span>
1992
+ <!-- REPLACE {{ intermission_11_caption }}: italic anchor sentence. -->
1993
+ <span class="caption-text">{{ intermission_11_caption }}</span>
1994
+ </div>
1995
+ </div>
1996
+ <div class="folio folio-dark">
1997
+ <span>{{ folio_strip }}</span>
1998
+ <span class="folio-mid">— <em>{{ folio_mid_10 }}</em> —</span>
1999
+ <span>11</span>
2000
+ </div>
2001
+ </section>
2002
+
2003
+
2004
+ <!-- ════════════════════════════════════════════════════
2005
+ SPREAD 12 — Chapter VI — Garden & ground
2006
+ ════════════════════════════════════════════════════ -->
2007
+ <section class="page folio-dark" data-screen-label="12 Garden ground">
2008
+ <img class="print-img" src="page12-print.png" alt="">
2009
+ <div class="spread spread-6">
2010
+ <div class="top-image">
2011
+ <!-- REPLACE {{ chapter6_top_src }} / {{ chapter6_top_alt }}: the full
2012
+ front elevation OR a wide aerial that frames the home in its
2013
+ setting. The overlay sits on top — verify the image has a
2014
+ contrast-quiet region for the overlay panel. -->
2015
+ <img src="images/{{ chapter6_top_src }}" alt="{{ chapter6_top_alt }}">
2016
+ <div class="overlay">
2017
+ <!-- REPLACE {{ chapter6_eyebrow }} / {{ chapter6_heading }}:
2018
+ "Chapter VI" and the chapter title. The heading reads as
2019
+ "Garden,<br>drive <em>&amp; outlook</em>" or similar — adapt
2020
+ to the property's actual ground-floor outdoor narrative. -->
2021
+ <div class="ed-eyebrow">{{ chapter6_eyebrow }}</div>
2022
+ <div class="ed-rule"></div>
2023
+ <h3 class="ed-headline">{{ chapter6_heading }}</h3>
2024
+ </div>
2025
+ </div>
2026
+
2027
+ <!-- REPLACE four .bottom panels — each is a one-paragraph mini-section
2028
+ with an italic h4 label and a 2–3 sentence body. Typical four:
2029
+ rear garden, paddocks/plot, front/approach, ancillary
2030
+ outbuildings. Re-title for the property. -->
2031
+ <div class="bottom">
2032
+ <h4>{{ chapter6_panel_1_heading }}</h4>
2033
+ <p class="ed-body">{{ chapter6_panel_1_body }}</p>
2034
+ </div>
2035
+ <div class="bottom">
2036
+ <h4>{{ chapter6_panel_2_heading }}</h4>
2037
+ <p class="ed-body">{{ chapter6_panel_2_body }}</p>
2038
+ </div>
2039
+ <div class="bottom">
2040
+ <h4>{{ chapter6_panel_3_heading }}</h4>
2041
+ <p class="ed-body">{{ chapter6_panel_3_body }}</p>
2042
+ </div>
2043
+ <div class="bottom">
2044
+ <h4>{{ chapter6_panel_4_heading }}</h4>
2045
+ <p class="ed-body">{{ chapter6_panel_4_body }}</p>
2046
+ </div>
2047
+ </div>
2048
+ <div class="folio">
2049
+ <span>{{ folio_strip }}</span>
2050
+ <span class="folio-mid">— <em>{{ folio_mid_12 }}</em> —</span>
2051
+ <span>12</span>
2052
+ </div>
2053
+ </section>
2054
+
2055
+
2056
+ <!-- ════════════════════════════════════════════════════
2057
+ PAGE 13 — SITE PLAN (continued from Chapter VI)
2058
+ ════════════════════════════════════════════════════ -->
2059
+ <section class="page" data-screen-label="13 Site plan">
2060
+ <img class="print-img" src="page13-print.png" alt="">
2061
+ <div class="siteplan-page">
2062
+ <div class="head">
2063
+ <!-- REPLACE {{ siteplan_eyebrow }}: "Continued, Chapter VI · The plot"
2064
+ or similar. -->
2065
+ <div class="ed-eyebrow">{{ siteplan_eyebrow }}</div>
2066
+ <div class="ed-rule"></div>
2067
+ <!-- REPLACE {{ siteplan_heading }}: the plot's headline fact —
2068
+ "In excess of <em>2.20 acres</em>", "The <em>plot &amp; outlook</em>",
2069
+ "Approximately <em>1.4 acres</em>". -->
2070
+ <h3 class="ed-headline smaller">{{ siteplan_heading }}</h3>
2071
+ </div>
2072
+ <div class="plan-area">
2073
+ <!-- REPLACE {{ siteplan_src }} / {{ siteplan_alt }}: the plot drawing
2074
+ (trees, boundary, paddocks, outbuildings). Filename is normally
2075
+ {{ property_slug }}-siteplan.png — line art, copied unchanged. -->
2076
+ <img src="images/{{ siteplan_src }}" alt="{{ siteplan_alt }}">
2077
+ </div>
2078
+ <div class="text-side">
2079
+ <!-- REPLACE three .text-side h4 + p pairs. Typical content: plot
2080
+ description, boundary/screening, what sits within the grounds
2081
+ (garden complex, paddocks, outbuildings). Then a small italic
2082
+ ed-caption note about plan accuracy. -->
2083
+ <h4>{{ siteplan_panel_1_heading }}</h4>
2084
+ <p class="ed-body">{{ siteplan_panel_1_body }}</p>
2085
+ <h4>{{ siteplan_panel_2_heading }}</h4>
2086
+ <p class="ed-body">{{ siteplan_panel_2_body }}</p>
2087
+ <h4>{{ siteplan_panel_3_heading }}</h4>
2088
+ <p class="ed-body">{{ siteplan_panel_3_body }}</p>
2089
+ <p class="ed-caption" style="margin-top: 4px;">Plan drawn to indicative scale; not to be relied on for legal purposes.</p>
2090
+ </div>
2091
+ </div>
2092
+ <div class="folio">
2093
+ <span>{{ folio_strip }}</span>
2094
+ <span class="folio-mid">— <em>{{ folio_mid_13 }}</em> —</span>
2095
+ <span>13</span>
2096
+ </div>
2097
+ </section>
2098
+
2099
+
2100
+ <!-- ════════════════════════════════════════════════════
2101
+ SPREAD 14 — Chapter VII — Plan & particulars
2102
+ ════════════════════════════════════════════════════ -->
2103
+ <section class="page" data-screen-label="14 Plan particulars">
2104
+ <img class="print-img" src="page14-print.png" alt="">
2105
+ <div class="spread spread-7">
2106
+ <div class="header">
2107
+ <!-- REPLACE {{ chapter7_eyebrow }}: "Chapter VII · Plan &amp; particulars". -->
2108
+ <div class="ed-eyebrow">{{ chapter7_eyebrow }}</div>
2109
+ <div class="ed-rule"></div>
2110
+ <!-- REPLACE {{ chapter7_heading }}: "All floors <em>at a glance</em>"
2111
+ or similar. -->
2112
+ <h3 class="ed-headline smaller">{{ chapter7_heading }}</h3>
2113
+ </div>
2114
+
2115
+ <div class="plan-area">
2116
+ <!-- REPLACE {{ floorplan_src }} / {{ floorplan_alt }}: the composite
2117
+ floor plan, typically {{ property_slug }}-floorplan.png. PNG,
2118
+ line art, copied unchanged from source (do NOT WebP-encode line
2119
+ art; see images.md "Floor plan exception"). -->
2120
+ <img src="images/{{ floorplan_src }}" alt="{{ floorplan_alt }}">
2121
+ <div class="meta">
2122
+ <!-- REPLACE {{ floorplan_lead }}: italic lead — "Total internal area
2123
+ · <em>X sq ft</em> · Y m&sup2;". -->
2124
+ <div class="lead">{{ floorplan_lead }}</div>
2125
+ <!-- REPLACE {{ floorplan_sub }}: floor-by-floor breakdown — "Floor 1
2126
+ · X sq ft &nbsp;·&nbsp; Floor 2 · Y sq ft" plus any ancillary
2127
+ footprints (garage, outbuildings, plot). Excluded outbuildings
2128
+ must be LISTED SEPARATELY — never silently rolled into the
2129
+ principal home's sq ft; see structure.md "Floor area". -->
2130
+ <div class="sub">{{ floorplan_sub }}</div>
2131
+ </div>
2132
+ </div>
2133
+
2134
+ <div class="spec-side">
2135
+ <div class="ed-eyebrow" style="margin-bottom: 6px;">Particulars</div>
2136
+ <!-- REPLACE 9 numbered particulars (.spec-list li × 9). Each is a
2137
+ single short sentence highlighting one feature with <strong> on
2138
+ the named element. Sequence: top-line architectural fact,
2139
+ character feature, kitchen specifics, heating/services, signature
2140
+ internal feature, signature outdoor feature, ancillary buildings,
2141
+ plot, outlook. Adapt count to the property — fewer if smaller,
2142
+ never more than 9 (the column overflows). -->
2143
+ <ol class="spec-list">
2144
+ <li><span class="num">i</span><span>{{ particular_1 }}</span></li>
2145
+ <li><span class="num">ii</span><span>{{ particular_2 }}</span></li>
2146
+ <li><span class="num">iii</span><span>{{ particular_3 }}</span></li>
2147
+ <li><span class="num">iv</span><span>{{ particular_4 }}</span></li>
2148
+ <li><span class="num">v</span><span>{{ particular_5 }}</span></li>
2149
+ <li><span class="num">vi</span><span>{{ particular_6 }}</span></li>
2150
+ <li><span class="num">vii</span><span>{{ particular_7 }}</span></li>
2151
+ <li><span class="num">viii</span><span>{{ particular_8 }}</span></li>
2152
+ <li><span class="num">ix</span><span>{{ particular_9 }}</span></li>
2153
+ </ol>
2154
+
2155
+ <div class="epc-block">
2156
+ <!-- REPLACE {{ epc_rating }}: the current band letter A–G. The CSS
2157
+ class .current on the matching <div class="epc-bar X"> lights
2158
+ that band; the others are dim. The exact pattern below shows
2159
+ band C as the "current" — substitute by changing which row
2160
+ carries `class="epc-bar X current"`. -->
2161
+ <div class="epc-title">Energy &amp; environment <em>· EPC {{ epc_rating }}</em></div>
2162
+ <div class="epc-bars">
2163
+ <div class="epc-bar a{{ epc_current_a }}">A</div>
2164
+ <div class="epc-bar b{{ epc_current_b }}">B</div>
2165
+ <div class="epc-bar c{{ epc_current_c }}">C</div>
2166
+ <div class="epc-bar d{{ epc_current_d }}">D</div>
2167
+ <div class="epc-bar e{{ epc_current_e }}">E</div>
2168
+ <div class="epc-bar f{{ epc_current_f }}">F</div>
2169
+ <div class="epc-bar g{{ epc_current_g }}">G</div>
2170
+ </div>
2171
+ <!-- REPLACE {{ epc_caption }}: 1–2 sentences on the heating system
2172
+ and what the EPC band reflects about the home's fabric. -->
2173
+ <p class="ed-caption" style="margin-top: 8px;">
2174
+ {{ epc_caption }}
2175
+ </p>
2176
+ </div>
2177
+ </div>
2178
+ </div>
2179
+ <div class="folio">
2180
+ <span>{{ folio_strip }}</span>
2181
+ <span class="folio-mid">— <em>{{ folio_mid_14 }}</em> —</span>
2182
+ <span>14</span>
2183
+ </div>
2184
+ </section>
2185
+
2186
+
2187
+ <!-- ════════════════════════════════════════════════════
2188
+ SPREAD 15 — Chapter VIII — Material Information (DMCCA 2024)
2189
+ ════════════════════════════════════════════════════ -->
2190
+ <section class="page" data-screen-label="15 Material information">
2191
+ <img class="print-img" src="page15-print.png" alt="">
2192
+ <div class="mi-page">
2193
+ <div class="mi-head">
2194
+ <div>
2195
+ <!-- REPLACE {{ chapter8_eyebrow }}: "Chapter VIII · Disclosure". -->
2196
+ <div class="ed-eyebrow">{{ chapter8_eyebrow }}</div>
2197
+ <div class="ed-rule"></div>
2198
+ <h3 class="ed-headline smaller">Material <em>information</em></h3>
2199
+ </div>
2200
+ <!-- Disclosure intro paragraph — DO NOT EDIT (boilerplate compliance text). -->
2201
+ <div class="mi-intro">
2202
+ Provided in accordance with the Consumer Protection from Unfair Trading Regulations 2008, the Digital Markets, Competition and Consumers Act 2024, and National Trading Standards guidance on material information in property listings.
2203
+ </div>
2204
+ </div>
2205
+
2206
+ <!-- REPLACE every .mi-row value (.v slot). The three columns are
2207
+ fixed Part A / Part B / Part C per UK DMCCA 2024 guidance. Mark
2208
+ unknowns "TBC" verbatim — never invent. Drop a row only if the
2209
+ field is genuinely not applicable to the property (e.g. "Coastal
2210
+ Erosion" for an inland home). Add a row if the property has a
2211
+ distinctive fact not in the canonical list (e.g. "Pool",
2212
+ "Annexe"). Keep all keys as single-line; values can be short
2213
+ pairs ("G · £3,890 pa") joined with "&nbsp;·&nbsp;". -->
2214
+ <div class="mi-grid">
2215
+ <div class="mi-section">
2216
+ <div class="mi-label">Part A · Material to all transactions</div>
2217
+ <div class="mi-row"><span class="k">Asking Price</span><span class="v">{{ mi_price }}</span></div>
2218
+ <div class="mi-row"><span class="k">Tenure</span><span class="v">{{ mi_tenure }}</span></div>
2219
+ <div class="mi-row"><span class="k">Title Number</span><span class="v">{{ mi_title_number }}</span></div>
2220
+ <div class="mi-row"><span class="k">Council Tax Band</span><span class="v">{{ mi_council_tax }}</span></div>
2221
+ <div class="mi-row"><span class="k">Local Authority</span><span class="v">{{ mi_local_authority }}</span></div>
2222
+ <div class="mi-row"><span class="k">Property Type</span><span class="v">{{ mi_property_type }}</span></div>
2223
+ <div class="mi-row"><span class="k">Year Built</span><span class="v">{{ mi_year_built }}</span></div>
2224
+ <div class="mi-row"><span class="k">Bedrooms</span><span class="v">{{ mi_bedrooms }}</span></div>
2225
+ <div class="mi-row"><span class="k">Bathrooms</span><span class="v">{{ mi_bathrooms }}</span></div>
2226
+ <div class="mi-row"><span class="k">Receptions</span><span class="v">{{ mi_receptions }}</span></div>
2227
+ <div class="mi-row"><span class="k">Floor Area</span><span class="v">{{ mi_floor_area }}</span></div>
2228
+ <div class="mi-row"><span class="k">Heating</span><span class="v">{{ mi_heating }}</span></div>
2229
+ <div class="mi-row"><span class="k">Electricity</span><span class="v">{{ mi_electricity }}</span></div>
2230
+ <div class="mi-row"><span class="k">Broadband</span><span class="v">{{ mi_broadband }}</span></div>
2231
+ <div class="mi-row"><span class="k">Mobile Signal</span><span class="v">{{ mi_mobile }}</span></div>
2232
+ <div class="mi-row"><span class="k">Parking</span><span class="v">{{ mi_parking }}</span></div>
2233
+ <div class="mi-row"><span class="k">EPC</span><span class="v">{{ epc_rating }}</span></div>
2234
+ </div>
2235
+
2236
+ <div class="mi-section">
2237
+ <div class="mi-label">Part B · Where applicable</div>
2238
+ <div class="mi-row"><span class="k">Building Safety</span><span class="v">{{ mi_building_safety }}</span></div>
2239
+ <div class="mi-row"><span class="k">Restrictive Covenants</span><span class="v">{{ mi_covenants }}</span></div>
2240
+ <div class="mi-row"><span class="k">Rights of Way</span><span class="v">{{ mi_rights_of_way }}</span></div>
2241
+ <div class="mi-row"><span class="k">Easements</span><span class="v">{{ mi_easements }}</span></div>
2242
+ <div class="mi-row"><span class="k">Listed Building</span><span class="v">{{ mi_listed }}</span></div>
2243
+ <div class="mi-row"><span class="k">Conservation Area</span><span class="v">{{ mi_conservation }}</span></div>
2244
+ <div class="mi-row"><span class="k">Tree Preservation</span><span class="v">{{ mi_tpo }}</span></div>
2245
+ <div class="mi-row"><span class="k">Accessibility</span><span class="v">{{ mi_accessibility }}</span></div>
2246
+ <div class="mi-row"><span class="k">Water Supply</span><span class="v">{{ mi_water }}</span></div>
2247
+ <div class="mi-row"><span class="k">Sewerage</span><span class="v">{{ mi_sewerage }}</span></div>
2248
+ <div class="mi-row"><span class="k">Outbuildings</span><span class="v">{{ mi_outbuildings }}</span></div>
2249
+ <div class="mi-row"><span class="k">{{ mi_part_b_extra_label }}</span><span class="v">{{ mi_part_b_extra_value }}</span></div>
2250
+ </div>
2251
+
2252
+ <div class="mi-section">
2253
+ <div class="mi-label">Part C · Additional material facts</div>
2254
+ <div class="mi-row"><span class="k">Flood Risk, Rivers &amp; Seas</span><span class="v">{{ mi_flood_rivers }}</span></div>
2255
+ <div class="mi-row"><span class="k">Flood Risk, Surface Water</span><span class="v">{{ mi_flood_surface }}</span></div>
2256
+ <div class="mi-row"><span class="k">Coastal Erosion</span><span class="v">{{ mi_coastal }}</span></div>
2257
+ <div class="mi-row"><span class="k">Planning</span><span class="v">{{ mi_planning }}</span></div>
2258
+ <div class="mi-row"><span class="k">Construction</span><span class="v">{{ mi_construction }}</span></div>
2259
+ <div class="mi-row"><span class="k">Structural</span><span class="v">{{ mi_structural }}</span></div>
2260
+ <div class="mi-row"><span class="k">Subsidence</span><span class="v">{{ mi_subsidence }}</span></div>
2261
+ <div class="mi-row"><span class="k">Damp</span><span class="v">{{ mi_damp }}</span></div>
2262
+ <div class="mi-row"><span class="k">Asbestos</span><span class="v">{{ mi_asbestos }}</span></div>
2263
+ <div class="mi-row"><span class="k">Japanese Knotweed</span><span class="v">{{ mi_knotweed }}</span></div>
2264
+ <div class="mi-row"><span class="k">Mining</span><span class="v">{{ mi_mining }}</span></div>
2265
+ <div class="mi-row"><span class="k">Electrical Cert.</span><span class="v">{{ mi_electrical_cert }}</span></div>
2266
+ <div class="mi-row"><span class="k">UPRN</span><span class="v">{{ mi_uprn }}</span></div>
2267
+ </div>
2268
+ </div>
2269
+
2270
+ <!-- Disclosure footer — keep boilerplate; tweak only if your jurisdiction requires different wording. -->
2271
+ <div class="mi-foot">
2272
+ The agent has made reasonable enquiries to verify this information; prospective purchasers should satisfy themselves as to its accuracy through their own legal and survey processes. Items marked TBC will be confirmed by the seller's solicitor.
2273
+ </div>
2274
+ </div>
2275
+ <div class="folio">
2276
+ <span>{{ folio_strip }}</span>
2277
+ <span class="folio-mid">— <em>Material information</em> —</span>
2278
+ <span>15</span>
2279
+ </div>
2280
+ </section>
2281
+
2282
+
2283
+ <!-- ════════════════════════════════════════════════════
2284
+ BACK PAGE
2285
+ ════════════════════════════════════════════════════ -->
2286
+ <section class="page backpage" data-screen-label="16 Back page">
2287
+ <img class="print-img" src="backpage-print.png" alt="">
2288
+ <div class="bg">
2289
+ <!-- REPLACE {{ backpage_bg_src }} / {{ backpage_bg_alt }}: the back-page
2290
+ atmospheric background. Typically a rear elevation or aerial at
2291
+ golden hour. Filename {{ property_slug }}-26 per images.md. -->
2292
+ <img src="images/{{ backpage_bg_src }}" alt="{{ backpage_bg_alt }}">
2293
+ </div>
2294
+ <div class="backpage-frame"></div>
2295
+
2296
+ <div class="backpage-inner">
2297
+ <!-- REPLACE {{ brand_slug }}: the brand's slug from the brand pack —
2298
+ used to resolve the LIGHT-ART logo on the dark back-page hero. The
2299
+ brand-design SKILL writes <brand>-logo-light.png; substituting
2300
+ {{ brand_slug }} resolves the path. Alt text is the brand name. -->
2301
+ <div class="back-mast">
2302
+ <img class="back-mast-logo" src="images/{{ brand_slug }}-logo-light.png" alt="{{ brand_name }}">
2303
+ </div>
2304
+
2305
+ <!-- REPLACE {{ backpage_headline }}: "Arrange a viewing of
2306
+ <em>{{ property_name }}</em>". The <em> on the property name is
2307
+ consistent with the cover and opener. Don't substitute a different
2308
+ CTA wording — this is the canonical closer. -->
2309
+ <h2 class="back-headline">{{ backpage_headline }}</h2>
2310
+
2311
+ <!-- REPLACE {{ backpage_tagline }}: single sentence summarising the
2312
+ property (size · key features · grounds). 25-45 words. Mirrors
2313
+ but does not duplicate the cover/opener copy. Close with "Best
2314
+ understood in person." or an equivalent property-specific clincher. -->
2315
+ <p class="back-tagline">{{ backpage_tagline }}</p>
2316
+
2317
+ <div class="back-rule"></div>
2318
+
2319
+ <!-- REPLACE the agent + office cells. {{ agent_first_name }} sits in
2320
+ <em>; {{ agent_surname }} follows in normal weight. {{ office_phone }}
2321
+ is the display format ("01873 377 575"); {{ office_email }} the
2322
+ contact email; {{ office_address_line_1 }} and
2323
+ {{ office_address_line_2 }} the postal lines. -->
2324
+ <div class="back-contact-grid">
2325
+ <div class="cell">
2326
+ <div class="k">The Agent</div>
2327
+ <div class="name"><em>{{ agent_first_name }}</em> {{ agent_surname }}</div>
2328
+ <div class="line">
2329
+ {{ office_phone }}<br>
2330
+ {{ office_email }}
2331
+ </div>
2332
+ </div>
2333
+ <div class="cell">
2334
+ <div class="k">The Office</div>
2335
+ <div class="name">{{ brand_name }} <span class="dot">·</span> <em>{{ brand_town }}</em></div>
2336
+ <div class="line">
2337
+ {{ office_address_line_1 }}<br>
2338
+ {{ office_address_line_2 }}
2339
+ </div>
2340
+ </div>
2341
+ </div>
2342
+
2343
+ <!-- REPLACE the QR strip — TWO clickable QR codes. The qr-video.png
2344
+ and qr-listing.png images are generated by qrencode at brochure-
2345
+ assembly time. Each <a> wraps the QR image + label + visible URL,
2346
+ all clickable. The visible URL beneath each QR is MANDATORY —
2347
+ the digital reader's equivalent of scanning. See structure.md
2348
+ "Back-page QR codes". If the listing has no video tour, drop
2349
+ the first <a> and let the listing QR span the strip. -->
2350
+ <div class="back-qr-strip">
2351
+ <a class="qr" href="{{ video_url }}" target="_blank" rel="noopener">
2352
+ <img src="images/qr-video.png" alt="Scan or click to view the property video tour">
2353
+ <div class="qr-label">Watch the <em>video tour</em></div>
2354
+ <div class="qr-link">{{ video_short_url }}</div>
2355
+ </a>
2356
+ <a class="qr" href="{{ listing_url }}" target="_blank" rel="noopener">
2357
+ <img src="images/qr-listing.png" alt="Scan or click to view the full property listing">
2358
+ <div class="qr-label">View the <em>full listing</em></div>
2359
+ <div class="qr-link">{{ listing_display }}</div>
2360
+ </a>
2361
+ </div>
2362
+ </div>
2363
+
2364
+ <div class="back-disclaimer">
2365
+ These particulars, whilst believed to be accurate, are set out as a general outline only for guidance and do not constitute any part of an offer or contract. Intending purchasers should not rely on them as statements or representations of fact, but must satisfy themselves by inspection or otherwise as to their accuracy. All measurements are approximate and floor plans are drawn to indicative scale. Some images may include CGI or AI enhancements for illustrative purposes.
2366
+ </div>
2367
+ </section>
2368
+
2369
+ </body>
2370
+ </html>