@tokenoftrust/storefront-runner 0.1.0

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 (337) hide show
  1. package/LICENSE +58 -0
  2. package/README.md +40 -0
  3. package/apps/storefront/.dev.vars.example +41 -0
  4. package/apps/storefront/.env.example +24 -0
  5. package/apps/storefront/astro.config.mjs +245 -0
  6. package/apps/storefront/env.d.ts +155 -0
  7. package/apps/storefront/lib/ensure-preview-reconcile-secret.sh +31 -0
  8. package/apps/storefront/lib/resolve-cf-token.sh +48 -0
  9. package/apps/storefront/lib/resolve-tot-credentials.sh +69 -0
  10. package/apps/storefront/migrations/0000_baseline.sql +54 -0
  11. package/apps/storefront/migrations/0001_products_fts.sql +9 -0
  12. package/apps/storefront/migrations/README.md +54 -0
  13. package/apps/storefront/migrations/meta/0000_snapshot.json +347 -0
  14. package/apps/storefront/migrations/meta/0001_snapshot.json +347 -0
  15. package/apps/storefront/migrations/meta/_journal.json +20 -0
  16. package/apps/storefront/package.json +41 -0
  17. package/apps/storefront/public/brand/northwind-logo-dark.svg +4 -0
  18. package/apps/storefront/public/brand/northwind-logo-light.svg +4 -0
  19. package/apps/storefront/public/brand/northwind-og.svg +13 -0
  20. package/apps/storefront/public/favicon.svg +5 -0
  21. package/apps/storefront/public/js/dashboard-team.js +147 -0
  22. package/apps/storefront/public/js/dashboard-vendor-search.js +115 -0
  23. package/apps/storefront/src/components/Badge.astro +34 -0
  24. package/apps/storefront/src/components/Breadcrumbs.astro +45 -0
  25. package/apps/storefront/src/components/CollectionCard.astro +56 -0
  26. package/apps/storefront/src/components/EmptyState.astro +35 -0
  27. package/apps/storefront/src/components/Img.astro +68 -0
  28. package/apps/storefront/src/components/ProductCard.astro +228 -0
  29. package/apps/storefront/src/components/Section.astro +39 -0
  30. package/apps/storefront/src/components/Seo.astro +70 -0
  31. package/apps/storefront/src/components/WidgetFrame.astro +34 -0
  32. package/apps/storefront/src/components/auth/AuthBadge.astro +44 -0
  33. package/apps/storefront/src/components/chrome/AnnouncementBar.astro +108 -0
  34. package/apps/storefront/src/components/chrome/MegaMenu.astro +26 -0
  35. package/apps/storefront/src/components/chrome/NavDropdown.astro +116 -0
  36. package/apps/storefront/src/components/chrome/SiteFooter.astro +181 -0
  37. package/apps/storefront/src/components/chrome/SiteHeader.astro +181 -0
  38. package/apps/storefront/src/components/chrome/UtilityNav.astro +79 -0
  39. package/apps/storefront/src/components/commerce/FoxyLoader.astro +23 -0
  40. package/apps/storefront/src/components/commerce/PriceDisplay.astro +91 -0
  41. package/apps/storefront/src/components/commerce/ProductCarousel.astro +197 -0
  42. package/apps/storefront/src/components/commerce/ProductGrid.astro +75 -0
  43. package/apps/storefront/src/components/commerce/RatingStars.astro +58 -0
  44. package/apps/storefront/src/components/compliance/NicotineWarning.astro +33 -0
  45. package/apps/storefront/src/components/home/Hero.astro +164 -0
  46. package/apps/storefront/src/components/islands/AgeGate.tsx +105 -0
  47. package/apps/storefront/src/components/islands/ImageGallery.tsx +237 -0
  48. package/apps/storefront/src/components/islands/IsolatedAgeGate.tsx +73 -0
  49. package/apps/storefront/src/components/islands/MobileNav.tsx +239 -0
  50. package/apps/storefront/src/components/islands/QuickView.tsx +138 -0
  51. package/apps/storefront/src/components/islands/RecentlyViewed.tsx +122 -0
  52. package/apps/storefront/src/components/islands/SavedList.tsx +99 -0
  53. package/apps/storefront/src/components/islands/SearchTypeahead.tsx +248 -0
  54. package/apps/storefront/src/components/islands/VariantSelector.tsx +378 -0
  55. package/apps/storefront/src/components/marketing/CardGrid.astro +72 -0
  56. package/apps/storefront/src/components/marketing/CodeSample.astro +20 -0
  57. package/apps/storefront/src/components/marketing/CtaBand.astro +24 -0
  58. package/apps/storefront/src/components/marketing/Faq.astro +37 -0
  59. package/apps/storefront/src/components/marketing/Integrations.astro +63 -0
  60. package/apps/storefront/src/components/marketing/MarketingBlocks.astro +53 -0
  61. package/apps/storefront/src/components/marketing/MarketingCtas.astro +48 -0
  62. package/apps/storefront/src/components/marketing/MarketingHero.astro +72 -0
  63. package/apps/storefront/src/components/marketing/ProofStrip.astro +37 -0
  64. package/apps/storefront/src/components/marketing/SplitCompare.astro +53 -0
  65. package/apps/storefront/src/components/marketing/Steps.astro +36 -0
  66. package/apps/storefront/src/components/marketing/Testimonials.astro +38 -0
  67. package/apps/storefront/src/components/marketing/TrustBar.astro +22 -0
  68. package/apps/storefront/src/components/nav/Footer.astro +148 -0
  69. package/apps/storefront/src/components/nav/Header.astro +190 -0
  70. package/apps/storefront/src/components/plp/ActiveFilters.astro +79 -0
  71. package/apps/storefront/src/components/plp/FacetSidebar.astro +146 -0
  72. package/apps/storefront/src/components/plp/Pagination.astro +99 -0
  73. package/apps/storefront/src/components/plp/SortSelect.astro +64 -0
  74. package/apps/storefront/src/config/devTenants.ts +16 -0
  75. package/apps/storefront/src/config/kvTenantResolver.ts +87 -0
  76. package/apps/storefront/src/config/resolver.ts +46 -0
  77. package/apps/storefront/src/config/tenants.ts +193 -0
  78. package/apps/storefront/src/layouts/Layout.astro +303 -0
  79. package/apps/storefront/src/lib/analytics/index.ts +47 -0
  80. package/apps/storefront/src/lib/auth/brokerAssertion.ts +136 -0
  81. package/apps/storefront/src/lib/auth/devAuth.ts +90 -0
  82. package/apps/storefront/src/lib/auth/gatePage.ts +81 -0
  83. package/apps/storefront/src/lib/auth/identityToken.ts +341 -0
  84. package/apps/storefront/src/lib/auth/loginGate.ts +107 -0
  85. package/apps/storefront/src/lib/auth/route.ts +146 -0
  86. package/apps/storefront/src/lib/auth/session.ts +203 -0
  87. package/apps/storefront/src/lib/auth/totAccessClient.ts +503 -0
  88. package/apps/storefront/src/lib/basePath.ts +41 -0
  89. package/apps/storefront/src/lib/cfImage.ts +55 -0
  90. package/apps/storefront/src/lib/chrome/model.ts +65 -0
  91. package/apps/storefront/src/lib/colors.ts +97 -0
  92. package/apps/storefront/src/lib/content-edit/client.ts +230 -0
  93. package/apps/storefront/src/lib/content-edit/index.ts +14 -0
  94. package/apps/storefront/src/lib/content-edit/route.ts +25 -0
  95. package/apps/storefront/src/lib/content-edit/types.ts +19 -0
  96. package/apps/storefront/src/lib/cspStaticHashes.ts +24 -0
  97. package/apps/storefront/src/lib/d1/catalog.ts +289 -0
  98. package/apps/storefront/src/lib/dashboard/staffAdmission.ts +43 -0
  99. package/apps/storefront/src/lib/dashboard/staffVendorAccess.ts +449 -0
  100. package/apps/storefront/src/lib/dashboard/tenantSelection.ts +136 -0
  101. package/apps/storefront/src/lib/dashboard/vendorQuery.ts +61 -0
  102. package/apps/storefront/src/lib/demoGate.ts +113 -0
  103. package/apps/storefront/src/lib/dev/ai-widget-client.js +127 -0
  104. package/apps/storefront/src/lib/dev/cliSignInCode.ts +132 -0
  105. package/apps/storefront/src/lib/diag/redact.ts +20 -0
  106. package/apps/storefront/src/lib/edgeCache.ts +128 -0
  107. package/apps/storefront/src/lib/email/magicLinkInviteEmail.ts +62 -0
  108. package/apps/storefront/src/lib/env.ts +60 -0
  109. package/apps/storefront/src/lib/fixtures/sampleProducts.ts +130 -0
  110. package/apps/storefront/src/lib/format.ts +29 -0
  111. package/apps/storefront/src/lib/foxyCommerce.ts +49 -0
  112. package/apps/storefront/src/lib/imageAttrs.ts +55 -0
  113. package/apps/storefront/src/lib/jsonld.ts +136 -0
  114. package/apps/storefront/src/lib/maintenance.ts +71 -0
  115. package/apps/storefront/src/lib/memoryKv.ts +32 -0
  116. package/apps/storefront/src/lib/messaging/messagesClient.ts +143 -0
  117. package/apps/storefront/src/lib/placeholder.ts +99 -0
  118. package/apps/storefront/src/lib/previewReload.ts +125 -0
  119. package/apps/storefront/src/lib/rawMarketingHtml.ts +133 -0
  120. package/apps/storefront/src/lib/search/index.ts +74 -0
  121. package/apps/storefront/src/lib/sections.ts +129 -0
  122. package/apps/storefront/src/lib/securityHeaders.ts +31 -0
  123. package/apps/storefront/src/lib/storyblok/content-model.ts +289 -0
  124. package/apps/storefront/src/lib/storyblok/provider.ts +524 -0
  125. package/apps/storefront/src/lib/tenantRouting.ts +91 -0
  126. package/apps/storefront/src/lib/tot/ToTClient.ts +177 -0
  127. package/apps/storefront/src/lib/tot/d1Client.ts +62 -0
  128. package/apps/storefront/src/lib/tot/query.ts +187 -0
  129. package/apps/storefront/src/lib/tot/totClientInterface.ts +30 -0
  130. package/apps/storefront/src/lib/url.ts +119 -0
  131. package/apps/storefront/src/lib/wishlist.ts +63 -0
  132. package/apps/storefront/src/middleware/index.ts +413 -0
  133. package/apps/storefront/src/pages/404.astro +61 -0
  134. package/apps/storefront/src/pages/[...slug].astro +90 -0
  135. package/apps/storefront/src/pages/api/auth/logout.ts +21 -0
  136. package/apps/storefront/src/pages/api/auth/magic-exchange.ts +107 -0
  137. package/apps/storefront/src/pages/api/auth/send.ts +85 -0
  138. package/apps/storefront/src/pages/api/auth/verify.ts +135 -0
  139. package/apps/storefront/src/pages/api/cache-purge.ts +44 -0
  140. package/apps/storefront/src/pages/api/content-edit/ai-edit.ts +64 -0
  141. package/apps/storefront/src/pages/api/csp-report.ts +25 -0
  142. package/apps/storefront/src/pages/api/dashboard/enter-vendor.ts +124 -0
  143. package/apps/storefront/src/pages/api/dashboard/vendor-search.ts +120 -0
  144. package/apps/storefront/src/pages/api/dev/cli-signin-code.ts +44 -0
  145. package/apps/storefront/src/pages/api/newsletter.ts +104 -0
  146. package/apps/storefront/src/pages/api/request-access.ts +172 -0
  147. package/apps/storefront/src/pages/auth/login.astro +149 -0
  148. package/apps/storefront/src/pages/auth/magic.astro +105 -0
  149. package/apps/storefront/src/pages/capabilities.astro +292 -0
  150. package/apps/storefront/src/pages/collections/[handle].astro +154 -0
  151. package/apps/storefront/src/pages/collections/index.astro +59 -0
  152. package/apps/storefront/src/pages/dashboard/[appDomain]/index.astro +100 -0
  153. package/apps/storefront/src/pages/dashboard/[appDomain]/team.astro +154 -0
  154. package/apps/storefront/src/pages/dashboard/index.astro +160 -0
  155. package/apps/storefront/src/pages/dev.astro +653 -0
  156. package/apps/storefront/src/pages/index.astro +290 -0
  157. package/apps/storefront/src/pages/llms.txt.ts +92 -0
  158. package/apps/storefront/src/pages/products/[handle].astro +443 -0
  159. package/apps/storefront/src/pages/robots.txt.ts +24 -0
  160. package/apps/storefront/src/pages/saved.astro +35 -0
  161. package/apps/storefront/src/pages/search.astro +150 -0
  162. package/apps/storefront/src/pages/sitemap.xml.ts +78 -0
  163. package/apps/storefront/src/pages/style-guide/[tenant]/[theme].astro +646 -0
  164. package/apps/storefront/src/pages/style-guide/[tenant]/index.astro +85 -0
  165. package/apps/storefront/src/pages/style-guide/index.astro +94 -0
  166. package/apps/storefront/src/pages/tenants/[id]/[...path].ts +57 -0
  167. package/apps/storefront/src/styles/global.css +277 -0
  168. package/apps/storefront/src/themes/reference.ts +61 -0
  169. package/apps/storefront/src/themes/schema.ts +111 -0
  170. package/apps/storefront/src/themes/tenants/index.ts +51 -0
  171. package/apps/storefront/tsconfig.json +16 -0
  172. package/apps/storefront/vitest.config.ts +22 -0
  173. package/apps/storefront/wrangler.toml +175 -0
  174. package/package.json +23 -0
  175. package/packages/public-runtime/LICENSE +58 -0
  176. package/packages/public-runtime/package.json +22 -0
  177. package/packages/public-runtime/src/binary-path.ts +68 -0
  178. package/packages/public-runtime/src/capabilities.ts +89 -0
  179. package/packages/public-runtime/src/catalog-api.ts +81 -0
  180. package/packages/public-runtime/src/catalog-d1.ts +192 -0
  181. package/packages/public-runtime/src/csp.ts +109 -0
  182. package/packages/public-runtime/src/customization-preview.ts +197 -0
  183. package/packages/public-runtime/src/customization-reconcile.ts +63 -0
  184. package/packages/public-runtime/src/customization-runtime.ts +157 -0
  185. package/packages/public-runtime/src/customization-scripts.ts +64 -0
  186. package/packages/public-runtime/src/customization-versioning.ts +95 -0
  187. package/packages/public-runtime/src/foxy.ts +184 -0
  188. package/packages/public-runtime/src/index.ts +30 -0
  189. package/packages/public-runtime/src/product.ts +159 -0
  190. package/packages/public-runtime/src/search.ts +45 -0
  191. package/packages/public-runtime/src/tenant-assets.ts +444 -0
  192. package/packages/public-runtime/src/tenant.ts +243 -0
  193. package/packages/public-runtime/tsconfig.json +8 -0
  194. package/packages/public-runtime/vitest.config.ts +8 -0
  195. package/pnpm-workspace.yaml +7 -0
  196. package/scripts/build/copy-tenant-assets.mjs +69 -0
  197. package/scripts/tot-dev.mjs +439 -0
  198. package/tenants/bigdvapor/content/blog.json +52 -0
  199. package/tenants/bigdvapor/content/chrome.html +149 -0
  200. package/tenants/bigdvapor/content/chrome.json +47 -0
  201. package/tenants/bigdvapor/content/home.html +463 -0
  202. package/tenants/bigdvapor/content/home.json +73 -0
  203. package/tenants/bigdvapor/content/pages/about.json +5 -0
  204. package/tenants/bigdvapor/content/pages/privacy.json +6 -0
  205. package/tenants/bigdvapor/content/pages/shipping-returns.json +6 -0
  206. package/tenants/bigdvapor/content/pages-html/blogs/news.html +86 -0
  207. package/tenants/bigdvapor/content/pages-html/pages/about-us.html +106 -0
  208. package/tenants/bigdvapor/content/pages-html/pages/contact-us.html +61 -0
  209. package/tenants/bigdvapor/content/pages-html/pages/privacy-policy.html +72 -0
  210. package/tenants/bigdvapor/content/pages-html/pages/shipping-returns.html +172 -0
  211. package/tenants/bigdvapor/content/themes/bigd-navy.json +109 -0
  212. package/tenants/bigdvapor/public/img/brands/adjust-vape-disposable.png +0 -0
  213. package/tenants/bigdvapor/public/img/brands/again-vape-disposable.png +0 -0
  214. package/tenants/bigdvapor/public/img/brands/al-fakher-vape-disposable.png +0 -0
  215. package/tenants/bigdvapor/public/img/brands/arro-vape-disposable.png +0 -0
  216. package/tenants/bigdvapor/public/img/brands/cookies-vape-disposable.png +0 -0
  217. package/tenants/bigdvapor/public/img/brands/core-vape-disposable.png +0 -0
  218. package/tenants/bigdvapor/public/img/brands/cyclone-vape-disposable.png +0 -0
  219. package/tenants/bigdvapor/public/img/brands/dinner-lady-vape-disposable.png +0 -0
  220. package/tenants/bigdvapor/public/img/brands/extre-bar-vape-disposable.png +0 -0
  221. package/tenants/bigdvapor/public/img/brands/fifty-bar-vape-disposable.jpg +0 -0
  222. package/tenants/bigdvapor/public/img/brands/firerose-vape-disposable.jpg +0 -0
  223. package/tenants/bigdvapor/public/img/brands/flavor-beast-vape-disposable.jpg +0 -0
  224. package/tenants/bigdvapor/public/img/brands/foger-vape-disposable.png +0 -0
  225. package/tenants/bigdvapor/public/img/brands/kk-energy-vape-disposable.png +0 -0
  226. package/tenants/bigdvapor/public/img/brands/kumi-vape-disposable.png +0 -0
  227. package/tenants/bigdvapor/public/img/brands/lost-vape-dispoable.png +0 -0
  228. package/tenants/bigdvapor/public/img/brands/melo-labs-vape-disposable.png +0 -0
  229. package/tenants/bigdvapor/public/img/brands/mixo-vape-disposable.webp +0 -0
  230. package/tenants/bigdvapor/public/img/brands/one-tank-vape-disposable.jpg +0 -0
  231. package/tenants/bigdvapor/public/img/brands/oxbar-vape-disposable.webp +0 -0
  232. package/tenants/bigdvapor/public/img/brands/pillow-talk-vape-disposable.jpg +0 -0
  233. package/tenants/bigdvapor/public/img/brands/pod-king-vape-disposable.jpg +0 -0
  234. package/tenants/bigdvapor/public/img/brands/raz-vape-disposable.png +0 -0
  235. package/tenants/bigdvapor/public/img/hero-texas.jpg +0 -0
  236. package/tenants/bigdvapor/public/img/og.jpg +0 -0
  237. package/tenants/bigdvapor/public/img/pages/AdobeStock_202106312_web.jpg +0 -0
  238. package/tenants/bigdvapor/public/img/pages/CREW_web.jpg +0 -0
  239. package/tenants/bigdvapor/public/img/pages/Hero-Image.jpg +0 -0
  240. package/tenants/bigdvapor/public/img/tiles/adjust.png +0 -0
  241. package/tenants/bigdvapor/public/img/tiles/again.png +0 -0
  242. package/tenants/bigdvapor/public/img/tiles/al-fakher.png +0 -0
  243. package/tenants/bigdvapor/public/img/tiles/arro.png +0 -0
  244. package/tenants/bigdvapor/public/img/tiles/cookies.png +0 -0
  245. package/tenants/bigdvapor/public/img/tiles/core.png +0 -0
  246. package/tenants/bigdvapor/public/img/tiles/cyclone.png +0 -0
  247. package/tenants/bigdvapor/public/img/tiles/disposables.svg +23 -0
  248. package/tenants/bigdvapor/public/logo-wordmark.png +0 -0
  249. package/tenants/bigdvapor/public/pages/home.css +118 -0
  250. package/tenants/bigdvapor/public/pages/mkt.css +185 -0
  251. package/tenants/bigdvapor/public/pages/page.css +148 -0
  252. package/tenants/bigdvapor/public/themes/bigd-navy.css +73 -0
  253. package/tenants/bigdvapor/theme.json +12 -0
  254. package/tenants/giantvapes/content/chrome.html +152 -0
  255. package/tenants/giantvapes/content/chrome.json +94 -0
  256. package/tenants/giantvapes/content/home.html +194 -0
  257. package/tenants/giantvapes/content/home.json +50 -0
  258. package/tenants/giantvapes/content/pages/about.json +10 -0
  259. package/tenants/giantvapes/content/pages/privacy.json +6 -0
  260. package/tenants/giantvapes/content/pages/shipping-returns.json +6 -0
  261. package/tenants/giantvapes/content/pages-html/blogs/news.html +68 -0
  262. package/tenants/giantvapes/content/pages-html/pages/about-us.html +95 -0
  263. package/tenants/giantvapes/content/pages-html/pages/contact-us.html +68 -0
  264. package/tenants/giantvapes/content/pages-html/pages/privacy-policy.html +65 -0
  265. package/tenants/giantvapes/content/pages-html/pages/shipping-returns.html +77 -0
  266. package/tenants/giantvapes/content/themes/giant-navy.json +73 -0
  267. package/tenants/giantvapes/public/img/hero-suicide-bunny.jpg +0 -0
  268. package/tenants/giantvapes/public/img/hero.webp +0 -0
  269. package/tenants/giantvapes/public/img/og.jpg +0 -0
  270. package/tenants/giantvapes/public/logo-wordmark.png +0 -0
  271. package/tenants/giantvapes/public/pages/home.css +120 -0
  272. package/tenants/giantvapes/public/pages/mkt.css +185 -0
  273. package/tenants/giantvapes/public/pages/page.css +155 -0
  274. package/tenants/giantvapes/public/themes/giant-navy.css +76 -0
  275. package/tenants/giantvapes/theme.json +39 -0
  276. package/tenants/home/content/chrome.json +11 -0
  277. package/tenants/home/content/home.html +304 -0
  278. package/tenants/home/content/home.json +13 -0
  279. package/tenants/home/public/js/storefront.js +210 -0
  280. package/tenants/home/public/logo-wordmark.png +0 -0
  281. package/tenants/home/public/pages/storefront.css +212 -0
  282. package/tenants/home/theme.json +6 -0
  283. package/tenants/tokenoftrust/.tot/config.json +9 -0
  284. package/tenants/tokenoftrust/content/chrome.json +55 -0
  285. package/tenants/tokenoftrust/content/home.html +723 -0
  286. package/tenants/tokenoftrust/content/home.json +233 -0
  287. package/tenants/tokenoftrust/content/pages-html/careers.html +231 -0
  288. package/tenants/tokenoftrust/content/pages-html/company.html +275 -0
  289. package/tenants/tokenoftrust/content/pages-html/contact/contact-sales.html +188 -0
  290. package/tenants/tokenoftrust/content/pages-html/contact/startup-apply.html +206 -0
  291. package/tenants/tokenoftrust/content/pages-html/contact.html +178 -0
  292. package/tenants/tokenoftrust/content/pages-html/industries/adult-content-age-verification.html +286 -0
  293. package/tenants/tokenoftrust/content/pages-html/industries/cannabis.html +277 -0
  294. package/tenants/tokenoftrust/content/pages-html/pact-act-pricing.html +289 -0
  295. package/tenants/tokenoftrust/content/pages-html/pricing.html +483 -0
  296. package/tenants/tokenoftrust/content/pages-html/product/age-assurance/age-estimation.html +278 -0
  297. package/tenants/tokenoftrust/content/pages-html/product/age-assurance/age-gate.html +279 -0
  298. package/tenants/tokenoftrust/content/pages-html/product/age-assurance/age-verification.html +265 -0
  299. package/tenants/tokenoftrust/content/pages-html/product/age-assurance.html +173 -0
  300. package/tenants/tokenoftrust/content/pages-html/product/compliance/aml.html +214 -0
  301. package/tenants/tokenoftrust/content/pages-html/product/compliance/pact-act.html +226 -0
  302. package/tenants/tokenoftrust/content/pages-html/product/fraud-prevention.html +254 -0
  303. package/tenants/tokenoftrust/content/pages-html/product/social-profile-verification.html +212 -0
  304. package/tenants/tokenoftrust/content/pages-html/product/tax/excise-tax.html +213 -0
  305. package/tenants/tokenoftrust/content/pages-html/product/verification/aml.html +259 -0
  306. package/tenants/tokenoftrust/content/pages-html/product/verification/biometric-selfie.html +305 -0
  307. package/tenants/tokenoftrust/content/pages-html/product/verification/coverage.html +254 -0
  308. package/tenants/tokenoftrust/content/pages-html/product/verification/document-verification.html +306 -0
  309. package/tenants/tokenoftrust/content/pages-html/product/verification/electronic-identity-verification.html +304 -0
  310. package/tenants/tokenoftrust/content/pages-html/product/verification/government-id-verification.html +308 -0
  311. package/tenants/tokenoftrust/content/pages-html/product/verification.html +183 -0
  312. package/tenants/tokenoftrust/content/pages-html/product.html +228 -0
  313. package/tenants/tokenoftrust/content/pages-html/resources/integrations/bigcommerce-integration.html +220 -0
  314. package/tenants/tokenoftrust/content/pages-html/resources/integrations/shopify-integration.html +221 -0
  315. package/tenants/tokenoftrust/content/pages-html/resources/integrations/wordpress.html +220 -0
  316. package/tenants/tokenoftrust/content/pages-html/resources/integrations.html +172 -0
  317. package/tenants/tokenoftrust/content/pages-html/resources/refer-a-friend-program.html +317 -0
  318. package/tenants/tokenoftrust/content/pages-html/resources.html +177 -0
  319. package/tenants/tokenoftrust/content/pages-html/reviews.html +273 -0
  320. package/tenants/tokenoftrust/content/pages-html/solutions.html +292 -0
  321. package/tenants/tokenoftrust/content/pages-html/vlp-alcohol.html +289 -0
  322. package/tenants/tokenoftrust/content/pages-html/vlp-cigars-and-tobacco.html +286 -0
  323. package/tenants/tokenoftrust/content/pages-html/vlp-firearm-accessories.html +267 -0
  324. package/tenants/tokenoftrust/content/pages-html/vlp-peptides.html +273 -0
  325. package/tenants/tokenoftrust/content/themes/tot-navy.json +88 -0
  326. package/tenants/tokenoftrust/public/favicon.png +0 -0
  327. package/tenants/tokenoftrust/public/logo-icon.png +0 -0
  328. package/tenants/tokenoftrust/public/logo-wordmark.png +0 -0
  329. package/tenants/tokenoftrust/public/pages/company.css +108 -0
  330. package/tenants/tokenoftrust/public/pages/home.css +457 -0
  331. package/tenants/tokenoftrust/public/pages/mkt.css +482 -0
  332. package/tenants/tokenoftrust/public/pages/pricing.css +214 -0
  333. package/tenants/tokenoftrust/public/pages/solutions.css +66 -0
  334. package/tenants/tokenoftrust/public/themes/tot-navy-1.0.0.css +136 -0
  335. package/tenants/tokenoftrust/public/themes/tot-navy.css +358 -0
  336. package/tenants/tokenoftrust/theme.json +31 -0
  337. package/tsconfig.base.json +20 -0
@@ -0,0 +1,210 @@
1
+ /* Storefront early-access landing — interactions + analytics.
2
+ * Served at /tenants/home/js/storefront.js (mirrored from tenants/home/public/).
3
+ *
4
+ * ---- tot20 analytics: public reportAnalytics endpoint --------------------
5
+ * GET /reportAnalytics/{origin}/{pluginVersion}/{subject}/{action}?...
6
+ * origin=totcom => anonymous marketing path (user_id null, device-id based).
7
+ * apiKeyNotRequired + allowCORs, so we fire a fire-and-forget GET beacon.
8
+ *
9
+ * Beacon transport is an Image() GET on purpose: the storefront CSP is
10
+ * `img-src https:` (allowed) but `connect-src 'self'` (a cross-origin fetch to
11
+ * qa.tokenoftrust.com would be BLOCKED). An <img> GET sidesteps connect-src.
12
+ *
13
+ * Detail rides in utm_content/utm_campaign (the endpoint's eventProperties).
14
+ * Events use subject=cust and are shaped onto two EXISTING registered wildcards
15
+ * in tot20's analytics schema (analyticEvents.json), so they validate (HTTP 200)
16
+ * with no schema change:
17
+ * - views → cust_viewed_totcom_page_* (the anonymous tokenoftrust.com convention)
18
+ * - clicks → cust_clicked_btn_*
19
+ * ------------------------------------------------------------------------- */
20
+ (function () {
21
+ const BASE = "https://qa.tokenoftrust.com/api"; // tot20 public API (qa; swap for prod)
22
+ const ORIGIN = "totcom", PLUGIN = "1.0", SUBJECT = "cust", APP_DOMAIN = "tokenoftrust.com";
23
+
24
+ function deviceId() {
25
+ try {
26
+ const k = "ampDeviceId";
27
+ let v = localStorage.getItem(k);
28
+ if (!v) { v = (crypto.randomUUID ? crypto.randomUUID() : String(Date.now()) + Math.random()); localStorage.setItem(k, v); }
29
+ return v;
30
+ } catch (e) { return "anon"; }
31
+ }
32
+ function track(action, detail, campaign) {
33
+ try {
34
+ const qs = new URLSearchParams({
35
+ appDomain: APP_DOMAIN, ampDeviceId: deviceId(),
36
+ title: document.title, referrer: document.referrer || "",
37
+ lang: navigator.language || "", screen_w: String(screen.width), screen_h: String(screen.height)
38
+ });
39
+ if (detail) qs.set("utm_content", detail);
40
+ qs.set("utm_campaign", campaign || "storefront_early_access");
41
+ qs.set("utm_source", "storefront-landing"); qs.set("utm_medium", "web");
42
+ const url = BASE + "/reportAnalytics/" + ORIGIN + "/" + PLUGIN + "/" + SUBJECT + "/" + encodeURIComponent(action) + "?" + qs.toString();
43
+ // Image() GET beacon — allowed by img-src https:; a fetch would hit connect-src 'self'.
44
+ new Image().src = url;
45
+ } catch (e) { /* fire-and-forget */ }
46
+ }
47
+ window.__totTrack = track;
48
+
49
+ // 1) page view
50
+ track("viewed_totcom_page_storefront_early_access");
51
+
52
+ // 2) every click on a labeled control (captures all CTAs, nav, deck links, login)
53
+ document.addEventListener("click", function (e) {
54
+ const el = e.target.closest("[data-ev]");
55
+ if (el) { const l = el.getAttribute("data-ev"); track("clicked_btn_" + l, l); }
56
+ });
57
+
58
+ // 3) section visibility (which parts of the page people actually reach)
59
+ if ("IntersectionObserver" in window) {
60
+ const seen = {};
61
+ const io = new IntersectionObserver(function (entries) {
62
+ entries.forEach(function (en) {
63
+ const name = en.target.getAttribute("data-section");
64
+ if (en.isIntersecting && !seen[name]) { seen[name] = 1; track("viewed_totcom_page_section_" + name, name); }
65
+ });
66
+ }, { threshold: .4 });
67
+ document.querySelectorAll("[data-section]").forEach(function (s) { io.observe(s); });
68
+ }
69
+
70
+ // 4) scroll depth
71
+ const marks = [25, 50, 75, 100], hit = {};
72
+ window.addEventListener("scroll", function () {
73
+ const sc = document.documentElement, pct = Math.round((sc.scrollTop + window.innerHeight) / sc.scrollHeight * 100);
74
+ marks.forEach(function (m) { if (pct >= m && !hit[m]) { hit[m] = 1; track("viewed_totcom_page_scroll_" + m, String(m)); } });
75
+ }, { passive: true });
76
+
77
+ // 5) comparison expand/collapse
78
+ document.querySelectorAll(".cmp .top").forEach(function (btn) {
79
+ btn.addEventListener("click", function () {
80
+ const card = btn.closest(".cmp"), open = card.getAttribute("aria-expanded") === "true";
81
+ card.setAttribute("aria-expanded", open ? "false" : "true");
82
+ btn.setAttribute("aria-expanded", open ? "false" : "true");
83
+ // (analytics for the open already fired via data-ev on the button)
84
+ });
85
+ });
86
+
87
+ // 6) persona tabs
88
+ const tabs = document.querySelectorAll(".seg [data-persona]");
89
+ const panels = document.querySelectorAll(".ppanel");
90
+ tabs.forEach(function (tab) {
91
+ tab.addEventListener("click", function () {
92
+ const who = tab.getAttribute("data-persona");
93
+ tabs.forEach(function (t) { t.setAttribute("aria-selected", t === tab ? "true" : "false"); });
94
+ panels.forEach(function (p) { p.classList.toggle("on", p.getAttribute("data-panel") === who); });
95
+ });
96
+ });
97
+
98
+ // 7) time on page (sent on leave)
99
+ const start = Date.now();
100
+ window.addEventListener("pagehide", function () {
101
+ track("viewed_totcom_page_exit", String(Math.round((Date.now() - start) / 1000)));
102
+ });
103
+
104
+ // ---- request-access modal --------------------------------------------------
105
+ // Board address the mailto: fallback targets (mirrors the server route's
106
+ // recipient). Kept in sync with apps/storefront/src/pages/api/request-access.ts.
107
+ const BOARD_EMAIL = "darrin84+l6gajmvvoo1x4edew5qs@boards.trello.com";
108
+ const modal = document.getElementById("ra-modal");
109
+ const form = modal && modal.querySelector("form.ra");
110
+
111
+ function openModal(source) {
112
+ if (!modal) return;
113
+ modal.classList.remove("done");
114
+ if (form) form.classList.remove("has-error");
115
+ modal.classList.add("on");
116
+ document.body.style.overflow = "hidden";
117
+ track("clicked_btn_request_access_open", source || "unknown");
118
+ const first = modal.querySelector("input[name=email]");
119
+ if (first) setTimeout(function () { first.focus(); }, 40);
120
+ }
121
+ function closeModal() {
122
+ if (!modal) return;
123
+ modal.classList.remove("on");
124
+ document.body.style.overflow = "";
125
+ }
126
+
127
+ // Any element pointing at #request opens the modal instead of jumping.
128
+ document.querySelectorAll('a[href="#request"]').forEach(function (a) {
129
+ a.addEventListener("click", function (e) {
130
+ e.preventDefault();
131
+ openModal(a.getAttribute("data-ev") || "cta");
132
+ });
133
+ });
134
+ if (modal) {
135
+ modal.querySelectorAll("[data-close]").forEach(function (el) {
136
+ el.addEventListener("click", closeModal);
137
+ });
138
+ document.addEventListener("keydown", function (e) {
139
+ if (e.key === "Escape" && modal.classList.contains("on")) closeModal();
140
+ });
141
+ }
142
+
143
+ function mailtoFallback(fields) {
144
+ const lines = [
145
+ "First name: " + fields.firstName,
146
+ "Last name: " + fields.lastName,
147
+ "Email: " + fields.email,
148
+ fields.phone ? "Phone: " + fields.phone : null,
149
+ fields.details ? "\nDetails:\n" + fields.details : null,
150
+ ].filter(Boolean).join("\n");
151
+ const subject = "Early-access request — " + fields.firstName + " " + fields.lastName;
152
+ return "mailto:" + BOARD_EMAIL + "?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(lines);
153
+ }
154
+
155
+ if (form) {
156
+ form.addEventListener("submit", async function (e) {
157
+ e.preventDefault();
158
+ form.classList.remove("has-error");
159
+ const fd = new FormData(form);
160
+ const fields = {
161
+ email: String(fd.get("email") || "").trim(),
162
+ firstName: String(fd.get("firstName") || "").trim(),
163
+ lastName: String(fd.get("lastName") || "").trim(),
164
+ phone: String(fd.get("phone") || "").trim(),
165
+ details: String(fd.get("details") || "").trim(),
166
+ };
167
+ track("clicked_btn_request_access_submit", fields.email ? "with_email" : "no_email");
168
+
169
+ const btn = form.querySelector("button[type=submit]");
170
+ const label = btn ? btn.textContent : "";
171
+ if (btn) { btn.disabled = true; btn.textContent = "Sending…"; }
172
+
173
+ try {
174
+ const res = await fetch("/api/request-access", {
175
+ method: "POST",
176
+ headers: { "content-type": "application/json", accept: "application/json" },
177
+ body: JSON.stringify(fields),
178
+ });
179
+ const data = await res.json().catch(function () { return {}; });
180
+ if (res.ok && data && data.ok) {
181
+ // If the endpoint couldn't send server-side yet, it hands back a
182
+ // mailto: so the request is never dropped on the floor.
183
+ if (data.fallback === "mailto") {
184
+ window.location.href = data.mailto || mailtoFallback(fields);
185
+ }
186
+ modal.classList.add("done");
187
+ } else {
188
+ throw new Error((data && data.error) || "send_failed");
189
+ }
190
+ } catch (err) {
191
+ // Never a dead form: offer the mailto: as a client-side last resort.
192
+ // Built with DOM methods (no innerHTML) so field values can't inject markup.
193
+ form.classList.add("has-error");
194
+ const errEl = form.querySelector(".err");
195
+ if (errEl) {
196
+ errEl.textContent = "Something went wrong. ";
197
+ const link = document.createElement("a");
198
+ link.href = mailtoFallback(fields);
199
+ link.style.color = "inherit";
200
+ link.style.textDecoration = "underline";
201
+ link.textContent = "Email us directly";
202
+ errEl.appendChild(link);
203
+ errEl.appendChild(document.createTextNode(" and we'll take it from there."));
204
+ }
205
+ } finally {
206
+ if (btn) { btn.disabled = false; btn.textContent = label; }
207
+ }
208
+ });
209
+ }
210
+ })();
@@ -0,0 +1,212 @@
1
+ /* Storefront by Token of Trust — early-access landing page.
2
+ * Ported from the approved prototype; served at /tenants/home/pages/storefront.css
3
+ * (mirrored from tenants/home/public/ by scripts/build/copy-tenant-assets.mjs).
4
+ * Sub-brand: Storefront lockup + teal→blue gradient on the tokenoftrust.com light theme. */
5
+ :root{
6
+ --navy:#10294b; --navy-2:#173763; --ink:#1b2a40; --muted:#4d5a70;
7
+ --cream:#faf8f4; --card:#fff; --line:#e6e2d9; --line-cool:#dfe6ee;
8
+ --teal:#0d9391; --teal-ink:#0b6360; --coral:#bf3d2c; --green:#1d9e5f; --gold:#8a6012;
9
+ --grad:linear-gradient(115deg,#0d9391,#3b82c4);
10
+ --r:20px; --r-sm:13px; --shadow:0 18px 50px rgba(16,41,75,.13); --shadow-soft:0 8px 24px rgba(27,42,64,.07);
11
+ --sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
12
+ --display:"Plus Jakarta Sans",var(--sans); --mono:"JetBrains Mono",ui-monospace,Menlo,monospace;
13
+ }
14
+ *{box-sizing:border-box;margin:0;padding:0}
15
+ body{font-family:var(--sans);background:var(--cream);color:var(--ink);line-height:1.6;-webkit-font-smoothing:antialiased}
16
+ .wrap{max-width:1200px;margin:0 auto;padding:0 40px}
17
+ a{color:inherit;text-decoration:none}
18
+ h1,h2,h3{font-family:var(--display);letter-spacing:-.02em;color:var(--navy)}
19
+ .grad{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
20
+ .btn{display:inline-flex;align-items:center;gap:9px;font-family:var(--display);font-weight:700;font-size:.94rem;
21
+ padding:12px 22px;border-radius:12px;border:0;cursor:pointer;transition:transform .15s,box-shadow .15s;color:inherit}
22
+ .btn:hover{transform:translateY(-2px)}
23
+ .btn-grad{background:var(--grad);color:#fff;box-shadow:0 10px 24px rgba(13,147,145,.32)}
24
+ .btn-grad:hover{box-shadow:0 14px 30px rgba(13,147,145,.4)}
25
+ .btn-line{background:#fff;color:var(--navy);border:1.5px solid var(--line-cool)}
26
+ .btn-line:hover{border-color:var(--navy)}
27
+ .arrow{transition:transform .2s}
28
+ .btn:hover .arrow{transform:translateX(3px)}
29
+ .kicker{font-size:.8rem;font-weight:800;letter-spacing:.14em;text-transform:uppercase;color:var(--teal-ink)}
30
+
31
+ /* header */
32
+ header{position:sticky;top:0;z-index:50;border-bottom:1px solid var(--line);background:rgba(250,248,244,.85);backdrop-filter:blur(12px)}
33
+ .nav{display:flex;align-items:center;justify-content:space-between;height:76px}
34
+ .lockup{display:flex;align-items:center;gap:12px}
35
+ .lockup img{height:30px;display:block}
36
+ .lockup .div{width:1px;height:22px;background:var(--line-cool)}
37
+ .lockup .prod{font-family:var(--display);font-weight:600;font-size:.95rem;letter-spacing:-.01em}
38
+ .nav-links{display:flex;gap:28px}
39
+ .nav-links a{font-size:.92rem;font-weight:500;color:var(--muted)}
40
+ .nav-links a:hover{color:var(--navy)}
41
+ .nav-right{display:flex;align-items:center;gap:20px}
42
+ .login{font-size:.92rem;font-weight:600;color:var(--muted)}
43
+ .login:hover{color:var(--navy)}
44
+
45
+ /* hero */
46
+ .hero{position:relative;overflow:hidden}
47
+ .blob{position:absolute;border-radius:50%;filter:blur(70px);opacity:.5;z-index:0;pointer-events:none}
48
+ .b1{width:520px;height:520px;background:radial-gradient(circle,#9fe4dd,transparent 70%);top:-160px;right:-120px}
49
+ .b2{width:440px;height:440px;background:radial-gradient(circle,#bcd6f5,transparent 70%);top:120px;right:220px;opacity:.4}
50
+ .hero-grid{position:relative;z-index:1;display:grid;grid-template-columns:1.02fr .98fr;gap:56px;align-items:center;padding:70px 0 84px}
51
+ .eyebrow{display:inline-flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--line);
52
+ border-radius:999px;padding:8px 16px;font-size:.82rem;font-weight:700;color:var(--navy);box-shadow:var(--shadow-soft)}
53
+ .eyebrow .dot{position:relative;width:8px;height:8px;border-radius:50%;background:var(--green)}
54
+ .eyebrow .dot::after{content:"";position:absolute;inset:0;border-radius:50%;background:var(--green);animation:pulse 2.2s infinite}
55
+ @keyframes pulse{0%{transform:scale(1);opacity:.6}100%{transform:scale(2.8);opacity:0}}
56
+ h1{font-weight:800;font-size:3.35rem;line-height:1.07;margin:22px 0 20px}
57
+ .lede{font-size:1.17rem;color:var(--muted);max-width:40ch;margin-bottom:14px}
58
+ .lede b{color:var(--ink);font-weight:600}
59
+ .hero-ctas{display:flex;gap:13px;margin:28px 0 26px}
60
+ .cues{display:flex;flex-direction:column;gap:9px}
61
+ .cues span{display:flex;align-items:center;gap:10px;font-size:.95rem;font-weight:500;color:var(--ink)}
62
+ .cues .tk{width:20px;height:20px;border-radius:50%;background:rgba(13,147,145,.12);display:inline-flex;align-items:center;justify-content:center;flex:none}
63
+ .cues .tk svg{width:12px;height:12px;color:var(--teal)}
64
+
65
+ /* console (from A) */
66
+ .console{background:var(--card);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);overflow:hidden}
67
+ .c-head{display:flex;align-items:center;justify-content:space-between;padding:15px 20px;border-bottom:1px solid var(--line);background:linear-gradient(180deg,#fbfcfe,#fff)}
68
+ .c-head .url{font-family:var(--mono);font-size:.82rem;color:var(--navy);display:flex;align-items:center;gap:9px}
69
+ .c-live{display:inline-flex;align-items:center;gap:7px;font-size:.76rem;font-weight:700;color:var(--green);background:rgba(29,158,95,.1);padding:5px 11px;border-radius:999px}
70
+ .c-live i{width:7px;height:7px;border-radius:50%;background:var(--green);animation:blip 1.8s infinite}
71
+ @keyframes blip{0%{box-shadow:0 0 0 0 rgba(29,158,95,.5)}70%{box-shadow:0 0 0 7px rgba(29,158,95,0)}100%{box-shadow:0 0 0 0 rgba(29,158,95,0)}}
72
+ .c-body{padding:8px 8px 12px}
73
+ .crow{display:flex;align-items:center;gap:13px;padding:13px 14px;border-radius:11px}
74
+ .crow .ic{width:26px;height:26px;border-radius:8px;background:rgba(13,147,145,.12);display:inline-flex;align-items:center;justify-content:center;flex:none}
75
+ .crow .ic svg{width:15px;height:15px;color:var(--teal)}
76
+ .crow .lab{font-weight:600;font-size:.95rem;color:var(--ink)}
77
+ .crow .val{margin-left:auto;font-family:var(--mono);font-size:.82rem;color:var(--muted)}
78
+ .crow .val b{color:var(--green);font-weight:500}
79
+ .crow.killed{opacity:.5}
80
+ .crow.killed .ic{background:rgba(191,61,44,.1)}.crow.killed .ic svg{color:var(--coral)}
81
+ .crow.killed .lab{text-decoration:line-through;text-decoration-color:rgba(191,61,44,.55);color:var(--muted)}
82
+ .crow.killed .val{color:var(--coral)}
83
+ .c-foot{margin:6px 10px 4px;padding:12px 14px;border-top:1px dashed var(--line-cool);display:flex;align-items:center;gap:10px;font-size:.86rem;color:var(--muted)}
84
+ .c-foot b{color:var(--navy);font-weight:700}
85
+ .migbadge{margin-left:auto;font-family:var(--mono);font-size:.74rem;color:var(--teal-ink);background:rgba(13,147,145,.1);padding:4px 9px;border-radius:7px}
86
+
87
+ /* fear band */
88
+ .fear{background:var(--navy);color:#e7eef8}
89
+ .fear .wrap{display:grid;grid-template-columns:auto 1fr;gap:36px;align-items:center;padding:44px 40px}
90
+ .fear .big{font-family:var(--display);font-weight:800;font-size:3.6rem;line-height:1;color:#fff;letter-spacing:-.03em}
91
+ .fear .big .u{color:#ff9d8e}
92
+ .fear h2{color:#fff;font-size:1.5rem;margin-bottom:8px}
93
+ .fear p{color:#aebfd6;max-width:62ch;font-size:1rem}
94
+ .fear .src{font-family:var(--mono);font-size:.74rem;color:#7d92b3;margin-top:10px}
95
+
96
+ /* generic section */
97
+ section.blk{padding:78px 0}
98
+ .center{text-align:center}
99
+ .center .section-lede{margin-inline:auto}
100
+ h2.big2{font-size:2.15rem;line-height:1.12;margin:12px 0 12px}
101
+ .section-lede{color:var(--muted);max-width:60ch;font-size:1.06rem}
102
+
103
+ /* pillars */
104
+ .pillars{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:40px}
105
+ .pillar{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:24px;box-shadow:var(--shadow-soft)}
106
+ .pillar .pic{width:44px;height:44px;border-radius:12px;background:rgba(13,147,145,.1);display:inline-flex;align-items:center;justify-content:center;margin-bottom:16px}
107
+ .pillar .pic svg{width:23px;height:23px;color:var(--teal)}
108
+ .pillar h3{font-size:1.18rem;margin-bottom:8px}
109
+ .pillar p{color:var(--muted);font-size:.96rem}
110
+ .pillar .tag{display:inline-block;margin-top:14px;font-family:var(--mono);font-size:.74rem;color:var(--teal-ink);background:rgba(13,147,145,.09);padding:5px 10px;border-radius:7px}
111
+
112
+ /* comparison */
113
+ .cmp-wrap{background:#fff}
114
+ .cmp-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:36px}
115
+ .cmp{border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:#fff;transition:box-shadow .2s}
116
+ .cmp:hover{box-shadow:var(--shadow-soft)}
117
+ .cmp .top{width:100%;text-align:left;background:none;border:0;cursor:pointer;padding:20px 22px;display:flex;align-items:center;gap:14px;font:inherit}
118
+ .cmp .logo{width:38px;height:38px;border-radius:10px;display:inline-flex;align-items:center;justify-content:center;font-family:var(--display);font-weight:800;color:#fff;font-size:1.05rem;flex:none}
119
+ .cmp .tt{flex:1}
120
+ .cmp .tt .nm{display:block;font-family:var(--display);font-weight:700;font-size:1.06rem;color:var(--navy)}
121
+ .cmp .tt .sub{display:block;font-size:.86rem;color:var(--muted);margin-top:2px}
122
+ .cmp .chev{width:20px;height:20px;color:var(--muted);transition:transform .25s;flex:none}
123
+ .cmp[aria-expanded="true"] .chev{transform:rotate(180deg)}
124
+ .cmp .panel{display:none;padding:0 22px 22px;border-top:1px solid var(--line)}
125
+ .cmp[aria-expanded="true"] .panel{display:block;animation:fade .3s ease}
126
+ @keyframes fade{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
127
+ .cmp .row2{padding-top:16px}
128
+ .cmp .row2 .h{display:flex;align-items:center;gap:8px;font-family:var(--display);font-weight:700;font-size:.82rem;text-transform:uppercase;letter-spacing:.06em;margin-bottom:8px}
129
+ .cmp .them .h{color:var(--coral)}
130
+ .cmp .us .h{color:var(--teal-ink)}
131
+ .cmp .row2 p{font-size:.92rem;color:var(--muted);line-height:1.55}
132
+ .cmp .row2 p b{color:var(--ink);font-weight:600}
133
+ .cmp .us{margin-top:16px;padding-top:16px;border-top:1px dashed var(--line-cool)}
134
+
135
+ /* persona */
136
+ .persona-wrap{background:linear-gradient(180deg,#f4f1ea,#faf8f4)}
137
+ .seg{display:inline-flex;background:#fff;border:1px solid var(--line);border-radius:14px;padding:5px;gap:4px;margin:28px 0 8px;box-shadow:var(--shadow-soft)}
138
+ .seg button{font-family:var(--display);font-weight:700;font-size:.95rem;color:var(--muted);background:none;border:0;padding:11px 20px;border-radius:10px;cursor:pointer;transition:.18s}
139
+ .seg button[aria-selected="true"]{background:var(--grad);color:#fff;box-shadow:0 6px 16px rgba(13,147,145,.28)}
140
+ .ppanel{display:none;margin-top:26px;background:#fff;border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);overflow:hidden}
141
+ .ppanel.on{display:grid;grid-template-columns:.9fr 1.1fr}
142
+ .ppanel .lft{padding:34px;border-right:1px solid var(--line);background:linear-gradient(180deg,#fbfcfe,#fff)}
143
+ .ppanel .lft .who{font-family:var(--mono);font-size:.76rem;letter-spacing:.1em;text-transform:uppercase;color:var(--teal-ink);font-weight:600}
144
+ .ppanel .lft h3{font-size:1.7rem;line-height:1.12;margin:12px 0 12px}
145
+ .ppanel .lft p{color:var(--muted);font-size:1rem;margin-bottom:20px}
146
+ .ppanel .deck{display:inline-flex;align-items:center;gap:8px;font-family:var(--display);font-weight:700;font-size:.9rem;color:var(--teal-ink)}
147
+ .ppanel .deck:hover{color:var(--navy)}
148
+ .ppanel .rgt{padding:30px 34px;display:flex;flex-direction:column;gap:16px}
149
+ .ben{display:flex;gap:13px}
150
+ .ben .bic{width:28px;height:28px;border-radius:8px;background:rgba(13,147,145,.12);display:inline-flex;align-items:center;justify-content:center;flex:none}
151
+ .ben .bic svg{width:15px;height:15px;color:var(--teal)}
152
+ .ben .bt{font-family:var(--display);font-weight:700;font-size:.98rem;color:var(--navy)}
153
+ .ben .bd{font-size:.9rem;color:var(--muted)}
154
+
155
+ /* final cta */
156
+ .final{padding:20px 0 88px}
157
+ .cta-band{background:var(--navy);border-radius:26px;padding:56px 40px;text-align:center;position:relative;overflow:hidden}
158
+ .cta-band .cb{position:absolute;width:360px;height:360px;border-radius:50%;filter:blur(80px);opacity:.35}
159
+ .cta-band .cb1{background:#0d9391;top:-120px;left:-60px}.cta-band .cb2{background:#3b82c4;bottom:-140px;right:-40px}
160
+ .cta-band .kicker{color:#7fe3d6;position:relative}
161
+ .cta-band h2{color:#fff;font-size:2.2rem;margin:12px 0 12px;position:relative}
162
+ .cta-band p{color:#aebfd6;max-width:56ch;margin:0 auto 26px;position:relative}
163
+ .cta-band .hero-ctas{justify-content:center;position:relative}
164
+ .btn-white{background:#fff;color:var(--navy)}
165
+
166
+ /* built strip / footer */
167
+ .strip{border-top:1px solid var(--line);border-bottom:1px solid var(--line);background:#fff}
168
+ .strip .wrap{display:flex;align-items:center;justify-content:space-between;padding:20px 40px;gap:24px;flex-wrap:wrap}
169
+ .strip .built{display:flex;align-items:center;gap:14px;font-size:.88rem;color:var(--muted);flex-wrap:wrap}
170
+ .strip .built .k{font-weight:700;color:var(--navy);font-size:.78rem;letter-spacing:.08em;text-transform:uppercase}
171
+ .strip .built .tag{font-weight:600;color:var(--ink)}
172
+ .strip .built .sep{color:var(--line-cool)}
173
+ .strip .repl{font-size:.85rem;color:var(--muted)}.strip .repl b{color:var(--navy);font-weight:700}
174
+ footer.foot{padding:40px 0;color:var(--muted);font-size:.85rem;text-align:center;background:#f4f1ea}
175
+
176
+ /* request-access modal */
177
+ .modal{position:fixed;inset:0;z-index:100;display:none;align-items:center;justify-content:center;padding:24px}
178
+ .modal.on{display:flex}
179
+ .modal .ov{position:absolute;inset:0;background:rgba(16,41,75,.5);backdrop-filter:blur(3px)}
180
+ .modal .dlg{position:relative;z-index:1;background:#fff;border-radius:var(--r);box-shadow:var(--shadow);width:100%;max-width:520px;max-height:92vh;overflow:auto;animation:fade .25s ease}
181
+ .modal .dlg-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:28px 30px 6px}
182
+ .modal .dlg-head h3{font-size:1.5rem;line-height:1.15}
183
+ .modal .dlg-head p{color:var(--muted);font-size:.95rem;margin-top:6px}
184
+ .modal .x{background:none;border:0;cursor:pointer;color:var(--muted);width:34px;height:34px;border-radius:9px;display:inline-flex;align-items:center;justify-content:center;flex:none}
185
+ .modal .x:hover{background:var(--cream);color:var(--navy)}
186
+ .modal .x svg{width:20px;height:20px}
187
+ form.ra{padding:14px 30px 30px;display:flex;flex-direction:column;gap:14px}
188
+ form.ra .fld{display:flex;flex-direction:column;gap:6px}
189
+ form.ra .row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
190
+ form.ra label{font-family:var(--display);font-weight:700;font-size:.82rem;color:var(--navy)}
191
+ form.ra label .opt{font-family:var(--sans);font-weight:500;color:var(--muted);text-transform:none;letter-spacing:0}
192
+ form.ra input,form.ra textarea{font:inherit;font-size:.95rem;color:var(--ink);background:#fff;border:1.5px solid var(--line-cool);
193
+ border-radius:10px;padding:11px 13px;transition:border-color .15s}
194
+ form.ra input:focus,form.ra textarea:focus{outline:none;border-color:var(--teal)}
195
+ form.ra textarea{resize:vertical;min-height:78px}
196
+ form.ra .btn-grad{justify-content:center;margin-top:4px}
197
+ form.ra .err{display:none;color:var(--coral);font-size:.9rem;font-weight:600}
198
+ form.ra.has-error .err{display:block}
199
+ .ra-done{display:none;padding:34px 30px 40px;text-align:center}
200
+ .modal.done form.ra{display:none}
201
+ .modal.done .ra-done{display:block}
202
+ .ra-done .tick{width:56px;height:56px;border-radius:50%;background:rgba(29,158,95,.12);display:inline-flex;align-items:center;justify-content:center;margin-bottom:16px}
203
+ .ra-done .tick svg{width:30px;height:30px;color:var(--green)}
204
+ .ra-done h3{font-size:1.5rem;margin-bottom:8px}
205
+ .ra-done p{color:var(--muted);font-size:1rem;max-width:34ch;margin:0 auto 18px}
206
+
207
+ @media (max-width:900px){
208
+ .hero-grid{grid-template-columns:1fr;gap:40px}.pillars,.cmp-cards{grid-template-columns:1fr}
209
+ .ppanel.on{grid-template-columns:1fr}.ppanel .lft{border-right:0;border-bottom:1px solid var(--line)}
210
+ .fear .wrap{grid-template-columns:1fr;gap:16px}h1{font-size:2.5rem}
211
+ form.ra .row{grid-template-columns:1fr}
212
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "color": {
3
+ "primary": "#0030a0",
4
+ "primary-contrast": "#ffffff"
5
+ }
6
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "tenant": "tokenoftrust",
3
+ "scope": "tokenoftrust.com",
4
+ "mappings": [
5
+ { "workspace": "theme.json", "repo": "tenants/tokenoftrust/theme.json", "kind": "file" },
6
+ { "workspace": "content/", "repo": "tenants/tokenoftrust/content/", "kind": "tree" },
7
+ { "workspace": "public/", "repo": "tenants/tokenoftrust/public/", "kind": "tree" }
8
+ ]
9
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "nav": [
3
+ { "label": "Platform", "href": "/#platform" },
4
+ { "label": "Industries", "href": "/#industries" },
5
+ { "label": "Resources", "href": "https://help.tokenoftrust.com" },
6
+ { "label": "Pricing", "href": "https://tokenoftrust.com/pricing/" },
7
+ { "label": "Login", "href": "https://app.tokenoftrust.com" }
8
+ ],
9
+ "headerCtas": [
10
+ { "label": "Book Demo", "href": "https://tokenoftrust.com/contact/", "variant": "secondary" },
11
+ { "label": "Start For Free", "href": "https://app.tokenoftrust.com", "variant": "primary" }
12
+ ],
13
+ "footer": {
14
+ "tagline": "Customer verification and compliance for regulated ecommerce. 200+ countries. We will never sell your data.",
15
+ "legal": "GDPR · CCPA · PIPEDA compliant. 256-bit SSL. We will never sell your data.",
16
+ "columns": [
17
+ {
18
+ "title": "Platform",
19
+ "links": [
20
+ { "label": "Identity Verification", "href": "/#platform" },
21
+ { "label": "Age Assurance", "href": "/#platform" },
22
+ { "label": "Fraud Prevention", "href": "/#platform" },
23
+ { "label": "Compliance Evidence", "href": "/#platform" },
24
+ { "label": "AML · PACT Act · Tax", "href": "/#platform" }
25
+ ]
26
+ },
27
+ {
28
+ "title": "Industries",
29
+ "links": [
30
+ { "label": "Alcohol", "href": "/#industries" },
31
+ { "label": "Tobacco & Vape", "href": "/#industries" },
32
+ { "label": "Age-Restricted Goods", "href": "/#industries" },
33
+ { "label": "Marketplaces", "href": "/#industries" }
34
+ ]
35
+ },
36
+ {
37
+ "title": "Company",
38
+ "links": [
39
+ { "label": "Pricing", "href": "https://tokenoftrust.com/pricing/" },
40
+ { "label": "Contact Sales", "href": "https://tokenoftrust.com/contact/" },
41
+ { "label": "Resources", "href": "https://help.tokenoftrust.com" },
42
+ { "label": "Login", "href": "https://app.tokenoftrust.com" }
43
+ ]
44
+ },
45
+ {
46
+ "title": "Legal",
47
+ "links": [
48
+ { "label": "Privacy Policy", "href": "https://tokenoftrust.com/privacy/" },
49
+ { "label": "Terms", "href": "https://tokenoftrust.com/terms/" }
50
+ ]
51
+ }
52
+ ],
53
+ "social": []
54
+ }
55
+ }