@rubytech/create-maxy-code 0.1.398 → 0.1.400

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 (186) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
  3. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +17 -1
  4. package/payload/platform/plugins/docs/references/graph.md +15 -0
  5. package/payload/platform/plugins/docs/references/plugins-guide.md +1 -0
  6. package/payload/platform/plugins/email/mcp/dist/__tests__/connect-timeout-observability.test.d.ts +2 -0
  7. package/payload/platform/plugins/email/mcp/dist/__tests__/connect-timeout-observability.test.d.ts.map +1 -0
  8. package/payload/platform/plugins/email/mcp/dist/__tests__/connect-timeout-observability.test.js +123 -0
  9. package/payload/platform/plugins/email/mcp/dist/__tests__/connect-timeout-observability.test.js.map +1 -0
  10. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +9 -0
  11. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
  12. package/payload/platform/plugins/email/mcp/dist/lib/imap.js +36 -12
  13. package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
  14. package/payload/platform/plugins/email/mcp/dist/lib/smtp.d.ts.map +1 -1
  15. package/payload/platform/plugins/email/mcp/dist/lib/smtp.js +18 -1
  16. package/payload/platform/plugins/email/mcp/dist/lib/smtp.js.map +1 -1
  17. package/payload/platform/plugins/memory/references/schema-estate-agent.md +2 -0
  18. package/payload/platform/plugins/web-designer/.claude-plugin/plugin.json +8 -0
  19. package/payload/platform/plugins/web-designer/PLUGIN.md +46 -0
  20. package/payload/platform/plugins/web-designer/bin/resolve-cf.sh +56 -0
  21. package/payload/platform/plugins/web-designer/skills/brand-extract/SKILL.md +86 -0
  22. package/payload/platform/plugins/web-designer/skills/socials/SKILL.md +139 -0
  23. package/payload/platform/plugins/web-designer/skills/socials/references/pii-strip.md +64 -0
  24. package/payload/platform/plugins/web-designer/skills/socials/references/sources.md +66 -0
  25. package/payload/platform/plugins/web-designer/skills/socials/templates/og.html +92 -0
  26. package/payload/platform/plugins/web-designer/skills/socials/templates/social-posts.md +46 -0
  27. package/payload/platform/plugins/web-designer/skills/socials/templates/socials.html +87 -0
  28. package/payload/platform/plugins/web-designer/skills/web-design/SKILL.md +98 -0
  29. package/payload/platform/plugins/web-designer/skills/web-design/references/deploy.md +59 -0
  30. package/payload/platform/plugins/web-designer/skills/web-design/references/e-sign.md +39 -0
  31. package/payload/platform/plugins/web-designer/skills/web-design/references/gating.md +55 -0
  32. package/payload/platform/plugins/web-designer/skills/web-design/references/placeholders.md +110 -0
  33. package/payload/platform/plugins/web-designer/skills/web-design/references/sections.md +52 -0
  34. package/payload/platform/plugins/web-designer/skills/web-design/templates/index.html +1004 -0
  35. package/payload/platform/plugins/web-designer/skills/web-design/templates/llms.txt +32 -0
  36. package/payload/platform/plugins/web-designer/skills/web-intake/SKILL.md +107 -0
  37. package/payload/platform/plugins/web-designer/skills/web-intake/references/intake.md +103 -0
  38. package/payload/platform/plugins/whatsapp/PLUGIN.md +7 -1
  39. package/payload/platform/scripts/merge-whatsapp-split-conversations.mjs +264 -0
  40. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  41. package/payload/platform/services/claude-session-manager/dist/http-server.js +22 -6
  42. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  43. package/payload/server/public/assets/{AdminLoginScreens-Bex48co9.js → AdminLoginScreens-rlk263u9.js} +1 -1
  44. package/payload/server/public/assets/{AdminShell-BOmS1NPG.js → AdminShell-C5vWTy2n.js} +1 -1
  45. package/payload/server/public/assets/{Checkbox-DDlXC5tq.js → Checkbox-Chz6bfy-.js} +1 -1
  46. package/payload/server/public/assets/{Transcript-CwItbNkx.js → Transcript-Bsx-bGgY.js} +2 -2
  47. package/payload/server/public/assets/{admin-n9zWE158.js → admin-BnZH758N.js} +1 -1
  48. package/payload/server/public/assets/{arc-C6-nr5UV.js → arc-DyzjCWmw.js} +1 -1
  49. package/payload/server/public/assets/architecture-YZFGNWBL-XiVs-N7Z.js +1 -0
  50. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DIdho_T6.js → architectureDiagram-Q4EWVU46-qWfElD16.js} +1 -1
  51. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-D5rTTBSy.js → blockDiagram-DXYQGD6D-DO2fFHC3.js} +1 -1
  52. package/payload/server/public/assets/{browser-CI8DR1YG.js → browser-CIrfyZWe.js} +1 -1
  53. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-pfUVHdmy.js → c4Diagram-AHTNJAMY-Ca-q5gDe.js} +1 -1
  54. package/payload/server/public/assets/{calendar-WuIAN47H.js → calendar-D6Z8Kmrn.js} +1 -1
  55. package/payload/server/public/assets/channel-CYBkRz7E.js +1 -0
  56. package/payload/server/public/assets/chat-h7SytZHx.js +1 -0
  57. package/payload/server/public/assets/chevron-left-DSTeS1_g.js +1 -0
  58. package/payload/server/public/assets/{chunk-2KRD3SAO-EF6cdj8U.js → chunk-2KRD3SAO-CX2PxuDw.js} +1 -1
  59. package/payload/server/public/assets/{chunk-336JU56O-DE-lcZAc.js → chunk-336JU56O-D8l6U4Ne.js} +2 -2
  60. package/payload/server/public/assets/chunk-426QAEUC-CPhOHriU.js +1 -0
  61. package/payload/server/public/assets/{chunk-4BX2VUAB--ANCzzyn.js → chunk-4BX2VUAB-CG32Lkbh.js} +1 -1
  62. package/payload/server/public/assets/{chunk-4TB4RGXK-DTO_X80J.js → chunk-4TB4RGXK-BnAQbO-v.js} +1 -1
  63. package/payload/server/public/assets/{chunk-55IACEB6-4J3nrz44.js → chunk-55IACEB6-ejqRH2M5.js} +1 -1
  64. package/payload/server/public/assets/{chunk-5FUZZQ4R-jH_eqAHL.js → chunk-5FUZZQ4R-ClkicQ-T.js} +1 -1
  65. package/payload/server/public/assets/{chunk-5PVQY5BW-C-qU6p6k.js → chunk-5PVQY5BW-Be-mE_rx.js} +1 -1
  66. package/payload/server/public/assets/{chunk-67CJDMHE-DXxH9Snb.js → chunk-67CJDMHE-DPsemed2.js} +1 -1
  67. package/payload/server/public/assets/{chunk-7N4EOEYR-CCkxuP7A.js → chunk-7N4EOEYR-BQRQJETl.js} +1 -1
  68. package/payload/server/public/assets/{chunk-AA7GKIK3-CyItuM8d.js → chunk-AA7GKIK3-B1wcAVCK.js} +1 -1
  69. package/payload/server/public/assets/{chunk-BSJP7CBP-Bg7gxYNf.js → chunk-BSJP7CBP-DIua053h.js} +1 -1
  70. package/payload/server/public/assets/{chunk-CIAEETIT-BAXbOqv5.js → chunk-CIAEETIT-C9GHSCS9.js} +1 -1
  71. package/payload/server/public/assets/{chunk-EDXVE4YY-vdoErQoc.js → chunk-EDXVE4YY-C1T3l1xj.js} +1 -1
  72. package/payload/server/public/assets/{chunk-ENJZ2VHE-Cz_z_6GK.js → chunk-ENJZ2VHE-8kPcXEQC.js} +1 -1
  73. package/payload/server/public/assets/{chunk-FMBD7UC4-Ck2jvOgW.js → chunk-FMBD7UC4-Bhoeq9sD.js} +1 -1
  74. package/payload/server/public/assets/{chunk-FOC6F5B3-DucR0Qo8.js → chunk-FOC6F5B3-BIBpJi8I.js} +1 -1
  75. package/payload/server/public/assets/{chunk-ICPOFSXX-DolYDD7g.js → chunk-ICPOFSXX-DELXp6fj.js} +2 -2
  76. package/payload/server/public/assets/{chunk-K5T4RW27-FRzx7E5I.js → chunk-K5T4RW27-DdckXldP.js} +1 -1
  77. package/payload/server/public/assets/{chunk-KGLVRYIC-Bb5S4Bmc.js → chunk-KGLVRYIC-BJhXejKT.js} +1 -1
  78. package/payload/server/public/assets/{chunk-LIHQZDEY-c8VZJ-lU.js → chunk-LIHQZDEY-BSd8nyM2.js} +1 -1
  79. package/payload/server/public/assets/{chunk-ORNJ4GCN-BAeh-LZ1.js → chunk-ORNJ4GCN-CBi55uxq.js} +1 -1
  80. package/payload/server/public/assets/{chunk-OYMX7WX6-BUg7Kysh.js → chunk-OYMX7WX6-Dfbzl8xh.js} +1 -1
  81. package/payload/server/public/assets/chunk-QZHKN3VN-CDnAAZVJ.js +1 -0
  82. package/payload/server/public/assets/{chunk-U2HBQHQK-K4r17UTk.js → chunk-U2HBQHQK-BN1w8_Cq.js} +1 -1
  83. package/payload/server/public/assets/{chunk-X2U36JSP-Byh-CyxC.js → chunk-X2U36JSP-CrRay1NJ.js} +1 -1
  84. package/payload/server/public/assets/{chunk-XPW4576I-DC7lhr93.js → chunk-XPW4576I-C_ZE776O.js} +1 -1
  85. package/payload/server/public/assets/{chunk-YZCP3GAM-B2cu7AEP.js → chunk-YZCP3GAM-CUSlqWBY.js} +1 -1
  86. package/payload/server/public/assets/{chunk-ZZ45TVLE-DH_p8sFX.js → chunk-ZZ45TVLE-BdPUfSiD.js} +1 -1
  87. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BdXUKVrS.js +1 -0
  88. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DAq-uJr_.js +1 -0
  89. package/payload/server/public/assets/clone-DQl28-jK.js +1 -0
  90. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-DeM6JI00.js → cose-bilkent-S5V4N54A-D4E9htTz.js} +1 -1
  91. package/payload/server/public/assets/{dagre-3drs3e4F.js → dagre-D1B5TQL1.js} +1 -1
  92. package/payload/server/public/assets/{dagre-KV5264BT-C6S-VUtN.js → dagre-KV5264BT-ByuvYV7N.js} +1 -1
  93. package/payload/server/public/assets/data-CL7CyX1C.js +1 -0
  94. package/payload/server/public/assets/{diagram-5BDNPKRD-BkvA32I3.js → diagram-5BDNPKRD-B-0KduTa.js} +1 -1
  95. package/payload/server/public/assets/{diagram-G4DWMVQ6-CVwtRMPB.js → diagram-G4DWMVQ6-CSQmo3eB.js} +1 -1
  96. package/payload/server/public/assets/{diagram-MMDJMWI5-DJ1JVMbd.js → diagram-MMDJMWI5-DK0kWiB3.js} +1 -1
  97. package/payload/server/public/assets/{diagram-TYMM5635-rfj-crtX.js → diagram-TYMM5635-CYbK2reZ.js} +1 -1
  98. package/payload/server/public/assets/{erDiagram-SMLLAGMA-TJPuweS5.js → erDiagram-SMLLAGMA-C-JQHvJF.js} +1 -1
  99. package/payload/server/public/assets/{flatten-BZkoyJ4e.js → flatten-ROVzlo1u.js} +1 -1
  100. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-LQWEUjbV.js → flowDiagram-DWJPFMVM-OTOd2czg.js} +1 -1
  101. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-DdYsxKRw.js → ganttDiagram-T4ZO3ILL-BWJ778ou.js} +1 -1
  102. package/payload/server/public/assets/gitGraph-7Q5UKJZL-BM-KaDZy.js +1 -0
  103. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-sx8-fokM.js → gitGraphDiagram-UUTBAWPF-CkNcyISe.js} +1 -1
  104. package/payload/server/public/assets/graph-XZJZHzvv.js +51 -0
  105. package/payload/server/public/assets/{graph-labels-DigwgCWY.js → graph-labels-Cabqmf35.js} +1 -1
  106. package/payload/server/public/assets/{graphlib-DixeJdCf.js → graphlib-8z59Ng6C.js} +1 -1
  107. package/payload/server/public/assets/info-OMHHGYJF-CtZajyAB.js +1 -0
  108. package/payload/server/public/assets/infoDiagram-42DDH7IO-C-_WYlmI.js +2 -0
  109. package/payload/server/public/assets/{isEmpty-VRKFml5R.js → isEmpty-DXf_sApt.js} +1 -1
  110. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-BKUCuKhZ.js → ishikawaDiagram-UXIWVN3A-Cg7pRRGp.js} +1 -1
  111. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-BafZP6pM.js → journeyDiagram-VCZTEJTY-CZT_4r_Z.js} +1 -1
  112. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-DQ4c6wRv.js → kanban-definition-6JOO6SKY-Dp1Vd5YM.js} +1 -1
  113. package/payload/server/public/assets/{line-0_x1Wivu.js → line-UPAcwY66.js} +1 -1
  114. package/payload/server/public/assets/{linear-CZrU-J2V.js → linear-BeeahLKw.js} +1 -1
  115. package/payload/server/public/assets/maximize-2-DPe-Noig.js +1 -0
  116. package/payload/server/public/assets/{mermaid-parser.core-DwJ1cyfO.js → mermaid-parser.core-CLKle8df.js} +2 -2
  117. package/payload/server/public/assets/{mermaid.core-DnUst0He.js → mermaid.core-CwRj5rL5.js} +3 -3
  118. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-oc-GwerE.js → mindmap-definition-QFDTVHPH-CNQUY9UJ.js} +1 -1
  119. package/payload/server/public/assets/{operator-D-Ad9OQ5.js → operator-BM_CDyCb.js} +1 -1
  120. package/payload/server/public/assets/{ordinal-v4prQcuq.js → ordinal-B2r5L1v4.js} +1 -1
  121. package/payload/server/public/assets/packet-4T2RLAQJ-T-SYedp7.js +1 -0
  122. package/payload/server/public/assets/{page-BjAKwjlS.js → page-CMIbXzSg.js} +3 -3
  123. package/payload/server/public/assets/{page-CpSVszGe.js → page-E7I5sEVt.js} +1 -1
  124. package/payload/server/public/assets/{pdf-render-NQmflZ7K.js → pdf-render-m08Xm2Nm.js} +1 -1
  125. package/payload/server/public/assets/pie-ZZUOXDRM-BWECFVVd.js +1 -0
  126. package/payload/server/public/assets/{pieDiagram-DEJITSTG-BnBtQNHM.js → pieDiagram-DEJITSTG-Scnq58FX.js} +1 -1
  127. package/payload/server/public/assets/{public-CbkiISZZ.js → public-CrdWCSk2.js} +1 -1
  128. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CkNqtzHI.js → quadrantDiagram-34T5L4WZ-wPfZo_vs.js} +1 -1
  129. package/payload/server/public/assets/radar-PYXPWWZC-Dx0YUklX.js +1 -0
  130. package/payload/server/public/assets/{reduce-0Mm1v1Rr.js → reduce-CFlDlJf5.js} +1 -1
  131. package/payload/server/public/assets/{requirementDiagram-MS252O5E-D7qc27KT.js → requirementDiagram-MS252O5E-yYkH12K2.js} +1 -1
  132. package/payload/server/public/assets/{rotate-ccw-BYmlylsD.js → rotate-ccw-Dwtj0NJ7.js} +1 -1
  133. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-2Y4sqRY7.js → sankeyDiagram-XADWPNL6-fVWRBzzV.js} +1 -1
  134. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-hXOiSHuT.js → sequenceDiagram-FGHM5R23-Dbap3X6h.js} +1 -1
  135. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-Dq4hhkLA.js → stateDiagram-FHFEXIEX-DkPLAqIh.js} +1 -1
  136. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DceWO1u6.js +1 -0
  137. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Dn9wBUEw.js → timeline-definition-GMOUNBTQ-DabKBJyd.js} +1 -1
  138. package/payload/server/public/assets/treeView-SZITEDCU-C3197Rac.js +1 -0
  139. package/payload/server/public/assets/treemap-W4RFUUIX-BPrpx29h.js +1 -0
  140. package/payload/server/public/assets/{useSubAccountSwitcher-DxHQSOzT.css → useSubAccountSwitcher-BH-YjP0H.css} +1 -1
  141. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BKVHJiIt.js → vennDiagram-DHZGUBPP-CaKT7c-c.js} +1 -1
  142. package/payload/server/public/assets/wardley-RL74JXVD-DW4Jlbhw.js +1 -0
  143. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-Bn9vvpdK.js → wardleyDiagram-NUSXRM2D-BZ5TTSOL.js} +1 -1
  144. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-FIoMdPB3.js → xychartDiagram-5P7HB3ND-CLfeklJ9.js} +1 -1
  145. package/payload/server/public/browser.html +4 -4
  146. package/payload/server/public/calendar.html +5 -5
  147. package/payload/server/public/chat.html +10 -9
  148. package/payload/server/public/data.html +9 -8
  149. package/payload/server/public/graph.html +9 -8
  150. package/payload/server/public/index.html +12 -11
  151. package/payload/server/public/operator.html +12 -11
  152. package/payload/server/public/public.html +10 -9
  153. package/payload/server/server.js +41 -6
  154. package/payload/server/public/assets/architecture-YZFGNWBL-DdgmZ93B.js +0 -1
  155. package/payload/server/public/assets/channel-Da-UUyqx.js +0 -1
  156. package/payload/server/public/assets/chat-L6IVvC9k.js +0 -1
  157. package/payload/server/public/assets/chevron-left-uJSGyCGe.js +0 -1
  158. package/payload/server/public/assets/chunk-426QAEUC-B1kFAxo1.js +0 -1
  159. package/payload/server/public/assets/chunk-QZHKN3VN-BjE-Glwf.js +0 -1
  160. package/payload/server/public/assets/classDiagram-6PBFFD2Q-Dol3Ogeh.js +0 -1
  161. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-VUMj7gWH.js +0 -1
  162. package/payload/server/public/assets/clone-m7oGrdBC.js +0 -1
  163. package/payload/server/public/assets/data-4K_negqE.js +0 -1
  164. package/payload/server/public/assets/gitGraph-7Q5UKJZL-cJEaiQq4.js +0 -1
  165. package/payload/server/public/assets/graph-UHR4Ez-V.js +0 -51
  166. package/payload/server/public/assets/info-OMHHGYJF-BUxfOTKa.js +0 -1
  167. package/payload/server/public/assets/infoDiagram-42DDH7IO-CD-d3Rgf.js +0 -2
  168. package/payload/server/public/assets/packet-4T2RLAQJ-B9U_2639.js +0 -1
  169. package/payload/server/public/assets/pie-ZZUOXDRM-Glh-lJOT.js +0 -1
  170. package/payload/server/public/assets/radar-PYXPWWZC-CTSgob8w.js +0 -1
  171. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DTj9o2vZ.js +0 -1
  172. package/payload/server/public/assets/treeView-SZITEDCU-CXApkW1l.js +0 -1
  173. package/payload/server/public/assets/treemap-W4RFUUIX-DzvTXAcT.js +0 -1
  174. package/payload/server/public/assets/wardley-RL74JXVD-BExXV4oI.js +0 -1
  175. /package/payload/server/public/assets/{_baseFor-C0Y1mc3g.js → _baseFor-BVuIxZJh.js} +0 -0
  176. /package/payload/server/public/assets/{array-DqLCdDFv.js → array-B9UHiPd-.js} +0 -0
  177. /package/payload/server/public/assets/{cytoscape.esm-Cn5b4Cdu.js → cytoscape.esm-D5_TRwB-.js} +0 -0
  178. /package/payload/server/public/assets/{defaultLocale-CrJzLgRD.js → defaultLocale-5eAKkKJC.js} +0 -0
  179. /package/payload/server/public/assets/{dist-Dlks0Bfw.js → dist-CADCHk0t.js} +0 -0
  180. /package/payload/server/public/assets/{init-C0r9Gk5G.js → init-DlZdxViB.js} +0 -0
  181. /package/payload/server/public/assets/{katex-BFwFoEts.js → katex-Xo0SyWvP.js} +0 -0
  182. /package/payload/server/public/assets/{path-DIKpVbHL.js → path-6uRLdFF7.js} +0 -0
  183. /package/payload/server/public/assets/{preload-helper-C5gCWwwF.js → preload-helper-CvXuAEud.js} +0 -0
  184. /package/payload/server/public/assets/{rough.esm-DsHEmXUZ.js → rough.esm-Djo4Abte.js} +0 -0
  185. /package/payload/server/public/assets/{src-Bv7ZWAzF.js → src-Bi0fLV9t.js} +0 -0
  186. /package/payload/server/public/assets/{useSubAccountSwitcher-BRWAIbzr.js → useSubAccountSwitcher-BVCMAnWK.js} +0 -0
@@ -0,0 +1,1004 @@
1
+ <!DOCTYPE html>
2
+ <html lang="{{ PAGE_LANG }}">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{ COMPANY_NAME }} · {{ SECTOR_LABEL }} · Est. {{ ESTABLISHED_YEAR }} · {{ REGION }}</title>
7
+ <meta name="description" content="{{ META_DESCRIPTION }}">
8
+ <link rel="canonical" href="{{ WEBSITE_URL }}">
9
+ <link rel="icon" href="favicon.png" type="image/png">
10
+ <meta property="og:type" content="website">
11
+ <meta property="og:site_name" content="{{ COMPANY_LEGAL_NAME }}">
12
+ <meta property="og:title" content="{{ COMPANY_NAME }} · {{ SECTOR_LABEL }} · Est. {{ ESTABLISHED_YEAR }} · {{ REGION }}">
13
+ <meta property="og:description" content="{{ META_DESCRIPTION }}">
14
+ <meta property="og:url" content="{{ WEBSITE_URL }}">
15
+ <meta property="og:image" content="{{ WEBSITE_URL }}socials/og-landscape-main.jpg">
16
+ <meta property="og:image:width" content="1200">
17
+ <meta property="og:image:height" content="628">
18
+ <meta name="twitter:card" content="summary_large_image">
19
+ <meta name="twitter:title" content="{{ COMPANY_NAME }} · {{ SECTOR_LABEL }} · Est. {{ ESTABLISHED_YEAR }}">
20
+ <meta name="twitter:description" content="{{ META_DESCRIPTION_SHORT }}">
21
+ <meta name="twitter:image" content="{{ WEBSITE_URL }}socials/og-landscape-main.jpg">
22
+ <link rel="preconnect" href="https://fonts.googleapis.com">
23
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
24
+ <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;1,400&family=Lora:ital,wght@0,400;0,500;1,400&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
25
+ <style>
26
+ :root {
27
+ /* Brand tokens — substituted per client by the brand-extract step.
28
+ Names are stable so all component CSS resolves regardless of brand. */
29
+ --paper: {{ PAPER_100 }}; /* paper-100 · white surface (dominant body) */
30
+ --paper-2: {{ PAPER_200 }}; /* paper-200 · page-bg tint (alternating bands, image cells, hover) */
31
+ --ink: {{ INK_900 }}; /* ink-900 · primary text, headings, dark surfaces */
32
+ --ink-2: {{ INK_700 }}; /* ink-700 · secondary text */
33
+ --slate: {{ INK_400 }}; /* ink-400 · muted / captions */
34
+ --rule: {{ RULE_100 }}; /* rule-100 · borders / dividers */
35
+ --rule-fine: {{ RULE_100 }};
36
+ --gold: {{ ACCENT_TEXT }}; /* copper, deepened for legible accent text (eyebrows, links, em) */
37
+ --gold-soft: {{ ACCENT }}; /* brand accent — decorative tone */
38
+ --copper: {{ ACCENT }}; /* brand accent */
39
+ --copper-soft:{{ ACCENT_SOFT }}; /* soft tint behind accent text (tag chip, quote ground) */
40
+ --brand-grey: {{ BRAND_GREY }}; /* {{ COMPANY_SHORT }} monogram / wordmark grey */
41
+
42
+ --serif: 'Cormorant Garamond', 'EB Garamond', Garamond, serif;
43
+ --body-serif: 'Lora', 'Source Serif Pro', Georgia, serif;
44
+ --sans: 'Inter', system-ui, -apple-system, sans-serif;
45
+ }
46
+
47
+ * { margin: 0; padding: 0; box-sizing: border-box; }
48
+ html { font-size: 16px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; scroll-behavior: smooth; }
49
+ body {
50
+ font-family: var(--body-serif);
51
+ background: var(--paper);
52
+ color: var(--ink);
53
+ line-height: 1.65;
54
+ }
55
+ img { display: block; max-width: 100%; height: auto; }
56
+ a { color: inherit; }
57
+
58
+ /* ───────── TOP NAV ───────── */
59
+ .topnav {
60
+ position: relative;
61
+ z-index: 50;
62
+ height: 112px;
63
+ display: flex; align-items: center; justify-content: space-between;
64
+ padding: 0 32px;
65
+ background: var(--paper);
66
+ border-bottom: 1px solid var(--rule);
67
+ }
68
+ .burger {
69
+ display: none; background: transparent; border: none;
70
+ padding: 10px; cursor: pointer; margin-left: -10px;
71
+ }
72
+ .burger span {
73
+ display: block; width: 22px; height: 1.5px; background: var(--ink);
74
+ margin: 4px 0; transition: transform 250ms ease, opacity 250ms ease;
75
+ }
76
+ .burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
77
+ .burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
78
+ .burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }
79
+
80
+ .drawer {
81
+ position: fixed; top: 0; right: 0; bottom: 0;
82
+ width: min(360px, 86vw);
83
+ background: var(--paper);
84
+ box-shadow: -2px 0 36px rgba(42,45,56,0.18);
85
+ transform: translateX(100%);
86
+ transition: transform 320ms ease;
87
+ z-index: 60; padding: 64px 28px 28px;
88
+ display: flex; flex-direction: column; gap: 18px; overflow-y: auto;
89
+ }
90
+ .drawer.open { transform: translateX(0); }
91
+ .drawer-close {
92
+ position: absolute; top: 16px; right: 18px;
93
+ width: 36px; height: 36px; background: transparent; border: none;
94
+ font-size: 32px; line-height: 1; color: var(--ink); cursor: pointer;
95
+ }
96
+ .drawer-nav { display: flex; flex-direction: column; gap: 4px; }
97
+ .drawer-nav a {
98
+ font-family: var(--sans); font-size: 12px; font-weight: 500;
99
+ letter-spacing: 0.18em; text-transform: uppercase;
100
+ color: var(--ink-2); text-decoration: none;
101
+ padding: 14px 0; border-bottom: 1px solid var(--rule);
102
+ }
103
+ .drawer-nav a:hover { color: var(--gold); }
104
+ .drawer-nav a.drawer-cta {
105
+ margin-top: 12px; padding: 14px 18px;
106
+ background: var(--ink); color: var(--paper);
107
+ text-align: center; border-bottom: none;
108
+ }
109
+ .drawer-nav a.drawer-cta:hover { background: var(--copper); color: #fff; }
110
+ .drawer-foot {
111
+ margin-top: auto; padding-top: 24px; border-top: 1px solid var(--rule);
112
+ font-family: var(--body-serif); font-size: 13px; color: var(--slate); line-height: 1.55;
113
+ }
114
+ .drawer-foot a {
115
+ color: var(--ink-2); text-decoration: underline;
116
+ text-decoration-color: rgba(232,146,78,0.5); text-underline-offset: 3px;
117
+ font-variant-numeric: tabular-nums;
118
+ }
119
+ .drawer-backdrop {
120
+ position: fixed; inset: 0; background: rgba(42,45,56,0.45);
121
+ opacity: 0; pointer-events: none; transition: opacity 320ms ease; z-index: 55;
122
+ }
123
+ .drawer-backdrop.open { opacity: 1; pointer-events: auto; }
124
+ body.drawer-open { overflow: hidden; }
125
+
126
+ .topnav .left, .topnav .right {
127
+ display: flex; align-items: center; gap: 26px;
128
+ font-family: var(--sans); font-size: 11px; font-weight: 500;
129
+ letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-2);
130
+ }
131
+ .topnav .left a, .topnav .right a { text-decoration: none; }
132
+ .topnav .left a:hover, .topnav .right a:hover { color: var(--gold); }
133
+ .topnav .center {
134
+ position: absolute; left: 50%; top: 50%;
135
+ transform: translate(-50%, -50%); display: flex; align-items: center;
136
+ }
137
+ .topnav .center img { height: 84px; width: auto; }
138
+
139
+ /* ───────── HERO — 10-slide rotator with Ken-Burns (JS-driven .active) ───────── */
140
+ .hero {
141
+ position: relative; width: 100%; height: 80vh; min-height: 580px;
142
+ overflow: hidden; background: var(--ink);
143
+ }
144
+ .hero-stage { position: absolute; inset: 0; overflow: hidden; }
145
+ .hero-slide {
146
+ position: absolute; inset: 0; opacity: 0;
147
+ transition: opacity 1000ms ease; will-change: opacity;
148
+ }
149
+ .hero-slide.active { opacity: 1; }
150
+ .hero-slide img {
151
+ width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%;
152
+ transform: scale(1.05); transform-origin: 50% 50%; will-change: transform;
153
+ }
154
+ /* the visible slide gets a slow push-in for the time it is on screen */
155
+ .hero-slide.active img { animation: heroKb 7s ease-out forwards; }
156
+ @keyframes heroKb { from { transform: scale(1.05); } to { transform: scale(1.16); } }
157
+ /* subtle scrim so the info-card edge reads against any slide */
158
+ .hero::after {
159
+ content: ''; position: absolute; inset: 0; pointer-events: none;
160
+ background: linear-gradient(90deg, rgba(42,45,56,0.34) 0%, rgba(42,45,56,0.05) 42%, rgba(42,45,56,0) 70%);
161
+ }
162
+ @media (prefers-reduced-motion: reduce) {
163
+ .hero-slide { transition: none; }
164
+ .hero-slide.active img { animation: none; transform: none; }
165
+ }
166
+
167
+ .info-card {
168
+ position: absolute; left: 6vw; bottom: 7vh; z-index: 2;
169
+ background: rgba(255, 255, 255, 0.97);
170
+ padding: 22px 28px 24px; width: 392px;
171
+ border-top: 3px solid var(--copper);
172
+ box-shadow: 0 8px 36px rgba(42,45,56,0.20);
173
+ }
174
+ .info-card .tag {
175
+ display: inline-block; font-family: var(--sans);
176
+ font-size: 9px; font-weight: 600; letter-spacing: 0.32em; text-transform: uppercase;
177
+ color: var(--gold); margin-bottom: 12px;
178
+ }
179
+ .info-card .title {
180
+ font-family: var(--serif); font-style: italic; font-weight: 400;
181
+ font-size: 36px; line-height: 1.04; color: var(--ink); margin-bottom: 10px;
182
+ }
183
+ .info-card .address {
184
+ font-family: var(--body-serif); font-size: 14px; color: var(--ink-2);
185
+ line-height: 1.5; margin-bottom: 14px;
186
+ }
187
+ .info-card .tagline {
188
+ font-family: var(--serif); font-style: italic; font-size: 20px;
189
+ color: var(--gold); margin-bottom: 4px; letter-spacing: 0.005em;
190
+ }
191
+ .info-card .meta {
192
+ font-family: var(--body-serif); font-size: 12.5px; color: var(--slate);
193
+ line-height: 1.55; margin-bottom: 14px;
194
+ }
195
+ .info-card .specs {
196
+ display: flex; flex-wrap: nowrap; gap: 0; padding: 10px 0; margin-bottom: 14px;
197
+ border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
198
+ font-family: var(--sans); font-size: 9px; font-weight: 600;
199
+ letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-2);
200
+ font-variant-numeric: tabular-nums; justify-content: space-between; align-items: baseline;
201
+ }
202
+ .info-card .specs span { white-space: nowrap; flex: 0 0 auto; }
203
+ .info-card .specs span + span::before { content: "·"; color: var(--copper); margin: 0 7px; }
204
+ .info-card .links {
205
+ display: flex; flex-wrap: nowrap; gap: 16px;
206
+ font-family: var(--sans); font-size: 9.5px; font-weight: 500;
207
+ letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-2); margin-bottom: 16px;
208
+ }
209
+ .info-card .links a {
210
+ text-decoration: none; border-bottom: 1px solid var(--gold-soft);
211
+ padding-bottom: 2px; white-space: nowrap; transition: color 200ms;
212
+ }
213
+ .info-card .links a:hover { color: var(--gold); }
214
+ .info-card .cta {
215
+ display: block; width: 100%; padding: 13px 16px;
216
+ background: var(--ink); color: var(--paper);
217
+ font-family: var(--sans); font-size: 11px; font-weight: 500;
218
+ letter-spacing: 0.26em; text-transform: uppercase; text-align: center;
219
+ text-decoration: none; border: none; cursor: pointer; transition: background 200ms;
220
+ }
221
+ .info-card .cta:hover { background: var(--copper); }
222
+
223
+ /* ───────── STICKY SUB-NAV ───────── */
224
+ .subnav {
225
+ /* fixed (not sticky): a reveal-on-scroll bar. position:fixed + translateY(-100%)
226
+ moves it genuinely above the viewport, so there is nothing to overlap. This
227
+ also avoids the Safari/WebKit bug where transform on a sticky element promotes
228
+ it to its own compositing layer and breaks the z-index overlap-hide. */
229
+ position: fixed; top: 0; left: 0; right: 0; z-index: 40;
230
+ background: var(--paper); border-bottom: 1px solid var(--rule);
231
+ padding: 14px 32px; display: flex; align-items: center; justify-content: space-between;
232
+ transform: translateY(-100%); transition: transform 300ms ease;
233
+ }
234
+ .subnav.visible { transform: translateY(0); }
235
+ .subnav .left { font-family: var(--serif); font-size: 18px; color: var(--ink); }
236
+ .subnav .left .price {
237
+ color: var(--slate); font-size: 11px; font-family: var(--sans);
238
+ letter-spacing: 0.16em; text-transform: uppercase; margin-left: 14px;
239
+ }
240
+ .subnav .right { display: flex; align-items: center; gap: 14px; }
241
+ .subnav .right a {
242
+ font-family: var(--sans); font-size: 10px; font-weight: 500;
243
+ letter-spacing: 0.20em; text-transform: uppercase; color: var(--ink-2);
244
+ text-decoration: none; padding: 6px 10px; border: 1px solid var(--rule);
245
+ }
246
+ .subnav .right a:hover { background: var(--paper-2); }
247
+ .subnav .right a.cta { background: var(--ink); color: var(--paper); border-color: var(--ink); }
248
+ .subnav .right a.cta:hover { background: var(--copper); border-color: var(--copper); }
249
+
250
+ /* ───────── BODY SECTIONS ───────── */
251
+ .body-block { max-width: 720px; margin: 0 auto; padding: 72px 32px 28px; }
252
+ .body-block.short { padding-bottom: 16px; }
253
+ .body-block h2 {
254
+ font-family: var(--serif); font-style: italic; font-weight: 400;
255
+ font-size: 27px; line-height: 1.2; color: var(--ink); margin-bottom: 18px; letter-spacing: -0.005em;
256
+ }
257
+ .body-block h2::before {
258
+ content: ''; display: block; width: 40px; height: 2px;
259
+ background: var(--copper); margin-bottom: 18px;
260
+ }
261
+ .body-block p {
262
+ font-family: var(--body-serif); font-size: 15.5px; line-height: 1.75;
263
+ color: var(--ink-2); letter-spacing: 0.005em;
264
+ }
265
+ .body-block p + p { margin-top: 16px; }
266
+ .body-block p strong { color: var(--ink); font-weight: 500; }
267
+ .body-block p em { color: var(--gold); font-style: italic; }
268
+ .body-block p:first-of-type::first-letter {
269
+ font-family: var(--serif); font-weight: 400; font-size: 3.6em; line-height: 0.85;
270
+ float: left; margin: 0.08em 0.12em -0.04em 0; color: var(--ink); letter-spacing: -0.02em;
271
+ }
272
+ .section-eyebrow {
273
+ font-family: var(--sans); font-size: 10px; font-weight: 600;
274
+ letter-spacing: 0.36em; text-transform: uppercase; color: var(--gold); margin-bottom: 14px;
275
+ }
276
+
277
+ /* ───────── PHOTO GRID ───────── */
278
+ .photo-grid {
279
+ max-width: 1100px; margin: 32px auto; padding: 0 32px;
280
+ display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
281
+ }
282
+ .photo-grid .cell {
283
+ position: relative; overflow: hidden; aspect-ratio: 4/3; background: var(--paper-2);
284
+ }
285
+ .photo-grid .cell img { width: 100%; height: 100%; object-fit: cover; transition: transform 600ms ease; }
286
+ .photo-grid .cell:hover img { transform: scale(1.03); }
287
+
288
+ .photo-full { margin: 36px 0; }
289
+ .photo-full img { width: 100%; height: auto; max-height: 78vh; object-fit: cover; }
290
+
291
+ /* ───────── TESTIMONIAL BAND (repurposed feature band) ───────── */
292
+ .testimonial { background: var(--ink); color: var(--paper); padding: 84px 32px; margin-top: 40px; }
293
+ .testimonial .inner {
294
+ max-width: 1040px; margin: 0 auto;
295
+ display: grid; grid-template-columns: 0.85fr 1fr; gap: 56px; align-items: center;
296
+ }
297
+ .testimonial .home-img img {
298
+ width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block;
299
+ box-shadow: 0 16px 48px rgba(0,0,0,0.38); border-top: 3px solid var(--copper);
300
+ }
301
+ .testimonial .person {
302
+ display: flex; align-items: center; gap: 14px;
303
+ margin-top: 26px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,0.18);
304
+ }
305
+ .testimonial .person img {
306
+ width: 62px; height: 62px; border-radius: 50%; object-fit: cover;
307
+ object-position: 50% 35%; flex: 0 0 auto; border: 2px solid var(--copper);
308
+ }
309
+ .testimonial .person .who { display: flex; flex-direction: column; line-height: 1.25; }
310
+ .testimonial .person .pn { font-family: var(--serif); font-style: italic; font-size: 20px; color: #fff; }
311
+ .testimonial .person .pr {
312
+ font-family: var(--sans); font-size: 10px; font-weight: 600;
313
+ letter-spacing: 0.22em; text-transform: uppercase; color: var(--copper); margin-top: 3px;
314
+ }
315
+ .testimonial .meta .eyebrow {
316
+ font-family: var(--sans); font-size: 10px; font-weight: 600;
317
+ letter-spacing: 0.36em; text-transform: uppercase; color: var(--copper); margin-bottom: 20px;
318
+ }
319
+ .testimonial blockquote {
320
+ font-family: var(--serif); font-style: italic; font-weight: 400;
321
+ font-size: 27px; line-height: 1.34; color: var(--paper); margin: 0 0 22px;
322
+ }
323
+ .testimonial blockquote .hl { color: var(--copper); }
324
+ .testimonial .attrib {
325
+ font-family: var(--sans); font-size: 11px; font-weight: 500;
326
+ letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255,255,255,0.72);
327
+ }
328
+ .testimonial .attrib span { color: var(--copper); }
329
+
330
+ /* ───────── FOUNDER ───────── */
331
+ .founder { background: var(--paper-2); padding: 84px 32px; }
332
+ .founder .inner {
333
+ max-width: 1100px; margin: 0 auto;
334
+ display: grid; grid-template-columns: 0.8fr 1fr; gap: 56px; align-items: center;
335
+ }
336
+ .founder .portrait img {
337
+ width: 100%; max-width: 420px; height: auto; display: block;
338
+ box-shadow: 0 16px 48px rgba(42,45,56,0.22); border-top: 3px solid var(--copper);
339
+ }
340
+ .founder .portrait .cap {
341
+ display: block; margin-top: 12px; font-family: var(--sans);
342
+ font-size: 10px; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase; color: var(--brand-grey);
343
+ }
344
+ .founder .words h2 {
345
+ font-family: var(--serif); font-style: italic; font-size: 28px; color: var(--ink); margin-bottom: 18px;
346
+ }
347
+ .founder .words h2::before { content: ''; display: block; width: 40px; height: 2px; background: var(--copper); margin-bottom: 18px; }
348
+ .founder .words p { font-family: var(--body-serif); font-size: 15.5px; line-height: 1.75; color: var(--ink-2); }
349
+ .founder .words p + p { margin-top: 14px; }
350
+ .founder .words blockquote {
351
+ font-family: var(--serif); font-style: italic; font-size: 21px; line-height: 1.4;
352
+ color: var(--ink); margin: 22px 0; padding-left: 20px; border-left: 3px solid var(--copper);
353
+ }
354
+ .founder .words .ethos { font-family: var(--body-serif); font-style: italic; font-size: 14.5px; color: var(--slate); }
355
+ .founder-extra {
356
+ max-width: 1100px; margin: 44px auto 0;
357
+ display: grid; grid-template-columns: 1.4fr 1fr; gap: 20px;
358
+ align-items: end;
359
+ }
360
+ .founder-extra figure { margin: 0; display: flex; flex-direction: column; }
361
+ .founder-extra img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
362
+ .founder-extra figcaption { margin-top: 10px; font-family: var(--body-serif); font-style: italic; font-size: 12.5px; color: var(--slate); }
363
+ .site-updates { max-width: 1100px; margin: 56px auto 0; }
364
+ .site-updates .eyebrow {
365
+ font-family: var(--sans); font-size: 10px; font-weight: 600; letter-spacing: 0.36em;
366
+ text-transform: uppercase; color: var(--gold); text-align: center; margin-bottom: 24px;
367
+ }
368
+ .site-updates .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
369
+ .site-updates .card {
370
+ background: var(--paper); border: 1px solid var(--rule); padding: 24px 24px 26px;
371
+ display: flex; flex-direction: column;
372
+ }
373
+ .site-updates .card .loc {
374
+ font-family: var(--sans); font-size: 10px; font-weight: 600; letter-spacing: 0.2em;
375
+ text-transform: uppercase; color: var(--copper); margin-bottom: 10px;
376
+ }
377
+ .site-updates .card p {
378
+ font-family: var(--body-serif); font-size: 13.5px; line-height: 1.6; color: var(--ink-2);
379
+ margin-top: auto;
380
+ }
381
+
382
+ /* ───────── SERVICES ───────── */
383
+ .services { max-width: 1100px; margin: 76px auto 32px; padding: 0 32px; }
384
+ .services h2 {
385
+ font-family: var(--serif); font-style: italic; font-size: 27px; color: var(--ink);
386
+ margin-bottom: 8px; text-align: center;
387
+ }
388
+ .services .lede {
389
+ text-align: center; font-family: var(--body-serif); font-size: 14.5px;
390
+ color: var(--ink-2); max-width: 560px; margin: 0 auto 36px;
391
+ }
392
+ .services h2::after {
393
+ content: ''; display: block; width: 40px; height: 2px; background: var(--copper); margin: 14px auto 0;
394
+ }
395
+ .services .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
396
+ .services .svc { background: var(--paper); padding: 30px 26px 32px; }
397
+ .services .svc .num {
398
+ font-family: var(--sans); font-size: 10px; font-weight: 600;
399
+ letter-spacing: 0.28em; color: var(--copper); margin-bottom: 14px;
400
+ }
401
+ .services .svc h3 {
402
+ font-family: var(--serif); font-style: italic; font-weight: 500;
403
+ font-size: 21px; color: var(--ink); margin-bottom: 10px;
404
+ }
405
+ .services .svc p { font-family: var(--body-serif); font-size: 13.5px; line-height: 1.6; color: var(--ink-2); }
406
+
407
+ /* ───────── KEY FACTS ───────── */
408
+ .key-facts { max-width: 1100px; margin: 76px auto 32px; padding: 0 32px; }
409
+ .key-facts h2 {
410
+ font-family: var(--serif); font-style: italic; font-size: 27px; color: var(--ink);
411
+ margin-bottom: 24px; text-align: center;
412
+ }
413
+ .key-facts h2::after {
414
+ content: ''; display: block; width: 40px; height: 2px; background: var(--copper); margin: 14px auto 0;
415
+ }
416
+ .key-facts .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px 36px; font-variant-numeric: tabular-nums; }
417
+ .key-facts .row { border-bottom: 1px solid var(--rule); padding: 12px 0 14px; }
418
+ .key-facts .row .k {
419
+ font-family: var(--sans); font-size: 9px; font-weight: 600;
420
+ letter-spacing: 0.28em; text-transform: uppercase; color: var(--slate); margin-bottom: 5px;
421
+ }
422
+ .key-facts .row .v { font-family: var(--body-serif); font-size: 14.5px; color: var(--ink); }
423
+ .key-facts .footnote {
424
+ grid-column: 1 / -1; margin-top: 18px; font-family: var(--body-serif);
425
+ font-style: italic; font-size: 12px; color: var(--slate); text-align: center;
426
+ }
427
+
428
+ /* ───────── SCROLL TO TOP ───────── */
429
+ .to-top {
430
+ position: fixed; right: 26px; bottom: 26px; z-index: 45;
431
+ width: 48px; height: 48px; border-radius: 50%;
432
+ background: var(--ink); color: #fff; border: none; cursor: pointer;
433
+ display: flex; align-items: center; justify-content: center;
434
+ box-shadow: 0 6px 22px rgba(42,45,56,0.30);
435
+ opacity: 0; visibility: hidden; transform: translateY(10px);
436
+ transition: opacity 240ms ease, transform 240ms ease, visibility 240ms, background 200ms;
437
+ }
438
+ .to-top.show { opacity: 1; visibility: visible; transform: translateY(0); }
439
+ .to-top:hover { background: var(--copper); }
440
+ .to-top svg { width: 18px; height: 18px; display: block; }
441
+ @media (max-width: 760px) { .to-top { right: 16px; bottom: 16px; } }
442
+
443
+ /* ───────── FAQ ───────── */
444
+ .faq { max-width: 760px; margin: 76px auto 16px; padding: 0 32px; }
445
+ .faq > h2 {
446
+ font-family: var(--serif); font-style: italic; font-size: 27px; color: var(--ink);
447
+ margin-bottom: 28px; text-align: center;
448
+ }
449
+ .faq > h2::after { content: ''; display: block; width: 40px; height: 2px; background: var(--copper); margin: 14px auto 0; }
450
+ .faq .qa { border-top: 1px solid var(--rule); padding: 22px 0; }
451
+ .faq .qa:last-child { border-bottom: 1px solid var(--rule); }
452
+ .faq .qa h3 {
453
+ font-family: var(--serif); font-style: italic; font-weight: 500;
454
+ font-size: 20px; color: var(--ink); margin-bottom: 8px;
455
+ }
456
+ .faq .qa p { font-family: var(--body-serif); font-size: 15px; line-height: 1.7; color: var(--ink-2); }
457
+
458
+ /* ───────── CTA STRIP ───────── */
459
+ .cta-strip { background: var(--copper); color: #fff; text-align: center; padding: 72px 32px; margin-top: 72px; }
460
+ .cta-strip .eyebrow {
461
+ font-family: var(--sans); font-size: 10px; font-weight: 600;
462
+ letter-spacing: 0.36em; text-transform: uppercase; color: rgba(255,255,255,0.85); margin-bottom: 16px;
463
+ }
464
+ .cta-strip h2 {
465
+ font-family: var(--serif); font-style: italic; font-weight: 400;
466
+ font-size: 38px; margin-bottom: 30px; color: #fff;
467
+ }
468
+ .cta-strip .cta-row { display: flex; gap: 18px; justify-content: center; align-items: center; flex-wrap: wrap; }
469
+ .cta-strip .cta-row a {
470
+ font-family: var(--sans); font-size: 11px; font-weight: 500;
471
+ letter-spacing: 0.24em; text-transform: uppercase; color: #fff; text-decoration: none;
472
+ padding: 13px 24px; border: 1px solid rgba(255,255,255,0.55); transition: background 200ms, color 200ms, border-color 200ms;
473
+ font-variant-numeric: tabular-nums;
474
+ }
475
+ .cta-strip .cta-row a:hover { background: rgba(255,255,255,0.14); }
476
+ .cta-strip .cta-row a.solid { background: var(--ink); color: #fff; border-color: var(--ink); }
477
+ .cta-strip .cta-row a.solid:hover { background: #fff; color: var(--ink); border-color: #fff; }
478
+
479
+ /* ───────── FOOTER ───────── */
480
+ footer { background: var(--paper); padding: 56px 32px 32px; border-top: 1px solid var(--rule); }
481
+ footer .inner {
482
+ max-width: 1100px; margin: 0 auto; display: flex;
483
+ justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: 40px;
484
+ }
485
+ footer .agent { font-family: var(--body-serif); font-size: 13.5px; color: var(--ink-2); line-height: 1.7; max-width: 320px; }
486
+ footer .agent .name { font-family: var(--serif); font-size: 19px; color: var(--ink); margin-bottom: 4px; }
487
+ footer .agent .name em { font-style: italic; color: var(--gold); }
488
+ footer .agent .label {
489
+ font-family: var(--sans); font-size: 9px; font-weight: 600;
490
+ letter-spacing: 0.32em; text-transform: uppercase; color: var(--slate); margin-bottom: 10px;
491
+ }
492
+ footer .agent a {
493
+ color: var(--ink-2); text-decoration: underline; text-decoration-color: rgba(232,146,78,0.5);
494
+ text-underline-offset: 3px; font-variant-numeric: tabular-nums;
495
+ }
496
+ footer .socials { display: flex; gap: 18px; margin-top: 14px; }
497
+ footer .socials a {
498
+ font-family: var(--sans); font-size: 10px; font-weight: 600;
499
+ letter-spacing: 0.18em; text-transform: uppercase; color: var(--brand-grey); text-decoration: none;
500
+ }
501
+ footer .socials a:hover { color: var(--gold); }
502
+ footer .legal {
503
+ font-family: var(--body-serif); font-style: italic; font-size: 11.5px;
504
+ color: var(--slate); line-height: 1.6; max-width: 560px;
505
+ align-self: flex-end;
506
+ }
507
+ footer .colophon {
508
+ width: 100%; border-top: 1px solid var(--rule); padding-top: 18px; margin-top: 28px;
509
+ display: flex; justify-content: space-between; align-items: center;
510
+ font-family: var(--sans); font-size: 10px; font-weight: 500;
511
+ letter-spacing: 0.20em; text-transform: uppercase; color: var(--slate);
512
+ }
513
+ footer .colophon img { height: 60px; width: auto; opacity: 0.9; }
514
+
515
+ /* ───────── RESPONSIVE ───────── */
516
+ /* Nav collapses to a hamburger early: a wide centred logo lockup needs room,
517
+ so the deep links would otherwise collide with it well above 960px. Tune this
518
+ width to the logo's rendered width if the lockup is much narrower or wider. */
519
+ @media (max-width: 1240px) {
520
+ .burger { display: block; }
521
+ .topnav .left, .topnav .right { display: none; }
522
+ .topnav .center { left: auto; right: auto; transform: none; position: static; margin-left: auto; margin-right: auto; }
523
+ }
524
+ @media (max-width: 960px) {
525
+ .testimonial .inner { grid-template-columns: 1fr; gap: 36px; }
526
+ .testimonial .home-img { max-width: 460px; margin: 0 auto; }
527
+ .services .grid { grid-template-columns: 1fr 1fr; }
528
+ .founder .inner { grid-template-columns: 1fr; gap: 32px; }
529
+ .founder .portrait img { max-width: 360px; margin: 0 auto; }
530
+ .site-updates .grid { grid-template-columns: 1fr; }
531
+ }
532
+ @media (max-width: 760px) {
533
+ .hero { height: auto; min-height: 0; display: flex; flex-direction: column; background: var(--paper); }
534
+ .hero::after { display: none; }
535
+ .hero-stage { position: relative; width: 100%; aspect-ratio: 4/3; flex: 0 0 auto; background: var(--ink); }
536
+ .info-card {
537
+ position: static; left: auto; right: auto; bottom: auto; width: auto; margin: 0;
538
+ padding: 26px 24px 28px; box-shadow: none; border-top: 3px solid var(--copper); background: var(--paper);
539
+ }
540
+ .info-card .title { font-size: 32px; }
541
+ .info-card .specs { font-size: 9px; }
542
+ .info-card .links { font-size: 10px; }
543
+ .photo-grid { grid-template-columns: 1fr; gap: 12px; }
544
+ .key-facts .grid { grid-template-columns: 1fr 1fr; }
545
+ .subnav .right a:not(.cta) { display: none; }
546
+ .body-block { padding: 52px 24px 24px; }
547
+ .topnav { padding: 0 18px; height: 88px; }
548
+ .topnav .center img { height: 60px; }
549
+ .testimonial { padding: 60px 24px; }
550
+ .testimonial blockquote { font-size: 23px; }
551
+ .founder { padding: 56px 24px; }
552
+ .founder-extra { grid-template-columns: 1fr; }
553
+ .cta-strip h2 { font-size: 30px; }
554
+ footer .colophon { flex-direction: column; align-items: flex-start; gap: 12px; }
555
+ }
556
+ @media (max-width: 440px) {
557
+ .hero-stage { aspect-ratio: 5/4; }
558
+ .key-facts .grid { grid-template-columns: 1fr; }
559
+ .services .grid { grid-template-columns: 1fr; }
560
+ .subnav .left .price { display: none; }
561
+ }
562
+ </style>
563
+ <script type="application/ld+json">
564
+ {
565
+ "@context": "https://schema.org",
566
+ "@type": "{{ SCHEMA_TYPE }}",
567
+ "name": "{{ COMPANY_NAME }}",
568
+ "legalName": "{{ COMPANY_LEGAL_NAME }}",
569
+ "url": "{{ WEBSITE_URL }}",
570
+ "image": "{{ WEBSITE_URL }}images/hero-01.webp",
571
+ "logo": "{{ WEBSITE_URL }}images/logo.png",
572
+ "slogan": "{{ TAGLINE }}",
573
+ "description": "{{ SCHEMA_DESCRIPTION }}",
574
+ "foundingDate": "{{ ESTABLISHED_YEAR }}",
575
+ "telephone": "{{ PHONE_INTL }}",
576
+ "email": "{{ EMAIL }}",
577
+ "identifier": { "@type": "PropertyValue", "name": "{{ COMPANY_NUMBER_LABEL }}", "value": "{{ COMPANY_NUMBER }}" },
578
+ "employee": { "@type": "Person", "name": "{{ FOUNDER_NAME }}" },
579
+ "address": {
580
+ "@type": "PostalAddress",
581
+ "streetAddress": "{{ STREET_ADDRESS }}",
582
+ "addressLocality": "{{ POST_TOWN }}",
583
+ "addressRegion": "{{ COUNTY }}",
584
+ "postalCode": "{{ POSTCODE }}",
585
+ "addressCountry": "{{ COUNTRY_CODE }}"
586
+ },
587
+ "areaServed": [
588
+ { "@type": "AdministrativeArea", "name": "{{ COUNTY }}" },
589
+ { "@type": "AdministrativeArea", "name": "{{ REGION_2 }}" }
590
+ ],
591
+ "sameAs": [
592
+ "{{ FACEBOOK_URL }}",
593
+ "{{ INSTAGRAM_URL }}",
594
+ "{{ TIKTOK_URL }}"
595
+ ],
596
+ "knowsAbout": ["{{ SERVICE_1_NAME }}", "{{ SERVICE_2_NAME }}", "{{ SERVICE_3_NAME }}", "{{ SERVICE_4_NAME }}", "{{ SERVICE_5_NAME }}", "{{ SERVICE_6_NAME }}"],
597
+ "hasOfferCatalog": {
598
+ "@type": "OfferCatalog",
599
+ "name": "{{ OFFER_CATALOG_NAME }}",
600
+ "itemListElement": [
601
+ { "@type": "Offer", "itemOffered": { "@type": "Service", "name": "{{ SERVICE_1_NAME }}", "description": "{{ SERVICE_1_DESC }}" } },
602
+ { "@type": "Offer", "itemOffered": { "@type": "Service", "name": "{{ SERVICE_2_NAME }}", "description": "{{ SERVICE_2_DESC }}" } },
603
+ { "@type": "Offer", "itemOffered": { "@type": "Service", "name": "{{ SERVICE_3_NAME }}", "description": "{{ SERVICE_3_DESC }}" } },
604
+ { "@type": "Offer", "itemOffered": { "@type": "Service", "name": "{{ SERVICE_4_NAME }}", "description": "{{ SERVICE_4_DESC }}" } },
605
+ { "@type": "Offer", "itemOffered": { "@type": "Service", "name": "{{ SERVICE_5_NAME }}", "description": "{{ SERVICE_5_DESC }}" } },
606
+ { "@type": "Offer", "itemOffered": { "@type": "Service", "name": "{{ SERVICE_6_NAME }}", "description": "{{ SERVICE_6_DESC }}" } }
607
+ ]
608
+ }
609
+ }
610
+ </script>
611
+ <script type="application/ld+json">
612
+ {
613
+ "@context": "https://schema.org",
614
+ "@type": "FAQPage",
615
+ "mainEntity": [
616
+ { "@type": "Question", "name": "{{ FAQ_1_Q }}",
617
+ "acceptedAnswer": { "@type": "Answer", "text": "{{ FAQ_1_A }}" } },
618
+ { "@type": "Question", "name": "{{ FAQ_2_Q }}",
619
+ "acceptedAnswer": { "@type": "Answer", "text": "{{ FAQ_2_A }}" } },
620
+ { "@type": "Question", "name": "{{ FAQ_3_Q }}",
621
+ "acceptedAnswer": { "@type": "Answer", "text": "{{ FAQ_3_A }}" } },
622
+ { "@type": "Question", "name": "{{ FAQ_4_Q }}",
623
+ "acceptedAnswer": { "@type": "Answer", "text": "{{ FAQ_4_A }}" } },
624
+ { "@type": "Question", "name": "{{ FAQ_5_Q }}",
625
+ "acceptedAnswer": { "@type": "Answer", "text": "{{ FAQ_5_A }}" } }
626
+ ]
627
+ }
628
+ </script>
629
+ </head>
630
+ <body>
631
+
632
+ <!-- ════════════════ TOP NAV ════════════════ -->
633
+ <nav class="topnav">
634
+ <button class="burger" aria-label="Open menu" aria-expanded="false" aria-controls="drawer">
635
+ <span></span><span></span><span></span>
636
+ </button>
637
+ <div class="left">
638
+ <a href="#story">About</a>
639
+ <a href="#offer">What we do</a>
640
+ <a href="#how">How we work</a>
641
+ <a href="#founder">{{ FOUNDER_SECTION_LABEL }}</a>
642
+ </div>
643
+ <div class="center">
644
+ <img src="images/logo.png" alt="{{ COMPANY_NAME }}, {{ SECTOR_LABEL }}, est. {{ ESTABLISHED_YEAR }}">
645
+ </div>
646
+ <div class="right">
647
+ <a href="#words">Reviews</a>
648
+ <a href="#services">Services</a>
649
+ <a href="mailto:{{ EMAIL }}?subject=Project%20enquiry">Enquire</a>
650
+ </div>
651
+ </nav>
652
+
653
+ <!-- Mobile drawer -->
654
+ <div class="drawer" id="drawer" aria-hidden="true">
655
+ <button class="drawer-close" aria-label="Close menu">&times;</button>
656
+ <nav class="drawer-nav">
657
+ <a href="#story">About</a>
658
+ <a href="#offer">What we do</a>
659
+ <a href="#how">How we work</a>
660
+ <a href="#founder">{{ FOUNDER_SECTION_LABEL }}</a>
661
+ <a href="#words">Reviews</a>
662
+ <a href="#services">Services</a>
663
+ <a href="#facts">{{ WHY_HEADLINE }}</a>
664
+ <a href="tel:{{ PHONE_TEL }}">Call {{ PHONE_DISPLAY }}</a>
665
+ <a href="{{ INSTAGRAM_URL }}" target="_blank" rel="noopener">Instagram</a>
666
+ <a href="{{ FACEBOOK_URL }}" target="_blank" rel="noopener">Facebook</a>
667
+ <a href="mailto:{{ EMAIL }}?subject=Project%20enquiry" class="drawer-cta">Request a callback</a>
668
+ </nav>
669
+ <div class="drawer-foot">
670
+ {{ COMPANY_LEGAL_NAME }} · {{ LOCALITY }}, {{ COUNTY }}<br>
671
+ <a href="tel:{{ PHONE_TEL }}">{{ PHONE_DISPLAY }}</a> · <a href="mailto:{{ EMAIL }}">{{ EMAIL }}</a>
672
+ </div>
673
+ </div>
674
+
675
+ <!-- ════════════════ STICKY SUB-NAV ════════════════ -->
676
+ <nav class="subnav" id="subnav">
677
+ <div class="left">
678
+ {{ COMPANY_NAME }}
679
+ <span class="price">{{ SECTOR_LABEL }} · Est. {{ ESTABLISHED_YEAR }}</span>
680
+ </div>
681
+ <div class="right">
682
+ <a href="#how">How we work</a>
683
+ <a href="#services">Services</a>
684
+ <a href="#words">Reviews</a>
685
+ <a href="mailto:{{ EMAIL }}?subject=Project%20enquiry" class="cta">Get in touch</a>
686
+ </div>
687
+ </nav>
688
+
689
+ <!-- ════════════════ HERO ════════════════ -->
690
+ <section class="hero">
691
+ <div class="hero-stage" aria-label="{{ COMPANY_NAME }}, views of our work" role="img">
692
+ <div class="hero-slide active"><img src="images/hero-01.webp" alt="{{ HERO_1_ALT }}"></div>
693
+ <div class="hero-slide"><img src="images/hero-02.webp" alt="{{ HERO_2_ALT }}"></div>
694
+ <div class="hero-slide"><img src="images/hero-03.webp" alt="{{ HERO_3_ALT }}"></div>
695
+ <div class="hero-slide"><img src="images/hero-04.webp" alt="{{ HERO_4_ALT }}"></div>
696
+ <div class="hero-slide"><img src="images/hero-05.webp" alt="{{ HERO_5_ALT }}"></div>
697
+ <div class="hero-slide"><img src="images/hero-06.webp" alt="{{ HERO_6_ALT }}"></div>
698
+ <div class="hero-slide"><img src="images/hero-07.webp" alt="{{ HERO_7_ALT }}"></div>
699
+ <div class="hero-slide"><img src="images/hero-08.webp" alt="{{ HERO_8_ALT }}"></div>
700
+ <div class="hero-slide"><img src="images/hero-09.webp" alt="{{ HERO_9_ALT }}"></div>
701
+ <div class="hero-slide"><img src="images/hero-10.webp" alt="{{ HERO_10_ALT }}"></div>
702
+ </div>
703
+ <div class="info-card">
704
+ <span class="tag">Est. {{ ESTABLISHED_YEAR }} · {{ COUNTY }}</span>
705
+ <h1 class="title">{{ COMPANY_NAME }}</h1>
706
+ <div class="address">{{ HERO_STRAPLINE }}</div>
707
+ <div class="tagline">{{ TAGLINE }}</div>
708
+ <div class="meta">{{ HERO_META }}</div>
709
+ <div class="specs">
710
+ <span>{{ HERO_SPEC_1 }}</span>
711
+ <span>{{ HERO_SPEC_2 }}</span>
712
+ <span>{{ HERO_SPEC_3 }}</span>
713
+ <span>{{ HERO_SPEC_4 }}</span>
714
+ </div>
715
+ <div class="links">
716
+ <a href="#offer">Our work</a>
717
+ <a href="#words">Reviews</a>
718
+ <a href="#services">Services</a>
719
+ </div>
720
+ <a href="mailto:{{ EMAIL }}?subject=Project%20enquiry" class="cta">Request a callback</a>
721
+ </div>
722
+ </section>
723
+
724
+ <!-- ════════════════ MAIN BODY ════════════════ -->
725
+ <main>
726
+
727
+ <!-- OUR STORY -->
728
+ <article class="body-block" id="story">
729
+ <div class="section-eyebrow">Since {{ ESTABLISHED_YEAR }}</div>
730
+ <h2>{{ STORY_HEADLINE }}</h2>
731
+ <p>{{ STORY_PARA_1 }}</p>
732
+ <p>{{ STORY_PARA_2 }}</p>
733
+ </article>
734
+
735
+ <!-- PHOTO GRID 1 — finished work -->
736
+ <div class="photo-grid">
737
+ <div class="cell"><img src="images/grid-01.webp" alt="{{ GRID_1_ALT }}"></div>
738
+ <div class="cell"><img src="images/grid-02.webp" alt="{{ GRID_2_ALT }}"></div>
739
+ <div class="cell"><img src="images/grid-03.webp" alt="{{ GRID_3_ALT }}"></div>
740
+ <div class="cell"><img src="images/grid-04.webp" alt="{{ GRID_4_ALT }}"></div>
741
+ </div>
742
+
743
+ <!-- WHAT WE DO -->
744
+ <article class="body-block" id="offer">
745
+ <div class="section-eyebrow">What we do</div>
746
+ <h2>{{ BUILD_HEADLINE }}</h2>
747
+ <p>{{ BUILD_PARA_1 }}</p>
748
+ <p>{{ BUILD_PARA_2 }}</p>
749
+ <p>{{ BUILD_PARA_3 }}</p>
750
+ </article>
751
+
752
+ <!-- PHOTO GRID 2 — interiors & finishes -->
753
+ <div class="photo-grid">
754
+ <div class="cell"><img src="images/grid-05.webp" alt="{{ GRID_5_ALT }}"></div>
755
+ <div class="cell"><img src="images/grid-06.webp" alt="{{ GRID_6_ALT }}"></div>
756
+ <div class="cell"><img src="images/grid-07.webp" alt="{{ GRID_7_ALT }}"></div>
757
+ <div class="cell"><img src="images/grid-08.webp" alt="{{ GRID_8_ALT }}"></div>
758
+ </div>
759
+
760
+ <!-- HOW WE WORK -->
761
+ <article class="body-block" id="how">
762
+ <div class="section-eyebrow">Start to finish</div>
763
+ <h2>{{ CRAFT_HEADLINE }}</h2>
764
+ <p>{{ CRAFT_PARA_1 }}</p>
765
+ <p>{{ CRAFT_PARA_2 }}</p>
766
+ <p>{{ CRAFT_PARA_3 }}</p>
767
+ </article>
768
+
769
+ <!-- FULL-BLEED CRAFT MOMENT -->
770
+ <div class="photo-full">
771
+ <img src="images/fullbleed-01.webp" alt="{{ FULLBLEED_1_ALT }}">
772
+ </div>
773
+
774
+ <!-- PHOTO GRID 4 — process / detail -->
775
+ <div class="photo-grid">
776
+ <div class="cell"><img src="images/grid-09.webp" alt="{{ GRID_9_ALT }}"></div>
777
+ <div class="cell"><img src="images/grid-10.webp" alt="{{ GRID_10_ALT }}"></div>
778
+ <div class="cell"><img src="images/grid-11.webp" alt="{{ GRID_11_ALT }}"></div>
779
+ <div class="cell"><img src="images/grid-12.webp" alt="{{ GRID_12_ALT }}"></div>
780
+ </div>
781
+
782
+ </main>
783
+
784
+ <!-- ════════════════ FOUNDER / TEAM LEAD ════════════════ -->
785
+ <section class="founder" id="founder">
786
+ <div class="inner">
787
+ <div class="portrait">
788
+ <img src="images/founder-portrait.webp" alt="{{ FOUNDER_PORTRAIT_ALT }}">
789
+ <span class="cap">{{ FOUNDER_NAME }} · {{ COMPANY_NAME }}</span>
790
+ </div>
791
+ <div class="words">
792
+ <div class="section-eyebrow">{{ FOUNDER_SECTION_LABEL }}</div>
793
+ <h2>{{ FOUNDER_HEADLINE }}</h2>
794
+ <p>{{ FOUNDER_INTRO }}</p>
795
+ <blockquote>{{ FOUNDER_QUOTE }}</blockquote>
796
+ <p class="ethos">{{ FOUNDER_ETHOS }}</p>
797
+ </div>
798
+ </div>
799
+ <div class="founder-extra">
800
+ <figure>
801
+ <img src="images/feature-project.webp" alt="{{ FEATURE_PROJECT_ALT }}">
802
+ <figcaption>{{ FEATURE_PROJECT_CAPTION }}</figcaption>
803
+ </figure>
804
+ <figure>
805
+ <img src="images/gift.webp" alt="{{ GIFT_ALT }}">
806
+ <figcaption>{{ GIFT_CAPTION }}</figcaption>
807
+ </figure>
808
+ </div>
809
+ <div class="site-updates">
810
+ <div class="eyebrow">{{ UPDATES_LABEL }}</div>
811
+ <div class="grid">
812
+ <div class="card">
813
+ <div class="loc">{{ UPDATE_1_LOC }}</div>
814
+ <p>{{ UPDATE_1_TEXT }}</p>
815
+ </div>
816
+ <div class="card">
817
+ <div class="loc">{{ UPDATE_2_LOC }}</div>
818
+ <p>{{ UPDATE_2_TEXT }}</p>
819
+ </div>
820
+ <div class="card">
821
+ <div class="loc">{{ UPDATE_3_LOC }}</div>
822
+ <p>{{ UPDATE_3_TEXT }}</p>
823
+ </div>
824
+ </div>
825
+ </div>
826
+ </section>
827
+
828
+ <!-- ════════════════ TESTIMONIAL BAND ════════════════ -->
829
+ <section class="testimonial" id="words">
830
+ <div class="inner">
831
+ <div class="home-img">
832
+ <img src="images/testimonial.webp" alt="{{ TESTIMONIAL_ALT }}">
833
+ </div>
834
+ <div class="meta">
835
+ <div class="eyebrow">In their words</div>
836
+ <blockquote>{{ TESTIMONIAL_QUOTE }}</blockquote>
837
+ <div class="attrib">{{ TESTIMONIAL_ATTRIB }} · <span>{{ TESTIMONIAL_CONTEXT }}</span></div>
838
+ <div class="person">
839
+ <img src="images/founder-avatar.webp" alt="{{ FOUNDER_AVATAR_ALT }}">
840
+ <div class="who"><span class="pn">{{ FOUNDER_NAME }}</span><span class="pr">{{ COMPANY_NAME }}</span></div>
841
+ </div>
842
+ </div>
843
+ </div>
844
+ </section>
845
+
846
+ <!-- ════════════════ SERVICES ════════════════ -->
847
+ <section class="services" id="services">
848
+ <h2>{{ SERVICES_HEADLINE }}</h2>
849
+ <p class="lede">{{ SERVICES_LEDE }}</p>
850
+ <div class="grid">
851
+ <div class="svc"><div class="num">01</div><h3>{{ SERVICE_1_NAME }}</h3><p>{{ SERVICE_1_DESC }}</p></div>
852
+ <div class="svc"><div class="num">02</div><h3>{{ SERVICE_2_NAME }}</h3><p>{{ SERVICE_2_DESC }}</p></div>
853
+ <div class="svc"><div class="num">03</div><h3>{{ SERVICE_3_NAME }}</h3><p>{{ SERVICE_3_DESC }}</p></div>
854
+ <div class="svc"><div class="num">04</div><h3>{{ SERVICE_4_NAME }}</h3><p>{{ SERVICE_4_DESC }}</p></div>
855
+ <div class="svc"><div class="num">05</div><h3>{{ SERVICE_5_NAME }}</h3><p>{{ SERVICE_5_DESC }}</p></div>
856
+ <div class="svc"><div class="num">06</div><h3>{{ SERVICE_6_NAME }}</h3><p>{{ SERVICE_6_DESC }}</p></div>
857
+ </div>
858
+ </section>
859
+
860
+ <!-- ════════════════ WHY-US / KEY FACTS ════════════════ -->
861
+ <section class="key-facts" id="facts">
862
+ <h2>{{ WHY_HEADLINE }}</h2>
863
+ <div class="grid">
864
+ <div class="row"><div class="k">Established</div><div class="v">{{ ESTABLISHED_YEAR }}</div></div>
865
+ <div class="row"><div class="k">{{ FACT_1_KEY }}</div><div class="v">{{ FACT_1_VALUE }}</div></div>
866
+ <div class="row"><div class="k">{{ FACT_2_KEY }}</div><div class="v">{{ FACT_2_VALUE }}</div></div>
867
+ <div class="row"><div class="k">Coverage</div><div class="v">{{ REGION }}</div></div>
868
+ <div class="row"><div class="k">Based</div><div class="v">{{ LOCALITY }}, {{ COUNTY }}</div></div>
869
+ <div class="row"><div class="k">{{ FACT_3_KEY }}</div><div class="v">{{ FACT_3_VALUE }}</div></div>
870
+ <div class="row"><div class="k">{{ FACT_4_KEY }}</div><div class="v">{{ FACT_4_VALUE }}</div></div>
871
+ <div class="row"><div class="k">{{ FACT_5_KEY }}</div><div class="v">{{ FACT_5_VALUE }}</div></div>
872
+ <div class="row"><div class="k">{{ FACT_6_KEY }}</div><div class="v">{{ FACT_6_VALUE }}</div></div>
873
+ <div class="footnote">{{ FACTS_FOOTNOTE }}</div>
874
+ </div>
875
+ </section>
876
+
877
+ <!-- ════════════════ FAQ (answer-first, AEO lift targets) ════════════════ -->
878
+ <section class="faq" id="faq">
879
+ <h2>Frequently asked questions</h2>
880
+ <div class="qa">
881
+ <h3>{{ FAQ_1_Q }}</h3>
882
+ <p>{{ FAQ_1_A }}</p>
883
+ </div>
884
+ <div class="qa">
885
+ <h3>{{ FAQ_2_Q }}</h3>
886
+ <p>{{ FAQ_2_A }}</p>
887
+ </div>
888
+ <div class="qa">
889
+ <h3>{{ FAQ_3_Q }}</h3>
890
+ <p>{{ FAQ_3_A }}</p>
891
+ </div>
892
+ <div class="qa">
893
+ <h3>{{ FAQ_4_Q }}</h3>
894
+ <p>{{ FAQ_4_A }}</p>
895
+ </div>
896
+ <div class="qa">
897
+ <h3>{{ FAQ_5_Q }}</h3>
898
+ <p>{{ FAQ_5_A }}</p>
899
+ </div>
900
+ </section>
901
+
902
+ <!-- ════════════════ CTA STRIP ════════════════ -->
903
+ <section class="cta-strip">
904
+ <div class="eyebrow">{{ TAGLINE }}</div>
905
+ <h2>{{ CTA_HEADLINE }}</h2>
906
+ <div class="cta-row">
907
+ <a href="tel:{{ PHONE_TEL }}">{{ PHONE_DISPLAY }}</a>
908
+ <a href="tel:{{ MOBILE_TEL }}">{{ MOBILE_DISPLAY }}</a>
909
+ <a href="mailto:{{ EMAIL }}?subject=Project%20enquiry" class="solid">Request a callback</a>
910
+ </div>
911
+ </section>
912
+
913
+ <!-- ════════════════ FOOTER ════════════════ -->
914
+ <footer>
915
+ <div class="inner">
916
+ <div class="agent">
917
+ <div class="label">{{ FOOTER_LABEL }}</div>
918
+ <div class="name"><em>{{ COMPANY_NAME }}</em></div>
919
+ {{ STREET_ADDRESS }},<br>
920
+ {{ POST_TOWN }}, {{ COUNTY }}, {{ POSTCODE }}<br>
921
+ <a href="tel:{{ PHONE_TEL }}">{{ PHONE_DISPLAY }}</a> · <a href="tel:{{ MOBILE_TEL }}">{{ MOBILE_DISPLAY }}</a><br>
922
+ <a href="mailto:{{ EMAIL }}">{{ EMAIL }}</a>
923
+ <div class="socials">
924
+ <a href="{{ FACEBOOK_URL }}" target="_blank" rel="noopener">Facebook</a>
925
+ <a href="{{ INSTAGRAM_URL }}" target="_blank" rel="noopener">Instagram</a>
926
+ <a href="{{ TIKTOK_URL }}" target="_blank" rel="noopener">TikTok</a>
927
+ </div>
928
+ </div>
929
+ <p class="legal">{{ FOOTER_LEGAL }}</p>
930
+ <div class="colophon">
931
+ <img src="images/icon.png" alt="{{ COMPANY_SHORT }} monogram">
932
+ <span>© {{ COPYRIGHT_YEAR }} {{ COMPANY_LEGAL_NAME }} · {{ TAGLINE }}</span>
933
+ </div>
934
+ </div>
935
+ </footer>
936
+
937
+ <button class="to-top" id="toTop" aria-label="Back to top">
938
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V5M5 12l7-7 7 7"/></svg>
939
+ </button>
940
+
941
+ <script>
942
+ // Hero rotator — cycle the .active slide (skipped for reduced-motion users)
943
+ (function() {
944
+ const slides = [...document.querySelectorAll('.hero-slide')];
945
+ if (slides.length < 2) return;
946
+ if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
947
+ let i = 0;
948
+ setInterval(() => {
949
+ slides[i].classList.remove('active');
950
+ i = (i + 1) % slides.length;
951
+ slides[i].classList.add('active');
952
+ }, 5200);
953
+ })();
954
+
955
+ // Back to top
956
+ (function() {
957
+ const btn = document.getElementById('toTop');
958
+ if (!btn) return;
959
+ function upd() { (window.scrollY > 600) ? btn.classList.add('show') : btn.classList.remove('show'); }
960
+ window.addEventListener('scroll', upd, { passive: true }); upd();
961
+ btn.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' }));
962
+ })();
963
+
964
+ // Sticky sub-nav after the hero scrolls past
965
+ (function() {
966
+ const subnav = document.getElementById('subnav');
967
+ const hero = document.querySelector('.hero');
968
+ function update() {
969
+ const heroBottom = hero.getBoundingClientRect().bottom;
970
+ if (heroBottom < 0) subnav.classList.add('visible');
971
+ else subnav.classList.remove('visible');
972
+ }
973
+ window.addEventListener('scroll', update, { passive: true });
974
+ update();
975
+ })();
976
+
977
+ // Hamburger / drawer
978
+ (function() {
979
+ const burger = document.querySelector('.burger');
980
+ const drawer = document.getElementById('drawer');
981
+ if (!burger || !drawer) return;
982
+ const backdrop = document.createElement('div');
983
+ backdrop.className = 'drawer-backdrop';
984
+ document.body.appendChild(backdrop);
985
+ function open() {
986
+ drawer.classList.add('open'); backdrop.classList.add('open');
987
+ document.body.classList.add('drawer-open');
988
+ burger.setAttribute('aria-expanded', 'true'); drawer.setAttribute('aria-hidden', 'false');
989
+ }
990
+ function close() {
991
+ drawer.classList.remove('open'); backdrop.classList.remove('open');
992
+ document.body.classList.remove('drawer-open');
993
+ burger.setAttribute('aria-expanded', 'false'); drawer.setAttribute('aria-hidden', 'true');
994
+ }
995
+ burger.addEventListener('click', () => { drawer.classList.contains('open') ? close() : open(); });
996
+ backdrop.addEventListener('click', close);
997
+ document.querySelector('.drawer-close').addEventListener('click', close);
998
+ drawer.querySelectorAll('a').forEach(a => a.addEventListener('click', close));
999
+ document.addEventListener('keydown', e => { if (e.key === 'Escape' && drawer.classList.contains('open')) close(); });
1000
+ })();
1001
+ </script>
1002
+
1003
+ </body>
1004
+ </html>