@elitedcs/ghl-mcp 3.53.2 → 3.54.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.
package/dist/index.js CHANGED
@@ -886,26 +886,26 @@ async function pollCaptureState(budgetMs, intervalMs = 2e3) {
886
886
  await sleep2(Math.min(intervalMs, Math.max(1, deadline - Date.now())));
887
887
  }
888
888
  }
889
- var fs4, path4, import_child_process, import_zod38, CaptureStateSchema, EXTRACT_FIREBASE_PAGE_FN, HEAL_POISONED_DB_PAGE_FN, EXTRACT_FIREBASE_EXPRESSION, HEAL_POISONED_DB_EXPRESSION, HELPER_LOGIN_TIMEOUT_MS, HEADLESS_PROBE_TIMEOUT_MS, CAPTURED_FRESH_MS, WAITING_FRESH_MS, sleep2;
889
+ var fs4, path4, import_child_process, import_zod39, CaptureStateSchema, EXTRACT_FIREBASE_PAGE_FN, HEAL_POISONED_DB_PAGE_FN, EXTRACT_FIREBASE_EXPRESSION, HEAL_POISONED_DB_EXPRESSION, HELPER_LOGIN_TIMEOUT_MS, HEADLESS_PROBE_TIMEOUT_MS, CAPTURED_FRESH_MS, WAITING_FRESH_MS, sleep2;
890
890
  var init_interactive_capture = __esm({
891
891
  "src/interactive-capture.ts"() {
892
892
  "use strict";
893
893
  fs4 = __toESM(require("fs"));
894
894
  path4 = __toESM(require("path"));
895
895
  import_child_process = require("child_process");
896
- import_zod38 = require("zod");
896
+ import_zod39 = require("zod");
897
897
  init_credentials_store();
898
- CaptureStateSchema = import_zod38.z.object({
899
- status: import_zod38.z.enum(["waiting_login", "captured", "timeout", "error"]),
900
- startedAt: import_zod38.z.string(),
901
- updatedAt: import_zod38.z.string(),
898
+ CaptureStateSchema = import_zod39.z.object({
899
+ status: import_zod39.z.enum(["waiting_login", "captured", "timeout", "error"]),
900
+ startedAt: import_zod39.z.string(),
901
+ updatedAt: import_zod39.z.string(),
902
902
  // Present when status === "captured"
903
- ghl_firebase_api_key: import_zod38.z.string().optional(),
904
- ghl_user_id: import_zod38.z.string().optional(),
905
- ghl_firebase_refresh_token: import_zod38.z.string().optional(),
906
- account_email: import_zod38.z.string().optional(),
903
+ ghl_firebase_api_key: import_zod39.z.string().optional(),
904
+ ghl_user_id: import_zod39.z.string().optional(),
905
+ ghl_firebase_refresh_token: import_zod39.z.string().optional(),
906
+ account_email: import_zod39.z.string().optional(),
907
907
  // Present when status === "error"
908
- error: import_zod38.z.string().optional()
908
+ error: import_zod39.z.string().optional()
909
909
  });
910
910
  EXTRACT_FIREBASE_PAGE_FN = `async () => {
911
911
  const pick = (rows) => {
@@ -1235,21 +1235,21 @@ async function validateFirebase(firebaseKey, refreshToken) {
1235
1235
  function registerSetupTool(server2) {
1236
1236
  server2.tool(
1237
1237
  "setup_ghl_mcp",
1238
- "First-run setup for GHL Command MCP. Validates your license and GHL credentials, then writes them to a per-user credentials file. Restart Claude after this completes to load all 232 tools (180 if you skip the optional Firebase fields; add Firebase later with enable_workflow_builder).",
1238
+ "First-run setup for GHL Command MCP. Validates your license and GHL credentials, then writes them to a per-user credentials file. Restart Claude after this completes to load all 234 tools (180 if you skip the optional Firebase fields; add Firebase later with enable_workflow_builder).",
1239
1239
  {
1240
- email: import_zod39.z.string().email().describe("Email used at purchase."),
1241
- license_key: import_zod39.z.string().min(20).describe("License key from your purchase email."),
1242
- ghl_api_key: import_zod39.z.string().min(10).describe("GHL Private Integration key (starts with 'pit-'). Created INSIDE the sub-account at Settings > Integrations > Private Integrations."),
1243
- ghl_location_id: import_zod39.z.string().min(10).describe("GHL Location ID (sub-account ID). Found in your GHL URL: /location/THIS_PART/dashboard."),
1244
- ghl_company_id: import_zod39.z.string().optional().describe("(Agency only) Company ID for multi-location access."),
1240
+ email: import_zod40.z.string().email().describe("Email used at purchase."),
1241
+ license_key: import_zod40.z.string().min(20).describe("License key from your purchase email."),
1242
+ ghl_api_key: import_zod40.z.string().min(10).describe("GHL Private Integration key (starts with 'pit-'). Created INSIDE the sub-account at Settings > Integrations > Private Integrations."),
1243
+ ghl_location_id: import_zod40.z.string().min(10).describe("GHL Location ID (sub-account ID). Found in your GHL URL: /location/THIS_PART/dashboard."),
1244
+ ghl_company_id: import_zod40.z.string().optional().describe("(Agency only) Company ID for multi-location access."),
1245
1245
  // v3.25.0: one-paste shortcut. Run `auto_capture_firebase_script` first;
1246
1246
  // it returns a console script that fills the clipboard with this exact
1247
1247
  // JSON payload. Pasting it here removes the need to fill ghl_user_id,
1248
1248
  // ghl_firebase_api_key, and ghl_firebase_refresh_token individually.
1249
- firebase_paste: import_zod39.z.string().optional().describe("(Workflow Builder, one-paste path) Paste the JSON output from auto_capture_firebase_script here. Replaces the three separate Firebase fields below."),
1250
- ghl_user_id: import_zod39.z.string().optional().describe("(Workflow Builder, manual path) Firebase User ID. Prefer firebase_paste instead."),
1251
- ghl_firebase_api_key: import_zod39.z.string().optional().describe("(Workflow Builder, manual path) Firebase API Key starting with 'AIza'. Prefer firebase_paste instead."),
1252
- ghl_firebase_refresh_token: import_zod39.z.string().optional().describe("(Workflow Builder, manual path) Firebase refresh token. Prefer firebase_paste instead.")
1249
+ firebase_paste: import_zod40.z.string().optional().describe("(Workflow Builder, one-paste path) Paste the JSON output from auto_capture_firebase_script here. Replaces the three separate Firebase fields below."),
1250
+ ghl_user_id: import_zod40.z.string().optional().describe("(Workflow Builder, manual path) Firebase User ID. Prefer firebase_paste instead."),
1251
+ ghl_firebase_api_key: import_zod40.z.string().optional().describe("(Workflow Builder, manual path) Firebase API Key starting with 'AIza'. Prefer firebase_paste instead."),
1252
+ ghl_firebase_refresh_token: import_zod40.z.string().optional().describe("(Workflow Builder, manual path) Firebase refresh token. Prefer firebase_paste instead.")
1253
1253
  },
1254
1254
  async (args) => {
1255
1255
  const lic = await validateLicense(args.email, args.license_key);
@@ -1317,7 +1317,7 @@ Note: Firebase credentials rejected (${fb.error}). Saved without Workflow Builde
1317
1317
  signed_attestation: lic.signedAttestation
1318
1318
  });
1319
1319
  const isFree = lic.tier === "free";
1320
- const toolCount = isFree ? workflowBuilderEnabled ? "106" : "88" : workflowBuilderEnabled ? "232" : "180";
1320
+ const toolCount = isFree ? workflowBuilderEnabled ? "106" : "88" : workflowBuilderEnabled ? "234" : "180";
1321
1321
  const wfLine = workflowBuilderEnabled ? "Workflow Builder: enabled." : "Workflow Builder: not configured (optional).";
1322
1322
  const wfTip = workflowBuilderEnabled ? "" : isFree ? `
1323
1323
  Unlock the account auditor next (the free tier's best tool): say "Unlock the Workflow Builder" \u2014 one browser login enables audit_workflows, validate_workflow, and the full-detail reads.` : "\nTo enable Workflow Builder later (52 extra Firebase-gated tools): run enable_workflow_builder with your three Firebase values. No need to re-enter license/API key/location ID.";
@@ -1347,16 +1347,16 @@ Unlock the account auditor next (the free tier's best tool): say "Unlock the Wor
1347
1347
  function registerEnableWorkflowBuilderTool(server2) {
1348
1348
  server2.tool(
1349
1349
  "enable_workflow_builder",
1350
- "Add Firebase credentials to an existing GHL Command install to unlock 52 additional tools across the internal-API modules: workflow builder (create/edit/clone/delete/publish/validate workflows, build_if_else_branch, build_goal_event, get_trigger_registry), funnel + page builder, form builder, pipeline builder, workflow cloner, smart lists, reputation, email campaigns, email templates, and memberships, plus the pre-deploy validator. On the FREE tier this same login unlocks the read-only auditor suite (audit_workflows, validate_workflow, full-detail workflow/funnel/pipeline reads). Requires you've already run setup_ghl_mcp. EASIEST PATH: run `capture_firebase_interactive` instead \u2014 a Chrome window opens, you log into GHL, zero pasting. Use THIS tool when you have JSON from `auto_capture_firebase_script` (console-paste path) to put in `firebase_paste`, or the three manual DevTools fields. Tool count goes from 180 to 232 after the next Claude restart.",
1350
+ "Add Firebase credentials to an existing GHL Command install to unlock 54 additional tools across the internal-API modules: workflow builder (create/edit/clone/delete/publish/validate workflows, build_if_else_branch, build_goal_event, get_trigger_registry), funnel + page builder, form builder, pipeline builder, workflow cloner, smart lists, reputation, email campaigns, email templates, and memberships, plus the pre-deploy validator. On the FREE tier this same login unlocks the read-only auditor suite (audit_workflows, validate_workflow, full-detail workflow/funnel/pipeline reads). Requires you've already run setup_ghl_mcp. EASIEST PATH: run `capture_firebase_interactive` instead \u2014 a Chrome window opens, you log into GHL, zero pasting. Use THIS tool when you have JSON from `auto_capture_firebase_script` (console-paste path) to put in `firebase_paste`, or the three manual DevTools fields. Tool count goes from 180 to 234 after the next Claude restart.",
1351
1351
  {
1352
1352
  // v3.25.0: one-paste path. Tool runs `auto_capture_firebase_script` to
1353
1353
  // get the console script; the script returns a JSON object that pastes
1354
1354
  // cleanly into this field. Saves the buyer from picking out three
1355
1355
  // separate fields in IndexedDB.
1356
- firebase_paste: import_zod39.z.string().optional().describe("Paste the JSON output from auto_capture_firebase_script here. Replaces the three separate Firebase fields below."),
1357
- ghl_user_id: import_zod39.z.string().min(10).optional().describe("(Manual path) Firebase User ID (uid). Prefer firebase_paste."),
1358
- ghl_firebase_api_key: import_zod39.z.string().min(10).optional().describe("(Manual path) Firebase API Key starting with 'AIza'. Prefer firebase_paste."),
1359
- ghl_firebase_refresh_token: import_zod39.z.string().min(10).optional().describe("(Manual path) Firebase refresh token. Prefer firebase_paste.")
1356
+ firebase_paste: import_zod40.z.string().optional().describe("Paste the JSON output from auto_capture_firebase_script here. Replaces the three separate Firebase fields below."),
1357
+ ghl_user_id: import_zod40.z.string().min(10).optional().describe("(Manual path) Firebase User ID (uid). Prefer firebase_paste."),
1358
+ ghl_firebase_api_key: import_zod40.z.string().min(10).optional().describe("(Manual path) Firebase API Key starting with 'AIza'. Prefer firebase_paste."),
1359
+ ghl_firebase_refresh_token: import_zod40.z.string().min(10).optional().describe("(Manual path) Firebase refresh token. Prefer firebase_paste.")
1360
1360
  },
1361
1361
  async (args) => {
1362
1362
  const existing = readCredentials();
@@ -1428,7 +1428,7 @@ DevTools steps: https://elitedcs.com/ghl-mcp-firebase`
1428
1428
  "",
1429
1429
  "**You MUST restart Claude before using any workflow-builder tool.** Quit Claude completely (Cmd+Q on Mac, full exit on Windows) and reopen. Without a restart, the workflow builder tools will keep using the OLD Firebase auth from before this call and fail with 401 errors \u2014 even though this tool reported success.",
1430
1430
  "",
1431
- 'After restart, all 232 tools load. Try: "List my workflows in full detail" or "Validate workflow <id>".',
1431
+ 'After restart, all 234 tools load. Try: "List my workflows in full detail" or "Validate workflow <id>".',
1432
1432
  "",
1433
1433
  "Note: Firebase refresh tokens rotate every few weeks. If workflow tools stop working in a few weeks (run `health_check` to confirm Firebase auth: FAIL), run `auto_capture_firebase_script` for fresh values and re-run this tool with the new firebase_paste."
1434
1434
  ].join("\n")
@@ -1524,7 +1524,7 @@ The login in the capture window may belong to the wrong GHL account, or the sess
1524
1524
  "",
1525
1525
  "**You MUST restart Claude before using any workflow-builder tool.** Quit Claude completely (Cmd+Q on Mac, full exit on Windows) and reopen.",
1526
1526
  "",
1527
- 'After restart, all 232 tools load. Try: "List my workflows in full detail".',
1527
+ 'After restart, all 234 tools load. Try: "List my workflows in full detail".',
1528
1528
  "",
1529
1529
  "Future token rotations re-capture silently \u2014 if workflow tools ever 401, just run capture_firebase_interactive again; no window should appear."
1530
1530
  ].join("\n")
@@ -1610,8 +1610,8 @@ function registerLeadCaptureTool(server2) {
1610
1610
  "request_license",
1611
1611
  "Get a GHL Command license. Use this if you installed from npm but don't have a license yet (or setup_ghl_mcp says your license is missing/invalid). GHL Command is $97/mo \u2014 every sub-account you manage, 3-machine activation, includes the only programmatic GHL workflow builder. There's also a FREE read-only tier (account audits + all reads on your own account) \u2014 instant key at https://ghlcommand.com/free. Leave your email and we'll send the purchase link + setup help; the tool also returns where to buy right now.",
1612
1612
  {
1613
- email: import_zod39.z.string().email().describe("Your email \u2014 where to send the purchase link and setup help."),
1614
- name: import_zod39.z.string().optional().describe("Your name (optional).")
1613
+ email: import_zod40.z.string().email().describe("Your email \u2014 where to send the purchase link and setup help."),
1614
+ name: import_zod40.z.string().optional().describe("Your name (optional).")
1615
1615
  },
1616
1616
  async (args) => {
1617
1617
  const buyUrl = "https://ghlcommand.com";
@@ -1648,13 +1648,13 @@ function registerLeadCaptureTool(server2) {
1648
1648
  }
1649
1649
  );
1650
1650
  }
1651
- var os2, crypto2, import_zod39, LICENSE_API, CAPTURE_API, GHL_API, FIREBASE_TOKEN_API;
1651
+ var os2, crypto2, import_zod40, LICENSE_API, CAPTURE_API, GHL_API, FIREBASE_TOKEN_API;
1652
1652
  var init_setup_tool = __esm({
1653
1653
  "src/setup-tool.ts"() {
1654
1654
  "use strict";
1655
1655
  os2 = __toESM(require("os"));
1656
1656
  crypto2 = __toESM(require("crypto"));
1657
- import_zod39 = require("zod");
1657
+ import_zod40 = require("zod");
1658
1658
  init_credentials_store();
1659
1659
  init_firebase_capture_script();
1660
1660
  init_firebase_claims();
@@ -2102,9 +2102,9 @@ var require_package = __commonJS({
2102
2102
  "package.json"(exports2, module2) {
2103
2103
  module2.exports = {
2104
2104
  name: "@elitedcs/ghl-mcp",
2105
- version: "3.53.2",
2105
+ version: "3.54.0",
2106
2106
  mcpName: "io.github.drjerryrelth/ghl-command",
2107
- description: "GoHighLevel MCP Server for Claude. 232 tools \u2014 full CRM, automation, marketing control, account-wide workflow audit, live funnel-capture verification, and the only programmatic GHL workflow builder, now multi-tenant across client accounts.",
2107
+ description: "GoHighLevel MCP Server for Claude. 234 tools \u2014 full CRM, automation, marketing control, account-wide workflow audit, live funnel-capture verification, and the only programmatic GHL workflow builder, now multi-tenant across client accounts.",
2108
2108
  main: "dist/index.js",
2109
2109
  bin: {
2110
2110
  "ghl-mcp": "dist/index.js"
@@ -2311,6 +2311,22 @@ var init_launcher = __esm({
2311
2311
  });
2312
2312
 
2313
2313
  // src/stage-runner.ts
2314
+ function buildPermission(locationId2, opts = {}) {
2315
+ const protectedName = PROTECTED_LOCATIONS[locationId2];
2316
+ if (protectedName) {
2317
+ return { allowed: false, kind: "protected", reason: `${protectedName} is permanently protected \u2014 builds are refused here, and no approval can override that.` };
2318
+ }
2319
+ const sandbox = SANDBOX_ALLOWLIST[locationId2];
2320
+ if (sandbox) return { allowed: true, kind: "sandbox", reason: `${sandbox} is a sandbox.` };
2321
+ if (opts.approvedAt) {
2322
+ return { allowed: true, kind: "approved", reason: `Approved for building on ${new Date(opts.approvedAt).toLocaleDateString()}.` };
2323
+ }
2324
+ return {
2325
+ allowed: false,
2326
+ kind: "not_approved",
2327
+ reason: `${opts.name || locationId2} is not approved for building yet. Approve it on the card first \u2014 that is the deliberate step that lets automation write into a real client account.`
2328
+ };
2329
+ }
2314
2330
  function stageBlockedBy(stages, stage) {
2315
2331
  if (!stages) return stage === 0 ? null : 0;
2316
2332
  for (let i = 0; i < stage; i++) {
@@ -2374,12 +2390,9 @@ function parseResultLine(text) {
2374
2390
  }
2375
2391
  }
2376
2392
  function runStage(locationId2, stage, onEvent, opts = {}) {
2377
- const locationName = SANDBOX_ALLOWLIST[locationId2];
2378
- if (!locationName) {
2379
- return Promise.reject(new Error(
2380
- `Refused: ${locationId2} is not a sandbox account. Powered stages run ONLY on: ${Object.values(SANDBOX_ALLOWLIST).join(", ")}.`
2381
- ));
2382
- }
2393
+ const permission = buildPermission(locationId2, { name: opts.name, approvedAt: opts.approvedAt });
2394
+ if (!permission.allowed) return Promise.reject(new Error(`Refused: ${permission.reason}`));
2395
+ const locationName = SANDBOX_ALLOWLIST[locationId2] || opts.name || locationId2;
2383
2396
  const spec = STAGE_SPECS[stage];
2384
2397
  if (!spec) return Promise.reject(new Error(`Stage ${stage} is not powered yet.`));
2385
2398
  return new Promise((resolve5) => {
@@ -2445,7 +2458,7 @@ function runStage(locationId2, stage, onEvent, opts = {}) {
2445
2458
  });
2446
2459
  });
2447
2460
  }
2448
- var import_child_process2, fs8, os4, path8, SANDBOX_ALLOWLIST, STAGE_SPECS, HUMAN_GATE_STAGES;
2461
+ var import_child_process2, fs8, os4, path8, SANDBOX_ALLOWLIST, PROTECTED_LOCATIONS, STAGE_SPECS, HUMAN_GATE_STAGES;
2449
2462
  var init_stage_runner = __esm({
2450
2463
  "src/stage-runner.ts"() {
2451
2464
  "use strict";
@@ -2457,6 +2470,9 @@ var init_stage_runner = __esm({
2457
2470
  JrV2p35O3hY2wqhr2c0T: "MCP Testing",
2458
2471
  jHP5wkYRineXDlzAOEbW: "Blueprint Demo"
2459
2472
  };
2473
+ PROTECTED_LOCATIONS = {
2474
+ HJfJXQdWwPNxYdjqI1ua: "QA Test Clinic - v3 (live CLL snapshot source)"
2475
+ };
2460
2476
  STAGE_SPECS = {
2461
2477
  0: {
2462
2478
  stage: 0,
@@ -2466,7 +2482,12 @@ var init_stage_runner = __esm({
2466
2482
  "mcp__ghl__get_current_location",
2467
2483
  "mcp__ghl__get_intake_question_set",
2468
2484
  "mcp__ghl__install_intake_form",
2469
- "mcp__ghl__get_forms"
2485
+ "mcp__ghl__get_forms",
2486
+ "mcp__ghl__get_workflows",
2487
+ "mcp__ghl__create_workflow",
2488
+ "mcp__ghl__update_workflow_actions",
2489
+ "mcp__ghl__publish_workflow",
2490
+ "mcp__ghl__get_users"
2470
2491
  ],
2471
2492
  prompt: (locationId2, locationName, ctx) => `You are running ONE unattended step of a GHL Command Blueprint build. Use ONLY the ghl MCP tools.
2472
2493
  ` + (ctx?.industry ? `This client is a ${ctx.industry} business \u2014 the intake is tailored to that.
@@ -2476,8 +2497,11 @@ var init_stage_runner = __esm({
2476
2497
  2. Call get_current_location and STOP with a line "RESULT: {\\"ok\\":false,\\"error\\":\\"wrong location\\"}" if it is not ${locationId2}.
2477
2498
  3. Call get_forms FIRST. If a form named "GHL Command Blueprint \u2014 Client Intake" ALREADY EXISTS, do NOT install another one \u2014 reuse it and report it. Only if none exists, install it with install_intake_form (use get_intake_question_set first if the tool needs the question set).
2478
2499
  4. Verify with get_forms that the form now exists.
2500
+ 5. Make sure nothing falls through the cracks: check get_workflows for a workflow named "Blueprint Intake \u2014 Submitted". If it does NOT exist, create and publish it:
2501
+ trigger = form_submission on that intake form; actions = internal_notification to the account users (title "Blueprint intake received", body naming the contact and that answers are in), then add_contact_tag ["blueprint-intake-received"], then add_notes with a short HTML note that the intake was submitted.
2502
+ Use get_users to pick a real user id for the notification \u2014 an empty recipient fails publish validation. If the workflow already exists, leave it alone.
2479
2503
  Finish with EXACTLY one final line in this format (valid JSON after the colon):
2480
- RESULT: {"ok":true,"formId":"...","formName":"..."}
2504
+ RESULT: {"ok":true,"formId":"...","formName":"...","summary":"<form + whether the submitted-notification workflow existed or was created>"}
2481
2505
  If anything fails, finish with: RESULT: {"ok":false,"error":"<short reason>"}`
2482
2506
  },
2483
2507
  1: {
@@ -2703,38 +2727,68 @@ var init_customization = __esm({
2703
2727
  function publicFormUrl(formId) {
2704
2728
  return `https://api.leadconnectorhq.com/widget/form/${formId}`;
2705
2729
  }
2730
+ function prefilledFormUrl(formUrl, queryKeys, answers, contact = {}) {
2731
+ const p = new URLSearchParams();
2732
+ if (contact.firstName) p.set("first_name", contact.firstName);
2733
+ if (contact.lastName) p.set("last_name", contact.lastName);
2734
+ if (contact.email) p.set("email", contact.email);
2735
+ if (contact.phone) p.set("phone", contact.phone);
2736
+ for (const [label, value] of Object.entries(answers)) {
2737
+ const key = queryKeys[label];
2738
+ if (key && value && String(value).trim()) p.set(key, String(value));
2739
+ }
2740
+ const qs = p.toString();
2741
+ return qs ? `${formUrl}?${qs}` : formUrl;
2742
+ }
2706
2743
  async function readIntakeSnapshot(client, locationId2, sentMarker) {
2707
- const empty = { status: "not_installed", fields: {}, submissions: 0 };
2744
+ const empty = { status: "not_installed", fields: {}, queryKeys: {}, submissions: 0 };
2708
2745
  try {
2709
2746
  const forms = await client.get("/forms/", { params: { locationId: locationId2, limit: 100 } });
2710
2747
  const form = (forms.forms ?? []).find((f) => f.name === INTAKE_FORM_NAME2);
2711
2748
  if (!form) return empty;
2712
2749
  const cf = await client.get("/locations/" + locationId2 + "/customFields");
2713
2750
  const fields = {};
2751
+ const queryKeys = {};
2714
2752
  for (const f of cf.customFields ?? []) {
2715
- if (f.name?.startsWith(INTAKE_FIELD_NAME_PREFIX)) fields[f.name.slice(INTAKE_FIELD_NAME_PREFIX.length)] = f.id;
2753
+ if (!f.name?.startsWith(INTAKE_FIELD_NAME_PREFIX)) continue;
2754
+ const label = f.name.slice(INTAKE_FIELD_NAME_PREFIX.length);
2755
+ fields[label] = f.id;
2756
+ if (f.fieldKey) queryKeys[label] = f.fieldKey.replace(/^contact\./, "");
2716
2757
  }
2717
2758
  let submissions = 0;
2718
2759
  let answeredAt;
2760
+ let channel;
2761
+ let contactId;
2719
2762
  try {
2720
2763
  const subs = await client.get("/forms/submissions", { params: { locationId: locationId2, formId: form.id, limit: 5 } });
2721
- submissions = (subs.submissions ?? []).length;
2722
- answeredAt = subs.submissions?.[0]?.createdAt;
2764
+ if ((subs.submissions ?? []).length) {
2765
+ submissions = subs.submissions.length;
2766
+ answeredAt = subs.submissions[0]?.createdAt;
2767
+ channel = "form";
2768
+ }
2723
2769
  } catch {
2724
2770
  }
2725
2771
  if (!submissions) {
2726
2772
  try {
2727
- const found = await client.get("/contacts/", { params: { locationId: locationId2, query: INTAKE_CONTACT_TAG, limit: 20 } });
2728
- const hit = (found.contacts ?? []).find((c) => (c.tags ?? []).includes(INTAKE_CONTACT_TAG));
2773
+ const seen = /* @__PURE__ */ new Map();
2774
+ for (const q2 of [INTAKE_CONTACT_TAG, INTAKE_FORM_NAME2]) {
2775
+ const found = await client.get("/contacts/", { params: { locationId: locationId2, query: q2, limit: 20 } });
2776
+ for (const c of found.contacts ?? []) seen.set(c.id, c);
2777
+ }
2778
+ const isFormSubmission = (c) => c.source === INTAKE_FORM_NAME2 || (c.attributions ?? []).some((a) => a.mediumId === form.id || a.medium === "form");
2779
+ const all = [...seen.values()];
2780
+ const hit = all.find(isFormSubmission) ?? all.find((c) => (c.tags ?? []).includes(INTAKE_CONTACT_TAG));
2729
2781
  if (hit) {
2730
2782
  submissions = 1;
2731
2783
  answeredAt = hit.dateUpdated;
2784
+ contactId = hit.id;
2785
+ channel = isFormSubmission(hit) ? "form" : "cockpit";
2732
2786
  }
2733
2787
  } catch {
2734
2788
  }
2735
2789
  }
2736
2790
  const status = submissions > 0 ? "received" : sentMarker ? "sent" : "installed";
2737
- return { status, formId: form.id, formUrl: publicFormUrl(form.id), fields, submissions, answeredAt };
2791
+ return { status, formId: form.id, formUrl: publicFormUrl(form.id), fields, queryKeys, submissions, answeredAt, channel, contactId };
2738
2792
  } catch {
2739
2793
  return empty;
2740
2794
  }
@@ -2941,16 +2995,36 @@ function parseReview(text) {
2941
2995
  return { ok: false, error: "the review came back malformed", raw: m[1].slice(0, 400) };
2942
2996
  }
2943
2997
  }
2998
+ function strictRetryPrompt(input) {
2999
+ return [
3000
+ reviewPrompt(input),
3001
+ "",
3002
+ "IMPORTANT: your previous answer did not include the RESULT line and was unusable.",
3003
+ "Output NOTHING except one line beginning with RESULT: followed by the JSON object.",
3004
+ "No preamble, no explanation, no markdown fences, no closing remarks."
3005
+ ].join("\n");
3006
+ }
2944
3007
  async function generateReview(spawnClaude, input) {
2945
3008
  const answered = Object.values(input.answers).filter((v) => v && String(v).trim()).length;
2946
3009
  if (answered < 5) {
2947
3010
  return { ok: false, error: `Only ${answered} intake answers so far \u2014 complete the intake first, or there is nothing to reason from.` };
2948
3011
  }
2949
- try {
2950
- return parseReview(await spawnClaude(reviewPrompt(input)));
2951
- } catch (e) {
2952
- return { ok: false, error: e instanceof Error ? e.message : String(e) };
3012
+ let lastRaw = "";
3013
+ for (const prompt of [reviewPrompt(input), strictRetryPrompt(input)]) {
3014
+ try {
3015
+ const raw = await spawnClaude(prompt);
3016
+ lastRaw = raw;
3017
+ const parsed = parseReview(raw);
3018
+ if (parsed.ok) return parsed;
3019
+ } catch (e) {
3020
+ lastRaw = e instanceof Error ? e.message : String(e);
3021
+ }
2953
3022
  }
3023
+ return {
3024
+ ok: false,
3025
+ error: "The review came back unusable twice. Press Generate again, or open the log if it keeps happening.",
3026
+ raw: lastRaw.slice(-600)
3027
+ };
2954
3028
  }
2955
3029
  function reviewDocumentHtml(review, opts) {
2956
3030
  const accent = opts.accent && /^#[0-9a-fA-F]{6}$/.test(opts.accent) ? opts.accent : "#B8934A";
@@ -3198,7 +3272,7 @@ async function resolvePlan2(creds) {
3198
3272
  }
3199
3273
  return { error: "Could not verify the license (offline and no valid cached attestation)." };
3200
3274
  }
3201
- function startRun(locationId2, stage, onDone) {
3275
+ function startRun(locationId2, stage, onDone, meta = {}) {
3202
3276
  activeRun = { locationId: locationId2, stage, running: true, lines: [] };
3203
3277
  const run = activeRun;
3204
3278
  const state = readCockpitState();
@@ -3217,7 +3291,7 @@ function startRun(locationId2, stage, onDone) {
3217
3291
  runStage(locationId2, stage, (e) => {
3218
3292
  run.lines.push(e.line);
3219
3293
  if (run.lines.length > 200) run.lines.shift();
3220
- }, { context }).then((outcome) => {
3294
+ }, { context, name: meta.name, approvedAt: meta.approvedAt }).then((outcome) => {
3221
3295
  run.running = false;
3222
3296
  run.ok = outcome.ok;
3223
3297
  if (outcome.summary || outcome.issues?.length) {
@@ -3348,7 +3422,7 @@ function html(roster) {
3348
3422
  <script>
3349
3423
  const STAGES=${JSON.stringify(STAGES)};const ROSTER=${JSON.stringify(roster)};
3350
3424
  const SANDBOX=${JSON.stringify(Object.keys(SANDBOX_ALLOWLIST))};const POWERED=${JSON.stringify(Object.keys(STAGE_SPECS).map(Number))};
3351
- const GATES=${JSON.stringify(HUMAN_GATE_STAGES)};
3425
+ const GATES=${JSON.stringify(HUMAN_GATE_STAGES)};const PROTECTED=${JSON.stringify(PROTECTED_LOCATIONS)};
3352
3426
  const TYPES=["client","sandbox","template","hidden"];
3353
3427
  const NEXT={pending:"in_progress",in_progress:"done",done:"pending"};
3354
3428
  let polling=false,query="",showParked=false,showNew=false,snapshots=null;
@@ -3396,7 +3470,18 @@ function intakePanel(){const d=document.createElement("div");d.className="ncform
3396
3470
  reset.onclick=()=>{if(confirm("Remove all your customizations and go back to the base question set?"))saveOverlay({})};
3397
3471
  d.appendChild(reset);
3398
3472
  return d}
3399
- let iOpen={},iData={},iMode={},iAnswers={},iIdx={},iPre={},iSub={};
3473
+ let iOpen={},iData={},iMode={},iAnswers={},iIdx={},iPre={},iSub={},oOpen={};
3474
+ function outcomePanel(id,i,state){const oc=(state.outcomes||{})[id+":"+i];if(!oc)return null;
3475
+ const d=document.createElement("div");d.className="ipanel";d.style.borderColor="#e0a75e";
3476
+ d.innerHTML="<h3>"+STAGES[i]+" \u2014 what came back</h3>";
3477
+ if(oc.summary){const p=document.createElement("p");p.style.cssText="font-size:.88rem;margin:.3rem 0 .5rem";p.textContent=oc.summary;d.appendChild(p)}
3478
+ for(const iss of (oc.issues||[])){const g=document.createElement("div");g.className="pendpanel";g.style.margin=".3rem 0";
3479
+ g.textContent="\u26A0 "+iss;d.appendChild(g)}
3480
+ const when=document.createElement("p");when.style.cssText="font-size:.72rem;color:#8a90a3;margin:.5rem 0 0";
3481
+ when.textContent="Checked "+new Date(oc.at).toLocaleString();d.appendChild(when);
3482
+ const x=document.createElement("button");x.className="intakebtn";x.style.marginTop=".5rem";x.textContent="Close";
3483
+ x.onclick=()=>{oOpen[id+":"+i]=false;render(lastState,lastRun)};d.appendChild(x);
3484
+ return d}
3400
3485
  async function iLoad(id){const r=await(await fetch("/api/client-intake?locationId="+id)).json();iData[id]=r;
3401
3486
  if(r.ok&&!iAnswers[id]){iAnswers[id]={}}render(lastState,lastRun)}
3402
3487
  function iField(id,q,val,prefilled){const w=document.createElement("div");w.className="ifield"+(prefilled?" prefilled":"");
@@ -3414,7 +3499,7 @@ function intakeWorkspace(id,name){const d=iData[id];const box=document.createEle
3414
3499
  if(!d.ok){box.innerHTML="<h3>Intake</h3><p style='font-size:.85rem;color:#b45309'>"+d.error+"</p>";return box}
3415
3500
  box.innerHTML="<h3>Intake for "+name+"</h3>";
3416
3501
  const sub=document.createElement("p");sub.style.cssText="margin:.1rem 0 .2rem;font-size:.8rem;color:#6b7280";
3417
- sub.textContent=d.status==="received"?("Answers received"+(d.answeredAt?" ("+new Date(d.answeredAt).toLocaleDateString()+")":"")):d.status==="sent"?"Link sent \u2014 waiting on the client":"Ready to complete";
3502
+ sub.textContent=d.status==="received"?((d.channel==="form"?"Submitted through the GHL form":"Saved from the cockpit")+(d.answeredAt?" \xB7 "+new Date(d.answeredAt).toLocaleString():"")):d.status==="sent"?"Link sent \u2014 waiting on the client":"Ready to complete";
3418
3503
  box.appendChild(sub);
3419
3504
  const ch=document.createElement("div");ch.className="ichoice";
3420
3505
  const modes=[["fill","Fill it here"],["interview","Interview mode"],["transcript","From a call"],["send","Send to client"],["link","Copy link"]];
@@ -3491,11 +3576,27 @@ function intakeWorkspace(id,name){const d=iData[id];const box=document.createEle
3491
3576
  for(const q of qs){if(q.sectionLabel!==lastSec){lastSec=q.sectionLabel;const h=document.createElement("p");
3492
3577
  h.style.cssText="margin:.8rem 0 .1rem;font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;color:#8a90a3";h.textContent=lastSec;box.appendChild(h)}
3493
3578
  box.appendChild(iField(id,q,ans[q.label],pre.includes(q.label)))}
3494
- const save=document.createElement("button");save.className="runbtn";save.style.marginTop=".8rem";save.textContent="Save intake to GHL";
3495
- save.onclick=async()=>{save.disabled=true;save.textContent="Saving\u2026";
3579
+ const save=document.createElement("button");save.className="runbtn";save.style.marginTop=".8rem";
3580
+ save.textContent="Review & submit the real form \u2192";
3581
+ save.title="Opens this client's actual GHL form with every answer filled in. One click submits it, so it lands as a genuine form submission.";
3582
+ save.onclick=async()=>{save.disabled=true;save.textContent="Preparing the form\u2026";
3583
+ const r=await(await fetch("/api/intake-prefill-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({locationId:id,answers:iAnswers[id]||{},contact:{firstName:(iAnswers[id]||{})["Business Name"]||name}})})).json();
3584
+ save.disabled=false;save.textContent="Review & submit the real form \u2192";
3585
+ if(!r.ok){alert(r.error);return}
3586
+ window.open(r.url,"_blank");
3587
+ const hint=document.createElement("p");hint.style.cssText="font-size:.8rem;color:#6b7280;margin:.5rem 0 0";
3588
+ hint.textContent="The form opened in a new tab with your answers filled in. Click Submit there \u2014 then come back and press Refresh.";
3589
+ box.appendChild(hint);
3590
+ const rf=document.createElement("button");rf.className="intakebtn";rf.style.marginTop=".4rem";rf.textContent="Refresh status";
3591
+ rf.onclick=()=>iLoad(id);box.appendChild(rf)};
3592
+ box.appendChild(save);
3593
+ const alt=document.createElement("button");alt.className="intakebtn";alt.style.cssText="margin-top:.8rem;margin-left:.5rem";
3594
+ alt.textContent="Save without submitting";
3595
+ alt.title="Stores the answers on a tagged contact only \u2014 no form submission.";
3596
+ alt.onclick=async()=>{alt.disabled=true;alt.textContent="Saving\u2026";
3496
3597
  const r=await(await fetch("/api/intake-submit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({locationId:id,answers:iAnswers[id]||{},contact:{firstName:(iAnswers[id]||{})["Business Name"]||name}})})).json();
3497
- if(r.ok){iMode[id]=null;iPre[id]=[];await iLoad(id)}else{alert(r.error);save.disabled=false;save.textContent="Save intake to GHL"}};
3498
- box.appendChild(save)}}
3598
+ if(r.ok){iMode[id]=null;iPre[id]=[];await iLoad(id)}else{alert(r.error);alt.disabled=false;alt.textContent="Save without submitting"}};
3599
+ box.appendChild(alt)}}
3499
3600
  return box}
3500
3601
  let rOpen={},rData={};
3501
3602
  async function rLoad(id){const r=await(await fetch("/api/review?locationId="+id)).json();rData[id]=r;render(lastState,lastRun)}
@@ -3600,17 +3701,37 @@ function card(c,state,run){const st=(state.clients[c.locationId]||{stages:STAGES
3600
3701
  if(gate)el.title=gate;
3601
3702
  const oc=(state.outcomes||{})[c.locationId+":"+i];
3602
3703
  if(oc&&(oc.summary||(oc.issues||[]).length)){const note=document.createElement("small");
3603
- note.style.cssText="display:block;margin-top:.25rem;color:"+((oc.issues||[]).length?"#b45309":"#16a34a")+";font-size:.66rem;line-height:1.25";
3604
- note.textContent=(oc.issues||[]).length?("\u26A0 "+oc.issues.length+" issue"+(oc.issues.length>1?"s":"")):(oc.summary||"").slice(0,90);
3605
- note.title=((oc.issues||[]).join(" \xB7 ")||oc.summary||"");el.appendChild(note)}
3704
+ const nIss=(oc.issues||[]).length;
3705
+ note.style.cssText="display:block;margin-top:.25rem;color:"+(nIss?"#b45309":"#16a34a")+";font-size:.66rem;line-height:1.25;text-decoration:"+(nIss?"underline":"none")+";cursor:"+(nIss?"pointer":"default");
3706
+ note.textContent=nIss?("\u26A0 "+nIss+" issue"+(nIss>1?"s":"")+" \u2014 see details"):(oc.summary||"").slice(0,90);
3707
+ if(nIss)note.onclick=(ev)=>{ev.stopPropagation();oOpen[c.locationId+":"+i]=!oOpen[c.locationId+":"+i];render(lastState,lastRun)};
3708
+ el.appendChild(note)}
3606
3709
  el.onclick=async()=>{await fetch("/api/stage",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({locationId:c.locationId,stage:i,status:NEXT[st[i]||"pending"]})});load()};
3607
- if(sandbox&&POWERED.includes(i)){const b=document.createElement("button");b.className="runbtn";
3710
+ const canBuild=sandbox||Boolean((state.buildApproved||{})[c.locationId]);
3711
+ if(canBuild&&POWERED.includes(i)){const b=document.createElement("button");b.className="runbtn";
3608
3712
  const busy=run&&run.running;b.textContent=busy&&run.locationId===c.locationId&&run.stage===i?"Running\u2026":"Run \u25B6";
3609
3713
  b.disabled=Boolean(busy);
3610
3714
  b.onclick=async(ev)=>{ev.stopPropagation();const res=await fetch("/api/run",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({locationId:c.locationId,stage:i})});const j=await res.json();if(!j.ok)alert(j.error);load()};
3611
3715
  el.appendChild(document.createElement("br"));el.appendChild(b)}
3612
3716
  row.appendChild(el)});
3613
3717
  div.appendChild(row);
3718
+ for(let i=0;i<STAGES.length;i++){if(oOpen[c.locationId+":"+i]){const op=outcomePanel(c.locationId,i,state);if(op)div.appendChild(op)}}
3719
+ const _prot=PROTECTED[c.locationId];
3720
+ const _appr=(state.buildApproved||{})[c.locationId];
3721
+ if(!sandbox){const ab=document.createElement("div");ab.style.cssText="margin-top:.55rem;font-size:.78rem";
3722
+ if(_prot){ab.innerHTML='<span class="istatus" style="background:#fdecec;color:#b33">PROTECTED</span> <span style="color:#6b7280">'+_prot+' \u2014 builds refused here.</span>'}
3723
+ else if(_appr){const s1=document.createElement("span");s1.className="istatus received";s1.textContent="APPROVED FOR BUILDING";
3724
+ const rv=document.createElement("button");rv.className="qdel";rv.style.marginLeft=".5rem";rv.textContent="revoke";
3725
+ rv.onclick=async()=>{await fetch("/api/build-approval",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({locationId:c.locationId,revoke:true})});load()};
3726
+ ab.appendChild(s1);ab.appendChild(rv)}
3727
+ else{const w=document.createElement("span");w.style.color="#6b7280";w.textContent="Automated building is off for this client. ";
3728
+ const btn=document.createElement("button");btn.className="intakebtn";btn.style.padding=".25rem .55rem";btn.textContent="Approve building\u2026";
3729
+ btn.onclick=async()=>{const typed=prompt('This lets Command OS write into "'+c.name+'" \u2014 a real client account.'+String.fromCharCode(10,10)+'Type the client name exactly to confirm:');
3730
+ if(typed===null)return;
3731
+ const r=await(await fetch("/api/build-approval",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({locationId:c.locationId,confirmName:typed})})).json();
3732
+ if(!r.ok)alert(r.error);load()};
3733
+ ab.appendChild(w);ab.appendChild(btn)}
3734
+ div.appendChild(ab)}
3614
3735
  const _intakeIn=(iData[c.locationId]&&iData[c.locationId].status==="received");
3615
3736
  if(_intakeIn||st[1]==="done"||st[2]==="done"||(rData[c.locationId]&&rData[c.locationId].ok)){
3616
3737
  const rr=document.createElement("div");rr.style.cssText="margin-top:.5rem";
@@ -3625,7 +3746,8 @@ function card(c,state,run){const st=(state.clients[c.locationId]||{stages:STAGES
3625
3746
  ir.appendChild(ib2);
3626
3747
  const dd=iData[c.locationId];
3627
3748
  if(dd&&dd.ok){const chip=document.createElement("span");chip.className="istatus "+dd.status;
3628
- chip.textContent=dd.status==="received"?"ANSWERS IN":dd.status==="sent"?"SENT":"NOT STARTED";ir.appendChild(chip)}
3749
+ chip.textContent=dd.status==="received"?("ANSWERS IN"+(dd.channel==="form"?" \xB7 FORM":dd.channel==="cockpit"?" \xB7 SAVED HERE":"")):dd.status==="sent"?"SENT":"NOT STARTED";
3750
+ chip.title=dd.channel==="form"?"A real form submission \u2014 visible in GHL's Submissions and re-readable later.":dd.channel==="cockpit"?"Saved from the cockpit onto a tagged contact (no form submission).":"";ir.appendChild(chip)}
3629
3751
  div.appendChild(ir);
3630
3752
  if(iOpen[c.locationId])div.appendChild(intakeWorkspace(c.locationId,c.name))}
3631
3753
  if(run&&run.locationId===c.locationId&&run.lines&&run.lines.length){const log=document.createElement("div");log.className="runlog";
@@ -3677,12 +3799,12 @@ async function runDashboard(argv) {
3677
3799
  `);
3678
3800
  return 0;
3679
3801
  }
3680
- const gate = await resolvePlan2(readCredentials());
3681
- if ("error" in gate) {
3682
- notify(gate.error);
3802
+ const gate2 = await resolvePlan2(readCredentials());
3803
+ if ("error" in gate2) {
3804
+ notify(gate2.error);
3683
3805
  return 3;
3684
3806
  }
3685
- if (gate.plan !== "command-os") {
3807
+ if (gate2.plan !== "command-os") {
3686
3808
  notify(UPGRADE_MSG.trim());
3687
3809
  return 3;
3688
3810
  }
@@ -3775,7 +3897,12 @@ async function runDashboard(argv) {
3775
3897
  try {
3776
3898
  const { locationId: locationId2, stage } = JSON.parse(body);
3777
3899
  if (activeRun?.running) throw new Error("a run is already in progress");
3778
- if (!SANDBOX_ALLOWLIST[locationId2]) throw new Error("powered stages run only on sandbox accounts (MCP Testing / Blueprint Demo)");
3900
+ const st0 = readCockpitState();
3901
+ const perm = buildPermission(locationId2, {
3902
+ name: currentRoster().find((r) => r.locationId === locationId2)?.name,
3903
+ approvedAt: st0.buildApproved?.[locationId2]
3904
+ });
3905
+ if (!perm.allowed) throw new Error(perm.reason);
3779
3906
  if (!STAGE_SPECS[stage]) {
3780
3907
  throw new Error(HUMAN_GATE_STAGES[stage] ? `That stage is a human step: ${HUMAN_GATE_STAGES[stage]}. Click it to mark it done when you have.` : "this stage is not powered yet");
3781
3908
  }
@@ -3785,7 +3912,7 @@ async function runDashboard(argv) {
3785
3912
  startRun(locationId2, stage, (ok) => {
3786
3913
  writeCockpitState(setStage(readCockpitState(), locationId2, stage, ok ? "done" : "pending"));
3787
3914
  pushShared(locationId2);
3788
- });
3915
+ }, { name: currentRoster().find((r) => r.locationId === locationId2)?.name, approvedAt: st0.buildApproved?.[locationId2] });
3789
3916
  pushShared(locationId2);
3790
3917
  res.writeHead(200, { "Content-Type": "application/json" });
3791
3918
  res.end(JSON.stringify({ ok: true }));
@@ -3850,6 +3977,28 @@ async function runDashboard(argv) {
3850
3977
  })();
3851
3978
  return;
3852
3979
  }
3980
+ if (req.method === "POST" && url === "/api/intake-prefill-url") {
3981
+ let body = "";
3982
+ req.on("data", (c) => {
3983
+ body += c;
3984
+ if (body.length > 2e5) req.destroy();
3985
+ });
3986
+ req.on("end", async () => {
3987
+ try {
3988
+ const args = JSON.parse(body);
3989
+ const c = clientFor(args.locationId);
3990
+ if (!c) throw new Error("this client isn't connected yet");
3991
+ const snap = await readIntakeSnapshot(c, args.locationId, false);
3992
+ if (!snap.formId || !snap.formUrl) throw new Error("run the Intake stage first \u2014 there's no form yet");
3993
+ res.writeHead(200, { "Content-Type": "application/json" });
3994
+ res.end(JSON.stringify({ ok: true, url: prefilledFormUrl(snap.formUrl, snap.queryKeys, args.answers ?? {}, args.contact ?? {}) }));
3995
+ } catch (e) {
3996
+ res.writeHead(400, { "Content-Type": "application/json" });
3997
+ res.end(JSON.stringify({ ok: false, error: e instanceof Error ? e.message : "failed" }));
3998
+ }
3999
+ });
4000
+ return;
4001
+ }
3853
4002
  if (req.method === "POST" && (url === "/api/intake-submit" || url === "/api/intake-send" || url === "/api/intake-prefill")) {
3854
4003
  let body = "";
3855
4004
  req.on("data", (c) => {
@@ -3950,6 +4099,37 @@ async function runDashboard(argv) {
3950
4099
  res.end(JSON.stringify(readCockpitState().reviews?.[locationId2] ?? { ok: false, error: "not generated yet" }));
3951
4100
  return;
3952
4101
  }
4102
+ if (req.method === "POST" && url === "/api/build-approval") {
4103
+ let body = "";
4104
+ req.on("data", (c) => {
4105
+ body += c;
4106
+ if (body.length > 5e3) req.destroy();
4107
+ });
4108
+ req.on("end", () => {
4109
+ try {
4110
+ const { locationId: locationId2, confirmName, revoke } = JSON.parse(body);
4111
+ const entry = currentRoster().find((r) => r.locationId === locationId2);
4112
+ if (!entry) throw new Error("unknown client");
4113
+ if (PROTECTED_LOCATIONS[locationId2]) throw new Error(PROTECTED_LOCATIONS[locationId2] + " can never be approved for building.");
4114
+ const st = readCockpitState();
4115
+ const approved = { ...st.buildApproved ?? {} };
4116
+ if (revoke) delete approved[locationId2];
4117
+ else {
4118
+ if (String(confirmName || "").trim().toLowerCase() !== entry.name.trim().toLowerCase()) {
4119
+ throw new Error(`Type the client's name exactly ("${entry.name}") to approve automated building.`);
4120
+ }
4121
+ approved[locationId2] = (/* @__PURE__ */ new Date()).toISOString();
4122
+ }
4123
+ writeCockpitState({ ...st, buildApproved: approved });
4124
+ res.writeHead(200, { "Content-Type": "application/json" });
4125
+ res.end(JSON.stringify({ ok: true }));
4126
+ } catch (e) {
4127
+ res.writeHead(400, { "Content-Type": "application/json" });
4128
+ res.end(JSON.stringify({ ok: false, error: e instanceof Error ? e.message : "bad request" }));
4129
+ }
4130
+ });
4131
+ return;
4132
+ }
3953
4133
  if (req.method === "POST" && url === "/api/branding") {
3954
4134
  let body = "";
3955
4135
  req.on("data", (c) => {
@@ -3988,9 +4168,9 @@ async function runDashboard(argv) {
3988
4168
  const answers = {};
3989
4169
  if (hit) {
3990
4170
  const full = await c.get(`/contacts/${hit.id}`);
3991
- const byId = Object.fromEntries(Object.entries(snap.fields).map(([label, id]) => [id, label]));
4171
+ const byId2 = Object.fromEntries(Object.entries(snap.fields).map(([label, id]) => [id, label]));
3992
4172
  for (const f of full.contact?.customFields ?? []) {
3993
- const label = byId[f.id];
4173
+ const label = byId2[f.id];
3994
4174
  if (label && f.value != null && String(f.value).trim()) answers[label] = String(f.value);
3995
4175
  }
3996
4176
  }
@@ -4776,7 +4956,7 @@ function getStringArray(value) {
4776
4956
  return value;
4777
4957
  }
4778
4958
  function validateActionChain(actions, existingIds) {
4779
- const byId = new Map(actions.filter(hasId).map((action) => [action.id, action]));
4959
+ const byId2 = new Map(actions.filter(hasId).map((action) => [action.id, action]));
4780
4960
  for (const action of actions) {
4781
4961
  const attr = isRecord(action.attributes) ? action.attributes : void 0;
4782
4962
  if (!attr) continue;
@@ -4830,8 +5010,8 @@ function validateActionChain(actions, existingIds) {
4830
5010
  const next = getStringArray(action.next);
4831
5011
  if (!action.id) throw new Error(`If/else condition node "${action.name}" missing id.`);
4832
5012
  if (!next || next.length !== 2) throw new Error(`If/else condition node "${action.name}" must have next as exactly [yesBranchId, noBranchId].`);
4833
- const yes = byId.get(next[0]);
4834
- const no = byId.get(next[1]);
5013
+ const yes = byId2.get(next[0]);
5014
+ const no = byId2.get(next[1]);
4835
5015
  if (!yes || yes.nodeType !== "branch-yes") throw new Error(`If/else condition node "${action.name}" next[0] must reference a branch-yes node.`);
4836
5016
  if (!no || no.nodeType !== "branch-no") throw new Error(`If/else condition node "${action.name}" next[1] must reference a branch-no node.`);
4837
5017
  if (yes.parent !== action.id || yes.parentKey !== action.id) throw new Error(`Branch-yes "${yes.name}" must have parent and parentKey set to condition node "${action.id}".`);
@@ -4856,7 +5036,7 @@ function validateActionChain(actions, existingIds) {
4856
5036
  throw new Error(`find_opportunity "${action.name}" must have next as exactly [foundTransitionId, notFoundTransitionId].`);
4857
5037
  }
4858
5038
  for (const tid of next) {
4859
- const t = byId.get(tid);
5039
+ const t = byId2.get(tid);
4860
5040
  if (!t || t.type !== "transition") {
4861
5041
  throw new Error(`find_opportunity "${action.name}" next must reference its two transition nodes.`);
4862
5042
  }
@@ -4865,7 +5045,7 @@ function validateActionChain(actions, existingIds) {
4865
5045
  }
4866
5046
  const firstChildId = typeof t.next === "string" ? t.next : void 0;
4867
5047
  if (firstChildId) {
4868
- const c = byId.get(firstChildId);
5048
+ const c = byId2.get(firstChildId);
4869
5049
  if (!c || c.parent !== tid || c.parentKey !== tid) {
4870
5050
  throw new Error(`First child of transition "${t.name}" must have parent and parentKey set to the transition id.`);
4871
5051
  }
@@ -9736,8 +9916,8 @@ ${text2}`);
9736
9916
  for (const sec of sections) {
9737
9917
  const bg = sec.metaData?.extra?.bgImage?.value;
9738
9918
  if (bg && bg.mediaType === "video" && bg.videoUrl) videoBackground = true;
9739
- const elements = Array.isArray(sec.elements) ? sec.elements : [];
9740
- for (const el of elements) {
9919
+ const elements2 = Array.isArray(sec.elements) ? sec.elements : [];
9920
+ for (const el of elements2) {
9741
9921
  if (el.type !== "element") continue;
9742
9922
  const meta = typeof el.meta === "string" ? el.meta : null;
9743
9923
  if (!meta) continue;
@@ -9774,7 +9954,7 @@ ${await response.text()}`);
9774
9954
  }
9775
9955
  server2.tool(
9776
9956
  "update_page_content",
9777
- "Update a funnel/website page's builder content \u2014 sections, elements, settings, pageStyles, trackingCode, popups, popupsList, fontsForPreview. Use get_page_content first to see the current structure, modify it, then pass the full envelope here. Writes via GHL's builder autosave: the server uploads the page to storage, bumps the version, and regenerates the preview snapshot, then returns the new pageDataUrl. The funnelId and current version are resolved automatically from the page. Saves as a draft unless isPublished is true.",
9957
+ "Update a funnel/website page's builder content \u2014 sections, elements, settings, pageStyles, trackingCode, popups, popupsList, fontsForPreview. Use get_page_content first to see the current structure, modify it, then pass the full envelope here. Writes via GHL's builder autosave and returns the new pageDataUrl. \u26A0\uFE0F RELIABLE ONLY AS THE FIRST SAVE ONTO A PAGE: live testing (2026-07-28) shows GHL accepts later saves but may never make them the visible version. For a page that already has content, verify with get_page_full afterward that pageDataUrl actually changed; if it did not, rebuild on a fresh step (create_funnel_page) instead. Saves as a draft unless isPublished is true.",
9778
9958
  {
9779
9959
  pageId: import_zod34.z.string().describe("The page ID to update."),
9780
9960
  content: import_zod34.z.record(import_zod34.z.unknown()).describe("The full page content JSON \u2014 the 8-field envelope: sections, settings, general, pageStyles, trackingCode, fontsForPreview, popups, popupsList. Start from get_page_content and modify it."),
@@ -9793,7 +9973,9 @@ ${await response.text()}`);
9793
9973
  if (!resolvedFunnelId) {
9794
9974
  throw new Error(`Could not resolve funnelId for page ${pageId}. Pass funnelId explicitly.`);
9795
9975
  }
9796
- const pageVersion = typeof meta.pageVersion === "number" ? meta.pageVersion : typeof meta.version === "number" ? meta.version : 1;
9976
+ const livePageVersion = typeof meta.pageVersion === "number" ? meta.pageVersion : typeof meta.version === "number" ? meta.version : 1;
9977
+ const hasExistingContent = typeof meta.pageDataDownloadUrl === "string" && meta.pageDataDownloadUrl.length > 0;
9978
+ const pageVersion = hasExistingContent ? livePageVersion + 1 : livePageVersion;
9797
9979
  const pageData = {
9798
9980
  ...content,
9799
9981
  pageVersion,
@@ -9831,8 +10013,901 @@ ${await response.text()}`);
9831
10013
  );
9832
10014
  }
9833
10015
 
9834
- // src/tools/form-builder.ts
10016
+ // src/tools/page-studio.ts
9835
10017
  var import_zod35 = require("zod");
10018
+
10019
+ // src/page-studio/theme.ts
10020
+ var DONOR_COLOR_SLOTS = [
10021
+ { hex: "#ec606a", slot: "primary" },
10022
+ { hex: "#f49ca2", slot: "primarySoft" },
10023
+ { hex: "#e9c7c1", slot: "primarySoft" },
10024
+ { hex: "#f3f3f3", slot: "surface" },
10025
+ { hex: "#434445", slot: "textDark" }
10026
+ ];
10027
+ var DONOR_HEADING_FONT = "Oswald";
10028
+ var DONOR_BODY_FONT = "Lato";
10029
+ function escapeRegExp(s) {
10030
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
10031
+ }
10032
+ function replaceHex(text, fromHex, toHex) {
10033
+ const re = new RegExp(escapeRegExp(fromHex), "gi");
10034
+ return text.replace(re, toHex);
10035
+ }
10036
+ function replaceFont(text, fromName, toName) {
10037
+ const fromSlug = fromName.toLowerCase().replace(/[^a-z0-9]+/g, "-");
10038
+ const toSlug = toName.toLowerCase().replace(/[^a-z0-9]+/g, "-");
10039
+ let out = text.replace(new RegExp(`--${escapeRegExp(fromSlug)}\\b`, "g"), `--${toSlug}`);
10040
+ out = out.replace(new RegExp(`(?<![A-Za-z0-9])${escapeRegExp(fromName)}(?![A-Za-z0-9])`, "g"), toName);
10041
+ return out;
10042
+ }
10043
+ function applyTheme(envelope, theme) {
10044
+ for (const font of [theme.headingFont, theme.bodyFont]) {
10045
+ if (font !== void 0 && !/^[A-Za-z0-9 ]{2,40}$/.test(font)) {
10046
+ throw new Error(`Invalid font name ${JSON.stringify(font)} \u2014 use a plain Google Fonts name (letters, digits, spaces).`);
10047
+ }
10048
+ }
10049
+ let text = JSON.stringify(envelope);
10050
+ for (const { hex, slot } of DONOR_COLOR_SLOTS) {
10051
+ const to = theme[slot];
10052
+ if (typeof to === "string" && /^#[0-9a-fA-F]{6}$/.test(to)) {
10053
+ text = replaceHex(text, hex, to);
10054
+ }
10055
+ }
10056
+ if (theme.headingFont && theme.headingFont !== DONOR_HEADING_FONT) {
10057
+ text = replaceFont(text, DONOR_HEADING_FONT, theme.headingFont);
10058
+ }
10059
+ if (theme.bodyFont && theme.bodyFont !== DONOR_BODY_FONT) {
10060
+ text = replaceFont(text, DONOR_BODY_FONT, theme.bodyFont);
10061
+ }
10062
+ return JSON.parse(text);
10063
+ }
10064
+ function themedFonts(theme) {
10065
+ return [
10066
+ `'${theme.bodyFont ?? DONOR_BODY_FONT}'`,
10067
+ `'${theme.headingFont ?? DONOR_HEADING_FONT}'`
10068
+ ];
10069
+ }
10070
+ function assertFontMatrixComplete(envelope, theme) {
10071
+ const problems = [];
10072
+ const text = JSON.stringify(envelope);
10073
+ if (theme.headingFont && theme.headingFont !== DONOR_HEADING_FONT && /(?<![A-Za-z0-9])Oswald(?![A-Za-z0-9])/.test(text)) {
10074
+ problems.push("donor heading font 'Oswald' still present after theming");
10075
+ }
10076
+ if (theme.bodyFont && theme.bodyFont !== DONOR_BODY_FONT && /(?<![A-Za-z0-9])Lato(?![A-Za-z0-9])/.test(text)) {
10077
+ problems.push("donor body font 'Lato' still present after theming");
10078
+ }
10079
+ return problems;
10080
+ }
10081
+
10082
+ // src/page-studio/donor-sections.json
10083
+ var donor_sections_default = { extractedAt: "2026-07-28", source: "templates/captured/medspa-reference (Med Spa Template Gc2kgDDpABIR8QDyJ6rf, read-only capture)", sections: { topbar: { id: "section-5koSt0KcJ", metaData: { id: "section-5koSt0KcJ", type: "section", child: ["row-Sj_71z4FVM"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: "10" }, paddingTop: { unit: "px", value: "10" }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, allowRowMaxWidth: { value: false } }, wrapper: {}, meta: "section", tagName: "c-section", title: "Top Header", _id: "section-5koSt0KcJ", isGlobal: true }, elements: [{ id: "row-Sj_71z4FVM", type: "row", child: ["col-57vCrX5BdC", "col-ontI0QwDAK", "col-fwzCuhI_RQ"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: "0" }, paddingBottom: { unit: "px", value: "0" }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, rowWidth: { value: 100, unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-row", meta: "row", title: "5 Column Row" }, { id: "col-57vCrX5BdC", type: "col", child: ["paragraph-jL-pjux8a"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: "0" }, paddingRight: { value: "0", unit: "px" }, paddingTop: { unit: "px", value: "10" }, paddingBottom: { unit: "px", value: "10" }, backgroundColor: { value: "var(--transparent)" }, width: { value: 24.4, unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "2nd Column" }, { extra: { nodeId: "cparagraph-jL-pjux8a", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p><strong>{{location.phone}}</strong></p>" }, mobileFontSize: { value: 14, unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--my-custom-color-44)" }, boldTextColor: { value: "var(--my-custom-color-44)" }, italicTextColor: { value: "var(--my-custom-color-44)" }, underlineTextColor: { value: "var(--my-custom-color-44)" }, linkTextColor: { value: "var(--my-custom-color-44)" }, iconColor: { value: "var(--my-custom-color-44)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: "60" }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: "1.5", unit: "em" }, textTransform: { value: "none" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-jL-pjux8a", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p", mobileStyles: { textAlign: { value: "center" }, paddingLeft: { unit: "px", value: 0 } } }, { id: "col-ontI0QwDAK", type: "col", child: ["image-YGGYHGoZw"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: 55.2, unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "center" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "3rd Column" }, { extra: { nodeId: "cimage-YGGYHGoZw", visibility: { value: { hideDesktop: false, hideMobile: false } }, imageActions: { value: "url" }, visitWebsite: { value: { url: "", newTab: false } }, imageProperties: { value: { width: null, height: "", url: "https://storage.googleapis.com/msgsndr/EVTjG29VnVlvwn3SRGve/media/fee997f8-92c7-4ee2-b0c1-3536b94b71a7.png", altText: "", compression: true, placeholderBase64: "", servingUrl: "", imageMeta: "" } } }, class: { imageRadius: { value: "img-none" }, imageBorder: { value: "img-border-none" }, imageShadow: { value: "img-shadow-none" }, imageEffects: { value: "img-effects-none" } }, styles: { paddingLeft: { unit: "px", value: 10 }, paddingRight: { value: 10, unit: "px" }, paddingTop: { unit: "px", value: "0" }, paddingBottom: { unit: "px", value: "0" }, backgroundColor: { value: "var(--transparent)" }, opacity: { value: "1" }, textAlign: { value: "center" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "image-YGGYHGoZw", type: "element", child: [], meta: "image", tagName: "c-image", title: "Image", tag: "" }, { id: "col-fwzCuhI_RQ", type: "col", child: ["social-icons-cjYa9pkQuv"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: "0" }, paddingRight: { value: "0", unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: 20.4, unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "5th Column" }, { extra: { nodeId: "csocial-icons-cjYa9pkQuv", socials: { value: [{ id: "facebook", label: "Facebook", link: "facebook.com", newWindow: true, nofollow: false, icon: "https://stcdn.leadconnectorhq.com/funnel/icons/brand/facebook-brand.svg" }, { id: "instagram", label: "Instagram", link: "instagram.com", newWindow: true, nofollow: false, icon: "https://stcdn.leadconnectorhq.com/funnel/icons/brand/instagram-brand.svg" }, { id: "youtube", label: "Youtube", link: "youtube.com", newWindow: true, nofollow: false, icon: "https://stcdn.leadconnectorhq.com/funnel/icons/brand/youtube-brand.svg" }] }, displayType: { value: "icon" }, theme: { value: "dark" }, align: { value: "right" }, iconSize: { value: { height: 20, width: 20 } }, customClass: { value: [] }, visibility: { value: { hideDesktop: false, hideMobile: false } } }, class: {}, styles: { fontFamily: { value: "Inter" }, fontSize: { value: 12, unit: "px" }, fontWeight: { value: 500, desktop: "Normal" }, color: { value: "#000000" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, paddingLeft: { unit: "px", value: 10 }, paddingRight: { value: 10, unit: "px" }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 } }, wrapper: {}, mobileStyles: {}, mobileWrapper: {}, mobileExtra: { align: { value: "center" } }, customCss: [], id: "social-icons-cjYa9pkQuv", version: 2, type: "element", child: [], meta: "social-icons", tagName: "c-social-icons", title: "Social Icons", tag: "" }], sequence: 0, pageId: "FYBFsBAezEtsY0uXW4IN", funnelId: "pK3yy9CFapchugRrgjgq", locationId: "Gc2kgDDpABIR8QDyJ6rf", isGlobal: true, general: { colors: [{ label: "Black", value: "#000000" }, { label: "Transparent", value: "transparent" }, { label: "my-custom-color-44", name: "My Custom Color 44", value: "#ec606a" }], fontsForPreview: ["'Lato'"], rootVars: { "--'lato'": "'Lato'", "--black": "#000000", "--transparent": "transparent", "--my-custom-color-44": "#ec606a" }, sectionStyles: ":root{--black:#000000;--transparent:transparent;--my-custom-color-44:#ec606a}.hl_page-preview--content .row-Sj_71z4FVM,.hl_page-preview--content .section-5koSt0KcJ{padding:10px 0;margin-top:0;margin-bottom:0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .row-Sj_71z4FVM{padding:0;width:100%}.hl_page-preview--content .col-57vCrX5BdC{width:24.4%}.hl_page-preview--content .col-57vCrX5BdC .inner,.hl_page-preview--content .col-fwzCuhI_RQ .inner,.hl_page-preview--content .col-ontI0QwDAK .inner{padding:10px 0;background-color:var(--transparent);width:24.4%;border-color:var(--black);border-width:2px;border-style:solid;margin-top:0;margin-bottom:0}.hl_page-preview--content .paragraph-jL-pjux8a{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-jL-pjux8a{font-family:var(--contentfont);background-color:var(--transparent);color:var(--my-custom-color-44);icon-color:var(--my-custom-color-44);font-weight:400;padding:0 0 0 60px;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.5em;text-transform:none;letter-spacing:0;text-align:left}@media screen and (min-width:0px) and (max-width:480px){.hl_page-preview--content .cparagraph-jL-pjux8a{text-align:center;padding-left:0}}.hl_page-preview--content .col-ontI0QwDAK{width:55.2%}.hl_page-preview--content .col-fwzCuhI_RQ .inner,.hl_page-preview--content .col-ontI0QwDAK .inner{padding:10px 5px;width:55.2%}.hl_page-preview--content .image-YGGYHGoZw{margin-top:0;margin-bottom:0}.hl_page-preview--content .cimage-YGGYHGoZw{padding:0 10px;background-color:var(--transparent);opacity:1;text-align:center}.hl_page-preview--content .col-fwzCuhI_RQ{width:20.4%}.hl_page-preview--content .col-fwzCuhI_RQ .inner{padding:10px 0;width:20.4%}.hl_page-preview--content .csocial-icons-cjYa9pkQuv{font-family:Inter;font-size:12px;font-weight:500;color:#000;padding:0 10px;margin:0}#section-5koSt0KcJ>.inner{max-width:1170px}#col-57vCrX5BdC>.inner{flex-direction:column;justify-content:center;align-items:inherit;flex-wrap:nowrap}.paragraph-jL-pjux8a{font-weight:undefined}.paragraph-jL-pjux8a em,.paragraph-jL-pjux8a strong,.paragraph-jL-pjux8a u{color:var(--my-custom-color-44)!important}.paragraph-jL-pjux8a a,.paragraph-jL-pjux8a a *{color:var(--my-custom-color-44)!important;text-decoration:none}.paragraph-jL-pjux8a a:hover{text-decoration:underline}@media screen and (min-width:0px) and (max-width:480px){.paragraph-jL-pjux8a h1,.paragraph-jL-pjux8a h2,.paragraph-jL-pjux8a h3,.paragraph-jL-pjux8a h4,.paragraph-jL-pjux8a h5,.paragraph-jL-pjux8a h6,.paragraph-jL-pjux8a ul li,.paragraph-jL-pjux8a.text-output{font-size:14px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-jL-pjux8a h1,.paragraph-jL-pjux8a h2,.paragraph-jL-pjux8a h3,.paragraph-jL-pjux8a h4,.paragraph-jL-pjux8a h5,.paragraph-jL-pjux8a h6,.paragraph-jL-pjux8a ul li,.paragraph-jL-pjux8a.text-output{font-size:16px!important;font-weight:undefined}}.paragraph-jL-pjux8a.text-output h1:first-child:before,.paragraph-jL-pjux8a.text-output h2:first-child:before,.paragraph-jL-pjux8a.text-output h3:first-child:before,.paragraph-jL-pjux8a.text-output h4:first-child:before,.paragraph-jL-pjux8a.text-output h5:first-child:before,.paragraph-jL-pjux8a.text-output h6:first-child:before,.paragraph-jL-pjux8a.text-output p:first-child:before{color:var(--my-custom-color-44);content:'\\';\n font-family: '';margin-right:5px;font-weight:700}#col-fwzCuhI_RQ>.inner,#col-ontI0QwDAK>.inner{flex-direction:column;justify-content:center;align-items:center;flex-wrap:nowrap}#col-fwzCuhI_RQ>.inner{align-items:inherit}#social-icons-cjYa9pkQuv .social-media-icon{height:20px;width:20px}#social-icons-cjYa9pkQuv .social-icons-container{justify-content:right}@media screen and (min-width:0px) and (max-width:480px){#social-icons-cjYa9pkQuv .social-icons-container{justify-content:center}}" } }, nav: { id: "section-O_4cMXt8V", metaData: { id: "section-O_4cMXt8V", type: "section", child: ["row-g-KFgj-Eth"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: "5" }, paddingTop: { unit: "px", value: "5" }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: "0" }, backgroundColor: { value: "var(--my-custom-color-44)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, allowRowMaxWidth: { value: false } }, wrapper: {}, meta: "section", tagName: "c-section", title: "Menu", _id: "section-O_4cMXt8V", isGlobal: true }, elements: [{ id: "row-g-KFgj-Eth", type: "row", child: ["col-u_bfKNLdt"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: "0" }, paddingBottom: { unit: "px", value: "0" }, backgroundColor: { value: "var(--my-custom-color-44)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, rowWidth: { value: 100, unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-row", meta: "row", title: "1 Column Row" }, { id: "col-u_bfKNLdt", type: "col", child: ["nav-menu-GPHNpOf5K"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: "0" }, paddingBottom: { unit: "px", value: "0" }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cnav-menu-GPHNpOf5K", visibility: { value: { hideDesktop: false, hideMobile: false } }, menuItems: { value: [{ id: "1", title: "Home", goTo: "go-to-funnel-step", url: "#home", goToId: "23f58e5f-0c70-43a8-b701-f4cb62e7a18f", openInNewTab: false, childs: [] }, { id: "2", title: "About", goTo: "go-to-funnel-step", url: "#about", goToId: "2b70293b-67cb-4f49-92bf-19d1513f14fc", openInNewTab: false, childs: [] }, { id: "menu-item-ld0VCcost", title: "Team", goTo: "url", url: "https://app.leadconnectorhq.com/v2/preview/WcJKBDYHBY2lXZHxN2EE#section-X3v76b5TI", goToId: "51741192-a852-4f8e-b136-2e1585f3181c", openInNewTab: false, childs: [] }, { id: "menu-item-muKlH7cA3", title: "Services", goTo: "go-to-funnel-step", url: "#new-menu-item", goToId: "b7c6d34d-f3d8-4ed9-8cf7-a66f5cf734e9", openInNewTab: false, childs: [] }, { id: "menu-item-DSPApGpQ5y", title: "FAQs", goTo: "url", url: "https://app.leadconnectorhq.com/v2/preview/WcJKBDYHBY2lXZHxN2EE#section-zJJ17L55C_", goToId: "", openInNewTab: false, childs: [] }, { id: "3", title: "Contacts", goTo: "url", url: "https://app.leadconnectorhq.com/v2/preview/WcJKBDYHBY2lXZHxN2EE#section-k4A5oCSjW", goToId: "18bcb00f-1151-4ae8-9852-45e1a803439b", openInNewTab: false, childs: [] }] }, mobileFontSize: { value: "18", unit: "px" }, desktopFontSize: { value: "18", unit: "px" }, typography: { value: "var(--headlinefont)" }, icon: { value: { name: "bars", unicode: "f0c9", fontFamily: "Font Awesome 5 Free", color: "var(--black)" } }, text: { value: "<p><strong>Business Name</strong></p>" }, imageProperties: { value: { width: "100px", height: "100px", url: "https://via.placeholder.com/100x100.png?text=Put your image", altText: "Brand Logo" } }, includeLogoInMenu: { value: false }, imageActions: { value: "none" }, visitWebsite: { value: { url: "", newTab: false } }, includeHeadlineInMenu: { value: false }, menuLayout: { value: "reverse" } }, class: { borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, marginTop: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--white)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, iconColor: { value: "var(--white)" }, secondaryColor: { value: "var(--white)" }, navMenuItemHoverBackgroundColor: { value: "var(--)" }, lineHeight: { value: "3.8", unit: "em" }, textTransform: { value: "uppercase" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "center" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, navMenuItemSpacingX: { value: "24", unit: "px" }, navMenuItemSpacingY: { value: "0", unit: "px" }, dropdownBackground: { value: "var(--my-custom-color-44)" }, dropdownTextColor: { value: "var(--white)" }, dropdownHoverColor: { value: "var(--white)" }, dropdownItemSpacing: { value: 10, unit: "px" } }, wrapper: {}, customCss: [], id: "nav-menu-GPHNpOf5K", type: "element", child: [], meta: "nav-menu", tagName: "c-nav-menu", title: "Navigation Menu", tag: "" }], sequence: 1, pageId: "FYBFsBAezEtsY0uXW4IN", funnelId: "pK3yy9CFapchugRrgjgq", locationId: "Gc2kgDDpABIR8QDyJ6rf", isGlobal: true, general: { colors: [{ label: "White", value: "#ffffff" }, { label: "Black", value: "#000000" }, { label: "Transparent", value: "transparent" }, { label: "my-custom-color-44", name: "My Custom Color 44", value: "#ec606a" }, { name: "", value: "#fff6", label: "" }], fontsForPreview: ["'Oswald'"], rootVars: { "--'oswald'": "'Oswald'", "--white": "#ffffff", "--black": "#000000", "--transparent": "transparent", "--my-custom-color-44": "#ec606a", "--": "#fff6" }, sectionStyles: ':root{--white:#ffffff;--black:#000000;--transparent:transparent;--my-custom-color-44:#ec606a;--:#fff6}.hl_page-preview--content .row-g-KFgj-Eth,.hl_page-preview--content .section-O_4cMXt8V{padding:5px 0;margin-top:0;margin-bottom:0;background-color:var(--my-custom-color-44);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .row-g-KFgj-Eth{padding:0;width:100%}.hl_page-preview--content .col-u_bfKNLdt{width:100%}.hl_page-preview--content .cnav-menu-GPHNpOf5K,.hl_page-preview--content .col-u_bfKNLdt .inner{margin-top:0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .col-u_bfKNLdt .inner{padding:0 5px;width:100%;margin-bottom:0}.hl_page-preview--content .cnav-menu-GPHNpOf5K{font-family:var(--headlinefont);padding:0;color:var(--white);bold-text-color:var(--text-color);italic-text-color:var(--text-color);underline-text-color:var(--text-color);icon-color:var(--white);secondary-color:var(--white);nav-menu-item-hover-background-color:var(--);line-height:3.8em;text-transform:uppercase;letter-spacing:0;text-align:center;nav-menu-item-spacing-x:24px;nav-menu-item-spacing-y:0;dropdown-background:var(--my-custom-color-44);dropdown-text-color:var(--white);dropdown-hover-color:var(--white);dropdown-item-spacing:10px}#section-O_4cMXt8V>.inner{max-width:1170px}#col-u_bfKNLdt>.inner{flex-direction:column;justify-content:center;align-items:inherit;flex-wrap:nowrap}#nav-menu-GPHNpOf5K .nav-menu,.--mobile #nav-menu-GPHNpOf5K .nav-menu{font-size:18px;font-weight:undefined}#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu-body{background:var(--transparent)}#nav-menu-GPHNpOf5K .nav-menu li.nav-menu-item{display:flex;align-items:center;white-space:nowrap}#nav-menu-GPHNpOf5K .items-cart,#nav-menu-GPHNpOf5K .items-cart-active{color:undefined}#nav-menu-GPHNpOf5K .nav-menu .nav-menu-item a,#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu .nav-menu-item a{color:var(--white);cursor:pointer;height:inherit;display:flex;align-items:center;padding:0 24px;transition:all .3s ease}#nav-menu-GPHNpOf5K .nav-menu .nav-menu-item:hover a{color:var(--white);background:var(--)}#nav-menu-GPHNpOf5K .nav-menu .dropdown-menu .dropdown-item:hover a,#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu .nav-menu-item:hover a,#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu-body .nav-dropdown-menu .nav-menu-item a,#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu-body .nav-menu .nav-menu-item:hover{color:var(--white)}.--mobile #nav-menu-GPHNpOf5K .nav-menu .dropdown-menu .dropdown-item{font-size:16px;font-weight:undefined}#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu{font-size:18px;font-family:var(--headlinefont);font-weight:undefined}#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu-body .close-menu{color:var(--white);font-size:18px;font-weight:600}#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu-body .nav-menu .nav-menu-item{color:var(--white);text-align:center;transition:all .3s ease;font-size:16px;font-weight:undefined}#nav-menu-GPHNpOf5K .nav-menu .dropdown-menu .dropdown-item{font-size:16px;text-align:center;font-weight:undefined}#nav-menu-GPHNpOf5K .nav-menu .dropdown-menu .dropdown-item a,#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu .nav-dropdown-menu .nav-menu-item:hover a{color:var(--white);background:var(--my-custom-color-44);padding:10px;transition:all .3s ease}#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu-body .nav-dropdown-menu .nav-menu-item{background:var(--my-custom-color-44);font-size:16px;font-weight:undefined}#nav-menu-popup.nav-menu-GPHNpOf5K .nav-menu-body .nav-dropdown-menu .nav-menu-item:hover a{color:var(--white)}#nav-menu-GPHNpOf5K .nav-menu-mobile span::before{cursor:pointer;color:var(--white);content:"\uF0C9";font-family:"Font Awesome 5 Free";font-size:18px;font-weight:600}@media screen and (min-width:0px) and (max-width:480px){.nav-menu-GPHNpOf5K .branding .title{font-size:18px;line-height:3.8em;font-weight:undefined}#nav-menu-GPHNpOf5K .hl-autocomplete-results li{font-size:18px}}@media screen and (min-width:481px) and (max-width:10000px){.nav-menu-GPHNpOf5K .branding .title{font-size:18px;line-height:3.8em;font-weight:undefined}#nav-menu-GPHNpOf5K .hl-autocomplete-results li{font-size:18px}}#nav-menu-GPHNpOf5K strong{font-weight:700}#nav-menu-GPHNpOf5K em,#nav-menu-GPHNpOf5K strong,#nav-menu-GPHNpOf5K u{color:var(--text-color)!important}#nav-menu-GPHNpOf5K .hl-autocomplete-input{border:1px solid #cacaca;margin:1px;border-radius:16px}#nav-menu-GPHNpOf5K .hl-autocomplete{font-family:inherit}#nav-menu-GPHNpOf5K .hl-autocomplete-button{background:#fff}#nav-menu-GPHNpOf5K .hl-autocomplete-input-wrapper{color:#000;background-color:#fff}#nav-menu-GPHNpOf5K .hl-autocomplete-results{border:1px solid #cacaca;border-top:none;border-radius:16px;border-top-left-radius:0;border-top-right-radius:0;color:var(--white);background-color:var(--transparent)}#nav-menu-GPHNpOf5K .hl-autocomplete-input:hover{border-width:1.5px;margin:.5px}#nav-menu-GPHNpOf5K .hl-autocomplete-input:focus-within{border-width:2px;margin:0}' } }, hero: { id: "section-i7rCIMA8O", metaData: { id: "section-i7rCIMA8O", type: "section", child: ["row-FSIe9k0QEZ"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: "100" }, paddingTop: { unit: "px", value: "100" }, marginTop: { unit: "px", value: "0" }, marginBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "https://firebasestorage.googleapis.com/v0/b/highlevel-backend.appspot.com/o/location%2Fh0gYqQIqOIBs6xxgZjft%2Fimages%2Fa1a2eeaa-7417-4c54-9f3f-655cc9b9b315.jpeg?alt=media", opacity: "1", options: "full-center", servingUrl: "https://lh3.googleusercontent.com/yk8oCaw8FkORxMxnBR6aWhT05h_QBbZR3_VSWb8Fwnpj5XxjLWRcmQeTEpW9wPK5bwMluRZiAfH63P6xT7L5wPivtvDVMsw", placeholderBase64: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAQEDAwEEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQVFBQUFBQUFBQUEhAPDRUNDRQUFBQUFRUNDRUVFBUVDg4NDf/AABEIAAMACgMBEQACEQEDEQH/xAAVAAEBAAAAAAAAAAAAAAAAAAAIBf/EAB0QAAICAgMBAAAAAAAAAAAAAAECBhEDBAAFBzH/xAAVAQEBAAAAAAAAAAAAAAAAAAAEA//EABwRAAEDBQAAAAAAAAAAAAAAAAEAAhIDESFBkf/aAAwDAQACEQMRAD8Ae/qfTaOr4BPHxR7EjFFWwg+FhfAVGiKfQcZqf1mtr5Y3H3eP6zu2JCzNgQkmhZJrkrA6VpOGAT1f/9k=", imageMeta: { height: 639, width: 1920 } } }, allowRowMaxWidth: { value: false } }, wrapper: {}, meta: "section", tagName: "c-section", title: "Section", _id: "section-i7rCIMA8O" }, elements: [{ id: "row-FSIe9k0QEZ", type: "row", child: ["col-6sfxZPMzf", "col-t4hGSsT54i"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 15 }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, rowWidth: { value: 100, unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-row", meta: "row", title: "2 Column Row" }, { id: "col-6sfxZPMzf", type: "col", child: ["heading-BcUsx4fVJi", "paragraph-WVEyivzTc", "button-XgW4LOq8Q"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: 67.2, unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cparagraph-WVEyivzTc", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>Experience luxurious, science-backed skincare and wellness services. From rejuvenating facials to body sculpting, our expert team helps you achieve radiant, youthful skin.</p>" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "22", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: "20" }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: "1.27", unit: "em" }, textTransform: { value: "none" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: "20" } }, customCss: [], id: "paragraph-WVEyivzTc", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cbutton-XgW4LOq8Q", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "make an appointment " }, subText: { value: "" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, subTextDesktopFontSize: { value: 15, unit: "px" }, subTextMobileFontSize: { value: 15, unit: "px" }, typography: { value: "var(--headlinefont)" }, iconStart: { value: { name: "", unicode: "", fontFamily: "" } }, iconEnd: { value: { name: "", unicode: "", fontFamily: "" } }, action: { value: "go-to-funnel-step" }, visitWebsite: { value: { url: "#", newTab: false } }, hideElements: { value: [] }, scrollToElement: { value: "" }, phoneNumber: { value: "" }, productId: { value: "" }, stepPath: { value: "0b1c9991-d57a-4c54-9c14-6b846e0c16eb" }, saleAction: { value: "go-to-next-funnel-step" } }, class: { buttonEffects: { value: "none" }, buttonBoxShadow: { value: "btnshadow" }, buttonBgStyle: { value: "custom", text: "Custom", targetConfig: { styles: {} } }, buttonVp: { value: "btn-vp" }, buttonHp: { value: "btn-hp" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--my-custom-color-44)" }, color: { value: "var(--white)" }, secondaryColor: { value: "var(--white)" }, textDecoration: { value: "none" }, paddingTop: { unit: "px", value: "12" }, paddingBottom: { unit: "px", value: "12" }, paddingLeft: { unit: "px", value: "30" }, paddingRight: { value: "30", unit: "px" }, fontWeight: { value: "bold" }, borderColor: { value: "var(--secondary)" }, borderWidth: { value: 3, unit: "px" }, borderStyle: { value: "solid" }, letterSpacing: { value: "0", unit: "px" }, textTransform: { value: "uppercase" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, width: { value: "auto", unit: "%" } }, wrapper: { marginTop: { unit: "px", value: "30" }, marginBottom: { unit: "px", value: 0 }, textAlign: { value: "left" } }, customCss: [], id: "button-XgW4LOq8Q", type: "element", child: [], meta: "button", tagName: "c-button", title: "Button", tag: "" }, { extra: { nodeId: "cheading-BcUsx4fVJi", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<h1>Welcome To {{location.name}}</h1>" }, mobileFontSize: { value: 65, unit: "px" }, desktopFontSize: { value: 65, unit: "px" }, typography: { value: "var(--headlinefont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } }, customClass: { value: [] } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal", desktop: "400" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 } }, customCss: [], mobileStyles: {}, mobileWrapper: {}, id: "heading-BcUsx4fVJi", type: "element", child: [], meta: "heading", tagName: "c-heading", title: "Headline", tag: "h1" }, { id: "col-t4hGSsT54i", type: "col", child: [], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: 32.8, unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: true } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "2nd Column" }], sequence: 2, pageId: "FYBFsBAezEtsY0uXW4IN", funnelId: "pK3yy9CFapchugRrgjgq", locationId: "Gc2kgDDpABIR8QDyJ6rf", general: { colors: [{ value: "#188bf6", label: "Secondary" }, { label: "White", value: "#ffffff" }, { label: "Black", value: "#000000" }, { label: "Transparent", value: "transparent" }, { label: "my-custom-color-44", name: "My Custom Color 44", value: "#ec606a" }], fontsForPreview: ["'Lato'", "'Oswald'"], rootVars: { "--'lato'": "'Lato'", "--'oswald'": "'Oswald'", "--secondary": "#188bf6", "--white": "#ffffff", "--black": "#000000", "--transparent": "transparent", "--my-custom-color-44": "#ec606a" }, sectionStyles: ":root{--secondary:#188bf6;--white:#ffffff;--black:#000000;--transparent:transparent;--my-custom-color-44:#ec606a}.hl_page-preview--content .row-FSIe9k0QEZ,.hl_page-preview--content .section-i7rCIMA8O{padding:100px 0;margin-top:0;margin-bottom:0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .row-FSIe9k0QEZ{padding:15px 0;width:100%}.hl_page-preview--content .col-6sfxZPMzf{width:67.2%}.hl_page-preview--content .col-6sfxZPMzf .inner{padding:10px 5px;width:67.2%;margin-top:0;margin-bottom:0}.hl_page-preview--content .paragraph-WVEyivzTc{margin-top:0;margin-bottom:20px}.hl_page-preview--content .col-6sfxZPMzf .inner,.hl_page-preview--content .cparagraph-WVEyivzTc{background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .cparagraph-WVEyivzTc{font-family:var(--contentfont);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:20px 0 0;opacity:1;text-shadow:0 0 0 transparent;line-height:1.27em;text-transform:none;letter-spacing:0;text-align:left}.hl_page-preview--content .button-XgW4LOq8Q{margin-top:30px;margin-bottom:0;text-align:left}.hl_page-preview--content .cbutton-XgW4LOq8Q{font-family:var(--headlinefont);background-color:var(--my-custom-color-44);color:var(--white);secondary-color:var(--white);text-decoration:none;padding:12px 30px;font-weight:700;border-color:var(--secondary);border-width:3px;border-style:solid;letter-spacing:0;text-transform:uppercase;text-shadow:0 0 0 transparent;width:auto%}.hl_page-preview--content .heading-BcUsx4fVJi{margin:0}.hl_page-preview--content .cheading-BcUsx4fVJi,.hl_page-preview--content .col-t4hGSsT54i .inner{background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .cheading-BcUsx4fVJi{font-family:var(--headlinefont);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .col-t4hGSsT54i{width:32.8%}.hl_page-preview--content .col-t4hGSsT54i .inner{padding:10px 5px;width:32.8%;margin-top:0;margin-bottom:0}#section-i7rCIMA8O>.inner{max-width:1170px}#col-6sfxZPMzf>.inner,#col-t4hGSsT54i>.inner{flex-direction:column;justify-content:center;align-items:inherit;flex-wrap:nowrap}.paragraph-WVEyivzTc{font-weight:undefined}.heading-BcUsx4fVJi em,.heading-BcUsx4fVJi strong,.heading-BcUsx4fVJi u,.paragraph-WVEyivzTc em,.paragraph-WVEyivzTc strong,.paragraph-WVEyivzTc u{color:var(--text-color)!important}.heading-BcUsx4fVJi a,.heading-BcUsx4fVJi a *,.paragraph-WVEyivzTc a,.paragraph-WVEyivzTc a *{color:var(--link-color)!important;text-decoration:none}.heading-BcUsx4fVJi a:hover,.paragraph-WVEyivzTc a:hover{text-decoration:underline}@media screen and (min-width:0px) and (max-width:480px){.paragraph-WVEyivzTc h1,.paragraph-WVEyivzTc h2,.paragraph-WVEyivzTc h3,.paragraph-WVEyivzTc h4,.paragraph-WVEyivzTc h5,.paragraph-WVEyivzTc h6,.paragraph-WVEyivzTc ul li,.paragraph-WVEyivzTc.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-WVEyivzTc h1,.paragraph-WVEyivzTc h2,.paragraph-WVEyivzTc h3,.paragraph-WVEyivzTc h4,.paragraph-WVEyivzTc h5,.paragraph-WVEyivzTc h6,.paragraph-WVEyivzTc ul li,.paragraph-WVEyivzTc.text-output{font-size:22px!important;font-weight:undefined}}.heading-BcUsx4fVJi.text-output h1:first-child:before,.heading-BcUsx4fVJi.text-output h2:first-child:before,.heading-BcUsx4fVJi.text-output h3:first-child:before,.heading-BcUsx4fVJi.text-output h4:first-child:before,.heading-BcUsx4fVJi.text-output h5:first-child:before,.heading-BcUsx4fVJi.text-output h6:first-child:before,.heading-BcUsx4fVJi.text-output p:first-child:before,.paragraph-WVEyivzTc.text-output h1:first-child:before,.paragraph-WVEyivzTc.text-output h2:first-child:before,.paragraph-WVEyivzTc.text-output h3:first-child:before,.paragraph-WVEyivzTc.text-output h4:first-child:before,.paragraph-WVEyivzTc.text-output h5:first-child:before,.paragraph-WVEyivzTc.text-output h6:first-child:before,.paragraph-WVEyivzTc.text-output p:first-child:before{color:var(--text-color);content:'\\';\n font-family: '';margin-right:5px;font-weight:700}@media screen and (min-width:481px) and (max-width:10000px){.button-XgW4LOq8Q .button-icon-end,.button-XgW4LOq8Q .button-icon-start,.button-XgW4LOq8Q .main-heading-button{font-size:16px;font-weight:undefined}.button-XgW4LOq8Q .button-icon-start{margin-right:5px}.button-XgW4LOq8Q .button-icon-end{margin-left:5px}.button-XgW4LOq8Q .sub-heading-button{font-size:15px;color:var(--white);font-weight:undefined}}@media screen and (min-width:0px) and (max-width:480px){.button-XgW4LOq8Q .button-icon-end,.button-XgW4LOq8Q .button-icon-start,.button-XgW4LOq8Q .main-heading-button{font-size:16px;font-weight:undefined}.button-XgW4LOq8Q .button-icon-start{margin-right:5px}.button-XgW4LOq8Q .button-icon-end{margin-left:5px}.button-XgW4LOq8Q .sub-heading-button{font-size:15px;color:var(--white);font-weight:undefined}}.heading-BcUsx4fVJi{font-weight:400}@media screen and (min-width:0px) and (max-width:480px){.heading-BcUsx4fVJi h1,.heading-BcUsx4fVJi h2,.heading-BcUsx4fVJi h3,.heading-BcUsx4fVJi h4,.heading-BcUsx4fVJi h5,.heading-BcUsx4fVJi h6,.heading-BcUsx4fVJi ul li,.heading-BcUsx4fVJi.text-output{font-size:65px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.heading-BcUsx4fVJi h1,.heading-BcUsx4fVJi h2,.heading-BcUsx4fVJi h3,.heading-BcUsx4fVJi h4,.heading-BcUsx4fVJi h5,.heading-BcUsx4fVJi h6,.heading-BcUsx4fVJi ul li,.heading-BcUsx4fVJi.text-output{font-size:65px!important;font-weight:undefined}}" } }, valueCards: { id: "section-_gNK8lmb6", metaData: { id: "section-_gNK8lmb6", type: "section", child: ["row-aVCgRa8ogS"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: 20 }, paddingTop: { unit: "px", value: "30" }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, allowRowMaxWidth: { value: false } }, wrapper: {}, meta: "section", tagName: "c-section", title: "Section", _id: "section-_gNK8lmb6" }, elements: [{ id: "row-aVCgRa8ogS", type: "row", child: ["col--YcAMCaa-", "col-O6hNBWA0L", "col-Ce4EQ7ehv"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 15 }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, rowWidth: { value: 100, unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-row", meta: "row", title: "4 Column Row" }, { id: "col--YcAMCaa-", type: "col", child: ["heading-ZvINOOFQi", "divider-y7JRL27_X", "paragraph-1XjOnx_r2", "paragraph-iuePsO6Jd", "paragraph-fBuGHkfQd"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: "10" }, paddingRight: { value: "10", unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "flex-start" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: "0" }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cheading-ZvINOOFQi", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>OPENING HOURS</p>" }, mobileFontSize: { value: "20", unit: "px" }, desktopFontSize: { value: "20", unit: "px" }, typography: { value: "var(--headlinefont)" }, icon: { value: { name: "calendar-week", unicode: "f784", fontFamily: "Font Awesome 5 Free", color: "var(--black)" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--my-custom-color-44)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--my-custom-color-44)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: "40" }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "none" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "heading-ZvINOOFQi", type: "element", child: [], meta: "heading", tagName: "c-heading", title: "Headline", tag: "h1" }, { extra: { nodeId: "cdivider-y7JRL27_X", visibility: { value: { hideDesktop: false, hideMobile: false } }, dividerProperties: { value: { width: "100%", height: "1px", borderStyle: "solid", align: "center", color: "var(--my-custom-color-71)" } } }, class: {}, styles: { paddingTop: { unit: "px", value: "5" }, paddingBottom: { unit: "px", value: 5 } }, wrapper: { marginTop: { unit: "px", value: "5" }, marginBottom: { unit: "px", value: 0 }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 } }, customCss: [], id: "divider-y7JRL27_X", type: "element", child: [], meta: "divider", tagName: "c-divider", title: "Divider", tag: "" }, { extra: { nodeId: "cparagraph-1XjOnx_r2", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>Mon\u2013Fri</p><p>8:00am\u20137:00pm</p>" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: "15" }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-1XjOnx_r2", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cparagraph-iuePsO6Jd", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>Saturday</p><p>9:00am\u20134:00pm</p>" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: "15" }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-iuePsO6Jd", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cparagraph-fBuGHkfQd", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>Sunday</p><p>CLOSED</p>" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: "15" }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-fBuGHkfQd", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { id: "col-O6hNBWA0L", type: "col", child: ["heading-h2fK7KiZ6", "divider-J9m382ioKb", "paragraph-y_I-jJh6ya"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: "10" }, paddingRight: { value: "10", unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: "10" }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "flex-start" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "2nd Column" }, { extra: { nodeId: "cdivider-J9m382ioKb", visibility: { value: { hideDesktop: false, hideMobile: false } }, dividerProperties: { value: { width: "100%", height: "1px", borderStyle: "solid", align: "center", color: "var(--my-custom-color-71)" } } }, class: {}, styles: { paddingTop: { unit: "px", value: 5 }, paddingBottom: { unit: "px", value: 5 } }, wrapper: { marginTop: { unit: "px", value: "5" }, marginBottom: { unit: "px", value: 0 }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 } }, customCss: [], id: "divider-J9m382ioKb", type: "element", child: [], meta: "divider", tagName: "c-divider", title: "Divider", tag: "" }, { extra: { nodeId: "cparagraph-y_I-jJh6ya", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>Booking an appointment at {{location.name}} is easy and convenient. Our expert team is here to provide personalized treatments tailored to your unique needs. Click below to schedule your session and start your journey to a more radiant, confident you.</p>" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: "1.5", unit: "em" }, textTransform: { value: "none" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-y_I-jJh6ya", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cheading-h2fK7KiZ6", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>APPOINTMENTS</p>" }, mobileFontSize: { value: "20", unit: "px" }, desktopFontSize: { value: "20", unit: "px" }, typography: { value: "var(--headlinefont)" }, icon: { value: { name: "phone-square-alt", unicode: "f87b", fontFamily: "Font Awesome 5 Free", color: "var(--black)" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--my-custom-color-44)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--my-custom-color-44)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: "40" }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "heading-h2fK7KiZ6", type: "element", child: [], meta: "heading", tagName: "c-heading", title: "Headline", tag: "h1" }, { id: "col-Ce4EQ7ehv", type: "col", child: ["heading-FBdJHQ1UZ", "divider-G2u9sBW4y8", "paragraph-nuxIv4A8ad", "paragraph-6KxQcCSVR", "paragraph--m28AM_yp9", "paragraph-pvUi7TFc7r"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: "10" }, paddingRight: { value: "10", unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: "10" }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "flex-start" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "2nd Column" }, { extra: { nodeId: "cheading-FBdJHQ1UZ", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>LOCATION &amp; CONTACT</p>" }, mobileFontSize: { value: "20", unit: "px" }, desktopFontSize: { value: "20", unit: "px" }, typography: { value: "var(--headlinefont)" }, icon: { value: { name: "map-marker-alt", unicode: "f3c5", fontFamily: "Font Awesome 5 Free", color: "var(--black)" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--my-custom-color-44)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--my-custom-color-44)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: "40" }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "heading-FBdJHQ1UZ", type: "element", child: [], meta: "heading", tagName: "c-heading", title: "Headline", tag: "h1" }, { extra: { nodeId: "cdivider-G2u9sBW4y8", visibility: { value: { hideDesktop: false, hideMobile: false } }, dividerProperties: { value: { width: "100%", height: "1px", borderStyle: "solid", align: "center", color: "var(--my-custom-color-71)" } } }, class: {}, styles: { paddingTop: { unit: "px", value: 5 }, paddingBottom: { unit: "px", value: 5 } }, wrapper: { marginTop: { unit: "px", value: "5" }, marginBottom: { unit: "px", value: 0 }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 } }, customCss: [], id: "divider-G2u9sBW4y8", type: "element", child: [], meta: "divider", tagName: "c-divider", title: "Divider", tag: "" }, { extra: { nodeId: "cparagraph--m28AM_yp9", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p><strong>{{location.phone}}</strong></p>" }, mobileFontSize: { value: "20", unit: "px" }, desktopFontSize: { value: 18, unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--my-custom-color-26)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: "0" }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: "1.5", unit: "em" }, textTransform: { value: "none" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: "2" } }, customCss: [], id: "paragraph--m28AM_yp9", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cparagraph-6KxQcCSVR", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>Visit us!</p>" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: "1.5", unit: "em" }, textTransform: { value: "none" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 10 } }, customCss: [], id: "paragraph-6KxQcCSVR", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cparagraph-nuxIv4A8ad", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p><strong>{{location.full_address}}</strong></p>" }, mobileFontSize: { value: "20", unit: "px" }, desktopFontSize: { value: 18, unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--my-custom-color-26)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: "0" }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: "1.5", unit: "em" }, textTransform: { value: "none" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: "2" } }, customCss: [], id: "paragraph-nuxIv4A8ad", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cparagraph-pvUi7TFc7r", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>Call us!</p>" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: "1.5", unit: "em" }, textTransform: { value: "none" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 10 } }, customCss: [], id: "paragraph-pvUi7TFc7r", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }], sequence: 3, pageId: "FYBFsBAezEtsY0uXW4IN", funnelId: "pK3yy9CFapchugRrgjgq", locationId: "Gc2kgDDpABIR8QDyJ6rf", general: { colors: [{ label: "Black", value: "#000000" }, { label: "Transparent", value: "transparent" }, { label: "my-custom-color-26", value: "#434445", name: "My Custom Color 26" }, { label: "my-custom-color-44", name: "My Custom Color 44", value: "#ec606a" }], fontsForPreview: ["'Oswald'", "'Lato'"], rootVars: { "--'oswald'": "'Oswald'", "--'lato'": "'Lato'", "--black": "#000000", "--transparent": "transparent", "--my-custom-color-26": "#434445", "--my-custom-color-44": "#ec606a" }, sectionStyles: `:root{--black:#000000;--transparent:transparent;--my-custom-color-26:#434445;--my-custom-color-44:#ec606a}.hl_page-preview--content .row-aVCgRa8ogS,.hl_page-preview--content .section-_gNK8lmb6{padding:30px 0 20px;margin-top:0;margin-bottom:0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .row-aVCgRa8ogS{padding:15px 0;width:100%}.hl_page-preview--content .col--YcAMCaa-{width:100%}.hl_page-preview--content .col--YcAMCaa- .inner,.hl_page-preview--content .col-Ce4EQ7ehv .inner,.hl_page-preview--content .col-O6hNBWA0L .inner{padding:10px;background-color:var(--transparent);width:100%;border-color:var(--black);border-width:2px;border-style:solid;margin-top:0;margin-bottom:0}.hl_page-preview--content .heading-ZvINOOFQi{margin-top:0;margin-bottom:0}.hl_page-preview--content .cheading-ZvINOOFQi{font-family:var(--headlinefont);background-color:var(--transparent);color:var(--my-custom-color-44);icon-color:var(--my-custom-color-44);font-weight:400;padding:0 0 0 40px;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;text-transform:none;letter-spacing:0;text-align:left}.hl_page-preview--content .divider-y7JRL27_X{margin-top:5px;margin-bottom:0;padding-top:10px;padding-bottom:10px}.hl_page-preview--content .cdivider-y7JRL27_X{padding-top:5px;padding-bottom:5px}.hl_page-preview--content .paragraph-1XjOnx_r2{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-1XjOnx_r2{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0 0 15px;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .paragraph-iuePsO6Jd{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-iuePsO6Jd{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0 0 15px;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .paragraph-fBuGHkfQd{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-fBuGHkfQd{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0 0 15px;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .col-O6hNBWA0L{width:100%}.hl_page-preview--content .divider-J9m382ioKb{margin-top:5px;margin-bottom:0;padding-top:10px;padding-bottom:10px}.hl_page-preview--content .cdivider-J9m382ioKb{padding-top:5px;padding-bottom:5px}.hl_page-preview--content .paragraph-y_I-jJh6ya{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-y_I-jJh6ya{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.5em;text-transform:none;letter-spacing:0;text-align:left}.hl_page-preview--content .heading-h2fK7KiZ6{margin-top:0;margin-bottom:0}.hl_page-preview--content .cheading-h2fK7KiZ6{font-family:var(--headlinefont);background-color:var(--transparent);color:var(--my-custom-color-44);icon-color:var(--my-custom-color-44);font-weight:400;padding:0 0 0 40px;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .col-Ce4EQ7ehv{width:100%}.hl_page-preview--content .heading-FBdJHQ1UZ{margin-top:0;margin-bottom:0}.hl_page-preview--content .cheading-FBdJHQ1UZ{font-family:var(--headlinefont);background-color:var(--transparent);color:var(--my-custom-color-44);icon-color:var(--my-custom-color-44);font-weight:400;padding:0 0 0 40px;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .divider-G2u9sBW4y8{margin-top:5px;margin-bottom:0;padding-top:10px;padding-bottom:10px}.hl_page-preview--content .cdivider-G2u9sBW4y8{padding-top:5px;padding-bottom:5px}.hl_page-preview--content .paragraph--m28AM_yp9{margin-top:0;margin-bottom:2px}.hl_page-preview--content .cparagraph--m28AM_yp9{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.5em;text-transform:none;letter-spacing:0;text-align:left}.hl_page-preview--content .paragraph-6KxQcCSVR{margin-top:0;margin-bottom:10px}.hl_page-preview--content .cparagraph-6KxQcCSVR{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.5em;text-transform:none;letter-spacing:0;text-align:left}.hl_page-preview--content .paragraph-nuxIv4A8ad{margin-top:0;margin-bottom:2px}.hl_page-preview--content .cparagraph-nuxIv4A8ad{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.5em;text-transform:none;letter-spacing:0;text-align:left}.hl_page-preview--content .paragraph-pvUi7TFc7r{margin-top:0;margin-bottom:10px}.hl_page-preview--content .cparagraph-pvUi7TFc7r{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.5em;text-transform:none;letter-spacing:0;text-align:left}#section-_gNK8lmb6>.inner{max-width:1170px}#col--YcAMCaa->.inner,#col-Ce4EQ7ehv>.inner,#col-O6hNBWA0L>.inner{flex-direction:column;justify-content:flex-start;align-items:inherit;flex-wrap:nowrap}.heading-FBdJHQ1UZ,.heading-ZvINOOFQi,.heading-h2fK7KiZ6,.paragraph--m28AM_yp9,.paragraph-1XjOnx_r2,.paragraph-6KxQcCSVR,.paragraph-fBuGHkfQd,.paragraph-iuePsO6Jd,.paragraph-nuxIv4A8ad,.paragraph-pvUi7TFc7r,.paragraph-y_I-jJh6ya{font-weight:undefined}.heading-FBdJHQ1UZ em,.heading-FBdJHQ1UZ strong,.heading-FBdJHQ1UZ u,.heading-ZvINOOFQi em,.heading-ZvINOOFQi strong,.heading-ZvINOOFQi u,.heading-h2fK7KiZ6 em,.heading-h2fK7KiZ6 strong,.heading-h2fK7KiZ6 u,.paragraph--m28AM_yp9 em,.paragraph--m28AM_yp9 strong,.paragraph--m28AM_yp9 u,.paragraph-1XjOnx_r2 em,.paragraph-1XjOnx_r2 strong,.paragraph-1XjOnx_r2 u,.paragraph-6KxQcCSVR em,.paragraph-6KxQcCSVR strong,.paragraph-6KxQcCSVR u,.paragraph-fBuGHkfQd em,.paragraph-fBuGHkfQd strong,.paragraph-fBuGHkfQd u,.paragraph-iuePsO6Jd em,.paragraph-iuePsO6Jd strong,.paragraph-iuePsO6Jd u,.paragraph-nuxIv4A8ad em,.paragraph-nuxIv4A8ad strong,.paragraph-nuxIv4A8ad u,.paragraph-pvUi7TFc7r em,.paragraph-pvUi7TFc7r strong,.paragraph-pvUi7TFc7r u,.paragraph-y_I-jJh6ya em,.paragraph-y_I-jJh6ya strong,.paragraph-y_I-jJh6ya u{color:var(--text-color)!important}.heading-FBdJHQ1UZ a,.heading-FBdJHQ1UZ a *,.heading-ZvINOOFQi a,.heading-ZvINOOFQi a *,.heading-h2fK7KiZ6 a,.heading-h2fK7KiZ6 a *,.paragraph-1XjOnx_r2 a,.paragraph-1XjOnx_r2 a *,.paragraph-fBuGHkfQd a,.paragraph-fBuGHkfQd a *,.paragraph-iuePsO6Jd a,.paragraph-iuePsO6Jd a *,.paragraph-y_I-jJh6ya a,.paragraph-y_I-jJh6ya a *{color:var(--link-color)!important;text-decoration:none}.heading-FBdJHQ1UZ a:hover,.heading-ZvINOOFQi a:hover,.heading-h2fK7KiZ6 a:hover,.paragraph--m28AM_yp9 a:hover,.paragraph-1XjOnx_r2 a:hover,.paragraph-6KxQcCSVR a:hover,.paragraph-fBuGHkfQd a:hover,.paragraph-iuePsO6Jd a:hover,.paragraph-nuxIv4A8ad a:hover,.paragraph-pvUi7TFc7r a:hover,.paragraph-y_I-jJh6ya a:hover{text-decoration:underline}@media screen and (min-width:0px) and (max-width:480px){.heading-ZvINOOFQi h1,.heading-ZvINOOFQi h2,.heading-ZvINOOFQi h3,.heading-ZvINOOFQi h4,.heading-ZvINOOFQi h5,.heading-ZvINOOFQi h6,.heading-ZvINOOFQi ul li,.heading-ZvINOOFQi.text-output{font-size:20px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.heading-ZvINOOFQi h1,.heading-ZvINOOFQi h2,.heading-ZvINOOFQi h3,.heading-ZvINOOFQi h4,.heading-ZvINOOFQi h5,.heading-ZvINOOFQi h6,.heading-ZvINOOFQi ul li,.heading-ZvINOOFQi.text-output{font-size:20px!important;font-weight:undefined}}.heading-ZvINOOFQi.text-output h1:first-child:before,.heading-ZvINOOFQi.text-output h2:first-child:before,.heading-ZvINOOFQi.text-output h3:first-child:before,.heading-ZvINOOFQi.text-output h4:first-child:before,.heading-ZvINOOFQi.text-output h5:first-child:before,.heading-ZvINOOFQi.text-output h6:first-child:before,.heading-ZvINOOFQi.text-output p:first-child:before{color:var(--my-custom-color-44);content:"\uF784";font-family:"Font Awesome 5 Free";margin-right:5px;font-weight:700}.divider-y7JRL27_X .divider-element{width:100%;border-top:1px solid var(--my-custom-color-71);margin:0 auto}@media screen and (min-width:0px) and (max-width:480px){.paragraph-1XjOnx_r2 h1,.paragraph-1XjOnx_r2 h2,.paragraph-1XjOnx_r2 h3,.paragraph-1XjOnx_r2 h4,.paragraph-1XjOnx_r2 h5,.paragraph-1XjOnx_r2 h6,.paragraph-1XjOnx_r2 ul li,.paragraph-1XjOnx_r2.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-1XjOnx_r2 h1,.paragraph-1XjOnx_r2 h2,.paragraph-1XjOnx_r2 h3,.paragraph-1XjOnx_r2 h4,.paragraph-1XjOnx_r2 h5,.paragraph-1XjOnx_r2 h6,.paragraph-1XjOnx_r2 ul li,.paragraph-1XjOnx_r2.text-output{font-size:16px!important;font-weight:undefined}}.paragraph-1XjOnx_r2.text-output h1:first-child:before,.paragraph-1XjOnx_r2.text-output h2:first-child:before,.paragraph-1XjOnx_r2.text-output h3:first-child:before,.paragraph-1XjOnx_r2.text-output h4:first-child:before,.paragraph-1XjOnx_r2.text-output h5:first-child:before,.paragraph-1XjOnx_r2.text-output h6:first-child:before,.paragraph-1XjOnx_r2.text-output p:first-child:before,.paragraph-fBuGHkfQd.text-output h1:first-child:before,.paragraph-fBuGHkfQd.text-output h2:first-child:before,.paragraph-fBuGHkfQd.text-output h3:first-child:before,.paragraph-fBuGHkfQd.text-output h4:first-child:before,.paragraph-fBuGHkfQd.text-output h5:first-child:before,.paragraph-fBuGHkfQd.text-output h6:first-child:before,.paragraph-fBuGHkfQd.text-output p:first-child:before,.paragraph-iuePsO6Jd.text-output h1:first-child:before,.paragraph-iuePsO6Jd.text-output h2:first-child:before,.paragraph-iuePsO6Jd.text-output h3:first-child:before,.paragraph-iuePsO6Jd.text-output h4:first-child:before,.paragraph-iuePsO6Jd.text-output h5:first-child:before,.paragraph-iuePsO6Jd.text-output h6:first-child:before,.paragraph-iuePsO6Jd.text-output p:first-child:before,.paragraph-y_I-jJh6ya.text-output h1:first-child:before,.paragraph-y_I-jJh6ya.text-output h2:first-child:before,.paragraph-y_I-jJh6ya.text-output h3:first-child:before,.paragraph-y_I-jJh6ya.text-output h4:first-child:before,.paragraph-y_I-jJh6ya.text-output h5:first-child:before,.paragraph-y_I-jJh6ya.text-output h6:first-child:before,.paragraph-y_I-jJh6ya.text-output p:first-child:before{color:var(--text-color);content:'\\';
10084
+ font-family: '';margin-right:5px;font-weight:700}@media screen and (min-width:0px) and (max-width:480px){.paragraph-iuePsO6Jd h1,.paragraph-iuePsO6Jd h2,.paragraph-iuePsO6Jd h3,.paragraph-iuePsO6Jd h4,.paragraph-iuePsO6Jd h5,.paragraph-iuePsO6Jd h6,.paragraph-iuePsO6Jd ul li,.paragraph-iuePsO6Jd.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-iuePsO6Jd h1,.paragraph-iuePsO6Jd h2,.paragraph-iuePsO6Jd h3,.paragraph-iuePsO6Jd h4,.paragraph-iuePsO6Jd h5,.paragraph-iuePsO6Jd h6,.paragraph-iuePsO6Jd ul li,.paragraph-iuePsO6Jd.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:0px) and (max-width:480px){.paragraph-fBuGHkfQd h1,.paragraph-fBuGHkfQd h2,.paragraph-fBuGHkfQd h3,.paragraph-fBuGHkfQd h4,.paragraph-fBuGHkfQd h5,.paragraph-fBuGHkfQd h6,.paragraph-fBuGHkfQd ul li,.paragraph-fBuGHkfQd.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-fBuGHkfQd h1,.paragraph-fBuGHkfQd h2,.paragraph-fBuGHkfQd h3,.paragraph-fBuGHkfQd h4,.paragraph-fBuGHkfQd h5,.paragraph-fBuGHkfQd h6,.paragraph-fBuGHkfQd ul li,.paragraph-fBuGHkfQd.text-output{font-size:16px!important;font-weight:undefined}}.divider-J9m382ioKb .divider-element{width:100%;border-top:1px solid var(--my-custom-color-71);margin:0 auto}@media screen and (min-width:0px) and (max-width:480px){.paragraph-y_I-jJh6ya h1,.paragraph-y_I-jJh6ya h2,.paragraph-y_I-jJh6ya h3,.paragraph-y_I-jJh6ya h4,.paragraph-y_I-jJh6ya h5,.paragraph-y_I-jJh6ya h6,.paragraph-y_I-jJh6ya ul li,.paragraph-y_I-jJh6ya.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-y_I-jJh6ya h1,.paragraph-y_I-jJh6ya h2,.paragraph-y_I-jJh6ya h3,.paragraph-y_I-jJh6ya h4,.paragraph-y_I-jJh6ya h5,.paragraph-y_I-jJh6ya h6,.paragraph-y_I-jJh6ya ul li,.paragraph-y_I-jJh6ya.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:0px) and (max-width:480px){.heading-h2fK7KiZ6 h1,.heading-h2fK7KiZ6 h2,.heading-h2fK7KiZ6 h3,.heading-h2fK7KiZ6 h4,.heading-h2fK7KiZ6 h5,.heading-h2fK7KiZ6 h6,.heading-h2fK7KiZ6 ul li,.heading-h2fK7KiZ6.text-output{font-size:20px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.heading-h2fK7KiZ6 h1,.heading-h2fK7KiZ6 h2,.heading-h2fK7KiZ6 h3,.heading-h2fK7KiZ6 h4,.heading-h2fK7KiZ6 h5,.heading-h2fK7KiZ6 h6,.heading-h2fK7KiZ6 ul li,.heading-h2fK7KiZ6.text-output{font-size:20px!important;font-weight:undefined}}.heading-h2fK7KiZ6.text-output h1:first-child:before,.heading-h2fK7KiZ6.text-output h2:first-child:before,.heading-h2fK7KiZ6.text-output h3:first-child:before,.heading-h2fK7KiZ6.text-output h4:first-child:before,.heading-h2fK7KiZ6.text-output h5:first-child:before,.heading-h2fK7KiZ6.text-output h6:first-child:before,.heading-h2fK7KiZ6.text-output p:first-child:before{color:var(--my-custom-color-44);content:"\uF87B";font-family:"Font Awesome 5 Free";margin-right:5px;font-weight:700}@media screen and (min-width:0px) and (max-width:480px){.heading-FBdJHQ1UZ h1,.heading-FBdJHQ1UZ h2,.heading-FBdJHQ1UZ h3,.heading-FBdJHQ1UZ h4,.heading-FBdJHQ1UZ h5,.heading-FBdJHQ1UZ h6,.heading-FBdJHQ1UZ ul li,.heading-FBdJHQ1UZ.text-output{font-size:20px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.heading-FBdJHQ1UZ h1,.heading-FBdJHQ1UZ h2,.heading-FBdJHQ1UZ h3,.heading-FBdJHQ1UZ h4,.heading-FBdJHQ1UZ h5,.heading-FBdJHQ1UZ h6,.heading-FBdJHQ1UZ ul li,.heading-FBdJHQ1UZ.text-output{font-size:20px!important;font-weight:undefined}}.heading-FBdJHQ1UZ.text-output h1:first-child:before,.heading-FBdJHQ1UZ.text-output h2:first-child:before,.heading-FBdJHQ1UZ.text-output h3:first-child:before,.heading-FBdJHQ1UZ.text-output h4:first-child:before,.heading-FBdJHQ1UZ.text-output h5:first-child:before,.heading-FBdJHQ1UZ.text-output h6:first-child:before,.heading-FBdJHQ1UZ.text-output p:first-child:before{color:var(--my-custom-color-44);content:"\uF3C5";font-family:"Font Awesome 5 Free";margin-right:5px;font-weight:700}.divider-G2u9sBW4y8 .divider-element{width:100%;border-top:1px solid var(--my-custom-color-71);margin:0 auto}.paragraph--m28AM_yp9 a,.paragraph--m28AM_yp9 a *{color:var(--my-custom-color-26)!important;text-decoration:none}@media screen and (min-width:0px) and (max-width:480px){.paragraph--m28AM_yp9 h1,.paragraph--m28AM_yp9 h2,.paragraph--m28AM_yp9 h3,.paragraph--m28AM_yp9 h4,.paragraph--m28AM_yp9 h5,.paragraph--m28AM_yp9 h6,.paragraph--m28AM_yp9 ul li,.paragraph--m28AM_yp9.text-output{font-size:20px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph--m28AM_yp9 h1,.paragraph--m28AM_yp9 h2,.paragraph--m28AM_yp9 h3,.paragraph--m28AM_yp9 h4,.paragraph--m28AM_yp9 h5,.paragraph--m28AM_yp9 h6,.paragraph--m28AM_yp9 ul li,.paragraph--m28AM_yp9.text-output{font-size:18px!important;font-weight:undefined}}.paragraph--m28AM_yp9.text-output h1:first-child:before,.paragraph--m28AM_yp9.text-output h2:first-child:before,.paragraph--m28AM_yp9.text-output h3:first-child:before,.paragraph--m28AM_yp9.text-output h4:first-child:before,.paragraph--m28AM_yp9.text-output h5:first-child:before,.paragraph--m28AM_yp9.text-output h6:first-child:before,.paragraph--m28AM_yp9.text-output p:first-child:before,.paragraph-6KxQcCSVR.text-output h1:first-child:before,.paragraph-6KxQcCSVR.text-output h2:first-child:before,.paragraph-6KxQcCSVR.text-output h3:first-child:before,.paragraph-6KxQcCSVR.text-output h4:first-child:before,.paragraph-6KxQcCSVR.text-output h5:first-child:before,.paragraph-6KxQcCSVR.text-output h6:first-child:before,.paragraph-6KxQcCSVR.text-output p:first-child:before,.paragraph-nuxIv4A8ad.text-output h1:first-child:before,.paragraph-nuxIv4A8ad.text-output h2:first-child:before,.paragraph-nuxIv4A8ad.text-output h3:first-child:before,.paragraph-nuxIv4A8ad.text-output h4:first-child:before,.paragraph-nuxIv4A8ad.text-output h5:first-child:before,.paragraph-nuxIv4A8ad.text-output h6:first-child:before,.paragraph-nuxIv4A8ad.text-output p:first-child:before,.paragraph-pvUi7TFc7r.text-output h1:first-child:before,.paragraph-pvUi7TFc7r.text-output h2:first-child:before,.paragraph-pvUi7TFc7r.text-output h3:first-child:before,.paragraph-pvUi7TFc7r.text-output h4:first-child:before,.paragraph-pvUi7TFc7r.text-output h5:first-child:before,.paragraph-pvUi7TFc7r.text-output h6:first-child:before,.paragraph-pvUi7TFc7r.text-output p:first-child:before{color:var(--text-color);content:'\\';
10085
+ font-family: '';margin-right:5px;font-weight:700}.paragraph-6KxQcCSVR a,.paragraph-6KxQcCSVR a *{color:var(--link-color)!important;text-decoration:none}@media screen and (min-width:0px) and (max-width:480px){.paragraph-6KxQcCSVR h1,.paragraph-6KxQcCSVR h2,.paragraph-6KxQcCSVR h3,.paragraph-6KxQcCSVR h4,.paragraph-6KxQcCSVR h5,.paragraph-6KxQcCSVR h6,.paragraph-6KxQcCSVR ul li,.paragraph-6KxQcCSVR.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-6KxQcCSVR h1,.paragraph-6KxQcCSVR h2,.paragraph-6KxQcCSVR h3,.paragraph-6KxQcCSVR h4,.paragraph-6KxQcCSVR h5,.paragraph-6KxQcCSVR h6,.paragraph-6KxQcCSVR ul li,.paragraph-6KxQcCSVR.text-output{font-size:16px!important;font-weight:undefined}}.paragraph-nuxIv4A8ad a,.paragraph-nuxIv4A8ad a *{color:var(--my-custom-color-26)!important;text-decoration:none}@media screen and (min-width:0px) and (max-width:480px){.paragraph-nuxIv4A8ad h1,.paragraph-nuxIv4A8ad h2,.paragraph-nuxIv4A8ad h3,.paragraph-nuxIv4A8ad h4,.paragraph-nuxIv4A8ad h5,.paragraph-nuxIv4A8ad h6,.paragraph-nuxIv4A8ad ul li,.paragraph-nuxIv4A8ad.text-output{font-size:20px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-nuxIv4A8ad h1,.paragraph-nuxIv4A8ad h2,.paragraph-nuxIv4A8ad h3,.paragraph-nuxIv4A8ad h4,.paragraph-nuxIv4A8ad h5,.paragraph-nuxIv4A8ad h6,.paragraph-nuxIv4A8ad ul li,.paragraph-nuxIv4A8ad.text-output{font-size:18px!important;font-weight:undefined}}.paragraph-pvUi7TFc7r a,.paragraph-pvUi7TFc7r a *{color:var(--link-color)!important;text-decoration:none}@media screen and (min-width:0px) and (max-width:480px){.paragraph-pvUi7TFc7r h1,.paragraph-pvUi7TFc7r h2,.paragraph-pvUi7TFc7r h3,.paragraph-pvUi7TFc7r h4,.paragraph-pvUi7TFc7r h5,.paragraph-pvUi7TFc7r h6,.paragraph-pvUi7TFc7r ul li,.paragraph-pvUi7TFc7r.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-pvUi7TFc7r h1,.paragraph-pvUi7TFc7r h2,.paragraph-pvUi7TFc7r h3,.paragraph-pvUi7TFc7r h4,.paragraph-pvUi7TFc7r h5,.paragraph-pvUi7TFc7r h6,.paragraph-pvUi7TFc7r ul li,.paragraph-pvUi7TFc7r.text-output{font-size:16px!important;font-weight:undefined}}` } }, imageText: { id: "section-MCURKhaM7", metaData: { id: "section-MCURKhaM7", type: "section", child: ["row-BafyFVpahF", "row-DTaBn6Nkpv"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: "90" }, paddingTop: { unit: "px", value: 20 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, allowRowMaxWidth: { value: false } }, wrapper: {}, meta: "section", tagName: "c-section", title: "Section", _id: "section-MCURKhaM7" }, elements: [{ id: "row-BafyFVpahF", type: "row", child: ["col-CAyTxea5q"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 15 }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, rowWidth: { value: 100, unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-row", meta: "row", title: "1 Column Row" }, { id: "col-CAyTxea5q", type: "col", child: ["sub-heading-MbvugAQFJf", "image-2hPEEKf7g"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cimage-2hPEEKf7g", visibility: { value: { hideDesktop: false, hideMobile: false } }, imageActions: { value: "none" }, visitWebsite: { value: { url: "", newTab: false } }, imageProperties: { value: { width: "", height: "", url: "https://storage.googleapis.com/msgsndr/locatation/EVTjG29VnVlvwn3SRGve/images/e04c0629-2eca-41d4-a320-ef634015616a.png", altText: "", compression: true, placeholderBase64: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAYAAABhYU3QAAAABHNCSVQICAgIfAhkiAAAAF96VFh0UmF3IHByb2ZpbGUgdHlwZSBBUFAxAAAImeNKT81LLcpMVigoyk/LzEnlUgADYxMuE0sTS6NEAwMDCwMIMDQwMDYEkkZAtjlUKNEABZgamFmaGZsZmgMxiM8FAEi2FMk61EMyAAAAVklEQVQImQXBMQ5AMBiA0a+tFpGIpBKLmRs4kCO5iMl9LMwmaUr93lPHtg7GGBsB9YYra9pZo8r73BdTe++AlNKTUVWjQGEBERcVFMJXuq6ftEguABB+L0UZOFcVeFYAAAAASUVORK5CYII=", servingUrl: "https://lh3.googleusercontent.com/8DcV-wSbJBKHjx-cmwagHA3SspBD4P3ScvvmZZog37NoIdaprLI5vt2nY7nfrqeCFVLFa0YTcL7jR3soFjmRqbNiESGeZ1Nm", imageMeta: { width: "", height: "" } } } }, class: { imageRadius: { value: "img-none" }, imageBorder: { value: "img-border-none" }, imageShadow: { value: "img-shadow-none" }, imageEffects: { value: "img-effects-none" } }, styles: { paddingLeft: { unit: "px", value: 10 }, paddingRight: { value: 10, unit: "px" }, paddingTop: { unit: "px", value: "10" }, paddingBottom: { unit: "px", value: "10" }, backgroundColor: { value: "var(--transparent)" }, opacity: { value: "1" }, textAlign: { value: "center" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "image-2hPEEKf7g", type: "element", child: [], meta: "image", tagName: "c-image", title: "Image", tag: "" }, { extra: { nodeId: "csub-heading-MbvugAQFJf", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<h2>WHAT MAKES US DIFFERENT</h2>" }, mobileFontSize: { value: 46, unit: "px" }, desktopFontSize: { value: 46, unit: "px" }, typography: { value: "var(--headlinefont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } }, customClass: { value: [] } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal", desktop: "400" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "center" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 } }, customCss: [], id: "sub-heading-MbvugAQFJf", type: "element", child: [], mobileStyles: {}, mobileWrapper: {}, meta: "sub-heading", tagName: "c-sub-heading", title: "Sub Headline", tag: "h3" }, { id: "row-DTaBn6Nkpv", type: "row", child: ["col-uYMJwyEml", "col-FIkE81-ke", "col-qanoGGetC"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 15 }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, rowWidth: { value: 100, unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-row", meta: "row", title: "3 Column Row" }, { id: "col-uYMJwyEml", type: "col", child: ["paragraph-PwtXX77o4", "paragraph-F9SB3vFfN"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: "70" }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "flex-start" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cparagraph-F9SB3vFfN", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>State-of-the-art technology ensures the highest quality treatments for optimal results and unparalleled skincare and wellness experiences.</p>" }, mobileFontSize: { value: 14, unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-F9SB3vFfN", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cparagraph-PwtXX77o4", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p><strong>Modern Equipment</strong></p>" }, mobileFontSize: { value: "20", unit: "px" }, desktopFontSize: { value: "22", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--red)" }, boldTextColor: { value: "var(--my-custom-color-44)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: "10" }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-PwtXX77o4", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { id: "col-FIkE81-ke", type: "col", child: ["paragraph-Ud7-Hmgyun", "paragraph-ECP1xCEVEa"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: "70" }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "flex-start" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cparagraph-Ud7-Hmgyun", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p><strong>Qualified Staff</strong></p>" }, mobileFontSize: { value: "20", unit: "px" }, desktopFontSize: { value: "22", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--red)" }, boldTextColor: { value: "var(--my-custom-color-44)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: "10" }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-Ud7-Hmgyun", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cparagraph-ECP1xCEVEa", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>Our highly trained and certified professionals provide expert care, ensuring safe and effective treatments for every client.</p>" }, mobileFontSize: { value: 14, unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-ECP1xCEVEa", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { id: "col-qanoGGetC", type: "col", child: ["paragraph-Dt21hDz3On", "paragraph-AU_CDh6MOl"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: "70" }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "flex-start" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cparagraph-Dt21hDz3On", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p><strong>Effective Results</strong></p>" }, mobileFontSize: { value: "20", unit: "px" }, desktopFontSize: { value: "22", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--red)" }, boldTextColor: { value: "var(--my-custom-color-44)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: "10" }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-Dt21hDz3On", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cparagraph-AU_CDh6MOl", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>Experience transformative results with our proven treatments, designed to deliver noticeable improvements and enhance your natural beauty.</p>" }, mobileFontSize: { value: 14, unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-AU_CDh6MOl", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }], sequence: 5, pageId: "FYBFsBAezEtsY0uXW4IN", funnelId: "pK3yy9CFapchugRrgjgq", locationId: "Gc2kgDDpABIR8QDyJ6rf", general: { colors: [{ label: "Black", value: "#000000" }, { label: "Red", value: "#e93d3d" }, { label: "Transparent", value: "transparent" }, { label: "my-custom-color-44", name: "My Custom Color 44", value: "#ec606a" }], fontsForPreview: ["'Oswald'", "'Lato'"], rootVars: { "--'oswald'": "'Oswald'", "--'lato'": "'Lato'", "--black": "#000000", "--red": "#e93d3d", "--transparent": "transparent", "--my-custom-color-44": "#ec606a" }, sectionStyles: ":root{--black:#000000;--red:#e93d3d;--transparent:transparent;--my-custom-color-44:#ec606a}.hl_page-preview--content .col-CAyTxea5q .inner,.hl_page-preview--content .row-BafyFVpahF,.hl_page-preview--content .section-MCURKhaM7{padding:20px 0 90px;margin-top:0;margin-bottom:0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .col-CAyTxea5q .inner,.hl_page-preview--content .row-BafyFVpahF{padding:15px 0;width:100%}.hl_page-preview--content .col-CAyTxea5q{width:100%}.hl_page-preview--content .col-CAyTxea5q .inner{padding:10px 5px}.hl_page-preview--content .image-2hPEEKf7g{margin-top:0;margin-bottom:0}.hl_page-preview--content .cimage-2hPEEKf7g{padding:10px;background-color:var(--transparent);opacity:1;text-align:center}.hl_page-preview--content .sub-heading-MbvugAQFJf{margin:0}.hl_page-preview--content .csub-heading-MbvugAQFJf,.hl_page-preview--content .row-DTaBn6Nkpv{background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .csub-heading-MbvugAQFJf{font-family:var(--headlinefont);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;line-height:1.3em;letter-spacing:0;text-align:center}.hl_page-preview--content .row-DTaBn6Nkpv{margin-top:0;margin-bottom:0;padding:15px 0;width:100%}.hl_page-preview--content .col-uYMJwyEml{width:100%}.hl_page-preview--content .col-FIkE81-ke .inner,.hl_page-preview--content .col-qanoGGetC .inner,.hl_page-preview--content .col-uYMJwyEml .inner{padding:10px 5px 10px 70px;background-color:var(--transparent);width:100%;border-color:var(--black);border-width:2px;border-style:solid;margin-top:0;margin-bottom:0}.hl_page-preview--content .paragraph-F9SB3vFfN{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-F9SB3vFfN{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .paragraph-PwtXX77o4{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-PwtXX77o4{font-family:var(--contentfont);background-color:var(--transparent);color:var(--red);icon-color:var(--text-color);font-weight:400;padding:0 0 10px;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .col-FIkE81-ke{width:100%}.hl_page-preview--content .paragraph-Ud7-Hmgyun{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-Ud7-Hmgyun{font-family:var(--contentfont);background-color:var(--transparent);color:var(--red);icon-color:var(--text-color);font-weight:400;padding:0 0 10px;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .paragraph-ECP1xCEVEa{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-ECP1xCEVEa{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .col-qanoGGetC{width:100%}.hl_page-preview--content .paragraph-Dt21hDz3On{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-Dt21hDz3On{font-family:var(--contentfont);background-color:var(--transparent);color:var(--red);icon-color:var(--text-color);font-weight:400;padding:0 0 10px;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .paragraph-AU_CDh6MOl{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-AU_CDh6MOl{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}#section-MCURKhaM7>.inner{max-width:1170px}#col-CAyTxea5q>.inner{flex-direction:column;justify-content:center;align-items:inherit;flex-wrap:nowrap}.sub-heading-MbvugAQFJf{font-weight:400}.paragraph-F9SB3vFfN em,.paragraph-F9SB3vFfN strong,.paragraph-F9SB3vFfN u,.paragraph-PwtXX77o4 em,.paragraph-PwtXX77o4 u,.paragraph-Ud7-Hmgyun em,.paragraph-Ud7-Hmgyun u,.sub-heading-MbvugAQFJf em,.sub-heading-MbvugAQFJf strong,.sub-heading-MbvugAQFJf u{color:var(--text-color)!important}.paragraph-AU_CDh6MOl a,.paragraph-AU_CDh6MOl a *,.paragraph-Dt21hDz3On a,.paragraph-Dt21hDz3On a *,.paragraph-ECP1xCEVEa a,.paragraph-ECP1xCEVEa a *,.paragraph-F9SB3vFfN a,.paragraph-F9SB3vFfN a *,.paragraph-PwtXX77o4 a,.paragraph-PwtXX77o4 a *,.paragraph-Ud7-Hmgyun a,.paragraph-Ud7-Hmgyun a *,.sub-heading-MbvugAQFJf a,.sub-heading-MbvugAQFJf a *{color:var(--link-color)!important;text-decoration:none}.paragraph-AU_CDh6MOl a:hover,.paragraph-Dt21hDz3On a:hover,.paragraph-ECP1xCEVEa a:hover,.paragraph-F9SB3vFfN a:hover,.paragraph-PwtXX77o4 a:hover,.paragraph-Ud7-Hmgyun a:hover,.sub-heading-MbvugAQFJf a:hover{text-decoration:underline}@media screen and (min-width:0px) and (max-width:480px){.sub-heading-MbvugAQFJf h1,.sub-heading-MbvugAQFJf h2,.sub-heading-MbvugAQFJf h3,.sub-heading-MbvugAQFJf h4,.sub-heading-MbvugAQFJf h5,.sub-heading-MbvugAQFJf h6,.sub-heading-MbvugAQFJf ul li,.sub-heading-MbvugAQFJf.text-output{font-size:46px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.sub-heading-MbvugAQFJf h1,.sub-heading-MbvugAQFJf h2,.sub-heading-MbvugAQFJf h3,.sub-heading-MbvugAQFJf h4,.sub-heading-MbvugAQFJf h5,.sub-heading-MbvugAQFJf h6,.sub-heading-MbvugAQFJf ul li,.sub-heading-MbvugAQFJf.text-output{font-size:46px!important;font-weight:undefined}}.paragraph-AU_CDh6MOl.text-output h1:first-child:before,.paragraph-AU_CDh6MOl.text-output h2:first-child:before,.paragraph-AU_CDh6MOl.text-output h3:first-child:before,.paragraph-AU_CDh6MOl.text-output h4:first-child:before,.paragraph-AU_CDh6MOl.text-output h5:first-child:before,.paragraph-AU_CDh6MOl.text-output h6:first-child:before,.paragraph-AU_CDh6MOl.text-output p:first-child:before,.paragraph-Dt21hDz3On.text-output h1:first-child:before,.paragraph-Dt21hDz3On.text-output h2:first-child:before,.paragraph-Dt21hDz3On.text-output h3:first-child:before,.paragraph-Dt21hDz3On.text-output h4:first-child:before,.paragraph-Dt21hDz3On.text-output h5:first-child:before,.paragraph-Dt21hDz3On.text-output h6:first-child:before,.paragraph-Dt21hDz3On.text-output p:first-child:before,.paragraph-ECP1xCEVEa.text-output h1:first-child:before,.paragraph-ECP1xCEVEa.text-output h2:first-child:before,.paragraph-ECP1xCEVEa.text-output h3:first-child:before,.paragraph-ECP1xCEVEa.text-output h4:first-child:before,.paragraph-ECP1xCEVEa.text-output h5:first-child:before,.paragraph-ECP1xCEVEa.text-output h6:first-child:before,.paragraph-ECP1xCEVEa.text-output p:first-child:before,.paragraph-F9SB3vFfN.text-output h1:first-child:before,.paragraph-F9SB3vFfN.text-output h2:first-child:before,.paragraph-F9SB3vFfN.text-output h3:first-child:before,.paragraph-F9SB3vFfN.text-output h4:first-child:before,.paragraph-F9SB3vFfN.text-output h5:first-child:before,.paragraph-F9SB3vFfN.text-output h6:first-child:before,.paragraph-F9SB3vFfN.text-output p:first-child:before,.paragraph-PwtXX77o4.text-output h1:first-child:before,.paragraph-PwtXX77o4.text-output h2:first-child:before,.paragraph-PwtXX77o4.text-output h3:first-child:before,.paragraph-PwtXX77o4.text-output h4:first-child:before,.paragraph-PwtXX77o4.text-output h5:first-child:before,.paragraph-PwtXX77o4.text-output h6:first-child:before,.paragraph-PwtXX77o4.text-output p:first-child:before,.paragraph-Ud7-Hmgyun.text-output h1:first-child:before,.paragraph-Ud7-Hmgyun.text-output h2:first-child:before,.paragraph-Ud7-Hmgyun.text-output h3:first-child:before,.paragraph-Ud7-Hmgyun.text-output h4:first-child:before,.paragraph-Ud7-Hmgyun.text-output h5:first-child:before,.paragraph-Ud7-Hmgyun.text-output h6:first-child:before,.paragraph-Ud7-Hmgyun.text-output p:first-child:before,.sub-heading-MbvugAQFJf.text-output h1:first-child:before,.sub-heading-MbvugAQFJf.text-output h2:first-child:before,.sub-heading-MbvugAQFJf.text-output h3:first-child:before,.sub-heading-MbvugAQFJf.text-output h4:first-child:before,.sub-heading-MbvugAQFJf.text-output h5:first-child:before,.sub-heading-MbvugAQFJf.text-output h6:first-child:before,.sub-heading-MbvugAQFJf.text-output p:first-child:before{color:var(--text-color);content:'\\';\n font-family: '';margin-right:5px;font-weight:700}#col-FIkE81-ke>.inner,#col-qanoGGetC>.inner,#col-uYMJwyEml>.inner{flex-direction:column;justify-content:flex-start;align-items:inherit;flex-wrap:nowrap}.paragraph-AU_CDh6MOl,.paragraph-Dt21hDz3On,.paragraph-ECP1xCEVEa,.paragraph-F9SB3vFfN,.paragraph-PwtXX77o4,.paragraph-Ud7-Hmgyun{font-weight:undefined}@media screen and (min-width:0px) and (max-width:480px){.paragraph-F9SB3vFfN h1,.paragraph-F9SB3vFfN h2,.paragraph-F9SB3vFfN h3,.paragraph-F9SB3vFfN h4,.paragraph-F9SB3vFfN h5,.paragraph-F9SB3vFfN h6,.paragraph-F9SB3vFfN ul li,.paragraph-F9SB3vFfN.text-output{font-size:14px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-F9SB3vFfN h1,.paragraph-F9SB3vFfN h2,.paragraph-F9SB3vFfN h3,.paragraph-F9SB3vFfN h4,.paragraph-F9SB3vFfN h5,.paragraph-F9SB3vFfN h6,.paragraph-F9SB3vFfN ul li,.paragraph-F9SB3vFfN.text-output{font-size:16px!important;font-weight:undefined}}.paragraph-PwtXX77o4 strong,.paragraph-Ud7-Hmgyun strong{color:var(--my-custom-color-44)!important}@media screen and (min-width:0px) and (max-width:480px){.paragraph-PwtXX77o4 h1,.paragraph-PwtXX77o4 h2,.paragraph-PwtXX77o4 h3,.paragraph-PwtXX77o4 h4,.paragraph-PwtXX77o4 h5,.paragraph-PwtXX77o4 h6,.paragraph-PwtXX77o4 ul li,.paragraph-PwtXX77o4.text-output{font-size:20px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-PwtXX77o4 h1,.paragraph-PwtXX77o4 h2,.paragraph-PwtXX77o4 h3,.paragraph-PwtXX77o4 h4,.paragraph-PwtXX77o4 h5,.paragraph-PwtXX77o4 h6,.paragraph-PwtXX77o4 ul li,.paragraph-PwtXX77o4.text-output{font-size:22px!important;font-weight:undefined}}@media screen and (min-width:0px) and (max-width:480px){.paragraph-Ud7-Hmgyun h1,.paragraph-Ud7-Hmgyun h2,.paragraph-Ud7-Hmgyun h3,.paragraph-Ud7-Hmgyun h4,.paragraph-Ud7-Hmgyun h5,.paragraph-Ud7-Hmgyun h6,.paragraph-Ud7-Hmgyun ul li,.paragraph-Ud7-Hmgyun.text-output{font-size:20px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-Ud7-Hmgyun h1,.paragraph-Ud7-Hmgyun h2,.paragraph-Ud7-Hmgyun h3,.paragraph-Ud7-Hmgyun h4,.paragraph-Ud7-Hmgyun h5,.paragraph-Ud7-Hmgyun h6,.paragraph-Ud7-Hmgyun ul li,.paragraph-Ud7-Hmgyun.text-output{font-size:22px!important;font-weight:undefined}}.paragraph-AU_CDh6MOl em,.paragraph-Dt21hDz3On em,.paragraph-Dt21hDz3On u,.paragraph-ECP1xCEVEa em,.paragraph-ECP1xCEVEa strong,.paragraph-ECP1xCEVEa u{color:var(--text-color)!important}@media screen and (min-width:0px) and (max-width:480px){.paragraph-ECP1xCEVEa h1,.paragraph-ECP1xCEVEa h2,.paragraph-ECP1xCEVEa h3,.paragraph-ECP1xCEVEa h4,.paragraph-ECP1xCEVEa h5,.paragraph-ECP1xCEVEa h6,.paragraph-ECP1xCEVEa ul li,.paragraph-ECP1xCEVEa.text-output{font-size:14px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-ECP1xCEVEa h1,.paragraph-ECP1xCEVEa h2,.paragraph-ECP1xCEVEa h3,.paragraph-ECP1xCEVEa h4,.paragraph-ECP1xCEVEa h5,.paragraph-ECP1xCEVEa h6,.paragraph-ECP1xCEVEa ul li,.paragraph-ECP1xCEVEa.text-output{font-size:16px!important;font-weight:undefined}}.paragraph-Dt21hDz3On strong{color:var(--my-custom-color-44)!important}@media screen and (min-width:0px) and (max-width:480px){.paragraph-Dt21hDz3On h1,.paragraph-Dt21hDz3On h2,.paragraph-Dt21hDz3On h3,.paragraph-Dt21hDz3On h4,.paragraph-Dt21hDz3On h5,.paragraph-Dt21hDz3On h6,.paragraph-Dt21hDz3On ul li,.paragraph-Dt21hDz3On.text-output{font-size:20px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-Dt21hDz3On h1,.paragraph-Dt21hDz3On h2,.paragraph-Dt21hDz3On h3,.paragraph-Dt21hDz3On h4,.paragraph-Dt21hDz3On h5,.paragraph-Dt21hDz3On h6,.paragraph-Dt21hDz3On ul li,.paragraph-Dt21hDz3On.text-output{font-size:22px!important;font-weight:undefined}}.paragraph-AU_CDh6MOl strong,.paragraph-AU_CDh6MOl u{color:var(--text-color)!important}@media screen and (min-width:0px) and (max-width:480px){.paragraph-AU_CDh6MOl h1,.paragraph-AU_CDh6MOl h2,.paragraph-AU_CDh6MOl h3,.paragraph-AU_CDh6MOl h4,.paragraph-AU_CDh6MOl h5,.paragraph-AU_CDh6MOl h6,.paragraph-AU_CDh6MOl ul li,.paragraph-AU_CDh6MOl.text-output{font-size:14px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-AU_CDh6MOl h1,.paragraph-AU_CDh6MOl h2,.paragraph-AU_CDh6MOl h3,.paragraph-AU_CDh6MOl h4,.paragraph-AU_CDh6MOl h5,.paragraph-AU_CDh6MOl h6,.paragraph-AU_CDh6MOl ul li,.paragraph-AU_CDh6MOl.text-output{font-size:16px!important;font-weight:undefined}}" } }, ctaBanner: { id: "section--JU5JdhYV", metaData: { id: "section--JU5JdhYV", type: "section", child: ["row-CazIBfKqbz"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: "100" }, paddingTop: { unit: "px", value: "100" }, marginTop: { unit: "px", value: "0" }, marginBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "https://firebasestorage.googleapis.com/v0/b/highlevel-backend.appspot.com/o/location%2Fh0gYqQIqOIBs6xxgZjft%2Fimages%2F9ef53318-6f0a-409c-ada2-11d53ce1a6e5.jpeg?alt=media", opacity: "1", options: "full-center", servingUrl: "https://lh3.googleusercontent.com/sT5WiBSUQqVKzeevrcTjiz6CoqIQlZQZ3VcYusidOhHeM9Mwv5fi5NZSODOUk5mCVR1n2H0OPR8OybU0kG5ANkDME4rqFDY", placeholderBase64: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgUDAwMEAwMEBQgFBQoEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUCg4BAwQEBQQFCQUFCRINCw0UFBQSFA4SFRINChQVFBQUDxQNDRUSDgoQFBQUFBQOFBQSCgoVFAoVCg4UDA4QCAgKCP/AABEIAAMACgMBEQACEQEDEQH/xAAVAAEBAAAAAAAAAAAAAAAAAAAIBf/EAB4QAQABAgcAAAAAAAAAAAAAAAERAJECAwQFEyFR/8QAFQEBAQAAAAAAAAAAAAAAAAAABQT/xAAZEQEBAAMBAAAAAAAAAAAAAAABAAMEEgL/2gAMAwEAAhEDEQA/AHrsMGZqQAOdxMESykvr0WofAr1N7IB5atVdDf/Z", imageMeta: { height: 537, width: 1920 } } }, allowRowMaxWidth: { value: false } }, wrapper: {}, meta: "section", tagName: "c-section", title: "Section", _id: "section--JU5JdhYV", mobileStyles: { paddingTop: { unit: "px", value: 60 }, paddingBottom: { unit: "px", value: 60 } } }, elements: [{ id: "row-CazIBfKqbz", type: "row", child: ["col-fbo_QJCXqk", "col-fwNPlL8ta"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 15 }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, rowWidth: { value: 100, unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-row", meta: "row", title: "2 Column Row" }, { id: "col-fbo_QJCXqk", type: "col", child: [], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: 38.6, unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: true } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { id: "col-fwNPlL8ta", type: "col", child: ["sub-heading-JJ_mZmXWcY", "paragraph-NAh24LKg8A", "button-H3ED7jvqBu"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: 61.4, unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cparagraph-NAh24LKg8A", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>At {{location.name}}, we offer a comprehensive range of treatments tailored to meet your unique beauty and wellness needs. Each service is designed to deliver exceptional results, ensuring you leave our spa feeling revitalized, confident, and radiant.</p>" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "18", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: "1.4", unit: "em" }, textTransform: { value: "none" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-NAh24LKg8A", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cbutton-H3ED7jvqBu", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "free consultation" }, subText: { value: "" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, subTextDesktopFontSize: { value: 15, unit: "px" }, subTextMobileFontSize: { value: 15, unit: "px" }, typography: { value: "var(--headlinefont)" }, iconStart: { value: { name: "", unicode: "", fontFamily: "" } }, iconEnd: { value: { name: "", unicode: "", fontFamily: "" } }, action: { value: "url" }, visitWebsite: { value: { url: "#", newTab: false } }, hideElements: { value: [] }, scrollToElement: { value: "" }, phoneNumber: { value: "" }, productId: { value: "" }, stepPath: { value: "" }, saleAction: { value: "go-to-next-funnel-step" } }, class: { buttonEffects: { value: "none" }, buttonBoxShadow: { value: "btnshadow" }, buttonBgStyle: { value: "custom", text: "Custom", targetConfig: { styles: {} } }, buttonVp: { value: "btn-vp" }, buttonHp: { value: "btn-hp" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--my-custom-color-44)" }, color: { value: "var(--white)" }, secondaryColor: { value: "var(--white)" }, textDecoration: { value: "none" }, paddingTop: { unit: "px", value: "12" }, paddingBottom: { unit: "px", value: "12" }, paddingLeft: { unit: "px", value: "30" }, paddingRight: { value: "30", unit: "px" }, fontWeight: { value: "bold" }, borderColor: { value: "var(--secondary)" }, borderWidth: { value: 3, unit: "px" }, borderStyle: { value: "solid" }, letterSpacing: { value: "0", unit: "px" }, textTransform: { value: "uppercase" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, width: { value: "auto", unit: "%" } }, wrapper: { marginTop: { unit: "px", value: "30" }, marginBottom: { unit: "px", value: 0 }, textAlign: { value: "left" } }, customCss: [], id: "button-H3ED7jvqBu", type: "element", child: [], meta: "button", tagName: "c-button", title: "Button", tag: "" }, { extra: { nodeId: "csub-heading-JJ_mZmXWcY", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<h2>ALL KINDS OF TREATMENTS</h2>" }, mobileFontSize: { value: 60, unit: "px" }, desktopFontSize: { value: 60, unit: "px" }, typography: { value: "var(--headlinefont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } }, customClass: { value: [] } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal", desktop: "400" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 } }, customCss: [], id: "sub-heading-JJ_mZmXWcY", type: "element", child: [], mobileStyles: {}, mobileWrapper: {}, meta: "sub-heading", tagName: "c-sub-heading", title: "Sub Headline", tag: "h3" }], sequence: 6, pageId: "FYBFsBAezEtsY0uXW4IN", funnelId: "pK3yy9CFapchugRrgjgq", locationId: "Gc2kgDDpABIR8QDyJ6rf", general: { colors: [{ value: "#188bf6", label: "Secondary" }, { label: "White", value: "#ffffff" }, { label: "Black", value: "#000000" }, { label: "Transparent", value: "transparent" }, { label: "my-custom-color-44", name: "My Custom Color 44", value: "#ec606a" }], fontsForPreview: ["'Lato'", "'Oswald'"], rootVars: { "--'lato'": "'Lato'", "--'oswald'": "'Oswald'", "--secondary": "#188bf6", "--white": "#ffffff", "--black": "#000000", "--transparent": "transparent", "--my-custom-color-44": "#ec606a" }, sectionStyles: ":root{--secondary:#188bf6;--white:#ffffff;--black:#000000;--transparent:transparent;--my-custom-color-44:#ec606a}.hl_page-preview--content .section--JU5JdhYV{padding:100px 0;margin-top:0;margin-bottom:0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}@media screen and (min-width:0px) and (max-width:480px){.hl_page-preview--content .section--JU5JdhYV{padding-top:60px;padding-bottom:60px}}.hl_page-preview--content .col-fbo_QJCXqk .inner,.hl_page-preview--content .col-fwNPlL8ta .inner,.hl_page-preview--content .row-CazIBfKqbz{margin-top:0;margin-bottom:0;padding:15px 0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid;width:100%}.hl_page-preview--content .col-fbo_QJCXqk{width:38.6%}.hl_page-preview--content .col-fbo_QJCXqk .inner,.hl_page-preview--content .col-fwNPlL8ta .inner{padding:10px 5px;width:38.6%}.hl_page-preview--content .col-fwNPlL8ta{width:61.4%}.hl_page-preview--content .col-fwNPlL8ta .inner{width:61.4%}.hl_page-preview--content .paragraph-NAh24LKg8A{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-NAh24LKg8A{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.4em;text-transform:none;letter-spacing:0;text-align:left}.hl_page-preview--content .button-H3ED7jvqBu{margin-top:30px;margin-bottom:0;text-align:left}.hl_page-preview--content .cbutton-H3ED7jvqBu{font-family:var(--headlinefont);background-color:var(--my-custom-color-44);color:var(--white);secondary-color:var(--white);text-decoration:none;padding:12px 30px;font-weight:700;border-color:var(--secondary);border-width:3px;border-style:solid;letter-spacing:0;text-transform:uppercase;text-shadow:0 0 0 transparent;width:auto%}.hl_page-preview--content .sub-heading-JJ_mZmXWcY{margin:0}.hl_page-preview--content .csub-heading-JJ_mZmXWcY{font-family:var(--headlinefont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}#section--JU5JdhYV>.inner{max-width:1170px}#col-fbo_QJCXqk>.inner,#col-fwNPlL8ta>.inner{flex-direction:column;justify-content:center;align-items:inherit;flex-wrap:nowrap}.paragraph-NAh24LKg8A{font-weight:undefined}.paragraph-NAh24LKg8A em,.paragraph-NAh24LKg8A strong,.paragraph-NAh24LKg8A u,.sub-heading-JJ_mZmXWcY em,.sub-heading-JJ_mZmXWcY strong,.sub-heading-JJ_mZmXWcY u{color:var(--text-color)!important}.paragraph-NAh24LKg8A a,.paragraph-NAh24LKg8A a *,.sub-heading-JJ_mZmXWcY a,.sub-heading-JJ_mZmXWcY a *{color:var(--link-color)!important;text-decoration:none}.paragraph-NAh24LKg8A a:hover,.sub-heading-JJ_mZmXWcY a:hover{text-decoration:underline}@media screen and (min-width:0px) and (max-width:480px){.paragraph-NAh24LKg8A h1,.paragraph-NAh24LKg8A h2,.paragraph-NAh24LKg8A h3,.paragraph-NAh24LKg8A h4,.paragraph-NAh24LKg8A h5,.paragraph-NAh24LKg8A h6,.paragraph-NAh24LKg8A ul li,.paragraph-NAh24LKg8A.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-NAh24LKg8A h1,.paragraph-NAh24LKg8A h2,.paragraph-NAh24LKg8A h3,.paragraph-NAh24LKg8A h4,.paragraph-NAh24LKg8A h5,.paragraph-NAh24LKg8A h6,.paragraph-NAh24LKg8A ul li,.paragraph-NAh24LKg8A.text-output{font-size:18px!important;font-weight:undefined}}.paragraph-NAh24LKg8A.text-output h1:first-child:before,.paragraph-NAh24LKg8A.text-output h2:first-child:before,.paragraph-NAh24LKg8A.text-output h3:first-child:before,.paragraph-NAh24LKg8A.text-output h4:first-child:before,.paragraph-NAh24LKg8A.text-output h5:first-child:before,.paragraph-NAh24LKg8A.text-output h6:first-child:before,.paragraph-NAh24LKg8A.text-output p:first-child:before,.sub-heading-JJ_mZmXWcY.text-output h1:first-child:before,.sub-heading-JJ_mZmXWcY.text-output h2:first-child:before,.sub-heading-JJ_mZmXWcY.text-output h3:first-child:before,.sub-heading-JJ_mZmXWcY.text-output h4:first-child:before,.sub-heading-JJ_mZmXWcY.text-output h5:first-child:before,.sub-heading-JJ_mZmXWcY.text-output h6:first-child:before,.sub-heading-JJ_mZmXWcY.text-output p:first-child:before{color:var(--text-color);content:'\\';\n font-family: '';margin-right:5px;font-weight:700}@media screen and (min-width:481px) and (max-width:10000px){.button-H3ED7jvqBu .button-icon-end,.button-H3ED7jvqBu .button-icon-start,.button-H3ED7jvqBu .main-heading-button{font-size:16px;font-weight:undefined}.button-H3ED7jvqBu .button-icon-start{margin-right:5px}.button-H3ED7jvqBu .button-icon-end{margin-left:5px}.button-H3ED7jvqBu .sub-heading-button{font-size:15px;color:var(--white);font-weight:undefined}}@media screen and (min-width:0px) and (max-width:480px){.button-H3ED7jvqBu .button-icon-end,.button-H3ED7jvqBu .button-icon-start,.button-H3ED7jvqBu .main-heading-button{font-size:16px;font-weight:undefined}.button-H3ED7jvqBu .button-icon-start{margin-right:5px}.button-H3ED7jvqBu .button-icon-end{margin-left:5px}.button-H3ED7jvqBu .sub-heading-button{font-size:15px;color:var(--white);font-weight:undefined}}.sub-heading-JJ_mZmXWcY{font-weight:400}@media screen and (min-width:0px) and (max-width:480px){.sub-heading-JJ_mZmXWcY h1,.sub-heading-JJ_mZmXWcY h2,.sub-heading-JJ_mZmXWcY h3,.sub-heading-JJ_mZmXWcY h4,.sub-heading-JJ_mZmXWcY h5,.sub-heading-JJ_mZmXWcY h6,.sub-heading-JJ_mZmXWcY ul li,.sub-heading-JJ_mZmXWcY.text-output{font-size:60px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.sub-heading-JJ_mZmXWcY h1,.sub-heading-JJ_mZmXWcY h2,.sub-heading-JJ_mZmXWcY h3,.sub-heading-JJ_mZmXWcY h4,.sub-heading-JJ_mZmXWcY h5,.sub-heading-JJ_mZmXWcY h6,.sub-heading-JJ_mZmXWcY ul li,.sub-heading-JJ_mZmXWcY.text-output{font-size:60px!important;font-weight:undefined}}" } }, faq: { id: "section-zJJ17L55C_", metaData: { id: "section-zJJ17L55C_", type: "section", child: ["row-zwaPMb51Ig", "row-B3nlfUUX-J"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: 40 }, paddingTop: { unit: "px", value: 40 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { mediaType: "image", url: "", opacity: "1", options: "bgCover", svgCode: "", videoUrl: "", videoThumbnail: "", videoLoop: true } }, allowRowMaxWidth: { value: false }, customClass: { value: [] } }, wrapper: {}, meta: "section", tagName: "c-section", title: "FAQs", mobileStyles: {}, mobileWrapper: {}, _id: "section-zJJ17L55C_", isGlobal: true }, elements: [{ id: "row-B3nlfUUX-J", type: "row", child: ["col-TgLmpbuj1O", "col-qmvDyClR0p"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 15 }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { mediaType: "image", url: "", opacity: "1", options: "bgCover", svgCode: "", videoUrl: "", videoThumbnail: "", videoLoop: true } }, rowWidth: { value: 100, unit: "%" }, customClass: { value: [] } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "", value: "auto" }, marginRight: { unit: "", value: "auto" } }, tagName: "c-row", meta: "row", title: "2 Column Row", mobileStyles: {}, mobileWrapper: {} }, { id: "col-TgLmpbuj1O", type: "col", child: ["faq-hC9kdZlk9d"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { unit: "px", value: 10 }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { mediaType: "image", url: "", opacity: "1", options: "bgCover", svgCode: "", videoUrl: "", videoThumbnail: "", videoLoop: true } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "flex-start" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true }, customClass: { value: [] }, elementVersion: { value: 2 } }, wrapper: { marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column", mobileStyles: {}, mobileWrapper: {} }, { extra: { nodeId: "cfaq-hC9kdZlk9d", faqType: { value: "simple" }, faqList: { value: [{ id: 1, heading: "<h4>What should I expect during my first visit?</h4>", text: "<p>Your first visit begins with a comprehensive consultation where our experts will assess your skin and discuss your aesthetic goals. We will recommend personalized treatment options and answer any questions you may have to ensure you feel comfortable and informed.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: true, compression: true }, { id: 2, heading: "<h4>Are your treatments safe?</h4>", text: "<p>Yes, all our treatments are performed by highly trained and certified professionals using state-of-the-art equipment and techniques. We prioritize your safety and comfort, adhering to the highest standards of medical care and hygiene.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: false, compression: true }, { id: 3, heading: "<h4>How do I know which treatment is right for me?</h4>", text: "<p>Our team will guide you through the selection process during your initial consultation. We\u2019ll evaluate your skin type, concerns, and goals to recommend the most suitable treatments to achieve the best results for you.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: false, compression: true }] }, typography: { value: "var(--contentfont)" }, faqCustomOptions: { value: { openIcon: { color: "var(--black)", fontFamily: "Font Awesome 5 Free", name: "chevron-down", unicode: "f078" }, closeIcon: { color: "var(--black)", fontFamily: "Font Awesome 5 Free", name: "chevron-up", unicode: "f077" }, iconPosition: "left", lineHeight: "1.5", showImagePopup: true, expandAllToggle: false, expandAll: true, firstItemOpen: false } }, featureHeadlineDesktopFontSize: { value: 20, unit: "px" }, featureHeadlineMobileFontSize: { value: 15, unit: "px" }, desktopFontSize: { value: 15, unit: "px" }, mobileFontSize: { value: 12, unit: "px" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, customClass: { value: [] } }, mobileExtra: {}, class: { borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" }, boxShadow: { value: "none" } }, styles: { faqOpenTitleTextColor: { value: "var(--white)" }, faqOpenTitleBackgroundColor: { value: "var(--my-custom-color-44)" }, faqDividerColor: { value: "var(--my-custom-color-16)" }, faqContentTextColor: { value: "var(--my-custom-color-26)" }, faqOpenBackgroundColor: { value: "var(--white)" }, faqClosedTitleTextColor: { value: "var(--my-custom-color-26)" }, faqClosedTitleBackgroundColor: { value: "var(--my-custom-color-60)" }, faqExpandAllButtonTextColor: { value: "var(--my-custom-color-44)" }, faqExpandAllButtonBorderColor: { value: "#D1D5DB" }, faqExpandAllButtonBackgroundColor: { value: "var(--transparent)" }, linkTextColor: { value: "#3B82F6" }, faqHeadingFontFamily: { value: "var(--headlinefont)" }, faqContentFontFamily: { value: "var(--contentfont)" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { unit: "px", value: 0 }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, borderColor: { value: "var(--black)" }, borderStyle: { value: "solid" }, borderWidth: { value: "2", unit: "px" }, fontWeight: { value: "bold", desktop: "400" }, fontWeightSub: { desktop: "400" } }, wrapper: {}, customCss: [], id: "faq-hC9kdZlk9d", version: 2, type: "element", child: [], meta: "faq", tagName: "c-faq", title: "FAQ", tag: "" }, { id: "col-qmvDyClR0p", type: "col", child: ["faq-xt8Q865Gfb"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 10 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { mediaType: "image", url: "", opacity: "1", options: "bgCover", svgCode: "", videoUrl: "", videoThumbnail: "", videoLoop: true } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "flex-start" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true }, customClass: { value: [] }, elementVersion: { value: 2 } }, wrapper: { marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "2nd Column", mobileStyles: {}, mobileWrapper: {} }, { extra: { nodeId: "cfaq-xt8Q865Gfb", faqType: { value: "simple" }, faqList: { value: [{ id: 1, heading: "<h4>Is there any downtime after treatments?</h4>", text: "<p>Most of our treatments are non-invasive or minimally invasive, requiring little to no downtime. However, the recovery time can vary depending on the specific treatment. During your consultation, we will provide detailed post-treatment care instructions and inform you about any necessary recovery time.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: true, compression: true }, { id: 2, heading: "<h4>How often should I schedule treatments?</h4>", text: "<p>The frequency of treatments depends on the type of service and your individual needs. Some treatments, like facials, may be done monthly, while others, like laser hair removal, may require a series of sessions spaced several weeks apart. We will create a personalized treatment plan to ensure optimal results.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: false, compression: true }, { id: 3, heading: "<h4>Do you offer packages or memberships?</h4>", text: "<p>Yes, we offer a variety of packages and memberships designed to provide you with ongoing care and savings. Our packages bundle popular treatments for comprehensive care, while our memberships offer exclusive benefits and discounts. Contact us to learn more about our current offerings and find the perfect plan for your needs.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: false, compression: true }] }, typography: { value: "var(--contentfont)" }, faqCustomOptions: { value: { openIcon: { color: "var(--black)", fontFamily: "Font Awesome 5 Free", name: "chevron-down", unicode: "f078" }, closeIcon: { color: "var(--black)", fontFamily: "Font Awesome 5 Free", name: "chevron-up", unicode: "f077" }, iconPosition: "left", lineHeight: "1.5", showImagePopup: true, expandAllToggle: false, expandAll: true, firstItemOpen: false } }, featureHeadlineDesktopFontSize: { value: 20, unit: "px" }, featureHeadlineMobileFontSize: { value: 15, unit: "px" }, desktopFontSize: { value: 15, unit: "px" }, mobileFontSize: { value: 12, unit: "px" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, customClass: { value: [] } }, mobileExtra: {}, class: { borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" }, boxShadow: { value: "none" } }, styles: { faqOpenTitleTextColor: { value: "var(--white)" }, faqOpenTitleBackgroundColor: { value: "var(--my-custom-color-44)" }, faqDividerColor: { value: "var(--my-custom-color-16)" }, faqContentTextColor: { value: "var(--my-custom-color-26)" }, faqOpenBackgroundColor: { value: "var(--white)" }, faqClosedTitleTextColor: { value: "var(--my-custom-color-26)" }, faqClosedTitleBackgroundColor: { value: "var(--my-custom-color-60)" }, faqExpandAllButtonTextColor: { value: "var(--my-custom-color-44)" }, faqExpandAllButtonBorderColor: { value: "#D1D5DB" }, faqExpandAllButtonBackgroundColor: { value: "var(--my-custom-color-26)" }, linkTextColor: { value: "#3B82F6" }, faqHeadingFontFamily: { value: "var(--headlinefont)" }, faqContentFontFamily: { value: "var(--contentfont)" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { unit: "px", value: 0 }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, borderColor: { value: "var(--black)" }, borderStyle: { value: "solid" }, borderWidth: { value: "2", unit: "px" }, fontWeight: { value: "bold", desktop: "400" }, fontWeightSub: { desktop: "400" } }, wrapper: {}, customCss: [], id: "faq-xt8Q865Gfb", version: 2, type: "element", child: [], meta: "faq", tagName: "c-faq", title: "FAQ", tag: "" }, { id: "row-zwaPMb51Ig", type: "row", child: ["col-uV9_D99Gtm"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 15 }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { mediaType: "image", url: "", opacity: "1", options: "bgCover", svgCode: "", videoUrl: "", videoThumbnail: "", videoLoop: true } }, rowWidth: { value: 100, unit: "%" }, customClass: { value: [] } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "", value: "auto" }, marginRight: { unit: "", value: "auto" } }, tagName: "c-row", meta: "row", title: "1 Column Row", mobileStyles: {}, mobileWrapper: {} }, { id: "col-uV9_D99Gtm", type: "col", child: ["sub-heading-bQudNu4eBG", "image-VMrslNNuUy"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { mediaType: "image", url: "", opacity: "1", options: "bgCover", svgCode: "", videoUrl: "", videoThumbnail: "", videoLoop: true } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true }, customClass: { value: [] }, elementVersion: { value: 2 } }, wrapper: { marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column", mobileStyles: {}, mobileWrapper: {} }, { extra: { nodeId: "cimage-VMrslNNuUy", visibility: { value: { hideDesktop: false, hideMobile: false } }, imageActions: { value: "none" }, visitWebsite: { value: { url: "", newTab: false } }, imageProperties: { value: { width: "", height: "", url: "https://storage.googleapis.com/msgsndr/locatation/EVTjG29VnVlvwn3SRGve/images/e04c0629-2eca-41d4-a320-ef634015616a.png", altText: "", compression: true, placeholderBase64: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAYAAABhYU3QAAAABHNCSVQICAgIfAhkiAAAAF96VFh0UmF3IHByb2ZpbGUgdHlwZSBBUFAxAAAImeNKT81LLcpMVigoyk/LzEnlUgADYxMuE0sTS6NEAwMDCwMIMDQwMDYEkkZAtjlUKNEABZgamFmaGZsZmgMxiM8FAEi2FMk61EMyAAAAVklEQVQImQXBMQ5AMBiA0a+tFpGIpBKLmRs4kCO5iMl9LMwmaUr93lPHtg7GGBsB9YYra9pZo8r73BdTe++AlNKTUVWjQGEBERcVFMJXuq6ftEguABB+L0UZOFcVeFYAAAAASUVORK5CYII=", servingUrl: "https://lh3.googleusercontent.com/8DcV-wSbJBKHjx-cmwagHA3SspBD4P3ScvvmZZog37NoIdaprLI5vt2nY7nfrqeCFVLFa0YTcL7jR3soFjmRqbNiESGeZ1Nm", imageMeta: { width: "", height: "" } } } }, class: { imageRadius: { value: "img-none" }, imageBorder: { value: "img-border-none" }, imageShadow: { value: "img-shadow-none" }, imageEffects: { value: "img-effects-none" } }, styles: { paddingLeft: { unit: "px", value: 10 }, paddingRight: { value: 10, unit: "px" }, paddingTop: { unit: "px", value: "10" }, paddingBottom: { unit: "px", value: "10" }, backgroundColor: { value: "var(--transparent)" }, opacity: { value: "1" }, textAlign: { value: "center" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "image-VMrslNNuUy", type: "element", child: [], meta: "image", tagName: "c-image", title: "Image", tag: "" }, { extra: { nodeId: "csub-heading-bQudNu4eBG", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<h2>FREQUENTLY ASKED QUESTIONS</h2>" }, mobileFontSize: { value: 46, unit: "px" }, desktopFontSize: { value: 46, unit: "px" }, typography: { value: "var(--headlinefont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } }, customClass: { value: [] } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal", desktop: "400" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "center" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 } }, customCss: [], id: "sub-heading-bQudNu4eBG", type: "element", child: [], mobileStyles: {}, mobileWrapper: {}, meta: "sub-heading", tagName: "c-sub-heading", title: "Sub Headline", tag: "h3" }], sequence: 9, pageId: "FYBFsBAezEtsY0uXW4IN", funnelId: "pK3yy9CFapchugRrgjgq", locationId: "Gc2kgDDpABIR8QDyJ6rf", isGlobal: true, general: { colors: [{ label: "Black", value: "#000000" }, { label: "Transparent", value: "transparent" }], fontsForPreview: ["'Lato'", "'Oswald'"], rootVars: { "--'lato'": "'Lato'", "--'oswald'": "'Oswald'", "--black": "#000000", "--transparent": "transparent" }, sectionStyles: `:root{--black:#000000;--transparent:transparent}.hl_page-preview--content .col-TgLmpbuj1O,.hl_page-preview--content .row-B3nlfUUX-J,.hl_page-preview--content .section-zJJ17L55C_{padding:40px 0;margin:0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .col-TgLmpbuj1O,.hl_page-preview--content .row-B3nlfUUX-J{margin:0 auto;padding:15px 0;width:100%}.hl_page-preview--content .col-TgLmpbuj1O{padding:0 10px 0 5px;margin:0}.hl_page-preview--content .cfaq-hC9kdZlk9d{font-family:var(--contentfont);faq-open-title-text-color:var(--white);faq-open-title-background-color:var(--my-custom-color-44);faq-divider-color:var(--my-custom-color-16);faq-content-text-color:var(--my-custom-color-26);faq-open-background-color:var(--white);faq-closed-title-text-color:var(--my-custom-color-26);faq-closed-title-background-color:var(--my-custom-color-60);faq-expand-all-button-text-color:var(--my-custom-color-44);faq-expand-all-button-border-color:#d1d5db;faq-expand-all-button-background-color:var(--transparent);link-text-color:#3b82f6;faq-heading-font-family:var(--headlinefont);faq-content-font-family:var(--contentfont);padding:0;margin:0;border-color:var(--black);border-style:solid;border-width:2px;font-weight:700;font-weight-sub:undefined}.hl_page-preview--content .col-qmvDyClR0p{padding:0 5px 0 10px;background-color:var(--transparent);width:100%;border-color:var(--black);border-width:2px;border-style:solid;margin:0}.hl_page-preview--content .cfaq-xt8Q865Gfb{font-family:var(--contentfont);faq-open-title-text-color:var(--white);faq-open-title-background-color:var(--my-custom-color-44);faq-divider-color:var(--my-custom-color-16);faq-content-text-color:var(--my-custom-color-26);faq-open-background-color:var(--white);faq-closed-title-text-color:var(--my-custom-color-26);faq-closed-title-background-color:var(--my-custom-color-60);faq-expand-all-button-text-color:var(--my-custom-color-44);faq-expand-all-button-border-color:#d1d5db;faq-expand-all-button-background-color:var(--my-custom-color-26);link-text-color:#3b82f6;faq-heading-font-family:var(--headlinefont);faq-content-font-family:var(--contentfont);padding:0;margin:0;border-color:var(--black);border-style:solid;border-width:2px;font-weight:700;font-weight-sub:undefined}.hl_page-preview--content .col-uV9_D99Gtm,.hl_page-preview--content .row-zwaPMb51Ig{margin:0 auto;padding:15px 0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid;width:100%}.hl_page-preview--content .col-uV9_D99Gtm{padding:10px 5px;margin:0}.hl_page-preview--content .image-VMrslNNuUy{margin-top:0;margin-bottom:0}.hl_page-preview--content .cimage-VMrslNNuUy{padding:10px;background-color:var(--transparent);opacity:1;text-align:center}.hl_page-preview--content .sub-heading-bQudNu4eBG{margin:0}.hl_page-preview--content .csub-heading-bQudNu4eBG{font-family:var(--headlinefont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:center}#section-zJJ17L55C_>.inner{max-width:1170px}#col-TgLmpbuj1O>.inner{flex-direction:column;justify-content:flex-start;align-items:inherit;flex-wrap:nowrap}#faq-hC9kdZlk9d .hl-faq-child-heading-text{font-size:20px}#faq-hC9kdZlk9d .hl-faq-child-heading-text .ProseMirror h4,#faq-hC9kdZlk9d .hl-faq-child-heading-text h4,#faq-hC9kdZlk9d .hl-faq-child-item-text .ProseMirror p,#faq-hC9kdZlk9d .hl-faq-child-item-text p{font-weight:400!important}#faq-hC9kdZlk9d .hl-faq-child-item-text{font-size:15px}#faq-hC9kdZlk9d .faq-separated-child{border-radius:10px}#faq-hC9kdZlk9d .faq-separated-child,#faq-hC9kdZlk9d .faq-separated-child.active{border:1.5px solid var(--my-custom-color-16)}#faq-hC9kdZlk9d .faq-contained-child{border:1px solid var(--my-custom-color-16)}#faq-hC9kdZlk9d .faq-simple-child .hl-faq-child-heading{border-top:1px solid var(--my-custom-color-16)}#faq-hC9kdZlk9d .faq-separated-child .hl-faq-child-heading{border-radius:10px}#faq-hC9kdZlk9d .faq-separated-child .hl-faq-child-heading.active{border-radius:10px 10px 0 0}#faq-hC9kdZlk9d .hl-faq-child-heading{background-color:var(--my-custom-color-60)}#faq-hC9kdZlk9d .hl-faq-child-heading.active{background-color:var(--my-custom-color-44)}#faq-hC9kdZlk9d .hl-faq-child-heading .hl-faq-child-head .hl-faq-child-heading-text,#faq-hC9kdZlk9d .hl-faq-child-heading .hl-faq-child-heading-icon{color:var(--my-custom-color-26)}#faq-hC9kdZlk9d .hl-faq-child-heading.active .hl-faq-child-head .hl-faq-child-heading-text,#faq-hC9kdZlk9d .hl-faq-child-heading.active .hl-faq-child-heading-icon{color:var(--white)}#faq-hC9kdZlk9d .hl-faq-child-heading .hl-faq-child-head .hl-faq-child-heading-text{line-height:1.5;font-family:var(--headlinefont)}#faq-hC9kdZlk9d .hl-faq-child .hl-faq-child-panel{background-color:var(--white)}#faq-hC9kdZlk9d .faq-separated-child .hl-faq-child-panel{border-radius:0}#faq-hC9kdZlk9d .faq-separated-child.active .hl-faq-child-panel{border-radius:0 0 10px 10px}#faq-hC9kdZlk9d .hl-faq-child .hl-faq-child-panel .hl-faq-child-item-text{color:var(--my-custom-color-26);line-height:1.5}#faq-hC9kdZlk9d .hl-faq-child-panel{display:flex;padding:15px;overflow:hidden}#faq-hC9kdZlk9d .hl-faq-child-panel .item-text{min-width:80%;margin:0;font-family:var(--contentfont)}#faq-hC9kdZlk9d .hl-faq-child-panel .item-img{padding:.5em;max-width:20%;height:100%}@media screen and (min-width:0px) and (max-width:480px){#faq-hC9kdZlk9d .hl-faq-child-panel{display:grid;padding:15px}#faq-hC9kdZlk9d .hl-faq-child-panel .item-img{max-width:100%;width:100%;margin:0;padding:0;height:auto}#faq-hC9kdZlk9d .hl-faq-child-panel .item-text{max-width:100%;width:100%;margin:0;height:auto;padding:0 0 5px}#faq-hC9kdZlk9d .hl-faq-child-heading-text{font-size:15px}#faq-hC9kdZlk9d .hl-faq-child-heading-text .ProseMirror h4,#faq-hC9kdZlk9d .hl-faq-child-heading-text h4,#faq-hC9kdZlk9d .hl-faq-child-item-text .ProseMirror p,#faq-hC9kdZlk9d .hl-faq-child-item-text p{font-weight:undefined!important}#faq-hC9kdZlk9d .hl-faq-child-item-text{font-size:12px}}#faq-hC9kdZlk9d .hl-faq-child-heading .hl-faq-child-heading-icon:before,#faq-xt8Q865Gfb .hl-faq-child-heading .hl-faq-child-heading-icon:before{content:"\uF078"!important;font-family:"Font Awesome 5 Free"}#faq-hC9kdZlk9d .hl-faq-child-heading.active .hl-faq-child-heading-icon:before,#faq-xt8Q865Gfb .hl-faq-child-heading.active .hl-faq-child-heading-icon:before{content:"\uF077"!important;font-family:"Font Awesome 5 Free"}#faq-hC9kdZlk9d .expand-collapse-all-button{color:var(--my-custom-color-44);border:1px solid #d1d5db;background-color:var(--transparent)}#faq-hC9kdZlk9d a,#faq-xt8Q865Gfb a{color:#3b82f6!important;text-decoration:none!important}#col-qmvDyClR0p>.inner{flex-direction:column;justify-content:flex-start;align-items:inherit;flex-wrap:nowrap}#faq-xt8Q865Gfb .hl-faq-child-heading-text{font-size:20px}#faq-xt8Q865Gfb .hl-faq-child-heading-text .ProseMirror h4,#faq-xt8Q865Gfb .hl-faq-child-heading-text h4,#faq-xt8Q865Gfb .hl-faq-child-item-text .ProseMirror p,#faq-xt8Q865Gfb .hl-faq-child-item-text p{font-weight:400!important}#faq-xt8Q865Gfb .hl-faq-child-item-text{font-size:15px}#faq-xt8Q865Gfb .faq-separated-child{border-radius:10px}#faq-xt8Q865Gfb .faq-separated-child,#faq-xt8Q865Gfb .faq-separated-child.active{border:1.5px solid var(--my-custom-color-16)}#faq-xt8Q865Gfb .faq-contained-child{border:1px solid var(--my-custom-color-16)}#faq-xt8Q865Gfb .faq-simple-child .hl-faq-child-heading{border-top:1px solid var(--my-custom-color-16)}#faq-xt8Q865Gfb .faq-separated-child .hl-faq-child-heading{border-radius:10px}#faq-xt8Q865Gfb .faq-separated-child .hl-faq-child-heading.active{border-radius:10px 10px 0 0}#faq-xt8Q865Gfb .hl-faq-child-heading{background-color:var(--my-custom-color-60)}#faq-xt8Q865Gfb .hl-faq-child-heading.active{background-color:var(--my-custom-color-44)}#faq-xt8Q865Gfb .hl-faq-child-heading .hl-faq-child-head .hl-faq-child-heading-text,#faq-xt8Q865Gfb .hl-faq-child-heading .hl-faq-child-heading-icon{color:var(--my-custom-color-26)}#faq-xt8Q865Gfb .hl-faq-child-heading.active .hl-faq-child-head .hl-faq-child-heading-text,#faq-xt8Q865Gfb .hl-faq-child-heading.active .hl-faq-child-heading-icon{color:var(--white)}#faq-xt8Q865Gfb .hl-faq-child-heading .hl-faq-child-head .hl-faq-child-heading-text{line-height:1.5;font-family:var(--headlinefont)}#faq-xt8Q865Gfb .hl-faq-child .hl-faq-child-panel{background-color:var(--white)}#faq-xt8Q865Gfb .faq-separated-child .hl-faq-child-panel{border-radius:0}#faq-xt8Q865Gfb .faq-separated-child.active .hl-faq-child-panel{border-radius:0 0 10px 10px}#faq-xt8Q865Gfb .hl-faq-child .hl-faq-child-panel .hl-faq-child-item-text{color:var(--my-custom-color-26);line-height:1.5}#faq-xt8Q865Gfb .hl-faq-child-panel{display:flex;padding:15px;overflow:hidden}#faq-xt8Q865Gfb .hl-faq-child-panel .item-text{min-width:80%;margin:0;font-family:var(--contentfont)}#faq-xt8Q865Gfb .hl-faq-child-panel .item-img{padding:.5em;max-width:20%;height:100%}@media screen and (min-width:0px) and (max-width:480px){#faq-xt8Q865Gfb .hl-faq-child-panel{display:grid;padding:15px}#faq-xt8Q865Gfb .hl-faq-child-panel .item-img{max-width:100%;width:100%;margin:0;padding:0;height:auto}#faq-xt8Q865Gfb .hl-faq-child-panel .item-text{max-width:100%;width:100%;margin:0;height:auto;padding:0 0 5px}#faq-xt8Q865Gfb .hl-faq-child-heading-text{font-size:15px}#faq-xt8Q865Gfb .hl-faq-child-heading-text .ProseMirror h4,#faq-xt8Q865Gfb .hl-faq-child-heading-text h4,#faq-xt8Q865Gfb .hl-faq-child-item-text .ProseMirror p,#faq-xt8Q865Gfb .hl-faq-child-item-text p{font-weight:undefined!important}#faq-xt8Q865Gfb .hl-faq-child-item-text{font-size:12px}}#faq-xt8Q865Gfb .expand-collapse-all-button{color:var(--my-custom-color-44);border:1px solid #d1d5db;background-color:var(--my-custom-color-26)}#col-uV9_D99Gtm>.inner{flex-direction:column;justify-content:center;align-items:inherit;flex-wrap:nowrap}.sub-heading-bQudNu4eBG{font-weight:400}.sub-heading-bQudNu4eBG em,.sub-heading-bQudNu4eBG strong,.sub-heading-bQudNu4eBG u{color:var(--text-color)!important}.sub-heading-bQudNu4eBG a,.sub-heading-bQudNu4eBG a *{color:var(--link-color)!important;text-decoration:none}.sub-heading-bQudNu4eBG a:hover{text-decoration:underline}@media screen and (min-width:0px) and (max-width:480px){.sub-heading-bQudNu4eBG h1,.sub-heading-bQudNu4eBG h2,.sub-heading-bQudNu4eBG h3,.sub-heading-bQudNu4eBG h4,.sub-heading-bQudNu4eBG h5,.sub-heading-bQudNu4eBG h6,.sub-heading-bQudNu4eBG ul li,.sub-heading-bQudNu4eBG.text-output{font-size:46px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.sub-heading-bQudNu4eBG h1,.sub-heading-bQudNu4eBG h2,.sub-heading-bQudNu4eBG h3,.sub-heading-bQudNu4eBG h4,.sub-heading-bQudNu4eBG h5,.sub-heading-bQudNu4eBG h6,.sub-heading-bQudNu4eBG ul li,.sub-heading-bQudNu4eBG.text-output{font-size:46px!important;font-weight:undefined}}.sub-heading-bQudNu4eBG.text-output h1:first-child:before,.sub-heading-bQudNu4eBG.text-output h2:first-child:before,.sub-heading-bQudNu4eBG.text-output h3:first-child:before,.sub-heading-bQudNu4eBG.text-output h4:first-child:before,.sub-heading-bQudNu4eBG.text-output h5:first-child:before,.sub-heading-bQudNu4eBG.text-output h6:first-child:before,.sub-heading-bQudNu4eBG.text-output p:first-child:before{color:var(--text-color);content:'\\';
10086
+ font-family: '';margin-right:5px;font-weight:700}` } }, map: { id: "section-k4A5oCSjW", metaData: { id: "section-k4A5oCSjW", type: "section", child: ["row-pQ0EjtpzhM"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: 20 }, paddingTop: { unit: "px", value: 20 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--my-custom-color-16)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, allowRowMaxWidth: { value: true } }, wrapper: {}, meta: "section", tagName: "c-section", title: "Map", _id: "section-k4A5oCSjW", isGlobal: true }, elements: [{ id: "row-pQ0EjtpzhM", type: "row", child: ["col-avDBDXfRP", "col-BumGktCM_n"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 15 }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, rowWidth: { value: 100, unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-row", meta: "row", title: "2 Column Row" }, { id: "col-avDBDXfRP", type: "col", child: ["map-tptsa5-Qnk"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cmap-tptsa5-Qnk", visibility: { value: { hideDesktop: false, hideMobile: false } }, mapScale: { value: true }, mapMarkerColor: { value: "var(--red)" }, mapZoom: { value: 13 }, mapLocation: { value: { name: "New York, NY, USA", placeId: "ChIJOwg_06VPwokRYv534QaPC8g", lat: 40.7127753, lng: -74.0059728, url: "https://firebasestorage.googleapis.com/v0/b/highlevel-backend.appspot.com/o/location%2FHdI06zRMberoHhoALSNH%2Fimages%2FWcJKBDYHBY2lXZHxN2EE%2FChIJOwg_06VPwokRYv534QaPC8g%2Fmap-tptsa5-Qnk.jpg?alt=media" } }, mapType: { value: "roadmap" }, mapWidth: { value: "640" }, mapHeight: { value: "500" }, newTab: { value: false }, customClass: { value: [] } }, class: {}, styles: { textAlign: { value: "center" } }, wrapper: {}, customCss: [], id: "map-tptsa5-Qnk", type: "element", child: [], meta: "map", tagName: "c-map", title: "Map", tag: "" }, { id: "col-BumGktCM_n", type: "col", child: ["heading-IUykdV_et", "divider-rwCGPGeRg", "paragraph-5ArwjI1rg", "paragraph-1i2Ja23aQ", "paragraph-pMPMaLeA3"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: "25" }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "2nd Column" }, { extra: { nodeId: "cheading-IUykdV_et", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>CONTACT US</p>" }, mobileFontSize: { value: "22", unit: "px" }, desktopFontSize: { value: "24", unit: "px" }, typography: { value: "var(--headlinefont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "heading-IUykdV_et", type: "element", child: [], meta: "heading", tagName: "c-heading", title: "Headline", tag: "h1" }, { extra: { nodeId: "cdivider-rwCGPGeRg", visibility: { value: { hideDesktop: false, hideMobile: false } }, dividerProperties: { value: { width: "50%", height: "1px", borderStyle: "solid", align: "left", color: "var(--my-custom-color-60)" } } }, class: {}, styles: { paddingTop: { unit: "px", value: 5 }, paddingBottom: { unit: "px", value: 5 } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 } }, customCss: [], id: "divider-rwCGPGeRg", type: "element", child: [], meta: "divider", tagName: "c-divider", title: "Divider", tag: "" }, { extra: { nodeId: "cparagraph-5ArwjI1rg", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>{{location.phone}}</p>" }, mobileFontSize: { value: 14, unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "phone-alt", unicode: "f879", fontFamily: "Font Awesome 5 Free", color: "var(--black)" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--my-custom-color-26)" }, iconColor: { value: "var(--my-custom-color-44)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: "0" }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: "10" }, paddingBottom: { unit: "px", value: "10" }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-5ArwjI1rg", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cparagraph-1i2Ja23aQ", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>{{location.full_address}}</p>" }, mobileFontSize: { value: 14, unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "map-marker-alt", unicode: "f3c5", fontFamily: "Font Awesome 5 Free", color: "var(--black)" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--my-custom-color-26)" }, iconColor: { value: "var(--my-custom-color-44)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: "0" }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: "10" }, paddingBottom: { unit: "px", value: "10" }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-1i2Ja23aQ", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "cparagraph-pMPMaLeA3", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>{{location.email}}</p>" }, mobileFontSize: { value: 14, unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "envelope", unicode: "f0e0", fontFamily: "Font Awesome 5 Free", color: "var(--black)" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--my-custom-color-44)" }, iconColor: { value: "var(--my-custom-color-44)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: "0" }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: "10" }, paddingBottom: { unit: "px", value: "10" }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-pMPMaLeA3", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }], sequence: 10, pageId: "FYBFsBAezEtsY0uXW4IN", funnelId: "pK3yy9CFapchugRrgjgq", locationId: "Gc2kgDDpABIR8QDyJ6rf", isGlobal: true, general: { colors: [{ label: "Black", value: "#000000" }, { label: "Red", value: "#e93d3d" }, { label: "Transparent", value: "transparent" }, { label: "my-custom-color-26", value: "#434445", name: "My Custom Color 26" }, { label: "my-custom-color-44", name: "My Custom Color 44", value: "#ec606a" }, { value: "#f3f3f3", name: "My Custom Color 16", label: "my-custom-color-16" }], fontsForPreview: ["'Oswald'", "'Lato'"], rootVars: { "--'oswald'": "'Oswald'", "--'lato'": "'Lato'", "--black": "#000000", "--red": "#e93d3d", "--transparent": "transparent", "--my-custom-color-26": "#434445", "--my-custom-color-44": "#ec606a", "--my-custom-color-16": "#f3f3f3" }, sectionStyles: `:root{--black:#000000;--red:#e93d3d;--transparent:transparent;--my-custom-color-26:#434445;--my-custom-color-44:#ec606a;--my-custom-color-16:#f3f3f3}.hl_page-preview--content .col-avDBDXfRP .inner,.hl_page-preview--content .row-pQ0EjtpzhM,.hl_page-preview--content .section-k4A5oCSjW{padding:20px 0;margin-top:0;margin-bottom:0;background-color:var(--my-custom-color-16);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .col-avDBDXfRP .inner,.hl_page-preview--content .row-pQ0EjtpzhM{padding:15px 0;background-color:var(--transparent);width:100%}.hl_page-preview--content .col-avDBDXfRP{width:100%}.hl_page-preview--content .col-avDBDXfRP .inner{padding:10px 5px}.hl_page-preview--content .cmap-tptsa5-Qnk{text-align:center}.hl_page-preview--content .col-BumGktCM_n{width:100%}.hl_page-preview--content .col-BumGktCM_n .inner{padding:10px 5px 10px 25px;width:100%;margin-top:0;margin-bottom:0}.hl_page-preview--content .heading-IUykdV_et{margin-top:0;margin-bottom:0}.hl_page-preview--content .cheading-IUykdV_et,.hl_page-preview--content .col-BumGktCM_n .inner{background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .cheading-IUykdV_et{font-family:var(--headlinefont);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .divider-rwCGPGeRg{margin-top:0;margin-bottom:0;padding-top:10px;padding-bottom:10px}.hl_page-preview--content .cdivider-rwCGPGeRg{padding-top:5px;padding-bottom:5px}.hl_page-preview--content .paragraph-5ArwjI1rg{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-5ArwjI1rg{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--my-custom-color-44);font-weight:400;padding:10px 0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .paragraph-1i2Ja23aQ{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-1i2Ja23aQ{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--my-custom-color-44);font-weight:400;padding:10px 0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .paragraph-pMPMaLeA3{margin-top:0;margin-bottom:0}.hl_page-preview--content .cparagraph-pMPMaLeA3{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--my-custom-color-44);font-weight:400;padding:10px 0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}#section-k4A5oCSjW>.inner{max-width:100%}#col-BumGktCM_n>.inner,#col-avDBDXfRP>.inner{flex-direction:column;justify-content:center;align-items:inherit;flex-wrap:nowrap}.heading-IUykdV_et,.paragraph-1i2Ja23aQ,.paragraph-5ArwjI1rg,.paragraph-pMPMaLeA3{font-weight:undefined}.heading-IUykdV_et em,.heading-IUykdV_et strong,.heading-IUykdV_et u,.paragraph-1i2Ja23aQ em,.paragraph-1i2Ja23aQ strong,.paragraph-1i2Ja23aQ u,.paragraph-5ArwjI1rg em,.paragraph-5ArwjI1rg strong,.paragraph-5ArwjI1rg u,.paragraph-pMPMaLeA3 em,.paragraph-pMPMaLeA3 strong,.paragraph-pMPMaLeA3 u{color:var(--text-color)!important}.heading-IUykdV_et a,.heading-IUykdV_et a *{color:var(--link-color)!important;text-decoration:none}.heading-IUykdV_et a:hover,.paragraph-1i2Ja23aQ a:hover,.paragraph-5ArwjI1rg a:hover,.paragraph-pMPMaLeA3 a:hover{text-decoration:underline}@media screen and (min-width:0px) and (max-width:480px){.heading-IUykdV_et h1,.heading-IUykdV_et h2,.heading-IUykdV_et h3,.heading-IUykdV_et h4,.heading-IUykdV_et h5,.heading-IUykdV_et h6,.heading-IUykdV_et ul li,.heading-IUykdV_et.text-output{font-size:22px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.heading-IUykdV_et h1,.heading-IUykdV_et h2,.heading-IUykdV_et h3,.heading-IUykdV_et h4,.heading-IUykdV_et h5,.heading-IUykdV_et h6,.heading-IUykdV_et ul li,.heading-IUykdV_et.text-output{font-size:24px!important;font-weight:undefined}}.heading-IUykdV_et.text-output h1:first-child:before,.heading-IUykdV_et.text-output h2:first-child:before,.heading-IUykdV_et.text-output h3:first-child:before,.heading-IUykdV_et.text-output h4:first-child:before,.heading-IUykdV_et.text-output h5:first-child:before,.heading-IUykdV_et.text-output h6:first-child:before,.heading-IUykdV_et.text-output p:first-child:before{color:var(--text-color);content:'\\';
10087
+ font-family: '';margin-right:5px;font-weight:700}.divider-rwCGPGeRg .divider-element{width:50%;border-top:1px solid var(--my-custom-color-60);margin:0 auto 0 0}.paragraph-1i2Ja23aQ a,.paragraph-1i2Ja23aQ a *,.paragraph-5ArwjI1rg a,.paragraph-5ArwjI1rg a *{color:var(--my-custom-color-26)!important;text-decoration:none}@media screen and (min-width:0px) and (max-width:480px){.paragraph-5ArwjI1rg h1,.paragraph-5ArwjI1rg h2,.paragraph-5ArwjI1rg h3,.paragraph-5ArwjI1rg h4,.paragraph-5ArwjI1rg h5,.paragraph-5ArwjI1rg h6,.paragraph-5ArwjI1rg ul li,.paragraph-5ArwjI1rg.text-output{font-size:14px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-5ArwjI1rg h1,.paragraph-5ArwjI1rg h2,.paragraph-5ArwjI1rg h3,.paragraph-5ArwjI1rg h4,.paragraph-5ArwjI1rg h5,.paragraph-5ArwjI1rg h6,.paragraph-5ArwjI1rg ul li,.paragraph-5ArwjI1rg.text-output{font-size:16px!important;font-weight:undefined}}.paragraph-5ArwjI1rg.text-output h1:first-child:before,.paragraph-5ArwjI1rg.text-output h2:first-child:before,.paragraph-5ArwjI1rg.text-output h3:first-child:before,.paragraph-5ArwjI1rg.text-output h4:first-child:before,.paragraph-5ArwjI1rg.text-output h5:first-child:before,.paragraph-5ArwjI1rg.text-output h6:first-child:before,.paragraph-5ArwjI1rg.text-output p:first-child:before{color:var(--my-custom-color-44);content:"\uF879";font-family:"Font Awesome 5 Free";margin-right:5px;font-weight:700}@media screen and (min-width:0px) and (max-width:480px){.paragraph-1i2Ja23aQ h1,.paragraph-1i2Ja23aQ h2,.paragraph-1i2Ja23aQ h3,.paragraph-1i2Ja23aQ h4,.paragraph-1i2Ja23aQ h5,.paragraph-1i2Ja23aQ h6,.paragraph-1i2Ja23aQ ul li,.paragraph-1i2Ja23aQ.text-output{font-size:14px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-1i2Ja23aQ h1,.paragraph-1i2Ja23aQ h2,.paragraph-1i2Ja23aQ h3,.paragraph-1i2Ja23aQ h4,.paragraph-1i2Ja23aQ h5,.paragraph-1i2Ja23aQ h6,.paragraph-1i2Ja23aQ ul li,.paragraph-1i2Ja23aQ.text-output{font-size:16px!important;font-weight:undefined}}.paragraph-1i2Ja23aQ.text-output h1:first-child:before,.paragraph-1i2Ja23aQ.text-output h2:first-child:before,.paragraph-1i2Ja23aQ.text-output h3:first-child:before,.paragraph-1i2Ja23aQ.text-output h4:first-child:before,.paragraph-1i2Ja23aQ.text-output h5:first-child:before,.paragraph-1i2Ja23aQ.text-output h6:first-child:before,.paragraph-1i2Ja23aQ.text-output p:first-child:before{color:var(--my-custom-color-44);content:"\uF3C5";font-family:"Font Awesome 5 Free";margin-right:5px;font-weight:700}.paragraph-pMPMaLeA3 a,.paragraph-pMPMaLeA3 a *{color:var(--my-custom-color-44)!important;text-decoration:none}@media screen and (min-width:0px) and (max-width:480px){.paragraph-pMPMaLeA3 h1,.paragraph-pMPMaLeA3 h2,.paragraph-pMPMaLeA3 h3,.paragraph-pMPMaLeA3 h4,.paragraph-pMPMaLeA3 h5,.paragraph-pMPMaLeA3 h6,.paragraph-pMPMaLeA3 ul li,.paragraph-pMPMaLeA3.text-output{font-size:14px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-pMPMaLeA3 h1,.paragraph-pMPMaLeA3 h2,.paragraph-pMPMaLeA3 h3,.paragraph-pMPMaLeA3 h4,.paragraph-pMPMaLeA3 h5,.paragraph-pMPMaLeA3 h6,.paragraph-pMPMaLeA3 ul li,.paragraph-pMPMaLeA3.text-output{font-size:16px!important;font-weight:undefined}}.paragraph-pMPMaLeA3.text-output h1:first-child:before,.paragraph-pMPMaLeA3.text-output h2:first-child:before,.paragraph-pMPMaLeA3.text-output h3:first-child:before,.paragraph-pMPMaLeA3.text-output h4:first-child:before,.paragraph-pMPMaLeA3.text-output h5:first-child:before,.paragraph-pMPMaLeA3.text-output h6:first-child:before,.paragraph-pMPMaLeA3.text-output p:first-child:before{color:var(--my-custom-color-44);content:"\uF0E0";font-family:"Font Awesome 5 Free";margin-right:5px;font-weight:700}` } }, footer: { id: "section-W2_3qK993", metaData: { id: "section-W2_3qK993", type: "section", child: ["row-wuNraoqgsg"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: 20 }, paddingTop: { unit: "px", value: 20 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--white)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, allowRowMaxWidth: { value: false } }, wrapper: {}, meta: "section", tagName: "c-section", title: "Footer", _id: "section-W2_3qK993", isGlobal: true }, elements: [{ id: "row-wuNraoqgsg", type: "row", child: ["col-6LxuCvSGc", "col-kQXDW5avz2", "col-W91BEMl7R9"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 15 }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, rowWidth: { value: 100, unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-row", meta: "row", title: "3 Column Row" }, { id: "col-6LxuCvSGc", type: "col", child: ["image-Fuy-QQVmM"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: 20.8, unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cimage-Fuy-QQVmM", visibility: { value: { hideDesktop: false, hideMobile: false } }, imageActions: { value: "none" }, visitWebsite: { value: { url: "", newTab: false } }, imageProperties: { value: { width: "190px", height: "", url: "https://storage.googleapis.com/msgsndr/EVTjG29VnVlvwn3SRGve/media/fee997f8-92c7-4ee2-b0c1-3536b94b71a7.png", altText: "", compression: true, placeholderBase64: "", servingUrl: "", imageMeta: "" } } }, class: { imageRadius: { value: "img-none" }, imageBorder: { value: "img-border-none" }, imageShadow: { value: "img-shadow-none" }, imageEffects: { value: "img-effects-none" } }, styles: { paddingLeft: { unit: "px", value: 10 }, paddingRight: { value: 10, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, opacity: { value: "1" }, textAlign: { value: "center" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "image-Fuy-QQVmM", type: "element", child: [], meta: "image", tagName: "c-image", title: "Image", tag: "" }, { id: "col-kQXDW5avz2", type: "col", child: ["paragraph-R6ogZueLM"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: 60.1, unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "2nd Column" }, { extra: { nodeId: "cparagraph-R6ogZueLM", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>\xA9 {{right_now.year}} All Rights Reserved. Terms of Use and Privacy Policy</p>" }, mobileFontSize: { value: 14, unit: "px" }, desktopFontSize: { value: "16", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--overlay)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "center" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "paragraph-R6ogZueLM", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { id: "col-W91BEMl7R9", type: "col", child: ["social-icons-zmn5hzO2aL"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { unit: "px", value: 0 }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, width: { value: 19.1, unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "row" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "center" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "3rd Column" }, { extra: { nodeId: "csocial-icons-zmn5hzO2aL", socials: { value: [{ id: "facebook", label: "Facebook", link: "facebook.com", newWindow: true, nofollow: false, icon: "https://stcdn.leadconnectorhq.com/funnel/icons/brand/facebook-brand.svg" }, { id: "instagram", label: "Instagram", link: "instagram.com", newWindow: true, nofollow: false, icon: "https://stcdn.leadconnectorhq.com/funnel/icons/brand/instagram-brand.svg" }, { id: "youtube", label: "Youtube", link: "youtube.com", newWindow: true, nofollow: false, icon: "https://stcdn.leadconnectorhq.com/funnel/icons/brand/youtube-brand.svg" }] }, displayType: { value: "icon" }, theme: { value: "dark" }, align: { value: "center" }, iconSize: { value: { height: 25, width: 25 } }, customClass: { value: [] }, visibility: { value: { hideDesktop: false, hideMobile: false } } }, class: {}, styles: { fontFamily: { value: "Inter" }, fontSize: { value: 12, unit: "px" }, fontWeight: { value: 500, desktop: "Normal" }, color: { value: "#000000" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { unit: "px", value: 0 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 } }, wrapper: {}, mobileStyles: {}, mobileWrapper: {}, mobileExtra: {}, customCss: [], id: "social-icons-zmn5hzO2aL", version: 2, type: "element", child: [], meta: "social-icons", tagName: "c-social-icons", title: "Social Icons", tag: "" }], sequence: 11, pageId: "FYBFsBAezEtsY0uXW4IN", funnelId: "pK3yy9CFapchugRrgjgq", locationId: "Gc2kgDDpABIR8QDyJ6rf", isGlobal: true, general: { colors: [{ label: "White", value: "#ffffff" }, { label: "Black", value: "#000000" }, { label: "Transparent", value: "transparent" }, { value: "rgba(0, 0, 0, 0.5)", label: "Overlay" }], fontsForPreview: ["'Lato'"], rootVars: { "--'lato'": "'Lato'", "--white": "#ffffff", "--black": "#000000", "--transparent": "transparent", "--overlay": "rgba(0, 0, 0, 0.5)" }, sectionStyles: ":root{--white:#ffffff;--black:#000000;--transparent:transparent;--overlay:rgba(0, 0, 0, 0.5)}.hl_page-preview--content .section-W2_3qK993{padding:20px 0;margin-top:0;margin-bottom:0;background-color:var(--white);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .col-6LxuCvSGc .inner,.hl_page-preview--content .col-kQXDW5avz2 .inner,.hl_page-preview--content .row-wuNraoqgsg{margin-top:0;margin-bottom:0;padding:15px 0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid;width:100%}.hl_page-preview--content .col-6LxuCvSGc{width:20.8%}.hl_page-preview--content .col-6LxuCvSGc .inner,.hl_page-preview--content .col-kQXDW5avz2 .inner{padding:10px 5px;width:20.8%}.hl_page-preview--content .image-Fuy-QQVmM{margin-top:0;margin-bottom:0}.hl_page-preview--content .cimage-Fuy-QQVmM{padding:10px;background-color:var(--transparent);opacity:1;text-align:center}.hl_page-preview--content .col-kQXDW5avz2{width:60.1%}.hl_page-preview--content .col-kQXDW5avz2 .inner{width:60.1%}.hl_page-preview--content .paragraph-R6ogZueLM{margin-top:0;margin-bottom:0}.hl_page-preview--content .col-W91BEMl7R9 .inner,.hl_page-preview--content .cparagraph-R6ogZueLM{padding:0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .cparagraph-R6ogZueLM{font-family:var(--contentfont);color:var(--overlay);icon-color:var(--text-color);font-weight:400;opacity:1;text-shadow:0 0 0 transparent;line-height:1.3em;letter-spacing:0;text-align:center}.hl_page-preview--content .col-W91BEMl7R9{width:19.1%}.hl_page-preview--content .col-W91BEMl7R9 .inner{width:19.1%;margin-top:0;margin-bottom:0}.hl_page-preview--content .csocial-icons-zmn5hzO2aL{font-family:Inter;font-size:12px;font-weight:500;color:#000;padding:0;margin:0}#section-W2_3qK993>.inner{max-width:1170px}#col-6LxuCvSGc>.inner,#col-kQXDW5avz2>.inner{flex-direction:column;justify-content:center;align-items:inherit;flex-wrap:nowrap}.paragraph-R6ogZueLM{font-weight:undefined}.paragraph-R6ogZueLM em,.paragraph-R6ogZueLM strong,.paragraph-R6ogZueLM u{color:var(--text-color)!important}.paragraph-R6ogZueLM a,.paragraph-R6ogZueLM a *{color:var(--link-color)!important;text-decoration:none}.paragraph-R6ogZueLM a:hover{text-decoration:underline}@media screen and (min-width:0px) and (max-width:480px){.paragraph-R6ogZueLM h1,.paragraph-R6ogZueLM h2,.paragraph-R6ogZueLM h3,.paragraph-R6ogZueLM h4,.paragraph-R6ogZueLM h5,.paragraph-R6ogZueLM h6,.paragraph-R6ogZueLM ul li,.paragraph-R6ogZueLM.text-output{font-size:14px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-R6ogZueLM h1,.paragraph-R6ogZueLM h2,.paragraph-R6ogZueLM h3,.paragraph-R6ogZueLM h4,.paragraph-R6ogZueLM h5,.paragraph-R6ogZueLM h6,.paragraph-R6ogZueLM ul li,.paragraph-R6ogZueLM.text-output{font-size:16px!important;font-weight:undefined}}.paragraph-R6ogZueLM.text-output h1:first-child:before,.paragraph-R6ogZueLM.text-output h2:first-child:before,.paragraph-R6ogZueLM.text-output h3:first-child:before,.paragraph-R6ogZueLM.text-output h4:first-child:before,.paragraph-R6ogZueLM.text-output h5:first-child:before,.paragraph-R6ogZueLM.text-output h6:first-child:before,.paragraph-R6ogZueLM.text-output p:first-child:before{color:var(--text-color);content:'\\';\n font-family: '';margin-right:5px;font-weight:700}#col-W91BEMl7R9>.inner{flex-direction:row;justify-content:center;align-items:center;flex-wrap:wrap}#social-icons-zmn5hzO2aL .social-media-icon{height:25px;width:25px}#social-icons-zmn5hzO2aL .social-icons-container{justify-content:center}" } }, formShell: { id: "section-XMYhZrXmbd", metaData: { id: "section-XMYhZrXmbd", type: "section", child: ["row-cq8LeYxp43"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: 20 }, paddingTop: { unit: "px", value: 20 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { mediaType: "image", url: "", opacity: "1", options: "bgCover", svgCode: "", videoUrl: "", videoThumbnail: "", videoLoop: true } }, allowRowMaxWidth: { value: false }, customClass: { value: [] } }, wrapper: {}, meta: "section", tagName: "c-section", title: "Section", mobileStyles: {}, mobileWrapper: {}, _id: "section-XMYhZrXmbd" }, elements: [{ id: "row-cq8LeYxp43", type: "row", child: ["col-ot-9fcEoch"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 15 }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { mediaType: "image", url: "", opacity: "1", options: "bgCover", svgCode: "", videoUrl: "", videoThumbnail: "", videoLoop: true } }, rowWidth: { value: 100, unit: "%" }, customClass: { value: [] } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "", value: "auto" }, marginRight: { unit: "", value: "auto" } }, tagName: "c-row", meta: "row", title: "1 Column Row", mobileStyles: {}, mobileWrapper: {} }, { id: "col-ot-9fcEoch", type: "col", child: ["heading-gQ8AnRpz8t", "faq-wEED3pufBs"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { mediaType: "image", url: "", opacity: "1", options: "bgCover", svgCode: "", videoUrl: "", videoThumbnail: "", videoLoop: true } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true }, customClass: { value: [] }, elementVersion: { value: 2 } }, wrapper: { marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column", mobileStyles: {}, mobileWrapper: {} }, { extra: { nodeId: "cfaq-wEED3pufBs", faqType: { value: "simple" }, faqList: { value: [{ id: 1, heading: "<h4>What should I expect during my first visit?</h4>", text: "<p>Your first visit begins with a comprehensive consultation where our experts will assess your skin and discuss your aesthetic goals. We will recommend personalized treatment options and answer any questions you may have to ensure you feel comfortable and informed.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: false, compression: true }, { id: 2, heading: "<h4>Are your treatments safe?</h4>", text: "<p>Yes, all our treatments are performed by highly trained and certified professionals using state-of-the-art equipment and techniques. We prioritize your safety and comfort, adhering to the highest standards of medical care and hygiene.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: false, compression: true }, { id: 3, heading: "<h4>How do I know which treatment is right for me?</h4>", text: "<p>Our team will guide you through the selection process during your initial consultation. We\u2019ll evaluate your skin type, concerns, and goals to recommend the most suitable treatments to achieve the best results for you.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: false, compression: true }, { heading: "<h4>Is there any downtime after treatments?</h4>", text: "<p>Most of our treatments are non-invasive or minimally invasive, requiring little to no downtime. However, the recovery time can vary depending on the specific treatment. During your consultation, we will provide detailed post-treatment care instructions and inform you about any necessary recovery time.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: false, compression: true, id: 4 }, { heading: "<h4>How often should I schedule treatments?</h4>", text: "<p>The frequency of treatments depends on the type of service and your individual needs. Some treatments, like facials, may be done monthly, while others, like laser hair removal, may require a series of sessions spaced several weeks apart. We will create a personalized treatment plan to ensure optimal results.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: false, compression: true, id: 5 }, { heading: "<h4>Do you offer packages or memberships?</h4>", text: "<p>Yes, we offer a variety of packages and memberships designed to provide you with ongoing care and savings. Our packages bundle popular treatments for comprehensive care, while our memberships offer exclusive benefits and discounts. Contact us to learn more about our current offerings and find the perfect plan for your needs.</p>", showImage: false, image: "https://storage.googleapis.com/msgsndr/knES3eSWYIsc5YSZ3YLl/media/62beef4f9f43b0c53e585a8f.jpeg", active: true, compression: true, id: 6 }] }, typography: { value: "var(--contentfont)" }, faqCustomOptions: { value: { openIcon: { color: "var(--black)", fontFamily: "Font Awesome 5 Free", name: "chevron-down", unicode: "f078" }, closeIcon: { color: "var(--black)", fontFamily: "Font Awesome 5 Free", name: "chevron-up", unicode: "f077" }, iconPosition: "right", lineHeight: "1.5", showImagePopup: true, expandAllToggle: true, expandAll: true, firstItemOpen: false } }, featureHeadlineDesktopFontSize: { value: 20, unit: "px" }, featureHeadlineMobileFontSize: { value: 15, unit: "px" }, desktopFontSize: { value: 15, unit: "px" }, mobileFontSize: { value: 12, unit: "px" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, customClass: { value: [] } }, mobileExtra: {}, class: { borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" }, boxShadow: { value: "none" } }, styles: { faqOpenTitleTextColor: { value: "var(--color-lwjrr318)" }, faqOpenTitleBackgroundColor: { value: "var(--white)" }, faqDividerColor: { value: "var(--color-lwktyvyq)" }, faqContentTextColor: { value: "var(--black)" }, faqOpenBackgroundColor: { value: "var(--white)" }, faqClosedTitleTextColor: { value: "#111827" }, faqClosedTitleBackgroundColor: { value: "var(--white)" }, faqExpandAllButtonTextColor: { value: "var(--color-lwjrr318)" }, faqExpandAllButtonBorderColor: { value: "var(--color-lwktyvyq)" }, faqExpandAllButtonBackgroundColor: { value: "var(--transparent)" }, linkTextColor: { value: "#3B82F6" }, faqHeadingFontFamily: { value: "var(--headlinefont)" }, faqContentFontFamily: { value: "var(--contentfont)" }, paddingLeft: { unit: "px", value: 10 }, paddingRight: { value: 10, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, borderColor: { value: "var(--black)" }, borderStyle: { value: "solid" }, borderWidth: { value: "2", unit: "px" }, fontWeight: { value: "bold", desktop: "400" }, fontWeightSub: { desktop: "400" } }, wrapper: {}, customCss: [], id: "faq-wEED3pufBs", version: 2, type: "element", child: [], meta: "faq", tagName: "c-faq", title: "FAQ", tag: "" }, { child: [], class: { borderRadius: { value: "radius0" }, borders: { value: "noBorder" }, boxShadow: { value: "none" }, radiusEdge: { value: "none" } }, customCss: [], extra: { desktopFontSize: { unit: "px", value: 32 }, icon: { value: { fontFamily: "", name: "", unicode: "" } }, mobileFontSize: { unit: "px", value: 32 }, nodeId: "cheading-gQ8AnRpz8t", text: { value: "<p><strong>FREQUENTLY ASKED QUESTIONS</strong></p>" }, typography: { value: "var(--headlinefont)" }, visibility: { value: { hideDesktop: false, hideMobile: false } } }, id: "heading-gQ8AnRpz8t", meta: "heading", styles: { backgroundColor: { value: "var(--transparent)" }, boldTextColor: { value: "var(--text-color)" }, borderColor: { value: "var(--black)" }, borderStyle: { value: "solid" }, borderWidth: { unit: "px", value: "2" }, color: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, iconColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, letterSpacing: { unit: "px", value: "0" }, lineHeight: { unit: "em", value: 1.3 }, linkTextColor: { value: "var(--link-color)" }, opacity: { value: "1" }, paddingBottom: { unit: "px", value: 0 }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { unit: "px", value: 0 }, paddingTop: { unit: "px", value: 0 }, textAlign: { value: "center" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, textTransform: { value: "none" }, underlineTextColor: { value: "var(--text-color)" } }, tag: "h1", tagName: "c-heading", title: "Headline", type: "element", wrapper: { marginBottom: { unit: "px", value: 0 }, marginTop: { unit: "px", value: 0 } } }], sequence: 3, pageId: "MNXtMkSaaJpvXyKjwRQr", funnelId: "O1vMlBmnKnMTFb7eObof", locationId: "Gc2kgDDpABIR8QDyJ6rf", general: { colors: [{ label: "Black", value: "#000000" }, { label: "Transparent", value: "transparent" }], fontsForPreview: ["'Lato'", "'Oswald'"], rootVars: { "--'lato'": "'Lato'", "--'oswald'": "'Oswald'", "--black": "#000000", "--transparent": "transparent" }, sectionStyles: `:root{--black:#000000;--transparent:transparent}.hl_page-preview--content .col-ot-9fcEoch,.hl_page-preview--content .row-cq8LeYxp43,.hl_page-preview--content .section-XMYhZrXmbd{padding:20px 0;margin:0;background-color:var(--transparent);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .col-ot-9fcEoch,.hl_page-preview--content .row-cq8LeYxp43{margin:0 auto;padding:15px 0;width:100%}.hl_page-preview--content .col-ot-9fcEoch{padding:10px 5px;margin:0}.hl_page-preview--content .cfaq-wEED3pufBs{font-family:var(--contentfont);faq-open-title-text-color:var(--color-lwjrr318);faq-open-title-background-color:var(--white);faq-divider-color:var(--color-lwktyvyq);faq-content-text-color:var(--black);faq-open-background-color:var(--white);faq-closed-title-text-color:#111827;faq-closed-title-background-color:var(--white);faq-expand-all-button-text-color:var(--color-lwjrr318);faq-expand-all-button-border-color:var(--color-lwktyvyq);faq-expand-all-button-background-color:var(--transparent);link-text-color:#3b82f6;faq-heading-font-family:var(--headlinefont);faq-content-font-family:var(--contentfont);padding:10px;margin:0;border-color:var(--black);border-style:solid;border-width:2px;font-weight:700;font-weight-sub:undefined}.hl_page-preview--content .heading-gQ8AnRpz8t{margin-bottom:0;margin-top:0}.hl_page-preview--content .cheading-gQ8AnRpz8t{font-family:var(--headlinefont);background-color:var(--transparent);border-color:var(--black);border-style:solid;border-width:2px;color:var(--text-color);font-weight:400;icon-color:var(--text-color);letter-spacing:0;line-height:1.3em;opacity:1;padding:0;text-align:center;text-shadow:0 0 0 transparent;text-transform:none}#section-XMYhZrXmbd>.inner{max-width:1170px}#col-ot-9fcEoch>.inner{flex-direction:column;justify-content:center;align-items:inherit;flex-wrap:nowrap}#faq-wEED3pufBs .hl-faq-child-heading-text{font-size:20px}#faq-wEED3pufBs .hl-faq-child-heading-text .ProseMirror h4,#faq-wEED3pufBs .hl-faq-child-heading-text h4,#faq-wEED3pufBs .hl-faq-child-item-text .ProseMirror p,#faq-wEED3pufBs .hl-faq-child-item-text p{font-weight:400!important}#faq-wEED3pufBs .hl-faq-child-item-text{font-size:15px}#faq-wEED3pufBs .faq-separated-child{border-radius:10px}#faq-wEED3pufBs .faq-separated-child,#faq-wEED3pufBs .faq-separated-child.active{border:1.5px solid var(--color-lwktyvyq)}#faq-wEED3pufBs .faq-contained-child{border:1px solid var(--color-lwktyvyq)}#faq-wEED3pufBs .faq-simple-child .hl-faq-child-heading{border-top:1px solid var(--color-lwktyvyq)}#faq-wEED3pufBs .faq-separated-child .hl-faq-child-heading{border-radius:10px}#faq-wEED3pufBs .faq-separated-child .hl-faq-child-heading.active{border-radius:10px 10px 0 0}#faq-wEED3pufBs .hl-faq-child-heading,#faq-wEED3pufBs .hl-faq-child-heading.active{background-color:var(--white)}#faq-wEED3pufBs .hl-faq-child-heading .hl-faq-child-head .hl-faq-child-heading-text,#faq-wEED3pufBs .hl-faq-child-heading .hl-faq-child-heading-icon{color:#111827}#faq-wEED3pufBs .hl-faq-child-heading.active .hl-faq-child-head .hl-faq-child-heading-text,#faq-wEED3pufBs .hl-faq-child-heading.active .hl-faq-child-heading-icon{color:var(--color-lwjrr318)}#faq-wEED3pufBs .hl-faq-child-heading .hl-faq-child-head .hl-faq-child-heading-text{line-height:1.5;font-family:var(--headlinefont)}#faq-wEED3pufBs .hl-faq-child .hl-faq-child-panel{background-color:var(--white)}#faq-wEED3pufBs .faq-separated-child .hl-faq-child-panel{border-radius:0}#faq-wEED3pufBs .faq-separated-child.active .hl-faq-child-panel{border-radius:0 0 10px 10px}#faq-wEED3pufBs .hl-faq-child .hl-faq-child-panel .hl-faq-child-item-text{color:var(--black);line-height:1.5}#faq-wEED3pufBs .hl-faq-child-panel{display:flex;padding:15px;overflow:hidden}#faq-wEED3pufBs .hl-faq-child-panel .item-text{min-width:80%;margin:0;font-family:var(--contentfont)}#faq-wEED3pufBs .hl-faq-child-panel .item-img{padding:.5em;max-width:20%;height:100%}@media screen and (min-width:0px) and (max-width:480px){#faq-wEED3pufBs .hl-faq-child-panel{display:grid;padding:15px}#faq-wEED3pufBs .hl-faq-child-panel .item-img{max-width:100%;width:100%;margin:0;padding:0;height:auto}#faq-wEED3pufBs .hl-faq-child-panel .item-text{max-width:100%;width:100%;margin:0;height:auto;padding:0 0 5px}#faq-wEED3pufBs .hl-faq-child-heading-text{font-size:15px}#faq-wEED3pufBs .hl-faq-child-heading-text .ProseMirror h4,#faq-wEED3pufBs .hl-faq-child-heading-text h4,#faq-wEED3pufBs .hl-faq-child-item-text .ProseMirror p,#faq-wEED3pufBs .hl-faq-child-item-text p{font-weight:undefined!important}#faq-wEED3pufBs .hl-faq-child-item-text{font-size:12px}}#faq-wEED3pufBs .hl-faq-child-heading .hl-faq-child-heading-icon:before{content:"\uF078"!important;font-family:"Font Awesome 5 Free"}#faq-wEED3pufBs .hl-faq-child-heading.active .hl-faq-child-heading-icon:before{content:"\uF077"!important;font-family:"Font Awesome 5 Free"}#faq-wEED3pufBs .expand-collapse-all-button{color:var(--color-lwjrr318);border:1px solid var(--color-lwktyvyq);background-color:var(--transparent)}#faq-wEED3pufBs a{color:#3b82f6!important;text-decoration:none!important}.heading-gQ8AnRpz8t{font-weight:undefined}.heading-gQ8AnRpz8t em,.heading-gQ8AnRpz8t strong,.heading-gQ8AnRpz8t u{color:var(--text-color)!important}.heading-gQ8AnRpz8t a,.heading-gQ8AnRpz8t a *{color:var(--link-color)!important;text-decoration:none}.heading-gQ8AnRpz8t a:hover{text-decoration:underline}@media screen and (min-width:0px) and (max-width:480px){.heading-gQ8AnRpz8t h1,.heading-gQ8AnRpz8t h2,.heading-gQ8AnRpz8t h3,.heading-gQ8AnRpz8t h4,.heading-gQ8AnRpz8t h5,.heading-gQ8AnRpz8t h6,.heading-gQ8AnRpz8t ul li,.heading-gQ8AnRpz8t.text-output{font-size:32px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.heading-gQ8AnRpz8t h1,.heading-gQ8AnRpz8t h2,.heading-gQ8AnRpz8t h3,.heading-gQ8AnRpz8t h4,.heading-gQ8AnRpz8t h5,.heading-gQ8AnRpz8t h6,.heading-gQ8AnRpz8t ul li,.heading-gQ8AnRpz8t.text-output{font-size:32px!important;font-weight:undefined}}.heading-gQ8AnRpz8t.text-output h1:first-child:before,.heading-gQ8AnRpz8t.text-output h2:first-child:before,.heading-gQ8AnRpz8t.text-output h3:first-child:before,.heading-gQ8AnRpz8t.text-output h4:first-child:before,.heading-gQ8AnRpz8t.text-output h5:first-child:before,.heading-gQ8AnRpz8t.text-output h6:first-child:before,.heading-gQ8AnRpz8t.text-output p:first-child:before{color:var(--text-color);content:'\\';
10088
+ font-family: '';margin-right:5px;font-weight:700}` } }, booking: { id: "section-MCURKhaM7", metaData: { id: "section-MCURKhaM7", type: "section", child: ["row-BafyFVpahF"], class: { width: { value: "fullSection" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingBottom: { unit: "px", value: "60" }, paddingTop: { unit: "px", value: 20 }, marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, backgroundColor: { value: "var(--white)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { sticky: { value: "noneSticky" }, visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, allowRowMaxWidth: { value: false } }, wrapper: {}, meta: "section", tagName: "c-section", title: "Section", _id: "section-MCURKhaM7" }, elements: [{ id: "row-BafyFVpahF", type: "row", child: ["col-CAyTxea5q"], class: { alignRow: { value: "row-align-center" }, boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: "0" }, paddingBottom: { unit: "px", value: 15 }, backgroundColor: { value: "var(--transparent)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, rowWidth: { value: 100, unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-row", meta: "row", title: "1 Column Row" }, { id: "col-CAyTxea5q", type: "col", child: ["heading-SlwxJ2A0nn", "image-2hPEEKf7g", "paragraph-dIjQJIFPn", "calendar-0Yj8r8Npwf", "button-kQavoEkvPP"], class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { paddingLeft: { unit: "px", value: 5 }, paddingRight: { value: 5, unit: "px" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, backgroundColor: { value: "var(--transparent)" }, width: { value: "100", unit: "%" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" } }, extra: { visibility: { value: { hideDesktop: false, hideMobile: false } }, bgImage: { value: { url: "", opacity: "1", options: "bgCover" } }, columnLayout: { value: "column" }, justifyContentColumnLayout: { value: "center" }, alignContentColumnLayout: { value: "inherit" }, forceColumnLayoutForMobile: { value: true } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, tagName: "c-column", meta: "col", title: "1st Column" }, { extra: { nodeId: "cimage-2hPEEKf7g", visibility: { value: { hideDesktop: false, hideMobile: false } }, imageActions: { value: "none" }, visitWebsite: { value: { url: "", newTab: false } }, imageProperties: { value: { width: "", height: "", url: "https://storage.googleapis.com/msgsndr/locatation/EVTjG29VnVlvwn3SRGve/images/e04c0629-2eca-41d4-a320-ef634015616a.png", altText: "", compression: true, placeholderBase64: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAYAAABhYU3QAAAABHNCSVQICAgIfAhkiAAAAF96VFh0UmF3IHByb2ZpbGUgdHlwZSBBUFAxAAAImeNKT81LLcpMVigoyk/LzEnlUgADYxMuE0sTS6NEAwMDCwMIMDQwMDYEkkZAtjlUKNEABZgamFmaGZsZmgMxiM8FAEi2FMk61EMyAAAAVklEQVQImQXBMQ5AMBiA0a+tFpGIpBKLmRs4kCO5iMl9LMwmaUr93lPHtg7GGBsB9YYra9pZo8r73BdTe++AlNKTUVWjQGEBERcVFMJXuq6ftEguABB+L0UZOFcVeFYAAAAASUVORK5CYII=", servingUrl: "https://lh3.googleusercontent.com/8DcV-wSbJBKHjx-cmwagHA3SspBD4P3ScvvmZZog37NoIdaprLI5vt2nY7nfrqeCFVLFa0YTcL7jR3soFjmRqbNiESGeZ1Nm", imageMeta: { width: "", height: "" } } } }, class: { imageRadius: { value: "img-none" }, imageBorder: { value: "img-border-none" }, imageShadow: { value: "img-shadow-none" }, imageEffects: { value: "img-effects-none" } }, styles: { paddingLeft: { unit: "px", value: 10 }, paddingRight: { value: 10, unit: "px" }, paddingTop: { unit: "px", value: "10" }, paddingBottom: { unit: "px", value: "10" }, backgroundColor: { value: "var(--transparent)" }, opacity: { value: "1" }, textAlign: { value: "center" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "image-2hPEEKf7g", type: "element", child: [], meta: "image", tagName: "c-image", title: "Image", tag: "" }, { extra: { nodeId: "cparagraph-dIjQJIFPn", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<p>Ready to embark on your journey to radiant skin and total wellness? Booking an appointment at {{location.name}} is simple and convenient. Our team of experts is here to provide personalized treatments tailored to your unique needs and goals. We offer flexible scheduling to accommodate your busy lifestyle. Whether you prefer a quick lunchtime session or a relaxing afternoon retreat, we have appointment times to fit your needs.</p><p></p><p>Use our booking calendar below to schedule your appointment at any time. Select your preferred service, choose a convenient date and time, and confirm your appointment with just a few clicks.</p><p></p><p>Not sure which treatment is right for you? Schedule a consultation with one of our experienced professionals. We\u2019ll assess your skin and discuss your goals to create a customized treatment plan just for you.</p><p></p><p>If you have any questions or need assistance with booking, please don\u2019t hesitate to contact us at {{location.phone}}. Our friendly team is here to help!</p>" }, mobileFontSize: { value: "16", unit: "px" }, desktopFontSize: { value: "18", unit: "px" }, typography: { value: "var(--contentfont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "left" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 20 } }, customCss: [], id: "paragraph-dIjQJIFPn", type: "element", child: [], meta: "paragraph", tagName: "c-paragraph", title: "Paragraph", tag: "p" }, { extra: { nodeId: "ccalendar-0Yj8r8Npwf", visibility: { value: { hideDesktop: false, hideMobile: false } }, calendarId: { value: "none", text: "You do not have any calendar yet" }, action: { value: "none" }, visitWebsite: { value: { url: "", newTab: false } }, customClass: { value: [] } }, class: {}, styles: { paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 } }, customCss: [], id: "calendar-0Yj8r8Npwf", type: "element", child: [], meta: "calendar", tagName: "c-calendar", title: "Calendar", tag: "" }, { extra: { nodeId: "cheading-SlwxJ2A0nn", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "<h1>BOOK YOUR APPOINTMENT</h1>" }, mobileFontSize: { value: 46, unit: "px" }, desktopFontSize: { value: 46, unit: "px" }, typography: { value: "var(--headlinefont)" }, icon: { value: { name: "", unicode: "", fontFamily: "" } }, customClass: { value: [] } }, class: { boxShadow: { value: "none" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--transparent)" }, color: { value: "var(--text-color)" }, boldTextColor: { value: "var(--text-color)" }, italicTextColor: { value: "var(--text-color)" }, underlineTextColor: { value: "var(--text-color)" }, linkTextColor: { value: "var(--link-color)" }, iconColor: { value: "var(--text-color)" }, fontFamily: { value: "" }, fontWeight: { value: "normal", desktop: "400" }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" }, paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, opacity: { value: "1" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, borderColor: { value: "var(--black)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, lineHeight: { value: 1.3, unit: "em" }, textTransform: { value: "" }, letterSpacing: { value: "0", unit: "px" }, textAlign: { value: "center" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 } }, customCss: [], mobileStyles: {}, mobileWrapper: {}, id: "heading-SlwxJ2A0nn", type: "element", child: [], meta: "heading", tagName: "c-heading", title: "Headline", tag: "h1" }, { extra: { nodeId: "cbutton-kQavoEkvPP", visibility: { value: { hideDesktop: false, hideMobile: false } }, text: { value: "SUBMIT" }, subText: { value: "" }, mobileFontSize: { value: 20, unit: "px" }, desktopFontSize: { value: 20, unit: "px" }, subTextDesktopFontSize: { value: 15, unit: "px" }, subTextMobileFontSize: { value: 15, unit: "px" }, typography: { value: "var(--headlinefont)" }, iconStart: { value: { name: "", unicode: "", fontFamily: "" } }, iconEnd: { value: { name: "", unicode: "", fontFamily: "" } }, action: { value: "go-to-funnel-step" }, visitWebsite: { value: { url: "", newTab: false } }, hideElements: { value: [] }, showElements: { value: [] }, scrollToElement: { value: "" }, phoneNumber: { value: "" }, emailAddress: { value: "" }, productId: { value: "" }, stepPath: { value: "63b348ae-75d9-4ba0-a32b-f8163075c1b1" }, saleAction: { value: "go-to-next-funnel-step" }, theme: { value: "brand" }, customClass: { value: [] } }, class: { buttonEffects: { value: "none" }, buttonBoxShadow: { value: "btnshadow" }, buttonBgStyle: { value: "custom" }, buttonVp: { value: "btn-vp" }, buttonHp: { value: "btn-hp" }, borders: { value: "noBorder" }, borderRadius: { value: "radius0" }, radiusEdge: { value: "none" } }, styles: { backgroundColor: { value: "var(--my-custom-color-44)" }, color: { value: "var(--white)" }, secondaryColor: { value: "var(--white)" }, textDecoration: { value: "none" }, paddingTop: { unit: "px", value: 10 }, paddingBottom: { unit: "px", value: 10 }, paddingLeft: { unit: "px", value: 30 }, paddingRight: { unit: "px", value: 30 }, fontWeight: { value: "", desktop: "400" }, fontWeightSub: { desktop: "400", value: "" }, borderColor: { value: "var(--green)" }, borderWidth: { value: "2", unit: "px" }, borderStyle: { value: "solid" }, letterSpacing: { value: "0", unit: "px" }, textTransform: { value: "" }, textShadow: { value: "0px 0px 0px rgba(0,0,0,0)" }, width: { value: "auto", unit: "%" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 }, marginLeft: { unit: "px", value: 0 }, marginRight: { unit: "px", value: 0 }, textAlign: { value: "center" } }, mobileWrapper: {}, customCss: [], id: "button-kQavoEkvPP", mobileStyles: {}, type: "element", child: [], meta: "button", tagName: "c-button", title: "Button", tag: "" }], sequence: 2, pageId: "n3Asu9D8CUHL3vM5aiJi", funnelId: "pK3yy9CFapchugRrgjgq", locationId: "Gc2kgDDpABIR8QDyJ6rf", general: { colors: [{ label: "White", value: "#ffffff" }, { label: "Black", value: "#000000" }, { label: "Green", value: "#9ae6b4" }, { label: "Transparent", value: "transparent" }, { name: "My Custom Color 44", value: "#ec606a", label: "my-custom-color-44" }], fontsForPreview: ["'Lato'", "'Oswald'"], rootVars: { "--'lato'": "'Lato'", "--'oswald'": "'Oswald'", "--white": "#ffffff", "--black": "#000000", "--green": "#9ae6b4", "--transparent": "transparent", "--my-custom-color-44": "#ec606a" }, sectionStyles: ":root{--white:#ffffff;--black:#000000;--green:#9ae6b4;--transparent:transparent;--my-custom-color-44:#ec606a}.hl_page-preview--content .col-CAyTxea5q .inner,.hl_page-preview--content .row-BafyFVpahF,.hl_page-preview--content .section-MCURKhaM7{padding:20px 0 60px;margin-top:0;margin-bottom:0;background-color:var(--white);border-color:var(--black);border-width:2px;border-style:solid}.hl_page-preview--content .col-CAyTxea5q .inner,.hl_page-preview--content .row-BafyFVpahF{padding:0 0 15px;background-color:var(--transparent);width:100%}.hl_page-preview--content .col-CAyTxea5q{width:100%}.hl_page-preview--content .col-CAyTxea5q .inner{padding:10px 5px}.hl_page-preview--content .image-2hPEEKf7g{margin-top:0;margin-bottom:0}.hl_page-preview--content .cimage-2hPEEKf7g{padding:10px;background-color:var(--transparent);opacity:1;text-align:center}.hl_page-preview--content .paragraph-dIjQJIFPn{margin-top:0;margin-bottom:20px}.hl_page-preview--content .cparagraph-dIjQJIFPn{font-family:var(--contentfont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:left}.hl_page-preview--content .calendar-0Yj8r8Npwf{margin:0}.hl_page-preview--content .ccalendar-0Yj8r8Npwf{padding:0}.hl_page-preview--content .heading-SlwxJ2A0nn{margin:0}.hl_page-preview--content .cheading-SlwxJ2A0nn{font-family:var(--headlinefont);background-color:var(--transparent);color:var(--text-color);icon-color:var(--text-color);font-weight:400;padding:0;opacity:1;text-shadow:0 0 0 transparent;border-color:var(--black);border-width:2px;border-style:solid;line-height:1.3em;letter-spacing:0;text-align:center}.hl_page-preview--content .button-kQavoEkvPP{margin:0;text-align:center}.hl_page-preview--content .cbutton-kQavoEkvPP{font-family:var(--headlinefont);background-color:var(--my-custom-color-44);color:var(--white);secondary-color:var(--white);text-decoration:none;padding:10px 30px;border-color:var(--green);border-width:2px;border-style:solid;letter-spacing:0;text-shadow:0 0 0 transparent;width:auto%}#section-MCURKhaM7>.inner{max-width:1170px}#col-CAyTxea5q>.inner{flex-direction:column;justify-content:center;align-items:inherit;flex-wrap:nowrap}.paragraph-dIjQJIFPn{font-weight:undefined}.heading-SlwxJ2A0nn em,.heading-SlwxJ2A0nn strong,.heading-SlwxJ2A0nn u,.paragraph-dIjQJIFPn em,.paragraph-dIjQJIFPn strong,.paragraph-dIjQJIFPn u{color:var(--text-color)!important}.heading-SlwxJ2A0nn a,.heading-SlwxJ2A0nn a *,.paragraph-dIjQJIFPn a,.paragraph-dIjQJIFPn a *{color:var(--link-color)!important;text-decoration:none}.heading-SlwxJ2A0nn a:hover,.paragraph-dIjQJIFPn a:hover{text-decoration:underline}@media screen and (min-width:0px) and (max-width:480px){.paragraph-dIjQJIFPn h1,.paragraph-dIjQJIFPn h2,.paragraph-dIjQJIFPn h3,.paragraph-dIjQJIFPn h4,.paragraph-dIjQJIFPn h5,.paragraph-dIjQJIFPn h6,.paragraph-dIjQJIFPn ul li,.paragraph-dIjQJIFPn.text-output{font-size:16px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.paragraph-dIjQJIFPn h1,.paragraph-dIjQJIFPn h2,.paragraph-dIjQJIFPn h3,.paragraph-dIjQJIFPn h4,.paragraph-dIjQJIFPn h5,.paragraph-dIjQJIFPn h6,.paragraph-dIjQJIFPn ul li,.paragraph-dIjQJIFPn.text-output{font-size:18px!important;font-weight:undefined}}.heading-SlwxJ2A0nn.text-output h1:first-child:before,.heading-SlwxJ2A0nn.text-output h2:first-child:before,.heading-SlwxJ2A0nn.text-output h3:first-child:before,.heading-SlwxJ2A0nn.text-output h4:first-child:before,.heading-SlwxJ2A0nn.text-output h5:first-child:before,.heading-SlwxJ2A0nn.text-output h6:first-child:before,.heading-SlwxJ2A0nn.text-output p:first-child:before,.paragraph-dIjQJIFPn.text-output h1:first-child:before,.paragraph-dIjQJIFPn.text-output h2:first-child:before,.paragraph-dIjQJIFPn.text-output h3:first-child:before,.paragraph-dIjQJIFPn.text-output h4:first-child:before,.paragraph-dIjQJIFPn.text-output h5:first-child:before,.paragraph-dIjQJIFPn.text-output h6:first-child:before,.paragraph-dIjQJIFPn.text-output p:first-child:before{color:var(--text-color);content:'\\';\n font-family: '';margin-right:5px;font-weight:700}.heading-SlwxJ2A0nn{font-weight:400}@media screen and (min-width:0px) and (max-width:480px){.heading-SlwxJ2A0nn h1,.heading-SlwxJ2A0nn h2,.heading-SlwxJ2A0nn h3,.heading-SlwxJ2A0nn h4,.heading-SlwxJ2A0nn h5,.heading-SlwxJ2A0nn h6,.heading-SlwxJ2A0nn ul li,.heading-SlwxJ2A0nn.text-output{font-size:46px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.heading-SlwxJ2A0nn h1,.heading-SlwxJ2A0nn h2,.heading-SlwxJ2A0nn h3,.heading-SlwxJ2A0nn h4,.heading-SlwxJ2A0nn h5,.heading-SlwxJ2A0nn h6,.heading-SlwxJ2A0nn ul li,.heading-SlwxJ2A0nn.text-output{font-size:46px!important;font-weight:undefined}}@media screen and (min-width:481px) and (max-width:10000px){.button-kQavoEkvPP .button-icon-end,.button-kQavoEkvPP .button-icon-start,.button-kQavoEkvPP .main-heading-button{font-size:20px;font-weight:400}.button-kQavoEkvPP .button-icon-start{margin-right:5px}.button-kQavoEkvPP .button-icon-end{margin-left:5px}.button-kQavoEkvPP .sub-heading-button{font-size:15px;color:var(--white);font-weight:400}}@media screen and (min-width:0px) and (max-width:480px){.button-kQavoEkvPP .button-icon-end,.button-kQavoEkvPP .button-icon-start,.button-kQavoEkvPP .main-heading-button{font-size:20px;font-weight:undefined}.button-kQavoEkvPP .button-icon-start{margin-right:5px}.button-kQavoEkvPP .button-icon-end{margin-left:5px}.button-kQavoEkvPP .sub-heading-button{font-size:15px;color:var(--white);font-weight:undefined}}" } } }, formElement: { extra: { nodeId: "cform-YTQVxc2ryY", visibility: { value: { hideDesktop: false, hideMobile: false } }, formId: { value: "nM86ifoBmhUmyDyaUedm", text: "Marketing Form - Claim Offer" }, action: { value: "none" }, visitWebsite: { value: { url: "", newTab: false } }, customClass: { value: [] } }, class: {}, styles: { paddingTop: { unit: "px", value: 0 }, paddingBottom: { unit: "px", value: 0 }, paddingLeft: { unit: "px", value: 0 }, paddingRight: { value: 0, unit: "px" } }, wrapper: { marginTop: { unit: "px", value: 0 }, marginBottom: { unit: "px", value: 0 } }, customCss: [], id: "form-YTQVxc2ryY", type: "element", child: [], meta: "form", tagName: "c-form", title: "Form", tag: "" }, base: { settings: { settings: { typography: { fonts: { headlineFont: { id: "headlinefont", value: { value: "var(--oswald)", text: "Oswald" }, text: "Headline Font" }, contentFont: { value: { text: "Lato", value: "var(--lato)" }, id: "contentfont", text: "Content Font" } }, colors: { linkColor: { value: { value: "var(--my-custom-color-44)", label: "var(--blue)" } }, textColor: { value: { value: "var(--my-custom-color-26)", label: "var(--black)" } } } }, background: { bgImage: { value: { url: "", options: "bgCover" } }, backgroundColor: { value: "var(--white)" } } } }, general: { general: { colors: [{ label: "Primary", value: "#37ca37" }, { value: "#188bf6", label: "Secondary" }, { label: "White", value: "#ffffff" }, { label: "Gray", value: "#cbd5e0" }, { label: "Black", value: "#000000" }, { label: "Red", value: "#e93d3d" }, { label: "Orange", value: "#f6ad55" }, { label: "Yellow", value: "#faf089" }, { value: "#9ae6b4", label: "Green" }, { value: "#81e6d9", label: "Teal" }, { value: "#63b3ed", label: "Malibu" }, { value: "#757BBD", label: "Indigo" }, { value: "#d6bcfa", label: "Purple" }, { label: "Pink", value: "#fbb6ce" }, { label: "Transparent", value: "transparent" }, { value: "rgba(0, 0, 0, 0.5)", label: "Overlay" }, { label: "my-custom-color-26", value: "#434445", name: "My Custom Color 26" }, { label: "my-custom-color-44", name: "My Custom Color 44", value: "#ec606a" }, { name: "", value: "#fff6", label: "" }, { name: "My Custom Color 71", label: "my-custom-color-71", value: "#d7d7d9" }, { label: "my-custom-color-60", value: "#e9c7c1", name: "My Custom Color 60" }, { name: "My Custom Color 94", value: "#f49ca2 ", label: "my-custom-color-94" }, { value: "#f3f3f3", name: "My Custom Color 16", label: "my-custom-color-16" }], fontsToLoad: ["Arial", "Lato", "Open Sans", "Montserrat", "Oswald", "Roboto", "'Lato'", "'Oswald'"], fontsToLoadForPreview: ["'Lato'", "'Oswald'"], pageStyles: "" } }, pageStyles: ":root{ --primary: #37ca37;\n--secondary: #188bf6;\n--white: #ffffff;\n--gray: #cbd5e0;\n--black: #000000;\n--red: #e93d3d;\n--orange: #f6ad55;\n--yellow: #faf089;\n--green: #9ae6b4;\n--teal: #81e6d9;\n--malibu: #63b3ed;\n--indigo: #757BBD;\n--purple: #d6bcfa;\n--pink: #fbb6ce;\n--transparent: transparent;\n--overlay: rgba(0, 0, 0, 0.5);\n--my-custom-color-26: #434445;\n--my-custom-color-44: #ec606a;\n--: #fff6;\n--my-custom-color-71: #d7d7d9;\n--my-custom-color-60: #e9c7c1;\n--my-custom-color-94: #f49ca2 ;\n--my-custom-color-16: #f3f3f3;\n--arial: 'Arial';\n--lato: 'Lato';\n--open-sans: 'Open Sans';\n--montserrat: 'Montserrat';\n--roboto: 'Roboto';\n--oswald: 'Oswald';\n--'lato': ''Lato'';\n--'oswald': ''Oswald'';\n--headlinefont: 'Oswald';\n--contentfont: 'Lato';\n--link-color: var(--my-custom-color-44);\n--text-color: var(--my-custom-color-26); } .bg-fixed{bottom:0;top:0;left:0;right:0;position:fixed;overflow:auto;background-color:var(--white)} \n \n .drop-zone-draggable .hl_main_popup{background-color:var(--white);border-style:solid;border-width:10px;margin-top:0;border-color:var(--gray);padding:20px}\n \n \n#hl_main_popup{background-color:var(--white);border-style:solid;border-width:10px;margin-top:0;border-color:var(--gray);padding:20px;width:720px} ", trackingCode: {}, fontsForPreview: [] } };
10089
+
10090
+ // src/page-studio/remint.ts
10091
+ var ID_FIELDS = ["id"];
10092
+ function isNodeId(v) {
10093
+ if (v.length < 8 || /^\d/.test(v)) return false;
10094
+ const dash = v.indexOf("-");
10095
+ return dash > 0 && v.length - dash - 1 >= 4;
10096
+ }
10097
+ function collectIds(node, acc) {
10098
+ if (Array.isArray(node)) {
10099
+ for (const item of node) collectIds(item, acc);
10100
+ return;
10101
+ }
10102
+ if (!node || typeof node !== "object") return;
10103
+ const rec = node;
10104
+ for (const f of ID_FIELDS) {
10105
+ const v = rec[f];
10106
+ if (typeof v === "string" && isNodeId(v)) acc.add(v);
10107
+ }
10108
+ const nodeId = rec.extra?.nodeId;
10109
+ if (typeof nodeId === "string" && isNodeId(nodeId)) acc.add(nodeId);
10110
+ for (const [k, v] of Object.entries(rec)) {
10111
+ if (k === "extra") {
10112
+ collectIds(v, acc);
10113
+ continue;
10114
+ }
10115
+ if (typeof v === "object" && v !== null) collectIds(v, acc);
10116
+ }
10117
+ }
10118
+ var mintCounter = 0;
10119
+ function defaultMint(oldId) {
10120
+ const dash = oldId.indexOf("-");
10121
+ const prefix = dash > 0 ? oldId.slice(0, dash) : oldId;
10122
+ mintCounter += 1;
10123
+ const rand = Math.random().toString(36).slice(2, 8);
10124
+ return `${prefix}-ps${rand}${mintCounter.toString(36)}`;
10125
+ }
10126
+ function escapeRegExp2(s) {
10127
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
10128
+ }
10129
+ function remintClone(node, mint = defaultMint) {
10130
+ const ids = /* @__PURE__ */ new Set();
10131
+ collectIds(node, ids);
10132
+ const idMap = /* @__PURE__ */ new Map();
10133
+ for (const oldId of ids) {
10134
+ if (!idMap.has(oldId)) idMap.set(oldId, mint(oldId));
10135
+ }
10136
+ for (const [oldId, newId] of idMap) {
10137
+ const cOld = "c" + oldId;
10138
+ if (idMap.has(cOld)) idMap.set(cOld, "c" + newId);
10139
+ }
10140
+ let text = JSON.stringify(node);
10141
+ const ordered = [...idMap.keys()].sort((a, b) => b.length - a.length);
10142
+ for (const oldId of ordered) {
10143
+ const newId = idMap.get(oldId);
10144
+ if (newId === void 0) continue;
10145
+ const re = new RegExp(`(?:(?<=%2F)|(?<![A-Za-z0-9_-]))${escapeRegExp2(oldId)}(?![A-Za-z0-9_-])`, "g");
10146
+ text = text.replace(re, newId);
10147
+ }
10148
+ return { cloned: JSON.parse(text), idMap };
10149
+ }
10150
+
10151
+ // src/page-studio/sections.ts
10152
+ var donors = donor_sections_default;
10153
+ function deepClone(v) {
10154
+ return JSON.parse(JSON.stringify(v));
10155
+ }
10156
+ function escapeHtml(s) {
10157
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
10158
+ }
10159
+ function elements(section2) {
10160
+ return section2.elements ?? [];
10161
+ }
10162
+ function byId(section2, donorId) {
10163
+ const el = elements(section2).find((e) => e.id === donorId);
10164
+ if (!el) throw new Error(`Page Studio internal: donor element ${donorId} missing \u2014 did the capture change without re-running extract-donors?`);
10165
+ return el;
10166
+ }
10167
+ function setText(el, html2) {
10168
+ const extra = el.extra ?? {};
10169
+ extra.text = { ...extra.text, value: html2 };
10170
+ el.extra = extra;
10171
+ }
10172
+ function setIcon(el, iconName) {
10173
+ const extra = el.extra ?? {};
10174
+ const icon = extra.icon ?? { value: {} };
10175
+ icon.value = { ...icon.value, name: iconName };
10176
+ extra.icon = icon;
10177
+ }
10178
+ function setImageUrl(el, url) {
10179
+ const extra = el.extra ?? {};
10180
+ const props = extra.imageProperties ?? { value: {} };
10181
+ const value = { ...props.value, url };
10182
+ delete value.servingUrl;
10183
+ delete value.placeholderBase64;
10184
+ props.value = value;
10185
+ extra.imageProperties = props;
10186
+ }
10187
+ function setSectionBgImage(section2, url) {
10188
+ const md = section2.metaData ?? {};
10189
+ const extra = md.extra ?? {};
10190
+ const bg = extra.bgImage ?? { value: {} };
10191
+ const value = { ...bg.value, url };
10192
+ delete value.servingUrl;
10193
+ delete value.placeholderBase64;
10194
+ bg.value = value;
10195
+ extra.bgImage = bg;
10196
+ md.extra = extra;
10197
+ section2.metaData = md;
10198
+ }
10199
+ function finish(section2) {
10200
+ const { cloned } = remintClone(section2);
10201
+ const rec = cloned;
10202
+ delete rec.isGlobal;
10203
+ return { section: rec, sectionId: rec.id };
10204
+ }
10205
+ function buildTopbar(params) {
10206
+ const s = deepClone(donors.sections.topbar);
10207
+ if (params.phoneHtml) setText(byId(s, "paragraph-jL-pjux8a"), params.phoneHtml);
10208
+ if (params.logoUrl) setImageUrl(byId(s, "image-YGGYHGoZw"), params.logoUrl);
10209
+ return finish(s);
10210
+ }
10211
+ function buildHero(params) {
10212
+ const s = deepClone(donors.sections.hero);
10213
+ setText(byId(s, "heading-BcUsx4fVJi"), `<h1>${escapeHtml(params.headline)}</h1>`);
10214
+ setText(byId(s, "paragraph-WVEyivzTc"), `<p>${escapeHtml(params.subhead)}</p>`);
10215
+ const btn = byId(s, "button-XgW4LOq8Q");
10216
+ setText(btn, escapeHtml(params.ctaLabel));
10217
+ const ctaUrl = params.ctaHref ?? (params.ctaAnchorId ? `#${params.ctaAnchorId}` : void 0);
10218
+ if (ctaUrl) {
10219
+ const extra = btn.extra ?? {};
10220
+ extra.action = { value: "url" };
10221
+ extra.visitWebsite = { value: { url: ctaUrl, newTab: false } };
10222
+ btn.extra = extra;
10223
+ }
10224
+ if (params.bgImageUrl) setSectionBgImage(s, params.bgImageUrl);
10225
+ return finish(s);
10226
+ }
10227
+ var CARD_SLOTS = [
10228
+ { title: "heading-ZvINOOFQi", body: "paragraph-1XjOnx_r2", blank: ["paragraph-iuePsO6Jd", "paragraph-fBuGHkfQd"] },
10229
+ { title: "heading-h2fK7KiZ6", body: "paragraph-y_I-jJh6ya", blank: [] },
10230
+ { title: "heading-FBdJHQ1UZ", body: "paragraph--m28AM_yp9", blank: ["paragraph-6KxQcCSVR", "paragraph-nuxIv4A8ad", "paragraph-pvUi7TFc7r"] }
10231
+ ];
10232
+ function buildValueCards(params) {
10233
+ const s = deepClone(donors.sections.valueCards);
10234
+ const removeIds = /* @__PURE__ */ new Set();
10235
+ params.cards.forEach((card, i) => {
10236
+ const slot = CARD_SLOTS[i];
10237
+ const title = byId(s, slot.title);
10238
+ setText(title, `<p>${escapeHtml(card.title)}</p>`);
10239
+ if (card.iconName) setIcon(title, card.iconName);
10240
+ setText(byId(s, slot.body), card.bodyHtml);
10241
+ for (const blankId of slot.blank) removeIds.add(blankId);
10242
+ });
10243
+ s.elements = elements(s).filter((e) => !removeIds.has(e.id));
10244
+ for (const col of elements(s).filter((e) => e.type === "col")) {
10245
+ col.child = (col.child ?? []).filter((c) => !removeIds.has(c));
10246
+ }
10247
+ return finish(s);
10248
+ }
10249
+ function buildFaq(params) {
10250
+ const s = deepClone(donors.sections.faq);
10251
+ if (params.title) setText(byId(s, "sub-heading-bQudNu4eBG"), `<h2>${escapeHtml(params.title)}</h2>`);
10252
+ if (params.imageUrl) setImageUrl(byId(s, "image-VMrslNNuUy"), params.imageUrl);
10253
+ const toFaqList = (items) => items.map((it, i) => ({ id: i + 1, heading: `<h4>${escapeHtml(it.q)}</h4>`, text: `<p>${escapeHtml(it.a)}</p>` }));
10254
+ const half = Math.ceil(params.items.length / 2);
10255
+ const widgets = ["faq-hC9kdZlk9d", "faq-xt8Q865Gfb"];
10256
+ const parts = [params.items.slice(0, half), params.items.slice(half)];
10257
+ widgets.forEach((wid, i) => {
10258
+ const el = byId(s, wid);
10259
+ const extra = el.extra ?? {};
10260
+ const faqList = extra.faqList ?? {};
10261
+ faqList.value = toFaqList(parts[i]);
10262
+ extra.faqList = faqList;
10263
+ el.extra = extra;
10264
+ });
10265
+ return finish(s);
10266
+ }
10267
+ function buildFooter(params) {
10268
+ const s = deepClone(donors.sections.footer);
10269
+ if (params.logoUrl) setImageUrl(byId(s, "image-Fuy-QQVmM"), params.logoUrl);
10270
+ const legal = byId(s, "paragraph-R6ogZueLM");
10271
+ setText(
10272
+ legal,
10273
+ `<p>${escapeHtml(params.businessLegalName)} \xB7 ${escapeHtml(params.mailingAddress)}</p><p>\xA9 {{right_now.year}} ${escapeHtml(params.businessLegalName)}. All Rights Reserved. <a href="${escapeHtml(params.privacyUrl)}" target="_blank">Privacy Policy</a> \xB7 <a href="${escapeHtml(params.termsUrl)}" target="_blank">Terms of Service</a></p>`
10274
+ );
10275
+ return finish(s);
10276
+ }
10277
+ function buildFormSection(params) {
10278
+ const title = deepClone(byId(donors.sections.faq, "sub-heading-bQudNu4eBG"));
10279
+ title.id = "sub-heading-FRMTITLE";
10280
+ (title.extra ?? {}).nodeId = "csub-heading-FRMTITLE";
10281
+ setText(title, `<h2>${escapeHtml(params.headline)}</h2>`);
10282
+ const disclosure = deepClone(byId(donors.sections.footer, "paragraph-R6ogZueLM"));
10283
+ disclosure.id = "paragraph-FRMDISC";
10284
+ (disclosure.extra ?? {}).nodeId = "cparagraph-FRMDISC";
10285
+ setText(disclosure, params.disclosureHtml);
10286
+ const form = deepClone(donors.formElement);
10287
+ form.id = "form-FRMEMBED";
10288
+ {
10289
+ const extra = form.extra ?? {};
10290
+ extra.nodeId = "cform-FRMEMBED";
10291
+ extra.formId = { value: params.formId, text: params.formName };
10292
+ form.extra = extra;
10293
+ }
10294
+ const legal = deepClone(byId(donors.sections.footer, "paragraph-R6ogZueLM"));
10295
+ legal.id = "paragraph-FRMLEGAL";
10296
+ (legal.extra ?? {}).nodeId = "cparagraph-FRMLEGAL";
10297
+ setText(
10298
+ legal,
10299
+ `<p><a href="${escapeHtml(params.privacyUrl)}" target="_blank">Privacy Policy</a> \xB7 <a href="${escapeHtml(params.termsUrl)}" target="_blank">Terms of Service</a></p>`
10300
+ );
10301
+ const section2 = deepClone(donors.sections.formShell);
10302
+ const els = elements(section2);
10303
+ const row = els.find((e) => e.type === "row");
10304
+ const col = els.find((e) => e.type === "col");
10305
+ if (!row || !col) throw new Error("Page Studio internal: formShell donor lost its row/col \u2014 re-run extract-donors.");
10306
+ const children = [title, disclosure, form, legal];
10307
+ col.child = children.map((c) => c.id);
10308
+ section2.elements = [row, col, ...children];
10309
+ return finish(section2);
10310
+ }
10311
+ function buildNav(params) {
10312
+ const s = deepClone(donors.sections.nav);
10313
+ const el = elements(s).find((e) => e.meta === "nav-menu");
10314
+ if (!el) throw new Error("Page Studio internal: nav donor lost its nav-menu element \u2014 re-run extract-donors.");
10315
+ const extra = el.extra ?? {};
10316
+ extra.menuItems = {
10317
+ value: params.items.map((it, i) => ({
10318
+ id: String(i + 1),
10319
+ title: escapeHtml(it.title),
10320
+ goTo: "go-to-funnel-step",
10321
+ url: `#${escapeHtml(it.slug)}`,
10322
+ goToId: it.stepId,
10323
+ openInNewTab: false,
10324
+ childs: []
10325
+ }))
10326
+ };
10327
+ if (params.brandHtml) extra.text = { ...extra.text, value: params.brandHtml };
10328
+ el.extra = extra;
10329
+ if (params.logoUrl) setImageUrl(el, params.logoUrl);
10330
+ return finish(s);
10331
+ }
10332
+ var IMAGETEXT_SLOTS = [
10333
+ { title: "paragraph-PwtXX77o4", body: "paragraph-F9SB3vFfN" },
10334
+ { title: "paragraph-Ud7-Hmgyun", body: "paragraph-ECP1xCEVEa" },
10335
+ { title: "paragraph-Dt21hDz3On", body: "paragraph-AU_CDh6MOl" }
10336
+ ];
10337
+ function buildImageText(params) {
10338
+ const s = deepClone(donors.sections.imageText);
10339
+ setText(byId(s, "sub-heading-MbvugAQFJf"), `<h2>${escapeHtml(params.title)}</h2>`);
10340
+ params.features.forEach((f, i) => {
10341
+ const slot = IMAGETEXT_SLOTS[i];
10342
+ setText(byId(s, slot.title), `<p><strong>${escapeHtml(f.title)}</strong></p>`);
10343
+ setText(byId(s, slot.body), f.bodyHtml);
10344
+ });
10345
+ if (params.imageUrl) setImageUrl(byId(s, "image-2hPEEKf7g"), params.imageUrl);
10346
+ return finish(s);
10347
+ }
10348
+ function buildCtaBanner(params) {
10349
+ const s = deepClone(donors.sections.ctaBanner);
10350
+ setText(byId(s, "sub-heading-JJ_mZmXWcY"), `<h2>${escapeHtml(params.title)}</h2>`);
10351
+ setText(byId(s, "paragraph-NAh24LKg8A"), params.bodyHtml);
10352
+ const btn = byId(s, "button-H3ED7jvqBu");
10353
+ setText(btn, escapeHtml(params.buttonLabel));
10354
+ const extra = btn.extra ?? {};
10355
+ extra.action = { value: "url" };
10356
+ extra.visitWebsite = { value: { url: params.buttonHref, newTab: false } };
10357
+ btn.extra = extra;
10358
+ return finish(s);
10359
+ }
10360
+ function buildMapSection(params) {
10361
+ const s = deepClone(donors.sections.map);
10362
+ if (params.title) setText(byId(s, "heading-IUykdV_et"), `<p>${escapeHtml(params.title)}</p>`);
10363
+ if (params.mapLocation) {
10364
+ const mapEl = byId(s, "map-tptsa5-Qnk");
10365
+ const extra = mapEl.extra ?? {};
10366
+ const loc = extra.mapLocation ?? {};
10367
+ const value = { ...loc.value ?? loc };
10368
+ value.name = params.mapLocation.name;
10369
+ value.lat = params.mapLocation.lat;
10370
+ value.lng = params.mapLocation.lng;
10371
+ if (params.mapLocation.placeId) value.placeId = params.mapLocation.placeId;
10372
+ delete value.url;
10373
+ if (loc.value !== void 0) loc.value = value;
10374
+ else Object.assign(loc, value);
10375
+ extra.mapLocation = loc.value !== void 0 ? loc : { ...loc };
10376
+ mapEl.extra = extra;
10377
+ }
10378
+ return finish(s);
10379
+ }
10380
+ function buildBooking(params) {
10381
+ const s = deepClone(donors.sections.booking);
10382
+ const cal = byId(s, "calendar-0Yj8r8Npwf");
10383
+ const extra = cal.extra ?? {};
10384
+ extra.calendarId = { value: params.calendarId, text: params.calendarName };
10385
+ cal.extra = extra;
10386
+ if (params.title) setText(byId(s, "heading-SlwxJ2A0nn"), `<h1>${escapeHtml(params.title)}</h1>`);
10387
+ if (params.bodyHtml) setText(byId(s, "paragraph-dIjQJIFPn"), params.bodyHtml);
10388
+ if (params.imageUrl) setImageUrl(byId(s, "image-2hPEEKf7g"), params.imageUrl);
10389
+ return finish(s);
10390
+ }
10391
+ function baseEnvelopeParts() {
10392
+ return deepClone(donors.base);
10393
+ }
10394
+
10395
+ // src/page-studio/compose.ts
10396
+ function requireField(value, name, problems) {
10397
+ if (typeof value !== "string" || value.trim().length === 0) problems.push(`missing required field: ${name}`);
10398
+ }
10399
+ function complianceGate(params) {
10400
+ const problems = [];
10401
+ const warnings = [];
10402
+ requireField(params.business?.legalName, "business.legalName", problems);
10403
+ requireField(params.business?.mailingAddress, "business.mailingAddress", problems);
10404
+ requireField(params.business?.privacyUrl, "business.privacyUrl", problems);
10405
+ requireField(params.business?.termsUrl, "business.termsUrl", problems);
10406
+ requireField(params.form?.formId, "form.formId", problems);
10407
+ requireField(params.form?.formName, "form.formName", problems);
10408
+ requireField(params.content?.headline, "content.headline", problems);
10409
+ requireField(params.content?.subhead, "content.subhead", problems);
10410
+ requireField(params.content?.ctaLabel, "content.ctaLabel", problems);
10411
+ for (const url of [params.business?.privacyUrl, params.business?.termsUrl]) {
10412
+ if (typeof url === "string" && url.length > 0 && !/^https?:\/\//.test(url)) {
10413
+ problems.push(`URL must be absolute (https://\u2026): ${url}`);
10414
+ }
10415
+ }
10416
+ if ((params.content?.cards?.length ?? 0) !== 3) problems.push("content.cards must have exactly 3 cards");
10417
+ if ((params.content?.faqs?.length ?? 0) < 2) problems.push("content.faqs needs at least 2 items");
10418
+ if ((params.content?.faqs?.length ?? 0) > 0 && (params.content?.faqs?.length ?? 0) < 4) {
10419
+ warnings.push("content contract recommends 4-8 FAQ items");
10420
+ }
10421
+ if (!params.images?.heroUrl) warnings.push("hero uses the donor template's stock image \u2014 replace with a client-owned image before customer use");
10422
+ if (!params.images?.logoUrl) warnings.push("topbar/footer use the donor template's placeholder logo \u2014 provide images.logoUrl before customer use");
10423
+ if (problems.length > 0) {
10424
+ throw new Error("Compliance gate failed (A2P/content contract):\n- " + problems.join("\n- "));
10425
+ }
10426
+ return warnings;
10427
+ }
10428
+ function composeOptinPage(params) {
10429
+ const warnings = complianceGate(params);
10430
+ const disclosure = params.content.disclosureHtml ?? `<p>Complete the form to claim this offer from ${params.business.legalName}. By submitting you agree to receive recurring informational and marketing messages (reply STOP to opt out, HELP for help; message frequency varies, msg &amp; data rates may apply).</p>`;
10431
+ const formSection = buildFormSection({
10432
+ formId: params.form.formId,
10433
+ formName: params.form.formName,
10434
+ headline: params.content.headline,
10435
+ disclosureHtml: disclosure,
10436
+ privacyUrl: params.business.privacyUrl,
10437
+ termsUrl: params.business.termsUrl
10438
+ });
10439
+ const topbar = buildTopbar({ phoneHtml: params.business.phoneHtml, logoUrl: params.images?.logoUrl });
10440
+ const hero = buildHero({
10441
+ headline: params.content.headline,
10442
+ subhead: params.content.subhead,
10443
+ ctaLabel: params.content.ctaLabel,
10444
+ ctaAnchorId: formSection.sectionId,
10445
+ bgImageUrl: params.images?.heroUrl
10446
+ });
10447
+ const valueCards = buildValueCards({ cards: params.content.cards });
10448
+ const faq = buildFaq({ title: params.content.faqTitle, items: params.content.faqs, imageUrl: params.images?.faqImageUrl });
10449
+ const footer = buildFooter({
10450
+ businessLegalName: params.business.legalName,
10451
+ mailingAddress: params.business.mailingAddress,
10452
+ privacyUrl: params.business.privacyUrl,
10453
+ termsUrl: params.business.termsUrl,
10454
+ logoUrl: params.images?.logoUrl
10455
+ });
10456
+ const ordered = [topbar, hero, valueCards, formSection, faq, footer];
10457
+ const base = baseEnvelopeParts();
10458
+ let envelope = {
10459
+ // sequence must reflect THIS page's order, not the donors' source pages
10460
+ sections: ordered.map((s, i) => ({ ...s.section, sequence: i })),
10461
+ settings: base.settings,
10462
+ general: base.general,
10463
+ pageStyles: base.pageStyles,
10464
+ trackingCode: base.trackingCode,
10465
+ fontsForPreview: themedFonts(params.theme ?? {}),
10466
+ popups: [],
10467
+ popupsList: []
10468
+ };
10469
+ if (params.theme) {
10470
+ envelope = applyTheme(envelope, params.theme);
10471
+ const fontProblems = assertFontMatrixComplete(envelope, params.theme);
10472
+ if (fontProblems.length > 0) {
10473
+ throw new Error("Font matrix incomplete after theming:\n- " + fontProblems.join("\n- "));
10474
+ }
10475
+ }
10476
+ return {
10477
+ envelope,
10478
+ report: {
10479
+ sections: ["topbar", "hero", "valueCards", "formSection", "faq", "footer"],
10480
+ formAnchorId: formSection.sectionId,
10481
+ warnings
10482
+ }
10483
+ };
10484
+ }
10485
+
10486
+ // src/page-studio/website.ts
10487
+ function gate(params) {
10488
+ const problems = [];
10489
+ const warnings = [];
10490
+ const req = (v, name) => {
10491
+ if (typeof v !== "string" || v.trim().length === 0) problems.push(`missing required field: ${name}`);
10492
+ };
10493
+ req(params.business?.legalName, "business.legalName");
10494
+ req(params.business?.mailingAddress, "business.mailingAddress");
10495
+ req(params.business?.privacyUrl, "business.privacyUrl");
10496
+ req(params.business?.termsUrl, "business.termsUrl");
10497
+ if (!params.pages?.length) problems.push("pages must not be empty");
10498
+ if (!params.pages?.some((p) => p.role === "home")) problems.push("a 'home' page is required");
10499
+ const roles = /* @__PURE__ */ new Set();
10500
+ for (const p of params.pages ?? []) {
10501
+ if (roles.has(p.role)) problems.push(`duplicate role: ${p.role} (one page per role)`);
10502
+ roles.add(p.role);
10503
+ req(p.pageId, `pages[${p.slug}].pageId`);
10504
+ req(p.stepId, `pages[${p.slug}].stepId`);
10505
+ req(p.slug, `pages[${p.slug}].slug`);
10506
+ if (p.role !== "home" && !params.content?.[p.role]) problems.push(`content.${p.role} is required for the ${p.role} page`);
10507
+ }
10508
+ if (roles.has("booking")) {
10509
+ const b = params.content?.booking;
10510
+ if (!b?.calendarId || !b?.calendarName) problems.push("content.booking.calendarId + calendarName are required (use get_calendars)");
10511
+ }
10512
+ if (!params.images?.logoUrl) warnings.push("topbar/nav/footer use the donor template's placeholder logo \u2014 provide images.logoUrl before customer use");
10513
+ if (!params.images?.heroUrl) warnings.push("home hero uses the donor template's stock image \u2014 replace before customer use");
10514
+ if (roles.has("contact") && !params.content?.contact?.mapLocation) warnings.push("contact map keeps the donor's placeholder location \u2014 pass content.contact.mapLocation");
10515
+ if (problems.length > 0) throw new Error("Website compliance gate failed:\n- " + problems.join("\n- "));
10516
+ return warnings;
10517
+ }
10518
+ function composeWebsitePage(spec, params) {
10519
+ const warnings = gate(params);
10520
+ const navItems = params.pages.map((p) => ({ title: p.navTitle, slug: p.slug, stepId: p.stepId }));
10521
+ const bookingPage = params.pages.find((p) => p.role === "booking");
10522
+ const bookingHref = bookingPage ? `/${bookingPage.slug}` : `/${params.pages[0].slug}`;
10523
+ const chrome = {
10524
+ topbar: () => buildTopbar({ phoneHtml: params.business.phoneHtml, logoUrl: params.images?.logoUrl }),
10525
+ nav: () => buildNav({ items: navItems, logoUrl: params.images?.logoUrl }),
10526
+ footer: () => buildFooter({
10527
+ businessLegalName: params.business.legalName,
10528
+ mailingAddress: params.business.mailingAddress,
10529
+ privacyUrl: params.business.privacyUrl,
10530
+ termsUrl: params.business.termsUrl,
10531
+ logoUrl: params.images?.logoUrl
10532
+ })
10533
+ };
10534
+ const body = [];
10535
+ const names = ["topbar", "nav"];
10536
+ const c = params.content;
10537
+ switch (spec.role) {
10538
+ case "home": {
10539
+ body.push(
10540
+ buildHero({ headline: c.home.headline, subhead: c.home.subhead, ctaLabel: c.home.ctaLabel, ctaHref: bookingHref, bgImageUrl: params.images?.heroUrl }),
10541
+ buildValueCards({ cards: c.home.cards }),
10542
+ buildImageText(c.home.imageText),
10543
+ buildCtaBanner({ title: "READY WHEN YOU ARE", bodyHtml: `<p>Book a time that suits you \u2014 we handle the rest.</p>`, buttonLabel: c.home.ctaLabel, buttonHref: bookingHref }),
10544
+ buildFaq({ title: c.home.faqTitle, items: c.home.faqs })
10545
+ );
10546
+ names.push("hero", "valueCards", "imageText", "ctaBanner", "faq");
10547
+ break;
10548
+ }
10549
+ case "about": {
10550
+ const a = c.about;
10551
+ if (!a) throw new Error("content.about missing");
10552
+ body.push(buildImageText(a.imageText));
10553
+ names.push("imageText");
10554
+ if (a.cta) {
10555
+ body.push(buildCtaBanner({ ...a.cta, buttonHref: bookingHref }));
10556
+ names.push("ctaBanner");
10557
+ }
10558
+ break;
10559
+ }
10560
+ case "services": {
10561
+ const sv = c.services;
10562
+ if (!sv) throw new Error("content.services missing");
10563
+ body.push(buildValueCards({ cards: sv.cards }));
10564
+ names.push("valueCards");
10565
+ if (sv.cta) {
10566
+ body.push(buildCtaBanner({ ...sv.cta, buttonHref: bookingHref }));
10567
+ names.push("ctaBanner");
10568
+ }
10569
+ break;
10570
+ }
10571
+ case "booking": {
10572
+ const b = c.booking;
10573
+ if (!b) throw new Error("content.booking missing");
10574
+ body.push(buildBooking(b));
10575
+ names.push("booking");
10576
+ break;
10577
+ }
10578
+ case "contact": {
10579
+ body.push(buildMapSection({ title: c.contact?.title, mapLocation: c.contact?.mapLocation }));
10580
+ names.push("map");
10581
+ break;
10582
+ }
10583
+ }
10584
+ names.push("footer");
10585
+ const ordered = [chrome.topbar(), chrome.nav(), ...body, chrome.footer()];
10586
+ const base = baseEnvelopeParts();
10587
+ let envelope = {
10588
+ sections: ordered.map((s, i) => ({ ...s.section, sequence: i })),
10589
+ settings: base.settings,
10590
+ general: base.general,
10591
+ pageStyles: base.pageStyles,
10592
+ trackingCode: base.trackingCode,
10593
+ fontsForPreview: themedFonts(params.theme ?? {}),
10594
+ popups: [],
10595
+ popupsList: []
10596
+ };
10597
+ if (params.theme) {
10598
+ envelope = applyTheme(envelope, params.theme);
10599
+ const fontProblems = assertFontMatrixComplete(envelope, params.theme);
10600
+ if (fontProblems.length > 0) throw new Error("Font matrix incomplete after theming:\n- " + fontProblems.join("\n- "));
10601
+ }
10602
+ return { spec, envelope, sections: names, warnings };
10603
+ }
10604
+
10605
+ // src/tools/page-studio.ts
10606
+ var valueCardSchema = import_zod35.z.object({
10607
+ title: import_zod35.z.string().describe("Card title (short, uppercase reads best)."),
10608
+ bodyHtml: import_zod35.z.string().describe("Card body as HTML (<p>\u2026</p>). May use {{location.*}} merge fields."),
10609
+ iconName: import_zod35.z.string().optional().describe("Font Awesome icon name (e.g. 'calendar-week', 'phone-square-alt', 'map-marker-alt').")
10610
+ });
10611
+ function registerPageStudioTools(server2, builderClient) {
10612
+ const client = builderClient;
10613
+ if (!client) return;
10614
+ async function funnelRequest(method, path11) {
10615
+ const headers = await client.buildHeaders();
10616
+ headers.Origin = "https://app.gohighlevel.com";
10617
+ headers.Referer = "https://app.gohighlevel.com/";
10618
+ const response = await fetch(`https://backend.leadconnectorhq.com/funnels${path11}`, { method, headers });
10619
+ if (!response.ok) throw new Error(`Funnel API Error ${response.status}: ${method} ${path11}
10620
+ ${await response.text()}`);
10621
+ const text = await response.text();
10622
+ return text ? JSON.parse(text) : {};
10623
+ }
10624
+ async function autosaveRequest(pageId, body) {
10625
+ const headers = await client.buildHeaders();
10626
+ headers.Origin = "https://page-builder.leadconnectorhq.com";
10627
+ headers.Referer = "https://page-builder.leadconnectorhq.com/";
10628
+ const response = await fetch(`https://backend.leadconnectorhq.com/funnels/builder/autosave/${pageId}`, {
10629
+ method: "POST",
10630
+ headers,
10631
+ body: JSON.stringify(body)
10632
+ });
10633
+ if (!response.ok) throw new Error(`Funnel API Error ${response.status}: POST /builder/autosave/${pageId}
10634
+ ${await response.text()}`);
10635
+ const text = await response.text();
10636
+ return text ? JSON.parse(text) : {};
10637
+ }
10638
+ function computeIntegrations(pageData) {
10639
+ const counts = {};
10640
+ const sections = Array.isArray(pageData.sections) ? pageData.sections : [];
10641
+ for (const sec of sections) {
10642
+ for (const el of sec.elements ?? []) {
10643
+ if (el.type !== "element" || typeof el.meta !== "string") continue;
10644
+ const key = el.meta.replace(/-([a-z])/g, (_m, c) => c.toUpperCase());
10645
+ counts[key] = (counts[key] ?? 0) + 1;
10646
+ }
10647
+ }
10648
+ return { videoBackground: false, blogMeta: { selectedBlogCategories: [], categoryNavigationList: [] }, ...counts, popup: false };
10649
+ }
10650
+ server2.tool(
10651
+ "compose_page",
10652
+ "Compose a COMPLETE designer-grade page from the built-in professional section library (cloned from a real GHL template: topbar, image hero, value cards, inline form with A2P disclosures, FAQ, compliant footer) and save it as a DRAFT onto an existing funnel/website page. Brand-themeable (colors + Google fonts). Copy may use {{location.*}} merge fields \u2014 GHL localizes them per account. Modes: dry_run returns the build report without writing; create writes only onto a page with no saved content. There is NO replace/overwrite mode \u2014 GHL only honors the FIRST save onto a page (later saves never become the visible version), so to redo a page delete its step and compose onto a fresh one. Existing pages can never be damaged: the tool refuses any page that has content, any page it cannot read, and any page belonging to a different funnel. The bound form must itself contain the SMS consent checkbox \u2014 this page provides the surrounding A2P disclosures (legal name, address, privacy/terms at point of capture, message description).",
10653
+ {
10654
+ pageId: import_zod35.z.string().describe("The page to write (from create_funnel_page or get_funnel_pages)."),
10655
+ funnelId: import_zod35.z.string().describe("The funnel/website that owns the page."),
10656
+ mode: import_zod35.z.enum(["dry_run", "create"]).describe("dry_run = build + report only. create = write only onto a page with no saved content. (There is no replace mode: GHL only honors the FIRST save onto a page \u2014 repeat saves are accepted but never become the visible version. To redo a page: delete the step, create a fresh one, compose again.)"),
10657
+ business: import_zod35.z.object({
10658
+ legalName: import_zod35.z.string().describe("Legal entity name (A2P: must be visible on the page)."),
10659
+ mailingAddress: import_zod35.z.string().describe("Full physical mailing address (A2P requirement)."),
10660
+ privacyUrl: import_zod35.z.string().describe("Live Privacy Policy URL (absolute)."),
10661
+ termsUrl: import_zod35.z.string().describe("Live Terms of Service URL (absolute)."),
10662
+ phoneHtml: import_zod35.z.string().optional().describe("Topbar phone HTML. Defaults to {{location.phone}}.")
10663
+ }),
10664
+ content: import_zod35.z.object({
10665
+ headline: import_zod35.z.string().describe("H1 + form section title."),
10666
+ subhead: import_zod35.z.string().describe("One-sentence supporting promise under the H1."),
10667
+ ctaLabel: import_zod35.z.string().describe("Hero button label; the button scrolls to the form."),
10668
+ cards: import_zod35.z.array(valueCardSchema).length(3).describe("Exactly 3 value cards."),
10669
+ faqTitle: import_zod35.z.string().optional().describe("FAQ section title. Default: donor's 'FREQUENTLY ASKED QUESTIONS'."),
10670
+ faqs: import_zod35.z.array(import_zod35.z.object({ q: import_zod35.z.string(), a: import_zod35.z.string() })).min(2).describe("FAQ items (4-8 recommended)."),
10671
+ disclosureHtml: import_zod35.z.string().optional().describe("A2P message description above the form. A compliant default is generated.")
10672
+ }),
10673
+ form: import_zod35.z.object({
10674
+ formId: import_zod35.z.string().describe("The GHL form to embed (must contain the SMS consent checkbox)."),
10675
+ formName: import_zod35.z.string().describe("The form's display name.")
10676
+ }),
10677
+ images: import_zod35.z.object({
10678
+ logoUrl: import_zod35.z.string().optional().describe("Brand logo URL (topbar + footer)."),
10679
+ heroUrl: import_zod35.z.string().optional().describe("Hero background image URL (client-owned)."),
10680
+ faqImageUrl: import_zod35.z.string().optional().describe("FAQ side image URL.")
10681
+ }).optional(),
10682
+ theme: import_zod35.z.object({
10683
+ primary: import_zod35.z.string().optional().describe("Brand primary hex (#rrggbb)."),
10684
+ primarySoft: import_zod35.z.string().optional().describe("Soft tint of the primary."),
10685
+ surface: import_zod35.z.string().optional().describe("Light surface background hex."),
10686
+ textDark: import_zod35.z.string().optional().describe("Dark text hex."),
10687
+ headingFont: import_zod35.z.string().optional().describe("Google Fonts name for headings."),
10688
+ bodyFont: import_zod35.z.string().optional().describe("Google Fonts name for body text.")
10689
+ }).optional().describe("Brand theme. Omit to keep the donor template's look.")
10690
+ },
10691
+ async (args) => {
10692
+ try {
10693
+ const params = {
10694
+ business: args.business,
10695
+ content: { ...args.content, cards: args.content.cards },
10696
+ form: args.form,
10697
+ images: args.images,
10698
+ theme: args.theme
10699
+ };
10700
+ const { envelope, report } = composeOptinPage(params);
10701
+ if (args.mode === "dry_run") {
10702
+ return jsonResponse({ mode: "dry_run", wrote: false, report, sectionCount: envelope.sections.length, envelopeBytes: JSON.stringify(envelope).length });
10703
+ }
10704
+ const result = await savePageGuarded({ pageId: args.pageId, funnelId: args.funnelId, envelope });
10705
+ return jsonResponse({ mode: args.mode, wrote: true, pageId: args.pageId, report, ...result, next: NEXT_NOTE });
10706
+ } catch (error) {
10707
+ return errorResponse(error);
10708
+ }
10709
+ }
10710
+ );
10711
+ const NEXT_NOTE = "The save is a DRAFT. Read get_page_full for the regenerated previewSnapshot (allow a few seconds), review desktop AND mobile, then publish in the GHL UI when it looks right.";
10712
+ async function preflightPage(input) {
10713
+ const { pageId, funnelId } = input;
10714
+ let meta = null;
10715
+ for (let attempt = 1; attempt <= 10; attempt++) {
10716
+ try {
10717
+ meta = await funnelRequest("GET", `/page/${pageId}?locationId=${client.locationId}`);
10718
+ break;
10719
+ } catch (e) {
10720
+ const freshRace = /does not exist or is deleted/i.test(String(e));
10721
+ if (attempt === 10) {
10722
+ throw new Error(
10723
+ `Refusing to write: page ${pageId} could not be read after ${attempt} attempts ` + (freshRace ? "(still propagating after creation \u2014 wait ~30s and retry)." : `(last error: ${String(e).slice(0, 200)}). Writing without reading the page risks overwriting existing content.`)
10724
+ );
10725
+ }
10726
+ await new Promise((r) => setTimeout(r, 700 * attempt));
10727
+ }
10728
+ }
10729
+ const m = meta;
10730
+ const metaFunnelId = typeof m.funnelId === "string" ? m.funnelId : null;
10731
+ if (metaFunnelId && metaFunnelId !== funnelId) {
10732
+ throw new Error(`Page ${pageId} belongs to funnel ${metaFunnelId}, not ${funnelId}. Refusing to write to a page outside the target funnel/website.`);
10733
+ }
10734
+ const livePageVersion = typeof m.pageVersion === "number" ? m.pageVersion : typeof m.version === "number" ? m.version : 1;
10735
+ const priorDataUrl = typeof m.pageDataDownloadUrl === "string" ? m.pageDataDownloadUrl : null;
10736
+ const refuseCreate = (version) => {
10737
+ throw new Error(
10738
+ `Page ${pageId} already has saved content (pageVersion ${version}). GHL only honors the FIRST save onto a page, so this page cannot be re-composed. Delete its step (delete_funnel_page), create a fresh one (create_funnel_page), and compose again.`
10739
+ );
10740
+ };
10741
+ if (priorDataUrl) refuseCreate(livePageVersion);
10742
+ for (let confirm = 0; confirm < 3; confirm++) {
10743
+ await new Promise((r) => setTimeout(r, 1500));
10744
+ let again = null;
10745
+ try {
10746
+ again = await funnelRequest("GET", `/page/${pageId}?locationId=${client.locationId}`);
10747
+ } catch {
10748
+ again = null;
10749
+ }
10750
+ if (again && typeof again.pageDataDownloadUrl === "string" && again.pageDataDownloadUrl.length > 0) {
10751
+ refuseCreate(typeof again.pageVersion === "number" ? again.pageVersion : livePageVersion);
10752
+ }
10753
+ }
10754
+ return { pageId, livePageVersion, priorDataUrl };
10755
+ }
10756
+ async function performSave(input) {
10757
+ const { funnelId, envelope, pre } = input;
10758
+ const savePageVersion = pre.livePageVersion;
10759
+ const sections = envelope.sections.map((s) => ({ ...s, pageId: pre.pageId, funnelId, locationId: client.locationId }));
10760
+ const pageData = {
10761
+ ...envelope,
10762
+ sections,
10763
+ pageVersion: savePageVersion,
10764
+ pageType: "draft",
10765
+ manualSave: true,
10766
+ integrations: computeIntegrations({ sections })
10767
+ };
10768
+ const saved = await autosaveRequest(pre.pageId, { funnelId, pageVersion: savePageVersion, pageData });
10769
+ const savedDataUrl = typeof saved.pageDataUrl === "string" ? saved.pageDataUrl : null;
10770
+ let verified = false;
10771
+ for (let attempt = 1; attempt <= 8 && !verified; attempt++) {
10772
+ await new Promise((r) => setTimeout(r, 4e3));
10773
+ try {
10774
+ const now = await funnelRequest("GET", `/page/${pre.pageId}?locationId=${client.locationId}`);
10775
+ const nowUrl = typeof now.pageDataUrl === "string" ? now.pageDataUrl : "";
10776
+ if (savedDataUrl !== null && nowUrl === savedDataUrl) verified = true;
10777
+ } catch {
10778
+ }
10779
+ }
10780
+ return {
10781
+ saved,
10782
+ verified,
10783
+ ...verified ? {} : { verifyNote: "The save was accepted but the page has not yet reported the new content (eventual consistency). Re-check get_page_full in a minute before publishing; if it never advances, the save did not take." }
10784
+ };
10785
+ }
10786
+ async function savePageGuarded(input) {
10787
+ const pre = await preflightPage({ pageId: input.pageId, funnelId: input.funnelId });
10788
+ return performSave({ funnelId: input.funnelId, envelope: input.envelope, pre });
10789
+ }
10790
+ const websitePageSpecSchema = import_zod35.z.object({
10791
+ pageId: import_zod35.z.string().describe("The page id (from create_funnel_page / get_funnel_pages)."),
10792
+ stepId: import_zod35.z.string().describe("The step id that owns the page (nav items wire to this)."),
10793
+ slug: import_zod35.z.string().describe("Step slug without the leading slash (e.g. 'home', 'booking')."),
10794
+ role: import_zod35.z.enum(["home", "about", "services", "booking", "contact"]).describe("Page archetype."),
10795
+ navTitle: import_zod35.z.string().describe("Menu label for this page.")
10796
+ });
10797
+ const imageTextSchema = import_zod35.z.object({
10798
+ title: import_zod35.z.string(),
10799
+ features: import_zod35.z.array(import_zod35.z.object({ title: import_zod35.z.string(), bodyHtml: import_zod35.z.string() })).length(3).describe("Exactly 3 feature blocks (title + HTML body)."),
10800
+ imageUrl: import_zod35.z.string().optional()
10801
+ });
10802
+ server2.tool(
10803
+ "compose_website",
10804
+ "Compose a COMPLETE multi-page WEBSITE (created via create_funnel type:'website') from the professional section library: every page gets topbar + nav (menu items wired to the real steps) + role-specific sections + A2P-compliant footer, brand-themed. Roles: home (hero, value cards, feature block, CTA banner, FAQ), about, services, booking (embeds a real calendar \u2014 verify the id with get_calendars first), contact (map + merge-field contact lines). Nav/header/footer are per-page copies (visually identical to shared sections). Create the website + one step per page first (create_funnel, create_funnel_page), then call this with each page's ids. Modes: dry_run builds + reports without writing; create writes only onto pages with no saved content (no overwrite mode exists \u2014 GHL honors only the FIRST save onto a page; redo = delete the step, create a fresh one). All pages are preflighted (readable, empty, owned by this funnel) BEFORE the first save; saves are DRAFTS and run sequentially with halt-and-report.",
10805
+ {
10806
+ funnelId: import_zod35.z.string().describe("The website's funnel id (create_funnel type:'website')."),
10807
+ mode: import_zod35.z.enum(["dry_run", "create"]).describe("dry_run = build + report only. create = write only onto pages with no saved content. (No replace mode: GHL only honors the FIRST save onto a page. To redo a page: delete its step, create a fresh one, re-run for that page.)"),
10808
+ pages: import_zod35.z.array(websitePageSpecSchema).min(1).describe("The pages to compose. Exactly one 'home' required; one page per role."),
10809
+ business: import_zod35.z.object({
10810
+ legalName: import_zod35.z.string(),
10811
+ mailingAddress: import_zod35.z.string(),
10812
+ privacyUrl: import_zod35.z.string(),
10813
+ termsUrl: import_zod35.z.string(),
10814
+ phoneHtml: import_zod35.z.string().optional()
10815
+ }).describe("Footer legal block on every page (A2P)."),
10816
+ images: import_zod35.z.object({ logoUrl: import_zod35.z.string().optional(), heroUrl: import_zod35.z.string().optional() }).optional(),
10817
+ theme: import_zod35.z.object({
10818
+ primary: import_zod35.z.string().optional(),
10819
+ primarySoft: import_zod35.z.string().optional(),
10820
+ surface: import_zod35.z.string().optional(),
10821
+ textDark: import_zod35.z.string().optional(),
10822
+ headingFont: import_zod35.z.string().optional(),
10823
+ bodyFont: import_zod35.z.string().optional()
10824
+ }).optional(),
10825
+ content: import_zod35.z.object({
10826
+ home: import_zod35.z.object({
10827
+ headline: import_zod35.z.string(),
10828
+ subhead: import_zod35.z.string(),
10829
+ ctaLabel: import_zod35.z.string(),
10830
+ cards: import_zod35.z.array(valueCardSchema).length(3),
10831
+ imageText: imageTextSchema,
10832
+ faqTitle: import_zod35.z.string().optional(),
10833
+ faqs: import_zod35.z.array(import_zod35.z.object({ q: import_zod35.z.string(), a: import_zod35.z.string() })).min(2)
10834
+ }),
10835
+ about: import_zod35.z.object({
10836
+ imageText: imageTextSchema,
10837
+ cta: import_zod35.z.object({ title: import_zod35.z.string(), bodyHtml: import_zod35.z.string(), buttonLabel: import_zod35.z.string() }).optional()
10838
+ }).optional(),
10839
+ services: import_zod35.z.object({
10840
+ cards: import_zod35.z.array(valueCardSchema).length(3),
10841
+ cta: import_zod35.z.object({ title: import_zod35.z.string(), bodyHtml: import_zod35.z.string(), buttonLabel: import_zod35.z.string() }).optional()
10842
+ }).optional(),
10843
+ booking: import_zod35.z.object({
10844
+ calendarId: import_zod35.z.string().describe("Real calendar id \u2014 verify with get_calendars; a bad id shows an empty booking widget."),
10845
+ calendarName: import_zod35.z.string(),
10846
+ title: import_zod35.z.string().optional(),
10847
+ bodyHtml: import_zod35.z.string().optional()
10848
+ }).optional(),
10849
+ contact: import_zod35.z.object({
10850
+ title: import_zod35.z.string().optional(),
10851
+ mapLocation: import_zod35.z.object({ name: import_zod35.z.string(), lat: import_zod35.z.number(), lng: import_zod35.z.number(), placeId: import_zod35.z.string().optional() }).optional()
10852
+ }).optional()
10853
+ })
10854
+ },
10855
+ async (args) => {
10856
+ try {
10857
+ const params = {
10858
+ business: args.business,
10859
+ images: args.images,
10860
+ theme: args.theme,
10861
+ pages: args.pages,
10862
+ content: args.content
10863
+ };
10864
+ const results = args.pages.map((spec) => composeWebsitePage(spec, params));
10865
+ if (args.mode === "dry_run") {
10866
+ return jsonResponse({
10867
+ mode: "dry_run",
10868
+ wrote: false,
10869
+ pages: results.map((r) => ({ slug: r.spec.slug, role: r.spec.role, sections: r.sections, envelopeBytes: JSON.stringify(r.envelope).length })),
10870
+ warnings: results[0]?.warnings ?? []
10871
+ });
10872
+ }
10873
+ const preflights = [];
10874
+ for (const r of results) {
10875
+ try {
10876
+ preflights.push({ r, pre: await preflightPage({ pageId: r.spec.pageId, funnelId: args.funnelId }) });
10877
+ } catch (e) {
10878
+ return jsonResponse({
10879
+ mode: args.mode,
10880
+ wrote: false,
10881
+ failedPreflight: { slug: r.spec.slug, pageId: r.spec.pageId, error: String(e) },
10882
+ note: "Nothing was written \u2014 the preflight failed before the first save. Fix the reported page and re-run."
10883
+ });
10884
+ }
10885
+ }
10886
+ const written = [];
10887
+ for (const { r, pre } of preflights) {
10888
+ try {
10889
+ const saved = await performSave({ funnelId: args.funnelId, envelope: r.envelope, pre });
10890
+ written.push({ slug: r.spec.slug, role: r.spec.role, pageId: r.spec.pageId, wrote: true, ...saved });
10891
+ } catch (e) {
10892
+ return jsonResponse({
10893
+ mode: args.mode,
10894
+ wrote: written.length > 0,
10895
+ pages: written,
10896
+ failedAt: { slug: r.spec.slug, pageId: r.spec.pageId, error: String(e) },
10897
+ note: "Run halted at the first failing save. Already-written pages are drafts and stay as saved. Fix the failure, delete + recreate any unfinished steps, and re-run for the remaining pages."
10898
+ });
10899
+ }
10900
+ }
10901
+ return jsonResponse({ mode: args.mode, wrote: true, pages: written, warnings: results[0]?.warnings ?? [], next: NEXT_NOTE });
10902
+ } catch (error) {
10903
+ return errorResponse(error);
10904
+ }
10905
+ }
10906
+ );
10907
+ }
10908
+
10909
+ // src/tools/form-builder.ts
10910
+ var import_zod36 = require("zod");
9836
10911
  function pickFormName(builderForm) {
9837
10912
  if (builderForm && typeof builderForm === "object" && "form" in builderForm) {
9838
10913
  const name = builderForm.form?.name;
@@ -9889,7 +10964,7 @@ function registerFormBuilderTools(server2, builderClient, publicClient) {
9889
10964
  "get_form_full",
9890
10965
  "Get a form with full builder data: all fields (labels, types, IDs, validation), conditional logic, auto-responder config, email notification settings, styling, and version history. This is the internal API \u2014 it returns everything the form builder UI shows.",
9891
10966
  {
9892
- formId: import_zod35.z.string().describe("The form ID to retrieve.")
10967
+ formId: import_zod36.z.string().describe("The form ID to retrieve.")
9893
10968
  },
9894
10969
  async ({ formId }) => {
9895
10970
  try {
@@ -9906,9 +10981,9 @@ function registerFormBuilderTools(server2, builderClient, publicClient) {
9906
10981
  "update_form",
9907
10982
  "Update a form's structure \u2014 fields, labels, conditional logic, auto-responder, email notifications, styling. Use get_form_full first to read the current form, modify the formData object, then pass it here. If name is omitted, the current name is preserved (one extra GET).",
9908
10983
  {
9909
- formId: import_zod35.z.string().describe("The form ID to update."),
9910
- formData: import_zod35.z.record(import_zod35.z.unknown()).describe("The updated formData object containing form fields, settings, autoResponder config, etc."),
9911
- name: import_zod35.z.string().optional().describe("Updated form name. If omitted, the current name is preserved.")
10984
+ formId: import_zod36.z.string().describe("The form ID to update."),
10985
+ formData: import_zod36.z.record(import_zod36.z.unknown()).describe("The updated formData object containing form fields, settings, autoResponder config, etc."),
10986
+ name: import_zod36.z.string().optional().describe("Updated form name. If omitted, the current name is preserved.")
9912
10987
  },
9913
10988
  async ({ formId, formData, name }) => {
9914
10989
  try {
@@ -9955,7 +11030,7 @@ function registerFormBuilderTools(server2, builderClient, publicClient) {
9955
11030
  "create_form",
9956
11031
  "Create a new form. Starts with a basic structure \u2014 use update_form to add fields and configure settings.",
9957
11032
  {
9958
- name: import_zod35.z.string().describe("Name for the new form.")
11033
+ name: import_zod36.z.string().describe("Name for the new form.")
9959
11034
  },
9960
11035
  async ({ name }) => {
9961
11036
  try {
@@ -9981,8 +11056,8 @@ function registerFormBuilderTools(server2, builderClient, publicClient) {
9981
11056
  "delete_form",
9982
11057
  "Permanently delete a form. IRREVERSIBLE.",
9983
11058
  {
9984
- formId: import_zod35.z.string().describe("The form ID to delete."),
9985
- confirm: import_zod35.z.literal("DELETE").describe("Must pass 'DELETE' to confirm this destructive action.")
11059
+ formId: import_zod36.z.string().describe("The form ID to delete."),
11060
+ confirm: import_zod36.z.literal("DELETE").describe("Must pass 'DELETE' to confirm this destructive action.")
9986
11061
  },
9987
11062
  async ({ formId }) => {
9988
11063
  try {
@@ -9999,9 +11074,9 @@ function registerFormBuilderTools(server2, builderClient, publicClient) {
9999
11074
  "get_form_submissions_full",
10000
11075
  "Get form submissions with full field data, contact info, and submission timestamps via the internal API. Offset-based pagination via skip/limit.",
10001
11076
  {
10002
- formId: import_zod35.z.string().optional().describe("Filter by form ID. If omitted, returns all submissions."),
10003
- limit: import_zod35.z.number().optional().describe("Max submissions to return. Defaults to 20."),
10004
- skip: import_zod35.z.number().optional().describe("Number to skip for pagination.")
11077
+ formId: import_zod36.z.string().optional().describe("Filter by form ID. If omitted, returns all submissions."),
11078
+ limit: import_zod36.z.number().optional().describe("Max submissions to return. Defaults to 20."),
11079
+ skip: import_zod36.z.number().optional().describe("Number to skip for pagination.")
10005
11080
  },
10006
11081
  async ({ formId, limit, skip }) => {
10007
11082
  try {
@@ -10020,7 +11095,7 @@ function registerFormBuilderTools(server2, builderClient, publicClient) {
10020
11095
  }
10021
11096
 
10022
11097
  // src/tools/funnel-qa.ts
10023
- var import_zod36 = require("zod");
11098
+ var import_zod37 = require("zod");
10024
11099
  var asObj = (v) => v && typeof v === "object" ? v : {};
10025
11100
  var asArr = (v) => Array.isArray(v) ? v : [];
10026
11101
  var str = (v) => typeof v === "string" ? v : void 0;
@@ -10144,34 +11219,34 @@ async function submit(url, body) {
10144
11219
  const text = (await res.text().catch(() => "")).slice(0, 300);
10145
11220
  return { httpStatus: res.status, blockedByCaptcha: res.status === 403 && /captcha|turnstile/i.test(text), text };
10146
11221
  }
10147
- var customFieldInput = import_zod36.z.object({
10148
- fieldId: import_zod36.z.string().describe("The VERIFIED GHL custom-field id the form sends (from apply_build_plan's wiring bundle)."),
10149
- value: import_zod36.z.string().describe("The value the form sends for this field \u2014 asserted to PERSIST on the contact."),
10150
- label: import_zod36.z.string().optional().describe("Human label (informational).")
11222
+ var customFieldInput = import_zod37.z.object({
11223
+ fieldId: import_zod37.z.string().describe("The VERIFIED GHL custom-field id the form sends (from apply_build_plan's wiring bundle)."),
11224
+ value: import_zod37.z.string().describe("The value the form sends for this field \u2014 asserted to PERSIST on the contact."),
11225
+ label: import_zod37.z.string().optional().describe("Human label (informational).")
10151
11226
  });
10152
11227
  function registerFunnelQaTools(server2, client, builderClient) {
10153
11228
  server2.tool(
10154
11229
  "verify_funnel",
10155
11230
  "Prove a live public funnel actually captures a lead AND the automation acts on it \u2014 the runtime companion to audit_workflows. Submits a sentinel lead to funnelUrl, then reads GHL back to verify what REALLY happened (the UI/thank-you page is never proof): (1) backend contact truth \u2014 the contact is actually created (search_contacts), with submit\u2192appear latency; (2) field-value fidelity \u2014 each expectCustom value actually PERSISTED on the contact (a wrong field id makes upsert succeed while silently dropping the value); (3) the triggerTag landed (else the workflow can't fire); (4) SMS/A2P pre-check \u2014 flags if the account has no SMS-capable number so any SMS step would silently fail; (5) workflow status \u2014 flags a DRAFT workflow (never fires on real leads); (6) outreach fired \u2014 an OUTBOUND message was actually logged for the contact (proves enrollment + send, not just a green log), with latency; (7) consent recorded when messaging fires (TCPA/CAN-SPAM); (8) duplicate-contact retest \u2014 a second identical submit dedups to ONE contact, not a duplicate/false-failure; (9) opportunity/routing (expectOpportunity/expectAssigned/expectSource); (10) multi-surface (extraUrls) + concurrent double-submit race. Booking can't be faked server-side, so a real burner appointment is surfaced as a manual step. WARNING: this creates a real (clearly-marked 'blueprint-qa') contact and MAY fire real automation + internal notifications; it deletes the sentinel afterward by default (cleanup). Run it on the REAL production URL.",
10156
11231
  {
10157
- funnelUrl: import_zod36.z.string().describe("The live URL the test submission POSTs to (your external lead-bridge Worker URL, or any endpoint that creates the GHL contact). POSTed as JSON."),
10158
- sentinelEmail: import_zod36.z.string().optional().describe("Override the minted sentinel email. Default: a unique blueprint-qa.<id>@example.com (won't deliver; used only to find the contact)."),
10159
- testPhone: import_zod36.z.string().optional().describe("Include a phone on the submission (enables SMS-path checks). Must be a test-safe number you control \u2014 real SMS may send + bill."),
10160
- submitBody: import_zod36.z.record(import_zod36.z.unknown()).optional().describe("Full JSON body to POST (advanced; for non-bridge endpoints). The sentinel email is injected if absent. Default body is the lead-bridge contract {first_name,last_name,email,phone,custom,_hp}."),
10161
- expectCustom: import_zod36.z.array(customFieldInput).optional().describe("Custom fields the form sends \u2014 each is asserted to PERSIST with the sent value (field-value fidelity, Carlos #3)."),
10162
- expectStandard: import_zod36.z.array(import_zod36.z.string()).optional().describe("Standard contact keys to assert saved (e.g. ['phone','first_name']). email is always asserted."),
10163
- triggerTag: import_zod36.z.string().optional().describe("The tag the form/bridge should add (the speed-to-lead trigger). Asserted to land on the contact."),
10164
- workflowId: import_zod36.z.string().optional().describe("The speed-to-lead workflow to inspect \u2014 flags DRAFT status and cross-checks SMS capability."),
10165
- consentFieldId: import_zod36.z.string().optional().describe("Custom field id that records consent \u2014 asserted populated when messaging fires (legal)."),
10166
- expectOutreach: import_zod36.z.boolean().optional().describe("Poll the message log for an OUTBOUND message to the contact (proves the automation fired + sent). Defaults true when triggerTag or workflowId is given."),
10167
- outreachWaitSec: import_zod36.z.number().optional().describe("How long to poll for the outbound message (default 90s)."),
10168
- expectOpportunity: import_zod36.z.object({ pipelineId: import_zod36.z.string().optional(), stageId: import_zod36.z.string().optional() }).optional().describe("Assert an opportunity was created for the contact (optionally in this pipeline/stage)."),
10169
- expectAssigned: import_zod36.z.boolean().optional().describe("Assert the contact was assigned to a user (someone follows up)."),
10170
- expectSource: import_zod36.z.boolean().optional().describe("Assert a lead source/attribution was captured (reporting works)."),
10171
- extraUrls: import_zod36.z.array(import_zod36.z.string()).optional().describe("Additional capture surfaces to test the same way (each gets its own sentinel) \u2014 popup/inline/exit-intent forms."),
10172
- testConcurrentDuplicate: import_zod36.z.boolean().optional().describe("Fire two simultaneous submits with a fresh email \u2192 assert exactly ONE contact (concurrent dedup race)."),
10173
- cleanup: import_zod36.z.boolean().optional().describe("Delete the sentinel contact(s) after verifying. Default true."),
10174
- locationId: import_zod36.z.string().optional().describe("Target sub-account. Must match the active location.")
11232
+ funnelUrl: import_zod37.z.string().describe("The live URL the test submission POSTs to (your external lead-bridge Worker URL, or any endpoint that creates the GHL contact). POSTed as JSON."),
11233
+ sentinelEmail: import_zod37.z.string().optional().describe("Override the minted sentinel email. Default: a unique blueprint-qa.<id>@example.com (won't deliver; used only to find the contact)."),
11234
+ testPhone: import_zod37.z.string().optional().describe("Include a phone on the submission (enables SMS-path checks). Must be a test-safe number you control \u2014 real SMS may send + bill."),
11235
+ submitBody: import_zod37.z.record(import_zod37.z.unknown()).optional().describe("Full JSON body to POST (advanced; for non-bridge endpoints). The sentinel email is injected if absent. Default body is the lead-bridge contract {first_name,last_name,email,phone,custom,_hp}."),
11236
+ expectCustom: import_zod37.z.array(customFieldInput).optional().describe("Custom fields the form sends \u2014 each is asserted to PERSIST with the sent value (field-value fidelity, Carlos #3)."),
11237
+ expectStandard: import_zod37.z.array(import_zod37.z.string()).optional().describe("Standard contact keys to assert saved (e.g. ['phone','first_name']). email is always asserted."),
11238
+ triggerTag: import_zod37.z.string().optional().describe("The tag the form/bridge should add (the speed-to-lead trigger). Asserted to land on the contact."),
11239
+ workflowId: import_zod37.z.string().optional().describe("The speed-to-lead workflow to inspect \u2014 flags DRAFT status and cross-checks SMS capability."),
11240
+ consentFieldId: import_zod37.z.string().optional().describe("Custom field id that records consent \u2014 asserted populated when messaging fires (legal)."),
11241
+ expectOutreach: import_zod37.z.boolean().optional().describe("Poll the message log for an OUTBOUND message to the contact (proves the automation fired + sent). Defaults true when triggerTag or workflowId is given."),
11242
+ outreachWaitSec: import_zod37.z.number().optional().describe("How long to poll for the outbound message (default 90s)."),
11243
+ expectOpportunity: import_zod37.z.object({ pipelineId: import_zod37.z.string().optional(), stageId: import_zod37.z.string().optional() }).optional().describe("Assert an opportunity was created for the contact (optionally in this pipeline/stage)."),
11244
+ expectAssigned: import_zod37.z.boolean().optional().describe("Assert the contact was assigned to a user (someone follows up)."),
11245
+ expectSource: import_zod37.z.boolean().optional().describe("Assert a lead source/attribution was captured (reporting works)."),
11246
+ extraUrls: import_zod37.z.array(import_zod37.z.string()).optional().describe("Additional capture surfaces to test the same way (each gets its own sentinel) \u2014 popup/inline/exit-intent forms."),
11247
+ testConcurrentDuplicate: import_zod37.z.boolean().optional().describe("Fire two simultaneous submits with a fresh email \u2192 assert exactly ONE contact (concurrent dedup race)."),
11248
+ cleanup: import_zod37.z.boolean().optional().describe("Delete the sentinel contact(s) after verifying. Default true."),
11249
+ locationId: import_zod37.z.string().optional().describe("Target sub-account. Must match the active location.")
10175
11250
  },
10176
11251
  async (args) => {
10177
11252
  try {
@@ -10383,21 +11458,21 @@ function registerFunnelQaTools(server2, client, builderClient) {
10383
11458
  checks.push({ id: "cleanup", label: "Sentinel cleanup", status: cleanedUp ? "pass" : "warn", detail: cleanedUp ? `Deleted ${deleted} sentinel contact(s).` : `Deleted ${deleted}/${uniq.length} sentinel contact(s) \u2014 remove any leftover "blueprint-qa" contacts manually.` });
10384
11459
  }
10385
11460
  }
10386
- return finish(checks, { contactId, sentinelEmail: searchEmail, cleanedUp });
11461
+ return finish2(checks, { contactId, sentinelEmail: searchEmail, cleanedUp });
10387
11462
  } catch (error) {
10388
11463
  return errorResponse(error);
10389
11464
  }
10390
11465
  }
10391
11466
  );
10392
11467
  }
10393
- function finish(checks, extra) {
11468
+ function finish2(checks, extra) {
10394
11469
  const { ok, verdict, summary } = rollupVerdict(checks);
10395
11470
  const note = "WARNING: verify_funnel created a real (clearly-marked 'blueprint-qa') contact and may have fired real automation + internal notifications. Run on the real production URL; the form/thank-you page is never proof \u2014 only the backend is.";
10396
11471
  return jsonResponse({ ok, verdict, summary, checks, note, ...extra });
10397
11472
  }
10398
11473
 
10399
11474
  // src/tools/pipeline-builder.ts
10400
- var import_zod37 = require("zod");
11475
+ var import_zod38 = require("zod");
10401
11476
  function registerPipelineBuilderTools(server2, builderClient) {
10402
11477
  const client = builderClient;
10403
11478
  if (!client) return;
@@ -10442,7 +11517,7 @@ ${text2}`);
10442
11517
  "get_pipeline_full",
10443
11518
  "Get a single pipeline with complete stage configuration: IDs, names, positions, display settings.",
10444
11519
  {
10445
- pipelineId: import_zod37.z.string().describe("The pipeline ID to retrieve.")
11520
+ pipelineId: import_zod38.z.string().describe("The pipeline ID to retrieve.")
10446
11521
  },
10447
11522
  async ({ pipelineId }) => {
10448
11523
  try {
@@ -10460,17 +11535,17 @@ ${text2}`);
10460
11535
  "create_pipeline",
10461
11536
  "Create a new pipeline with stages. Each stage needs a name and position (0-based).",
10462
11537
  {
10463
- name: import_zod37.z.string().describe("Pipeline name."),
10464
- stages: import_zod37.z.array(
10465
- import_zod37.z.object({
10466
- name: import_zod37.z.string().describe("Stage name."),
10467
- position: import_zod37.z.number().describe("Stage position (0-based)."),
10468
- showInFunnel: import_zod37.z.boolean().optional().describe("Show in funnel view. Defaults to true."),
10469
- showInPieChart: import_zod37.z.boolean().optional().describe("Show in pie chart. Defaults to true.")
11538
+ name: import_zod38.z.string().describe("Pipeline name."),
11539
+ stages: import_zod38.z.array(
11540
+ import_zod38.z.object({
11541
+ name: import_zod38.z.string().describe("Stage name."),
11542
+ position: import_zod38.z.number().describe("Stage position (0-based)."),
11543
+ showInFunnel: import_zod38.z.boolean().optional().describe("Show in funnel view. Defaults to true."),
11544
+ showInPieChart: import_zod38.z.boolean().optional().describe("Show in pie chart. Defaults to true.")
10470
11545
  })
10471
11546
  ).describe("Array of stages in order."),
10472
- showInFunnel: import_zod37.z.boolean().optional().describe("Show pipeline in funnel view. Defaults to true."),
10473
- showInPieChart: import_zod37.z.boolean().optional().describe("Show pipeline in pie chart. Defaults to true.")
11547
+ showInFunnel: import_zod38.z.boolean().optional().describe("Show pipeline in funnel view. Defaults to true."),
11548
+ showInPieChart: import_zod38.z.boolean().optional().describe("Show pipeline in pie chart. Defaults to true.")
10474
11549
  },
10475
11550
  async ({ name, stages, showInFunnel, showInPieChart }) => {
10476
11551
  try {
@@ -10500,19 +11575,19 @@ ${text2}`);
10500
11575
  "update_pipeline",
10501
11576
  "Update a pipeline's name, stages, or display settings. You can add, remove, rename, or reorder stages. Pass the complete stages array \u2014 stages not included will be removed.",
10502
11577
  {
10503
- pipelineId: import_zod37.z.string().describe("The pipeline ID to update."),
10504
- name: import_zod37.z.string().optional().describe("New pipeline name."),
10505
- stages: import_zod37.z.array(
10506
- import_zod37.z.object({
10507
- id: import_zod37.z.string().optional().describe("Existing stage ID (omit for new stages)."),
10508
- name: import_zod37.z.string().describe("Stage name."),
10509
- position: import_zod37.z.number().describe("Stage position (0-based)."),
10510
- showInFunnel: import_zod37.z.boolean().optional().describe("Show in funnel view."),
10511
- showInPieChart: import_zod37.z.boolean().optional().describe("Show in pie chart.")
11578
+ pipelineId: import_zod38.z.string().describe("The pipeline ID to update."),
11579
+ name: import_zod38.z.string().optional().describe("New pipeline name."),
11580
+ stages: import_zod38.z.array(
11581
+ import_zod38.z.object({
11582
+ id: import_zod38.z.string().optional().describe("Existing stage ID (omit for new stages)."),
11583
+ name: import_zod38.z.string().describe("Stage name."),
11584
+ position: import_zod38.z.number().describe("Stage position (0-based)."),
11585
+ showInFunnel: import_zod38.z.boolean().optional().describe("Show in funnel view."),
11586
+ showInPieChart: import_zod38.z.boolean().optional().describe("Show in pie chart.")
10512
11587
  })
10513
11588
  ).optional().describe("Complete stages array. Stages not included will be removed."),
10514
- showInFunnel: import_zod37.z.boolean().optional().describe("Show pipeline in funnel view."),
10515
- showInPieChart: import_zod37.z.boolean().optional().describe("Show pipeline in pie chart.")
11589
+ showInFunnel: import_zod38.z.boolean().optional().describe("Show pipeline in funnel view."),
11590
+ showInPieChart: import_zod38.z.boolean().optional().describe("Show pipeline in pie chart.")
10516
11591
  },
10517
11592
  async ({ pipelineId, name, stages, showInFunnel, showInPieChart }) => {
10518
11593
  try {
@@ -10535,8 +11610,8 @@ ${text2}`);
10535
11610
  "delete_pipeline",
10536
11611
  "Permanently delete a pipeline and all its stages. Opportunities become unassigned. IRREVERSIBLE.",
10537
11612
  {
10538
- pipelineId: import_zod37.z.string().describe("The pipeline ID to delete."),
10539
- confirm: import_zod37.z.literal("DELETE").describe("Must pass 'DELETE' to confirm this destructive action.")
11613
+ pipelineId: import_zod38.z.string().describe("The pipeline ID to delete."),
11614
+ confirm: import_zod38.z.literal("DELETE").describe("Must pass 'DELETE' to confirm this destructive action.")
10540
11615
  },
10541
11616
  async ({ pipelineId }) => {
10542
11617
  try {
@@ -10553,7 +11628,7 @@ ${text2}`);
10553
11628
  }
10554
11629
 
10555
11630
  // src/tools/location-switcher.ts
10556
- var import_zod40 = require("zod");
11631
+ var import_zod41 = require("zod");
10557
11632
  init_ghl_client();
10558
11633
  init_provisioning();
10559
11634
  init_setup_tool();
@@ -10638,7 +11713,7 @@ Token registry: ${registeredCount} location(s) registered${versionLine}`
10638
11713
  "switch_location",
10639
11714
  "Switch the active GHL sub-account. Automatically swaps the API key from the token registry if available. After switching, all tools default to the new location.",
10640
11715
  {
10641
- locationId: import_zod40.z.string().describe("The Location ID to switch to.")
11716
+ locationId: import_zod41.z.string().describe("The Location ID to switch to.")
10642
11717
  },
10643
11718
  async ({ locationId: locationId2 }) => withSwitchLock(async () => {
10644
11719
  const previousId = client.defaultLocationId;
@@ -10711,9 +11786,9 @@ Still on: ${previousId || "none"}${hint}` }],
10711
11786
  "register_location",
10712
11787
  "Add a GHL sub-account to the token registry so switch_location can automatically use its API key. Each sub-account needs its own Private Integration key created in GHL Settings > Integrations.",
10713
11788
  {
10714
- locationId: import_zod40.z.string().describe("The GHL Location ID (from Settings > Business Profile)."),
10715
- name: import_zod40.z.string().describe("A friendly name for this sub-account (e.g. 'PNTracker', 'Med Spa Template')."),
10716
- apiKey: import_zod40.z.string().describe("The Private Integration API key for this sub-account (starts with 'pit-').")
11789
+ locationId: import_zod41.z.string().describe("The GHL Location ID (from Settings > Business Profile)."),
11790
+ name: import_zod41.z.string().describe("A friendly name for this sub-account (e.g. 'PNTracker', 'Med Spa Template')."),
11791
+ apiKey: import_zod41.z.string().describe("The Private Integration API key for this sub-account (starts with 'pit-').")
10717
11792
  },
10718
11793
  async ({ locationId: locationId2, name, apiKey: apiKey2 }) => {
10719
11794
  if (!registry2) {
@@ -10770,7 +11845,7 @@ The API key could not access location ${locationId2}. Make sure:
10770
11845
  "register_agency_key",
10771
11846
  "Store the AGENCY-level (company-scoped) API key in the token registry. This key powers agency-wide tools: list_snapshots, create_snapshot_share_link, and list_available_locations across all sub-accounts. Create it at the AGENCY level in GHL (Agency Settings > Private Integrations) \u2014 it is different from a sub-account's key. The key is validated before saving.",
10772
11847
  {
10773
- apiKey: import_zod40.z.string().describe("The agency-level Private Integration API key (starts with 'pit-'). Must be created in AGENCY settings, not inside a sub-account.")
11848
+ apiKey: import_zod41.z.string().describe("The agency-level Private Integration API key (starts with 'pit-'). Must be created in AGENCY settings, not inside a sub-account.")
10774
11849
  },
10775
11850
  async ({ apiKey: apiKey2 }) => {
10776
11851
  if (!registry2) {
@@ -10824,7 +11899,7 @@ Agency-wide tools now available: list_snapshots, create_snapshot_share_link, and
10824
11899
  "unregister_location",
10825
11900
  "Remove a GHL sub-account from the token registry.",
10826
11901
  {
10827
- locationId: import_zod40.z.string().describe("The Location ID to remove.")
11902
+ locationId: import_zod41.z.string().describe("The Location ID to remove.")
10828
11903
  },
10829
11904
  async ({ locationId: locationId2 }) => {
10830
11905
  if (!registry2) {
@@ -10850,12 +11925,12 @@ Agency-wide tools now available: list_snapshots, create_snapshot_share_link, and
10850
11925
  "register_company_firebase",
10851
11926
  "Register a GHL company's Firebase credentials so the workflow builder and all Firebase-gated tools work when you switch into THAT company's sub-accounts. Firebase refresh tokens are company-scoped, so managing a client's GHL (e.g. an account where you're an admin user) requires that company's own token. Capture the values from a browser session logged into the client's account. The tool stores them under the company ID the Firebase token itself authenticates as (decoded from the token), so you do NOT need to hunt down the exact internal company ID \u2014 pass whatever ID you have and it self-corrects. After this, switch_location to any of that company's locations authenticates the workflow builder correctly. DevTools capture steps: elitedcs.com/ghl-mcp-firebase.",
10852
11927
  {
10853
- companyId: import_zod40.z.string().describe("A GHL company/agency ID for this client (from switch_location/register_location output, or the GHL agency URL). Best-effort only: the tool re-keys the entry to the company ID the Firebase token actually authenticates as, which can differ from the ID shown in the agency URL. Just pass what you have."),
10854
- name: import_zod40.z.string().describe("Friendly name for this client/company (e.g. 'Nathan \u2014 Acme Health')."),
10855
- ghl_firebase_refresh_token: import_zod40.z.string().min(10).describe("Firebase refresh token captured from a browser session logged into THIS company's GHL. value.stsTokenManager.refreshToken in the firebase:authUser IndexedDB row."),
10856
- ghl_user_id: import_zod40.z.string().min(5).describe("Firebase User ID (uid) from the same session. value.uid in the firebase:authUser row."),
10857
- ghl_firebase_api_key: import_zod40.z.string().optional().describe("Firebase API key (starts with 'AIza'). Optional \u2014 defaults to your home Firebase API key, which is identical across GHL accounts."),
10858
- test_location_id: import_zod40.z.string().optional().describe("Optional but recommended: a registered location ID belonging to this company. The tool then makes a real workflow-builder call to confirm these credentials actually work for this company before you rely on them.")
11928
+ companyId: import_zod41.z.string().describe("A GHL company/agency ID for this client (from switch_location/register_location output, or the GHL agency URL). Best-effort only: the tool re-keys the entry to the company ID the Firebase token actually authenticates as, which can differ from the ID shown in the agency URL. Just pass what you have."),
11929
+ name: import_zod41.z.string().describe("Friendly name for this client/company (e.g. 'Nathan \u2014 Acme Health')."),
11930
+ ghl_firebase_refresh_token: import_zod41.z.string().min(10).describe("Firebase refresh token captured from a browser session logged into THIS company's GHL. value.stsTokenManager.refreshToken in the firebase:authUser IndexedDB row."),
11931
+ ghl_user_id: import_zod41.z.string().min(5).describe("Firebase User ID (uid) from the same session. value.uid in the firebase:authUser row."),
11932
+ ghl_firebase_api_key: import_zod41.z.string().optional().describe("Firebase API key (starts with 'AIza'). Optional \u2014 defaults to your home Firebase API key, which is identical across GHL accounts."),
11933
+ test_location_id: import_zod41.z.string().optional().describe("Optional but recommended: a registered location ID belonging to this company. The tool then makes a real workflow-builder call to confirm these credentials actually work for this company before you rely on them.")
10859
11934
  },
10860
11935
  async (args) => {
10861
11936
  if (!registry2) {
@@ -10959,7 +12034,7 @@ Now run switch_location to any of this company's sub-accounts \u2014 the workflo
10959
12034
  "unregister_company_firebase",
10960
12035
  "Remove a company's Firebase credentials from the registry. Workflow-builder tools will stop working for that company's sub-accounts until re-registered.",
10961
12036
  {
10962
- companyId: import_zod40.z.string().describe("The company ID to remove Firebase credentials for.")
12037
+ companyId: import_zod41.z.string().describe("The company ID to remove Firebase credentials for.")
10963
12038
  },
10964
12039
  async ({ companyId }) => {
10965
12040
  if (!registry2) {
@@ -11027,8 +12102,8 @@ ${lines.join("\n")}
11027
12102
  "list_available_locations",
11028
12103
  "List all GHL sub-accounts (locations) accessible with the current or agency API key. Shows locations that exist in the GHL account \u2014 use register_location to add their tokens. Offset-based pagination via skip/limit.",
11029
12104
  {
11030
- limit: import_zod40.z.number().optional().describe("Max locations to return. Defaults to 20."),
11031
- skip: import_zod40.z.number().optional().describe("Number to skip for pagination.")
12105
+ limit: import_zod41.z.number().optional().describe("Max locations to return. Defaults to 20."),
12106
+ skip: import_zod41.z.number().optional().describe("Number to skip for pagination.")
11032
12107
  },
11033
12108
  async ({ limit, skip }) => {
11034
12109
  try {
@@ -11072,21 +12147,21 @@ ${lines.join("\n")}
11072
12147
  "create_sub_account",
11073
12148
  "Create a NEW GHL sub-account (location) under the agency, optionally loading a snapshot at creation \u2014 the first step of fully programmatic client provisioning (create \u2192 Blueprint build \u2192 verify_funnel). Requires an agency-level API key with the locations.write scope (add via register_agency_key). After creating, this probes whether the agency key can operate the new location and auto-registers it in the token registry when it can (switch_location then works immediately); if the probe fails, create a Private Integration Token inside the new sub-account and run register_location. Company Firebase (register_company_firebase) covers the internal-API builder tools in the new location either way.",
11074
12149
  {
11075
- name: import_zod40.z.string().min(1).describe("Business / sub-account name."),
11076
- snapshot_id: import_zod40.z.string().optional().describe("Snapshot ID to load at creation (see list_snapshots)."),
11077
- company_id: import_zod40.z.string().optional().describe("Agency company ID. Defaults to the active location's registered companyId."),
11078
- first_name: import_zod40.z.string().optional().describe("Prospect/owner first name."),
11079
- last_name: import_zod40.z.string().optional().describe("Prospect/owner last name."),
11080
- email: import_zod40.z.string().email().optional().describe("Prospect/owner email."),
11081
- phone: import_zod40.z.string().optional().describe("Business phone (E.164, e.g. +15551234567)."),
11082
- address: import_zod40.z.string().optional().describe("Street address."),
11083
- city: import_zod40.z.string().optional(),
11084
- state: import_zod40.z.string().optional(),
11085
- postal_code: import_zod40.z.string().optional(),
11086
- country: import_zod40.z.string().optional().describe("Two-letter country code. Defaults to US."),
11087
- website: import_zod40.z.string().optional(),
11088
- timezone: import_zod40.z.string().optional().describe("IANA timezone, e.g. America/Los_Angeles."),
11089
- auto_register: import_zod40.z.boolean().optional().describe("Probe the new location with the agency key and add it to the token registry on success. Default true.")
12150
+ name: import_zod41.z.string().min(1).describe("Business / sub-account name."),
12151
+ snapshot_id: import_zod41.z.string().optional().describe("Snapshot ID to load at creation (see list_snapshots)."),
12152
+ company_id: import_zod41.z.string().optional().describe("Agency company ID. Defaults to the active location's registered companyId."),
12153
+ first_name: import_zod41.z.string().optional().describe("Prospect/owner first name."),
12154
+ last_name: import_zod41.z.string().optional().describe("Prospect/owner last name."),
12155
+ email: import_zod41.z.string().email().optional().describe("Prospect/owner email."),
12156
+ phone: import_zod41.z.string().optional().describe("Business phone (E.164, e.g. +15551234567)."),
12157
+ address: import_zod41.z.string().optional().describe("Street address."),
12158
+ city: import_zod41.z.string().optional(),
12159
+ state: import_zod41.z.string().optional(),
12160
+ postal_code: import_zod41.z.string().optional(),
12161
+ country: import_zod41.z.string().optional().describe("Two-letter country code. Defaults to US."),
12162
+ website: import_zod41.z.string().optional(),
12163
+ timezone: import_zod41.z.string().optional().describe("IANA timezone, e.g. America/Los_Angeles."),
12164
+ auto_register: import_zod41.z.boolean().optional().describe("Probe the new location with the agency key and add it to the token registry on success. Default true.")
11090
12165
  },
11091
12166
  async (args) => {
11092
12167
  const outcome = await provisionSubAccount(client, registry2, args);
@@ -11114,9 +12189,9 @@ ${lines.join("\n")}
11114
12189
  "delete_sub_account",
11115
12190
  "Permanently delete a GHL sub-account (location) via the agency API. IRREVERSIBLE \u2014 every contact, workflow, funnel, and setting inside the sub-account is destroyed. Refuses to delete the currently active location. Also removes the location from the token registry. Requires an agency-level key with locations.write.",
11116
12191
  {
11117
- location_id: import_zod40.z.string().min(1).describe("The location ID to delete."),
11118
- confirm: import_zod40.z.literal("DELETE").describe("Must pass 'DELETE' to confirm this destructive action."),
11119
- delete_twilio: import_zod40.z.boolean().optional().describe("Also delete the location's Twilio sub-account. Default false.")
12192
+ location_id: import_zod41.z.string().min(1).describe("The location ID to delete."),
12193
+ confirm: import_zod41.z.literal("DELETE").describe("Must pass 'DELETE' to confirm this destructive action."),
12194
+ delete_twilio: import_zod41.z.boolean().optional().describe("Also delete the location's Twilio sub-account. Default false.")
11120
12195
  },
11121
12196
  async ({ location_id, delete_twilio }) => {
11122
12197
  const agencyKey = registry2?.getAgencyKey();
@@ -11154,7 +12229,7 @@ ${lines.join("\n")}
11154
12229
  }
11155
12230
 
11156
12231
  // src/tools/bulk-operations.ts
11157
- var import_zod41 = require("zod");
12232
+ var import_zod42 = require("zod");
11158
12233
  function delay(ms) {
11159
12234
  return new Promise((resolve5) => setTimeout(resolve5, ms));
11160
12235
  }
@@ -11166,8 +12241,8 @@ function registerBulkOperationTools(server2, client) {
11166
12241
  "bulk_add_tags",
11167
12242
  "Add tags to multiple contacts at once. Rate-limited to avoid API throttling. Returns a summary of successes and failures.",
11168
12243
  {
11169
- contactIds: import_zod41.z.array(import_zod41.z.string()).min(1, "At least one contact ID required.").describe("Array of contact IDs to tag."),
11170
- tags: import_zod41.z.array(import_zod41.z.string()).min(1, "At least one tag required.").describe("Tags to add to each contact.")
12244
+ contactIds: import_zod42.z.array(import_zod42.z.string()).min(1, "At least one contact ID required.").describe("Array of contact IDs to tag."),
12245
+ tags: import_zod42.z.array(import_zod42.z.string()).min(1, "At least one tag required.").describe("Tags to add to each contact.")
11171
12246
  },
11172
12247
  async ({ contactIds, tags }) => {
11173
12248
  const results = { success: 0, failed: 0, errors: [] };
@@ -11189,8 +12264,8 @@ function registerBulkOperationTools(server2, client) {
11189
12264
  "bulk_remove_tags",
11190
12265
  "Remove tags from multiple contacts at once. Rate-limited.",
11191
12266
  {
11192
- contactIds: import_zod41.z.array(import_zod41.z.string()).min(1, "At least one contact ID required.").describe("Array of contact IDs."),
11193
- tags: import_zod41.z.array(import_zod41.z.string()).min(1, "At least one tag required.").describe("Tags to remove from each contact.")
12267
+ contactIds: import_zod42.z.array(import_zod42.z.string()).min(1, "At least one contact ID required.").describe("Array of contact IDs."),
12268
+ tags: import_zod42.z.array(import_zod42.z.string()).min(1, "At least one tag required.").describe("Tags to remove from each contact.")
11194
12269
  },
11195
12270
  async ({ contactIds, tags }) => {
11196
12271
  const results = { success: 0, failed: 0, errors: [] };
@@ -11211,8 +12286,8 @@ function registerBulkOperationTools(server2, client) {
11211
12286
  "bulk_update_contacts",
11212
12287
  "Update the same field(s) on multiple contacts at once. Rate-limited. Example: set a custom field value, change source, update address for a batch of contacts.",
11213
12288
  {
11214
- contactIds: import_zod41.z.array(import_zod41.z.string()).min(1, "At least one contact ID required.").describe("Array of contact IDs to update."),
11215
- fields: import_zod41.z.record(import_zod41.z.unknown()).describe("Fields to set on each contact (e.g. {customField: {id: 'xxx', value: 'yyy'}}, {source: 'Import'}).")
12289
+ contactIds: import_zod42.z.array(import_zod42.z.string()).min(1, "At least one contact ID required.").describe("Array of contact IDs to update."),
12290
+ fields: import_zod42.z.record(import_zod42.z.unknown()).describe("Fields to set on each contact (e.g. {customField: {id: 'xxx', value: 'yyy'}}, {source: 'Import'}).")
11216
12291
  },
11217
12292
  async ({ contactIds, fields }) => {
11218
12293
  const results = { success: 0, failed: 0, errors: [] };
@@ -11233,8 +12308,8 @@ function registerBulkOperationTools(server2, client) {
11233
12308
  "bulk_add_to_workflow",
11234
12309
  "Enroll multiple contacts into a workflow at once. Rate-limited.",
11235
12310
  {
11236
- contactIds: import_zod41.z.array(import_zod41.z.string()).min(1, "At least one contact ID required.").describe("Array of contact IDs to enroll."),
11237
- workflowId: import_zod41.z.string().describe("The workflow ID to enroll contacts into.")
12311
+ contactIds: import_zod42.z.array(import_zod42.z.string()).min(1, "At least one contact ID required.").describe("Array of contact IDs to enroll."),
12312
+ workflowId: import_zod42.z.string().describe("The workflow ID to enroll contacts into.")
11238
12313
  },
11239
12314
  async ({ contactIds, workflowId }) => {
11240
12315
  const results = { success: 0, failed: 0, errors: [] };
@@ -11255,8 +12330,8 @@ function registerBulkOperationTools(server2, client) {
11255
12330
  "bulk_delete_contacts",
11256
12331
  "Delete multiple contacts at once. IRREVERSIBLE. Rate-limited. Use with extreme caution.",
11257
12332
  {
11258
- contactIds: import_zod41.z.array(import_zod41.z.string()).min(1, "At least one contact ID required.").describe("Array of contact IDs to permanently delete."),
11259
- confirm: import_zod41.z.literal("DELETE").describe("Must pass the string 'DELETE' to confirm. This is a safety check.")
12333
+ contactIds: import_zod42.z.array(import_zod42.z.string()).min(1, "At least one contact ID required.").describe("Array of contact IDs to permanently delete."),
12334
+ confirm: import_zod42.z.literal("DELETE").describe("Must pass the string 'DELETE' to confirm. This is a safety check.")
11260
12335
  },
11261
12336
  async ({ contactIds, confirm }) => {
11262
12337
  if (confirm !== "DELETE") {
@@ -11279,7 +12354,7 @@ function registerBulkOperationTools(server2, client) {
11279
12354
  }
11280
12355
 
11281
12356
  // src/tools/account-export.ts
11282
- var import_zod42 = require("zod");
12357
+ var import_zod43 = require("zod");
11283
12358
  function delay2(ms) {
11284
12359
  return new Promise((resolve5) => setTimeout(resolve5, ms));
11285
12360
  }
@@ -11289,8 +12364,8 @@ function registerAccountExportTools(server2, client) {
11289
12364
  "export_account",
11290
12365
  "Export a complete inventory of the GHL sub-account: location info, contacts (count + sample), pipelines with stages, workflows (with full actions if builder auth is configured), funnels with pages, forms, custom fields, custom values, tags, calendars, and users. Returns a comprehensive JSON report for auditing or backup.",
11291
12366
  {
11292
- locationId: import_zod42.z.string().optional().describe("Location ID to export. Uses default if not specified."),
11293
- includeContacts: import_zod42.z.boolean().optional().describe("Include contact list (first 100). Defaults to false for speed.")
12367
+ locationId: import_zod43.z.string().optional().describe("Location ID to export. Uses default if not specified."),
12368
+ includeContacts: import_zod43.z.boolean().optional().describe("Include contact list (first 100). Defaults to false for speed.")
11294
12369
  },
11295
12370
  async ({ locationId: locationId2, includeContacts }) => {
11296
12371
  try {
@@ -11418,8 +12493,8 @@ function registerAccountExportTools(server2, client) {
11418
12493
  "compare_locations",
11419
12494
  "Compare two GHL sub-accounts side by side \u2014 shows differences in pipelines, workflows, custom fields, tags, forms, and funnels. Useful for ensuring consistency across locations or auditing before/after changes.",
11420
12495
  {
11421
- locationA: import_zod42.z.string().describe("First Location ID."),
11422
- locationB: import_zod42.z.string().describe("Second Location ID.")
12496
+ locationA: import_zod43.z.string().describe("First Location ID."),
12497
+ locationB: import_zod43.z.string().describe("Second Location ID.")
11423
12498
  },
11424
12499
  async ({ locationA, locationB }) => {
11425
12500
  try {
@@ -11497,7 +12572,7 @@ function registerAccountExportTools(server2, client) {
11497
12572
  }
11498
12573
 
11499
12574
  // src/tools/workflow-cloner.ts
11500
- var import_zod43 = require("zod");
12575
+ var import_zod44 = require("zod");
11501
12576
  var crypto3 = __toESM(require("crypto"));
11502
12577
  function registerWorkflowClonerTools(server2, builderClient) {
11503
12578
  const client = builderClient;
@@ -11506,8 +12581,8 @@ function registerWorkflowClonerTools(server2, builderClient) {
11506
12581
  "clone_workflow",
11507
12582
  "Deep clone a workflow \u2014 creates an exact copy with new IDs for all actions, triggers, and references. The clone starts as a draft. Useful for creating templates or duplicating workflows across projects.",
11508
12583
  {
11509
- sourceWorkflowId: import_zod43.z.string().describe("The workflow ID to clone."),
11510
- newName: import_zod43.z.string().describe("Name for the cloned workflow.")
12584
+ sourceWorkflowId: import_zod44.z.string().describe("The workflow ID to clone."),
12585
+ newName: import_zod44.z.string().describe("Name for the cloned workflow.")
11511
12586
  },
11512
12587
  async ({ sourceWorkflowId, newName }) => {
11513
12588
  try {
@@ -11596,7 +12671,7 @@ function registerWorkflowClonerTools(server2, builderClient) {
11596
12671
  }
11597
12672
 
11598
12673
  // src/tools/smart-lists.ts
11599
- var import_zod44 = require("zod");
12674
+ var import_zod45 = require("zod");
11600
12675
  var SMARTLIST_BASE = "https://backend.leadconnectorhq.com/lists/dynamic";
11601
12676
  var OBJECT_KEYS = ["contacts", "opportunity"];
11602
12677
  function registerSmartListTools(server2, builderClient) {
@@ -11623,11 +12698,11 @@ ${text2}`);
11623
12698
  "list_smart_lists",
11624
12699
  "List smart lists (dynamic / saved-filter lists) in a location. Smart Lists are saved searches over contacts or opportunities \u2014 agencies use them to segment by complex criteria. Filters and columns aren't returned in the list view; use get_smart_list for the full filter spec.",
11625
12700
  {
11626
- objectKey: import_zod44.z.enum(OBJECT_KEYS).describe("The object type the lists segment over. 'contacts' for contact-segments, 'opportunity' for opportunity-segments. Required \u2014 GHL rejects requests without it."),
11627
- query: import_zod44.z.string().optional().describe("Free-text search across smart list names."),
11628
- limit: import_zod44.z.number().optional().describe("Max smart lists per page. Defaults to 20 on GHL's side."),
11629
- startAfter: import_zod44.z.string().optional().describe("Cursor for pagination \u2014 pass the last list's id from the previous page."),
11630
- locationId: import_zod44.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
12701
+ objectKey: import_zod45.z.enum(OBJECT_KEYS).describe("The object type the lists segment over. 'contacts' for contact-segments, 'opportunity' for opportunity-segments. Required \u2014 GHL rejects requests without it."),
12702
+ query: import_zod45.z.string().optional().describe("Free-text search across smart list names."),
12703
+ limit: import_zod45.z.number().optional().describe("Max smart lists per page. Defaults to 20 on GHL's side."),
12704
+ startAfter: import_zod45.z.string().optional().describe("Cursor for pagination \u2014 pass the last list's id from the previous page."),
12705
+ locationId: import_zod45.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11631
12706
  },
11632
12707
  async ({ objectKey, query, limit, startAfter, locationId: locationId2 }) => {
11633
12708
  try {
@@ -11647,8 +12722,8 @@ ${text2}`);
11647
12722
  "get_smart_list",
11648
12723
  "Get a single smart list by ID with its full configuration: filters, columns, permissions, and metadata. The filters array is what defines who/what is in the list.",
11649
12724
  {
11650
- listId: import_zod44.z.string().describe("The smart list ID (from list_smart_lists or a previous create_smart_list response)."),
11651
- locationId: import_zod44.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
12725
+ listId: import_zod45.z.string().describe("The smart list ID (from list_smart_lists or a previous create_smart_list response)."),
12726
+ locationId: import_zod45.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11652
12727
  },
11653
12728
  async ({ listId, locationId: locationId2 }) => {
11654
12729
  try {
@@ -11664,13 +12739,13 @@ ${text2}`);
11664
12739
  "create_smart_list",
11665
12740
  "Create a new smart list (dynamic filter list). Required: name + objectKey. Filters define the saved-search criteria \u2014 pass an empty array to create an empty list and add filters later via update_smart_list. The shape of filters/columns is opaque here; query an existing smart list with get_smart_list to see the format GHL expects.",
11666
12741
  {
11667
- name: import_zod44.z.string().describe("Display name for the smart list."),
11668
- objectKey: import_zod44.z.enum(OBJECT_KEYS).describe("Object type the list segments over. 'contacts' or 'opportunity'."),
11669
- filters: import_zod44.z.array(import_zod44.z.record(import_zod44.z.unknown())).optional().describe("Array of filter objects. Each object has fields like {field, operator, value} \u2014 exact shape varies by filter type. See get_smart_list on an existing list to learn the format."),
11670
- columns: import_zod44.z.array(import_zod44.z.record(import_zod44.z.unknown())).optional().describe("Array of column definitions for the smart list view in GHL UI. Each defines which contact/opportunity field shows as a column. Defaults to GHL's standard columns if omitted."),
11671
- pipelineIds: import_zod44.z.array(import_zod44.z.string()).optional().describe("(opportunity objectKey only) Pipeline IDs to restrict this smart list to. Empty array = all pipelines."),
11672
- defaultInPipelines: import_zod44.z.array(import_zod44.z.string()).optional().describe("(opportunity objectKey only) Pipeline IDs where this list is the default view."),
11673
- locationId: import_zod44.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
12742
+ name: import_zod45.z.string().describe("Display name for the smart list."),
12743
+ objectKey: import_zod45.z.enum(OBJECT_KEYS).describe("Object type the list segments over. 'contacts' or 'opportunity'."),
12744
+ filters: import_zod45.z.array(import_zod45.z.record(import_zod45.z.unknown())).optional().describe("Array of filter objects. Each object has fields like {field, operator, value} \u2014 exact shape varies by filter type. See get_smart_list on an existing list to learn the format."),
12745
+ columns: import_zod45.z.array(import_zod45.z.record(import_zod45.z.unknown())).optional().describe("Array of column definitions for the smart list view in GHL UI. Each defines which contact/opportunity field shows as a column. Defaults to GHL's standard columns if omitted."),
12746
+ pipelineIds: import_zod45.z.array(import_zod45.z.string()).optional().describe("(opportunity objectKey only) Pipeline IDs to restrict this smart list to. Empty array = all pipelines."),
12747
+ defaultInPipelines: import_zod45.z.array(import_zod45.z.string()).optional().describe("(opportunity objectKey only) Pipeline IDs where this list is the default view."),
12748
+ locationId: import_zod45.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11674
12749
  },
11675
12750
  async ({ name, objectKey, filters, columns, pipelineIds, defaultInPipelines, locationId: locationId2 }) => {
11676
12751
  try {
@@ -11691,13 +12766,13 @@ ${text2}`);
11691
12766
  "update_smart_list",
11692
12767
  "Update an existing smart list's name, filters, or columns. The objectKey CANNOT be changed after creation (GHL rejects with 422 if you try). Use get_smart_list first to inspect the current filters; partial updates work \u2014 pass only the fields you want to change.",
11693
12768
  {
11694
- listId: import_zod44.z.string().describe("The smart list ID to update."),
11695
- name: import_zod44.z.string().optional().describe("New display name."),
11696
- filters: import_zod44.z.array(import_zod44.z.record(import_zod44.z.unknown())).optional().describe("Replace the filter array entirely. To add a filter, fetch the current list, append, and pass the new array."),
11697
- columns: import_zod44.z.array(import_zod44.z.record(import_zod44.z.unknown())).optional().describe("Replace the column array entirely."),
11698
- pipelineIds: import_zod44.z.array(import_zod44.z.string()).optional().describe("(opportunity only) Update the pipeline scope."),
11699
- defaultInPipelines: import_zod44.z.array(import_zod44.z.string()).optional().describe("(opportunity only) Update the default-in-pipelines list."),
11700
- locationId: import_zod44.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
12769
+ listId: import_zod45.z.string().describe("The smart list ID to update."),
12770
+ name: import_zod45.z.string().optional().describe("New display name."),
12771
+ filters: import_zod45.z.array(import_zod45.z.record(import_zod45.z.unknown())).optional().describe("Replace the filter array entirely. To add a filter, fetch the current list, append, and pass the new array."),
12772
+ columns: import_zod45.z.array(import_zod45.z.record(import_zod45.z.unknown())).optional().describe("Replace the column array entirely."),
12773
+ pipelineIds: import_zod45.z.array(import_zod45.z.string()).optional().describe("(opportunity only) Update the pipeline scope."),
12774
+ defaultInPipelines: import_zod45.z.array(import_zod45.z.string()).optional().describe("(opportunity only) Update the default-in-pipelines list."),
12775
+ locationId: import_zod45.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11701
12776
  },
11702
12777
  async ({ listId, name, filters, columns, pipelineIds, defaultInPipelines, locationId: locationId2 }) => {
11703
12778
  try {
@@ -11722,9 +12797,9 @@ ${text2}`);
11722
12797
  "delete_smart_list",
11723
12798
  "Permanently delete a smart list. IRREVERSIBLE. The list configuration is removed but the contacts/opportunities themselves are NOT touched \u2014 smart lists are just saved filters. Any workflow trigger / dashboard / report that referenced this list by ID will stop working.",
11724
12799
  {
11725
- listId: import_zod44.z.string().describe("The smart list ID to delete."),
11726
- confirm: import_zod44.z.literal("DELETE").describe("Must pass 'DELETE' to confirm this destructive action."),
11727
- locationId: import_zod44.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
12800
+ listId: import_zod45.z.string().describe("The smart list ID to delete."),
12801
+ confirm: import_zod45.z.literal("DELETE").describe("Must pass 'DELETE' to confirm this destructive action."),
12802
+ locationId: import_zod45.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11728
12803
  },
11729
12804
  async ({ listId, locationId: locationId2 }) => {
11730
12805
  try {
@@ -11739,7 +12814,7 @@ ${text2}`);
11739
12814
  }
11740
12815
 
11741
12816
  // src/tools/reputation.ts
11742
- var import_zod45 = require("zod");
12817
+ var import_zod46 = require("zod");
11743
12818
  var REPUTATION_BASE = "https://backend.leadconnectorhq.com/reputation";
11744
12819
  function registerReputationTools(server2, builderClient) {
11745
12820
  const client = builderClient;
@@ -11761,7 +12836,7 @@ ${text2}`);
11761
12836
  "get_review_link_list",
11762
12837
  "List the review-link destinations configured for a location \u2014 the platforms (Google, Facebook, etc.) where review requests send contacts. Each entry has a label and the public review URL. Useful for: building review-request workflows (the workflow goal condition `review_request_clicked` references these review-link ids), and auditing which review platforms a sub-account has connected.",
11763
12838
  {
11764
- locationId: import_zod45.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
12839
+ locationId: import_zod46.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11765
12840
  },
11766
12841
  async ({ locationId: locationId2 }) => {
11767
12842
  const loc = locationId2 ?? client.locationId;
@@ -11773,11 +12848,11 @@ ${text2}`);
11773
12848
  "list_reviews",
11774
12849
  "List the reviews a location has received (Google, Facebook, etc.) with rating, author, text, reply status, and source. Supports paging and an optional rating filter. NOTE: location is resolved through nested filter params internally \u2014 a flat locationId is what caused the long-standing 'No Location Found' error, now fixed. Responding to a review is not yet available via API. Requires Firebase auth.",
11775
12850
  {
11776
- locationId: import_zod45.z.string().optional().describe("Location ID. Falls back to the active builder client's location."),
11777
- pageNumber: import_zod45.z.number().optional().describe("1-based page number. Defaults to 1."),
11778
- pageSize: import_zod45.z.number().optional().describe("Results per page. Defaults to 10."),
11779
- rating: import_zod45.z.number().optional().describe("Optional: only return reviews with this star rating (1-5)."),
11780
- includeDeleted: import_zod45.z.boolean().optional().describe("Include deleted reviews. Defaults to false.")
12851
+ locationId: import_zod46.z.string().optional().describe("Location ID. Falls back to the active builder client's location."),
12852
+ pageNumber: import_zod46.z.number().optional().describe("1-based page number. Defaults to 1."),
12853
+ pageSize: import_zod46.z.number().optional().describe("Results per page. Defaults to 10."),
12854
+ rating: import_zod46.z.number().optional().describe("Optional: only return reviews with this star rating (1-5)."),
12855
+ includeDeleted: import_zod46.z.boolean().optional().describe("Include deleted reviews. Defaults to false.")
11781
12856
  },
11782
12857
  async ({ locationId: locationId2, pageNumber, pageSize, rating, includeDeleted }) => {
11783
12858
  const loc = locationId2 ?? client.locationId;
@@ -11807,7 +12882,7 @@ function buildReviewsQuery(locationId2, opts = {}) {
11807
12882
  }
11808
12883
 
11809
12884
  // src/tools/email-campaigns.ts
11810
- var import_zod46 = require("zod");
12885
+ var import_zod47 = require("zod");
11811
12886
  var SVC_BASE = "https://services.leadconnectorhq.com";
11812
12887
  function registerEmailCampaignTools(server2, builderClient) {
11813
12888
  const client = builderClient;
@@ -11817,15 +12892,15 @@ function registerEmailCampaignTools(server2, builderClient) {
11817
12892
  "create_email_campaign",
11818
12893
  "Create an email campaign / broadcast DRAFT from an existing email template. Requires a templateId (create one first with create_email_template). The campaign is created as a draft \u2014 to actually SEND or schedule it, finish in the GHL UI: the send/schedule endpoint isn't available through the API yet. There's also no API delete for campaigns, so drafts created here are removed via the GHL UI. Despite those limits, this gets the campaign 90% built \u2014 template, subject, sender, name all set programmatically.",
11819
12894
  {
11820
- templateId: import_zod46.z.string().describe("ID of an email template (from create_email_template or list_email_templates) to use as the campaign body."),
11821
- name: import_zod46.z.string().optional().describe("Internal campaign name (shown in the campaigns list, not to recipients). Defaults to a GHL-generated name."),
11822
- subject: import_zod46.z.string().optional().describe("Email subject line recipients see."),
11823
- fromName: import_zod46.z.string().optional().describe("Sender display name."),
11824
- fromEmail: import_zod46.z.string().optional().describe("Sender email address. Must be a verified sending address in the location."),
11825
- isPlainText: import_zod46.z.boolean().optional().describe("Send as plain text instead of HTML. Defaults to false."),
11826
- enableResendToUnopened: import_zod46.z.boolean().optional().describe("Auto-resend to contacts who didn't open. Defaults to false."),
11827
- hasUtmTracking: import_zod46.z.boolean().optional().describe("Append UTM tracking params to links. Defaults to false."),
11828
- locationId: import_zod46.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
12895
+ templateId: import_zod47.z.string().describe("ID of an email template (from create_email_template or list_email_templates) to use as the campaign body."),
12896
+ name: import_zod47.z.string().optional().describe("Internal campaign name (shown in the campaigns list, not to recipients). Defaults to a GHL-generated name."),
12897
+ subject: import_zod47.z.string().optional().describe("Email subject line recipients see."),
12898
+ fromName: import_zod47.z.string().optional().describe("Sender display name."),
12899
+ fromEmail: import_zod47.z.string().optional().describe("Sender email address. Must be a verified sending address in the location."),
12900
+ isPlainText: import_zod47.z.boolean().optional().describe("Send as plain text instead of HTML. Defaults to false."),
12901
+ enableResendToUnopened: import_zod47.z.boolean().optional().describe("Auto-resend to contacts who didn't open. Defaults to false."),
12902
+ hasUtmTracking: import_zod47.z.boolean().optional().describe("Append UTM tracking params to links. Defaults to false."),
12903
+ locationId: import_zod47.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11829
12904
  },
11830
12905
  async ({ templateId, name, subject, fromName, fromEmail, isPlainText, enableResendToUnopened, hasUtmTracking, locationId: locationId2 }) => {
11831
12906
  const loc = locationId2 ?? client.locationId;
@@ -11859,7 +12934,7 @@ ${text2}`);
11859
12934
  }
11860
12935
 
11861
12936
  // src/tools/memberships.ts
11862
- var import_zod47 = require("zod");
12937
+ var import_zod48 = require("zod");
11863
12938
  var MEMBERSHIP_BASE = "https://backend.leadconnectorhq.com/membership";
11864
12939
  function registerMembershipTools(server2, builderClient) {
11865
12940
  const client = builderClient;
@@ -11885,7 +12960,7 @@ ${text2}`);
11885
12960
  "list_membership_offers",
11886
12961
  "List a location's membership offers and products in one call. Returns { products: [...], offers: [...] }. Products are courses/communities; offers are the access grants (what a contact gets enrolled in). Use the returned ids with membership trigger conditions like offer_access_granted / product_completed.",
11887
12962
  {
11888
- locationId: import_zod47.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
12963
+ locationId: import_zod48.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11889
12964
  },
11890
12965
  async ({ locationId: locationId2 }) => {
11891
12966
  const loc = locationId2 ?? client.locationId;
@@ -11897,8 +12972,8 @@ ${text2}`);
11897
12972
  "list_membership_categories",
11898
12973
  "List all membership/course categories in a location. Categories group lessons inside a course/product. Use the returned ids with the category_completed / category_started trigger conditions. READ-ONLY.",
11899
12974
  {
11900
- limit: import_zod47.z.number().optional().describe("Max categories to return. Defaults to a large value (effectively all)."),
11901
- locationId: import_zod47.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
12975
+ limit: import_zod48.z.number().optional().describe("Max categories to return. Defaults to a large value (effectively all)."),
12976
+ locationId: import_zod48.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11902
12977
  },
11903
12978
  async ({ limit, locationId: locationId2 }) => {
11904
12979
  const loc = locationId2 ?? client.locationId;
@@ -11910,8 +12985,8 @@ ${text2}`);
11910
12985
  "list_membership_lessons",
11911
12986
  "List all membership/course lessons in a location. Use the returned ids with the lesson_completed / lesson_started trigger conditions. READ-ONLY.",
11912
12987
  {
11913
- limit: import_zod47.z.number().optional().describe("Max lessons to return. Defaults to a large value (effectively all)."),
11914
- locationId: import_zod47.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
12988
+ limit: import_zod48.z.number().optional().describe("Max lessons to return. Defaults to a large value (effectively all)."),
12989
+ locationId: import_zod48.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11915
12990
  },
11916
12991
  async ({ limit, locationId: locationId2 }) => {
11917
12992
  const loc = locationId2 ?? client.locationId;
@@ -11923,9 +12998,9 @@ ${text2}`);
11923
12998
  "create_course",
11924
12999
  "Create a membership course (a 'product') in a location. Creates the course shell with a title and description; add categories (create_membership_category) and lessons (create_membership_lesson) into it, and an offer (create_membership_offer) to grant access. Returns the new product, including its id. Requires Firebase auth.",
11925
13000
  {
11926
- title: import_zod47.z.string().describe("Course title."),
11927
- description: import_zod47.z.string().optional().describe("Course description. Defaults to empty."),
11928
- locationId: import_zod47.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
13001
+ title: import_zod48.z.string().describe("Course title."),
13002
+ description: import_zod48.z.string().optional().describe("Course description. Defaults to empty."),
13003
+ locationId: import_zod48.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11929
13004
  },
11930
13005
  async ({ title, description, locationId: locationId2 }) => {
11931
13006
  const loc = locationId2 ?? client.locationId;
@@ -11937,13 +13012,13 @@ ${text2}`);
11937
13012
  "create_membership_category",
11938
13013
  "Create a category (module/section) inside a membership course. Categories group lessons. Needs the productId of the course (from create_course or list_membership_offers). Returns the new category, including its id (use it as categoryId when creating lessons). Requires Firebase auth.",
11939
13014
  {
11940
- title: import_zod47.z.string().describe("Category title (e.g. 'Module 1')."),
11941
- productId: import_zod47.z.string().describe("The course/product id this category belongs to."),
11942
- description: import_zod47.z.string().optional().describe("Category description. Defaults to empty."),
11943
- visibility: import_zod47.z.enum(["published", "draft"]).optional().describe("'published' (default) or 'draft'."),
11944
- sequenceNo: import_zod47.z.number().optional().describe("Display order within the course. Defaults to 0."),
11945
- dripDays: import_zod47.z.number().optional().describe("Days after enrollment before this category unlocks. Defaults to 0 (no drip)."),
11946
- locationId: import_zod47.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
13015
+ title: import_zod48.z.string().describe("Category title (e.g. 'Module 1')."),
13016
+ productId: import_zod48.z.string().describe("The course/product id this category belongs to."),
13017
+ description: import_zod48.z.string().optional().describe("Category description. Defaults to empty."),
13018
+ visibility: import_zod48.z.enum(["published", "draft"]).optional().describe("'published' (default) or 'draft'."),
13019
+ sequenceNo: import_zod48.z.number().optional().describe("Display order within the course. Defaults to 0."),
13020
+ dripDays: import_zod48.z.number().optional().describe("Days after enrollment before this category unlocks. Defaults to 0 (no drip)."),
13021
+ locationId: import_zod48.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11947
13022
  },
11948
13023
  async ({ title, productId, description, visibility, sequenceNo, dripDays, locationId: locationId2 }) => {
11949
13024
  const loc = locationId2 ?? client.locationId;
@@ -11955,14 +13030,14 @@ ${text2}`);
11955
13030
  "create_membership_lesson",
11956
13031
  "Create a lesson (a 'post') inside a membership course category. Needs both the categoryId (from create_membership_category) and the productId of the course. Description is the lesson body as HTML. Returns the new lesson, including its id. Requires Firebase auth.",
11957
13032
  {
11958
- title: import_zod47.z.string().describe("Lesson title."),
11959
- categoryId: import_zod47.z.string().describe("The category id this lesson belongs to (from create_membership_category)."),
11960
- productId: import_zod47.z.string().describe("The course/product id this lesson belongs to."),
11961
- description: import_zod47.z.string().optional().describe("Lesson body as HTML. Defaults to empty."),
11962
- contentType: import_zod47.z.enum(["video", "audio", "text", "pdf", "assignment"]).optional().describe("Lesson content type. Defaults to 'video'."),
11963
- visibility: import_zod47.z.enum(["published", "draft"]).optional().describe("'published' (default) or 'draft'."),
11964
- sequenceNo: import_zod47.z.number().optional().describe("Display order within the category. Defaults to 0."),
11965
- locationId: import_zod47.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
13033
+ title: import_zod48.z.string().describe("Lesson title."),
13034
+ categoryId: import_zod48.z.string().describe("The category id this lesson belongs to (from create_membership_category)."),
13035
+ productId: import_zod48.z.string().describe("The course/product id this lesson belongs to."),
13036
+ description: import_zod48.z.string().optional().describe("Lesson body as HTML. Defaults to empty."),
13037
+ contentType: import_zod48.z.enum(["video", "audio", "text", "pdf", "assignment"]).optional().describe("Lesson content type. Defaults to 'video'."),
13038
+ visibility: import_zod48.z.enum(["published", "draft"]).optional().describe("'published' (default) or 'draft'."),
13039
+ sequenceNo: import_zod48.z.number().optional().describe("Display order within the category. Defaults to 0."),
13040
+ locationId: import_zod48.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11966
13041
  },
11967
13042
  async ({ title, categoryId, productId, description, contentType, visibility, sequenceNo, locationId: locationId2 }) => {
11968
13043
  const loc = locationId2 ?? client.locationId;
@@ -11974,12 +13049,12 @@ ${text2}`);
11974
13049
  "create_membership_offer",
11975
13050
  "Create a membership offer \u2014 the access grant that enrolls contacts into one or more courses/products. Link it to course product ids. Defaults to a free offer; for paid, set type to 'recurring' or 'one_time' with an amount. Returns the new offer, including its id (referenced by the offer_access_granted trigger). Requires Firebase auth.",
11976
13051
  {
11977
- title: import_zod47.z.string().describe("Offer title (shown at checkout / in the offer list)."),
11978
- productIds: import_zod47.z.array(import_zod47.z.string()).describe("Course/product ids this offer grants access to (from create_course or list_membership_offers)."),
11979
- type: import_zod47.z.enum(["free", "recurring", "one_time"]).optional().describe("Offer type. Defaults to 'free'."),
11980
- amount: import_zod47.z.number().optional().describe("Price for paid offers. Defaults to 0 (free)."),
11981
- currency: import_zod47.z.string().optional().describe("Currency code for paid offers. Defaults to 'USD'."),
11982
- locationId: import_zod47.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
13052
+ title: import_zod48.z.string().describe("Offer title (shown at checkout / in the offer list)."),
13053
+ productIds: import_zod48.z.array(import_zod48.z.string()).describe("Course/product ids this offer grants access to (from create_course or list_membership_offers)."),
13054
+ type: import_zod48.z.enum(["free", "recurring", "one_time"]).optional().describe("Offer type. Defaults to 'free'."),
13055
+ amount: import_zod48.z.number().optional().describe("Price for paid offers. Defaults to 0 (free)."),
13056
+ currency: import_zod48.z.string().optional().describe("Currency code for paid offers. Defaults to 'USD'."),
13057
+ locationId: import_zod48.z.string().optional().describe("Location ID. Falls back to the active builder client's location.")
11983
13058
  },
11984
13059
  async ({ title, productIds, type, amount, currency, locationId: locationId2 }) => {
11985
13060
  const loc = locationId2 ?? client.locationId;
@@ -12038,41 +13113,41 @@ function buildOfferPayload(o) {
12038
13113
  }
12039
13114
 
12040
13115
  // src/tools/template-deployer.ts
12041
- var import_zod48 = require("zod");
13116
+ var import_zod49 = require("zod");
12042
13117
  var fs5 = __toESM(require("fs"));
12043
13118
  var path5 = __toESM(require("path"));
12044
13119
  function delay3(ms) {
12045
13120
  return new Promise((resolve5) => setTimeout(resolve5, ms));
12046
13121
  }
12047
- var TemplateSchema = import_zod48.z.object({
12048
- templateName: import_zod48.z.string(),
12049
- templateVersion: import_zod48.z.string().optional(),
12050
- description: import_zod48.z.string().optional().default(""),
12051
- questionnaire: import_zod48.z.array(import_zod48.z.object({
12052
- id: import_zod48.z.string(),
12053
- question: import_zod48.z.string(),
12054
- type: import_zod48.z.string(),
12055
- required: import_zod48.z.boolean().optional(),
12056
- placeholder: import_zod48.z.string().optional()
13122
+ var TemplateSchema = import_zod49.z.object({
13123
+ templateName: import_zod49.z.string(),
13124
+ templateVersion: import_zod49.z.string().optional(),
13125
+ description: import_zod49.z.string().optional().default(""),
13126
+ questionnaire: import_zod49.z.array(import_zod49.z.object({
13127
+ id: import_zod49.z.string(),
13128
+ question: import_zod49.z.string(),
13129
+ type: import_zod49.z.string(),
13130
+ required: import_zod49.z.boolean().optional(),
13131
+ placeholder: import_zod49.z.string().optional()
12057
13132
  })).optional().default([]),
12058
- location: import_zod48.z.record(import_zod48.z.unknown()).optional(),
12059
- tags: import_zod48.z.array(import_zod48.z.string()).optional(),
12060
- customFields: import_zod48.z.array(import_zod48.z.object({
12061
- name: import_zod48.z.string(),
12062
- dataType: import_zod48.z.string()
13133
+ location: import_zod49.z.record(import_zod49.z.unknown()).optional(),
13134
+ tags: import_zod49.z.array(import_zod49.z.string()).optional(),
13135
+ customFields: import_zod49.z.array(import_zod49.z.object({
13136
+ name: import_zod49.z.string(),
13137
+ dataType: import_zod49.z.string()
12063
13138
  })).optional(),
12064
- pipelines: import_zod48.z.array(import_zod48.z.object({
12065
- name: import_zod48.z.string(),
12066
- stages: import_zod48.z.array(import_zod48.z.object({ position: import_zod48.z.number(), name: import_zod48.z.string() }))
13139
+ pipelines: import_zod49.z.array(import_zod49.z.object({
13140
+ name: import_zod49.z.string(),
13141
+ stages: import_zod49.z.array(import_zod49.z.object({ position: import_zod49.z.number(), name: import_zod49.z.string() }))
12067
13142
  })).optional(),
12068
- workflows: import_zod48.z.array(import_zod48.z.object({
12069
- name: import_zod48.z.string(),
12070
- condition: import_zod48.z.string().optional(),
12071
- actions: import_zod48.z.array(import_zod48.z.record(import_zod48.z.unknown())).optional().default([])
13143
+ workflows: import_zod49.z.array(import_zod49.z.object({
13144
+ name: import_zod49.z.string(),
13145
+ condition: import_zod49.z.string().optional(),
13146
+ actions: import_zod49.z.array(import_zod49.z.record(import_zod49.z.unknown())).optional().default([])
12072
13147
  })).optional(),
12073
- calendars: import_zod48.z.array(import_zod48.z.object({
12074
- name: import_zod48.z.string(),
12075
- description: import_zod48.z.string().optional()
13148
+ calendars: import_zod49.z.array(import_zod49.z.object({
13149
+ name: import_zod49.z.string(),
13150
+ description: import_zod49.z.string().optional()
12076
13151
  })).optional()
12077
13152
  });
12078
13153
  function registerTemplateDeployerTools(server2, client) {
@@ -12143,7 +13218,7 @@ function registerTemplateDeployerTools(server2, client) {
12143
13218
  "get_template_questionnaire",
12144
13219
  "Get the questionnaire for a specific template. Returns all the questions that need to be answered before deploying. Present these to the user one at a time in a conversational style.",
12145
13220
  {
12146
- templateFile: import_zod48.z.string().describe("Path to the template JSON file (from list_templates).")
13221
+ templateFile: import_zod49.z.string().describe("Path to the template JSON file (from list_templates).")
12147
13222
  },
12148
13223
  async ({ templateFile }) => {
12149
13224
  try {
@@ -12176,10 +13251,10 @@ function registerTemplateDeployerTools(server2, client) {
12176
13251
  "deploy_template",
12177
13252
  "Deploy a template to set up a GHL sub-account. Creates tags, custom fields, pipelines with stages, calendars, workflows, and forms based on the template and the user's questionnaire answers. This is the main setup automation tool.",
12178
13253
  {
12179
- templateFile: import_zod48.z.string().describe("Path to the template JSON file."),
12180
- answers: import_zod48.z.record(import_zod48.z.unknown()).describe("Questionnaire answers keyed by question ID (e.g. {business_name: 'My Clinic', business_phone: '+15551234567', ...})."),
12181
- locationId: import_zod48.z.string().optional().describe("Location ID to deploy to. Uses default if not specified."),
12182
- dryRun: import_zod48.z.boolean().optional().describe("If true, shows what would be created without actually creating anything. Defaults to false.")
13254
+ templateFile: import_zod49.z.string().describe("Path to the template JSON file."),
13255
+ answers: import_zod49.z.record(import_zod49.z.unknown()).describe("Questionnaire answers keyed by question ID (e.g. {business_name: 'My Clinic', business_phone: '+15551234567', ...})."),
13256
+ locationId: import_zod49.z.string().optional().describe("Location ID to deploy to. Uses default if not specified."),
13257
+ dryRun: import_zod49.z.boolean().optional().describe("If true, shows what would be created without actually creating anything. Defaults to false.")
12183
13258
  },
12184
13259
  async ({ templateFile, answers, locationId: locationId2, dryRun }) => {
12185
13260
  try {
@@ -12425,7 +13500,7 @@ ${errors.join("\n")}` : "\nNo errors!",
12425
13500
  }
12426
13501
 
12427
13502
  // src/tools/validators.ts
12428
- var import_zod49 = require("zod");
13503
+ var import_zod50 = require("zod");
12429
13504
  var ALL_CATEGORIES = ["pipeline", "stage", "custom_field", "user", "workflow", "form", "calendar", "survey"];
12430
13505
  var STANDARD_CONTACT_FIELDS = /* @__PURE__ */ new Set([
12431
13506
  "first_name",
@@ -12694,7 +13769,7 @@ function collectCustomFieldKeys(envelope) {
12694
13769
  }
12695
13770
  return keys;
12696
13771
  }
12697
- function collectIds(envelope, listKeys) {
13772
+ function collectIds2(envelope, listKeys) {
12698
13773
  const ids = /* @__PURE__ */ new Set();
12699
13774
  let arr = null;
12700
13775
  if (Array.isArray(envelope)) arr = envelope;
@@ -12766,7 +13841,7 @@ async function fetchAndBuildLookups(client, builderClient, locationId2, workflow
12766
13841
  status[cat] = "failed";
12767
13842
  return /* @__PURE__ */ new Set();
12768
13843
  }
12769
- const { ids, found } = collectIds(data[key], listKeys);
13844
+ const { ids, found } = collectIds2(data[key], listKeys);
12770
13845
  if (!found) status[cat] = "unparseable";
12771
13846
  return ids;
12772
13847
  }
@@ -12883,7 +13958,7 @@ function registerValidatorTools(server2, client, builderClient) {
12883
13958
  server2.tool(
12884
13959
  "validate_workflow",
12885
13960
  "Pre-flight ID validation for ONE deployed GHL workflow. Scans every trigger and action for references to pipelines, pipeline stages, custom fields, users, workflows, forms, calendars, and surveys; verifies each ID exists in the current location. Use BEFORE publish_workflow when a workflow was edited, or when a published workflow stops behaving. Catches the silent-failure bug where invalid IDs make GHL skip all subsequent actions. Never reports a false break \u2014 anything it cannot fully verify is marked 'unverified', not 'error'.",
12886
- { workflowId: import_zod49.z.string().describe("The workflow ID to validate.") },
13961
+ { workflowId: import_zod50.z.string().describe("The workflow ID to validate.") },
12887
13962
  async ({ workflowId }) => {
12888
13963
  try {
12889
13964
  const workflow = await builderClient.getWorkflow(workflowId);
@@ -13135,11 +14210,11 @@ function registerDiagnosticTools(server2, installedVersion, client, builderClien
13135
14210
  }
13136
14211
 
13137
14212
  // src/tools/snapshots.ts
13138
- var import_zod50 = require("zod");
14213
+ var import_zod51 = require("zod");
13139
14214
  init_ghl_client();
13140
- var SnapshotSchema = import_zod50.z.object({ id: import_zod50.z.string(), name: import_zod50.z.string(), type: import_zod50.z.string() }).passthrough();
13141
- var SnapshotsResponseSchema = import_zod50.z.object({ snapshots: import_zod50.z.array(SnapshotSchema) }).passthrough();
13142
- var ShareLinkResponseSchema = import_zod50.z.object({ id: import_zod50.z.string(), shareLink: import_zod50.z.string() }).passthrough();
14215
+ var SnapshotSchema = import_zod51.z.object({ id: import_zod51.z.string(), name: import_zod51.z.string(), type: import_zod51.z.string() }).passthrough();
14216
+ var SnapshotsResponseSchema = import_zod51.z.object({ snapshots: import_zod51.z.array(SnapshotSchema) }).passthrough();
14217
+ var ShareLinkResponseSchema = import_zod51.z.object({ id: import_zod51.z.string(), shareLink: import_zod51.z.string() }).passthrough();
13143
14218
  var SHARE_TYPES = [
13144
14219
  "link",
13145
14220
  "permanent_link",
@@ -13186,7 +14261,7 @@ function registerSnapshotTools(server2, client, registry2) {
13186
14261
  "list_snapshots",
13187
14262
  "List the agency's GHL snapshots (id, name, type) so you can pick the right one by name before applying it to a sub-account. Reads the agency/company-scoped key (not a sub-account PIT). companyId defaults to the active location's company; pass it explicitly to target a different company you have the agency key for. Read-only.",
13188
14263
  {
13189
- companyId: import_zod50.z.string().optional().describe(
14264
+ companyId: import_zod51.z.string().optional().describe(
13190
14265
  "Agency/company ID whose snapshots to list. Defaults to the active location's company. Must match the company your agency key is scoped to."
13191
14266
  )
13192
14267
  },
@@ -13211,11 +14286,11 @@ function registerSnapshotTools(server2, client, registry2) {
13211
14286
  "create_snapshot_share_link",
13212
14287
  "Create a shareable load link for one of the agency's snapshots (returns a gohighlevel.com/?share=... URL to import the snapshot into a sub-account). Uses the agency/company-scoped key. WARNING: this is NOT idempotent \u2014 each call mints a NEW link, and there is no API to list or revoke links (revoke in the GHL UI under the snapshot's share settings). Pick share_type deliberately. Use list_snapshots first to get the snapshot id.",
13213
14288
  {
13214
- snapshot_id: import_zod50.z.string().describe("The snapshot id to share (from list_snapshots)."),
13215
- share_type: import_zod50.z.enum(SHARE_TYPES).describe(
14289
+ snapshot_id: import_zod51.z.string().describe("The snapshot id to share (from list_snapshots)."),
14290
+ share_type: import_zod51.z.enum(SHARE_TYPES).describe(
13216
14291
  "Share link type. 'link' = standard share link; 'permanent_link' = non-expiring; 'agency_link' = share to agencies; 'location_link' = load into a sub-account/location; 'marketplace_link' = marketplace listing. No default \u2014 choose intentionally."
13217
14292
  ),
13218
- companyId: import_zod50.z.string().optional().describe(
14293
+ companyId: import_zod51.z.string().optional().describe(
13219
14294
  "Agency/company ID that owns the snapshot. Defaults to the active location's company. Must match the company your agency key is scoped to."
13220
14295
  )
13221
14296
  },
@@ -13245,17 +14320,17 @@ function registerSnapshotTools(server2, client, registry2) {
13245
14320
  }
13246
14321
 
13247
14322
  // src/tools/phone.ts
13248
- var import_zod51 = require("zod");
13249
- var PhoneNumberSchema = import_zod51.z.object({ sid: import_zod51.z.string(), value: import_zod51.z.string(), title: import_zod51.z.string().optional() }).passthrough();
13250
- var NumbersResponseSchema = import_zod51.z.object({ phoneNumbers: import_zod51.z.array(PhoneNumberSchema) }).passthrough();
13251
- var PoolsResponseSchema = import_zod51.z.object({ pools: import_zod51.z.array(import_zod51.z.object({}).passthrough()) }).passthrough();
14323
+ var import_zod52 = require("zod");
14324
+ var PhoneNumberSchema = import_zod52.z.object({ sid: import_zod52.z.string(), value: import_zod52.z.string(), title: import_zod52.z.string().optional() }).passthrough();
14325
+ var NumbersResponseSchema = import_zod52.z.object({ phoneNumbers: import_zod52.z.array(PhoneNumberSchema) }).passthrough();
14326
+ var PoolsResponseSchema = import_zod52.z.object({ pools: import_zod52.z.array(import_zod52.z.object({}).passthrough()) }).passthrough();
13252
14327
  function registerPhoneTools(server2, client) {
13253
14328
  safeTool(
13254
14329
  server2,
13255
14330
  "list_phone_numbers",
13256
14331
  "List the LC Phone numbers provisioned for a location (sid, number, label). Read-only. Use to verify or count purchased numbers (e.g. provisioning step 11). Number purchase is not exposed (billable write).",
13257
14332
  {
13258
- locationId: import_zod51.z.string().optional().describe("Defaults to the active location.")
14333
+ locationId: import_zod52.z.string().optional().describe("Defaults to the active location.")
13259
14334
  },
13260
14335
  async ({ locationId: locationId2 }) => {
13261
14336
  const loc = client.resolveLocationId(locationId2);
@@ -13273,7 +14348,7 @@ function registerPhoneTools(server2, client) {
13273
14348
  "list_number_pools",
13274
14349
  "List LC Phone number pools configured for a location. Read-only.",
13275
14350
  {
13276
- locationId: import_zod51.z.string().optional().describe("Defaults to the active location.")
14351
+ locationId: import_zod52.z.string().optional().describe("Defaults to the active location.")
13277
14352
  },
13278
14353
  async ({ locationId: locationId2 }) => {
13279
14354
  const loc = client.resolveLocationId(locationId2);
@@ -13285,10 +14360,10 @@ function registerPhoneTools(server2, client) {
13285
14360
  }
13286
14361
 
13287
14362
  // src/tools/account-health.ts
13288
- var import_zod52 = require("zod");
13289
- var MetaTotalSchema = import_zod52.z.object({ meta: import_zod52.z.object({ total: import_zod52.z.number() }).passthrough() }).passthrough();
13290
- var TotalSchema = import_zod52.z.object({ total: import_zod52.z.number() }).passthrough();
13291
- var NumbersSchema = import_zod52.z.object({ phoneNumbers: import_zod52.z.array(import_zod52.z.unknown()) }).passthrough();
14363
+ var import_zod53 = require("zod");
14364
+ var MetaTotalSchema = import_zod53.z.object({ meta: import_zod53.z.object({ total: import_zod53.z.number() }).passthrough() }).passthrough();
14365
+ var TotalSchema = import_zod53.z.object({ total: import_zod53.z.number() }).passthrough();
14366
+ var NumbersSchema = import_zod53.z.object({ phoneNumbers: import_zod53.z.array(import_zod53.z.unknown()) }).passthrough();
13292
14367
  var OPP_STATUSES = ["open", "won", "lost", "abandoned"];
13293
14368
  async function section(scope, fn) {
13294
14369
  try {
@@ -13303,8 +14378,8 @@ function registerAccountHealthTools(server2, client) {
13303
14378
  "get_account_health_summary",
13304
14379
  "Account-health summary for a location, composed from existing reads (GHL has no reporting API). Returns: total contacts + NEW contacts in the window; total opportunities + counts by status (open/won/lost/abandoned); total conversations; phone-number count. Every metric is explicitly labeled all_time vs window (with start/end) \u2014 windowed and all-time numbers are never conflated. Sections that can't be read return status:'unavailable' (never a misleading 0). Revenue and appointments are intentionally excluded (not reachable / too costly via the public API).",
13305
14380
  {
13306
- locationId: import_zod52.z.string().optional().describe("Defaults to the active location."),
13307
- windowDays: import_zod52.z.number().int().positive().max(365).optional().describe("Lookback window in days for windowed metrics (new contacts). Default 30.")
14381
+ locationId: import_zod53.z.string().optional().describe("Defaults to the active location."),
14382
+ windowDays: import_zod53.z.number().int().positive().max(365).optional().describe("Lookback window in days for windowed metrics (new contacts). Default 30.")
13308
14383
  },
13309
14384
  async ({ locationId: locationId2, windowDays }) => {
13310
14385
  const loc = client.resolveLocationId(locationId2);
@@ -13376,7 +14451,7 @@ function registerAccountHealthTools(server2, client) {
13376
14451
  }
13377
14452
 
13378
14453
  // src/tools/intake-to-build.ts
13379
- var import_zod55 = require("zod");
14454
+ var import_zod56 = require("zod");
13380
14455
 
13381
14456
  // src/intake-to-build/form-template.ts
13382
14457
  init_question_set();
@@ -13660,7 +14735,7 @@ init_question_set();
13660
14735
  init_question_set();
13661
14736
 
13662
14737
  // src/intake-to-build/brief.ts
13663
- var import_zod53 = require("zod");
14738
+ var import_zod54 = require("zod");
13664
14739
  var BRIEF_SCHEMA_VERSION = "0.1";
13665
14740
  var PRESETS = [
13666
14741
  "generic",
@@ -13670,67 +14745,67 @@ var PRESETS = [
13670
14745
  "ecom",
13671
14746
  "agency"
13672
14747
  ];
13673
- var presetSchema = import_zod53.z.enum(PRESETS);
14748
+ var presetSchema = import_zod54.z.enum(PRESETS);
13674
14749
  var BRIEF_SOURCES = ["agency_os", "business_os", "intake_form", "hybrid"];
13675
- var briefSourceSchema = import_zod53.z.enum(BRIEF_SOURCES);
13676
- var pricePointSchema = import_zod53.z.object({
13677
- name: import_zod53.z.string(),
13678
- price: import_zod53.z.string()
14750
+ var briefSourceSchema = import_zod54.z.enum(BRIEF_SOURCES);
14751
+ var pricePointSchema = import_zod54.z.object({
14752
+ name: import_zod54.z.string(),
14753
+ price: import_zod54.z.string()
13679
14754
  });
13680
- var briefSchema = import_zod53.z.object({
13681
- schemaVersion: import_zod53.z.string(),
13682
- briefId: import_zod53.z.string(),
14755
+ var briefSchema = import_zod54.z.object({
14756
+ schemaVersion: import_zod54.z.string(),
14757
+ briefId: import_zod54.z.string(),
13683
14758
  preset: presetSchema,
13684
14759
  briefSource: briefSourceSchema,
13685
14760
  /** Partner-OS deep structures (ICA / offer / brand-DNA), carried verbatim. */
13686
- extended: import_zod53.z.record(import_zod53.z.unknown()).optional(),
13687
- business: import_zod53.z.object({
13688
- name: import_zod53.z.string(),
13689
- type: import_zod53.z.string().optional(),
13690
- website: import_zod53.z.string().optional(),
13691
- location: import_zod53.z.string().optional(),
13692
- timezone: import_zod53.z.string().optional(),
14761
+ extended: import_zod54.z.record(import_zod54.z.unknown()).optional(),
14762
+ business: import_zod54.z.object({
14763
+ name: import_zod54.z.string(),
14764
+ type: import_zod54.z.string().optional(),
14765
+ website: import_zod54.z.string().optional(),
14766
+ location: import_zod54.z.string().optional(),
14767
+ timezone: import_zod54.z.string().optional(),
13693
14768
  // Ratified additions (atlas 2026-06-15). Enum-ish but kept as strings for
13694
14769
  // the same tolerance reason as business.type (don't reject valid briefs).
13695
- teamSize: import_zod53.z.string().optional(),
13696
- monthlyLeadVolume: import_zod53.z.string().optional(),
13697
- hours: import_zod53.z.string().optional()
14770
+ teamSize: import_zod54.z.string().optional(),
14771
+ monthlyLeadVolume: import_zod54.z.string().optional(),
14772
+ hours: import_zod54.z.string().optional()
13698
14773
  }).passthrough(),
13699
- offer: import_zod53.z.object({
13700
- summary: import_zod53.z.string().optional(),
14774
+ offer: import_zod54.z.object({
14775
+ summary: import_zod54.z.string().optional(),
13701
14776
  // Parsed best-effort; tolerate a raw string when parsing was not possible.
13702
- pricePoints: import_zod53.z.union([import_zod53.z.array(pricePointSchema), import_zod53.z.string()]).optional(),
13703
- leadMagnet: import_zod53.z.string().optional(),
13704
- avgDealValue: import_zod53.z.string().optional()
14777
+ pricePoints: import_zod54.z.union([import_zod54.z.array(pricePointSchema), import_zod54.z.string()]).optional(),
14778
+ leadMagnet: import_zod54.z.string().optional(),
14779
+ avgDealValue: import_zod54.z.string().optional()
13705
14780
  }).passthrough().optional(),
13706
- audience: import_zod53.z.object({
13707
- ideal: import_zod53.z.string().optional(),
13708
- painPoints: import_zod53.z.array(import_zod53.z.string()).optional(),
13709
- objections: import_zod53.z.array(import_zod53.z.string()).optional()
14781
+ audience: import_zod54.z.object({
14782
+ ideal: import_zod54.z.string().optional(),
14783
+ painPoints: import_zod54.z.array(import_zod54.z.string()).optional(),
14784
+ objections: import_zod54.z.array(import_zod54.z.string()).optional()
13710
14785
  }).passthrough().optional(),
13711
- goal: import_zod53.z.object({
14786
+ goal: import_zod54.z.object({
13712
14787
  // Kept as string: the form option labels are the canonical values, but
13713
14788
  // the contract sample shortens some (e.g. "high-touch"). See §7 note.
13714
- primary: import_zod53.z.string(),
13715
- salesStages: import_zod53.z.array(import_zod53.z.string()).optional(),
13716
- bookingNeeded: import_zod53.z.boolean().optional(),
13717
- followUpStyle: import_zod53.z.string().optional()
14789
+ primary: import_zod54.z.string(),
14790
+ salesStages: import_zod54.z.array(import_zod54.z.string()).optional(),
14791
+ bookingNeeded: import_zod54.z.boolean().optional(),
14792
+ followUpStyle: import_zod54.z.string().optional()
13718
14793
  }).passthrough(),
13719
- channels: import_zod53.z.object({
13720
- email: import_zod53.z.boolean().optional(),
13721
- sms: import_zod53.z.boolean().optional(),
13722
- a2pStatus: import_zod53.z.string().optional(),
13723
- payment: import_zod53.z.string().optional(),
13724
- calendarConnected: import_zod53.z.boolean().optional(),
13725
- social: import_zod53.z.array(import_zod53.z.string()).optional()
14794
+ channels: import_zod54.z.object({
14795
+ email: import_zod54.z.boolean().optional(),
14796
+ sms: import_zod54.z.boolean().optional(),
14797
+ a2pStatus: import_zod54.z.string().optional(),
14798
+ payment: import_zod54.z.string().optional(),
14799
+ calendarConnected: import_zod54.z.boolean().optional(),
14800
+ social: import_zod54.z.array(import_zod54.z.string()).optional()
13726
14801
  }).passthrough().optional(),
13727
- assets: import_zod53.z.object({
13728
- existingPipeline: import_zod53.z.string().optional(),
13729
- existingWorkflows: import_zod53.z.string().optional(),
13730
- brand: import_zod53.z.string().optional(),
13731
- notes: import_zod53.z.string().optional()
14802
+ assets: import_zod54.z.object({
14803
+ existingPipeline: import_zod54.z.string().optional(),
14804
+ existingWorkflows: import_zod54.z.string().optional(),
14805
+ brand: import_zod54.z.string().optional(),
14806
+ notes: import_zod54.z.string().optional()
13732
14807
  }).passthrough().optional(),
13733
- flags: import_zod53.z.array(import_zod53.z.string()).optional()
14808
+ flags: import_zod54.z.array(import_zod54.z.string()).optional()
13734
14809
  }).strict();
13735
14810
  function validateBrief(input) {
13736
14811
  const parsed = briefSchema.safeParse(input);
@@ -13886,7 +14961,7 @@ function normalizeSubmissionToBrief(opts) {
13886
14961
  }
13887
14962
 
13888
14963
  // src/intake-to-build/plan.ts
13889
- var import_zod54 = require("zod");
14964
+ var import_zod55 = require("zod");
13890
14965
  var REF_NAMESPACES = [
13891
14966
  "pipeline",
13892
14967
  "stage",
@@ -13903,22 +14978,22 @@ var REF_NAMESPACES = [
13903
14978
  "handoff"
13904
14979
  ];
13905
14980
  var REF_RE = new RegExp(`^(${REF_NAMESPACES.join("|")})\\.[a-z0-9]+(_[a-z0-9]+)*$`);
13906
- var refSchema = import_zod54.z.string().regex(REF_RE, "must be a <namespace>.<snake_case_slug> ref (no real GHL IDs)");
14981
+ var refSchema = import_zod55.z.string().regex(REF_RE, "must be a <namespace>.<snake_case_slug> ref (no real GHL IDs)");
13907
14982
  function nsRef(ns) {
13908
- return import_zod54.z.string().regex(new RegExp(`^${ns}\\.[a-z0-9]+(_[a-z0-9]+)*$`), `must be a ${ns}.* ref`);
14983
+ return import_zod55.z.string().regex(new RegExp(`^${ns}\\.[a-z0-9]+(_[a-z0-9]+)*$`), `must be a ${ns}.* ref`);
13909
14984
  }
13910
14985
  function refNamespace(ref) {
13911
14986
  return ref.split(".")[0];
13912
14987
  }
13913
- var stageSchema = import_zod54.z.object({
14988
+ var stageSchema = import_zod55.z.object({
13914
14989
  ref: nsRef("stage"),
13915
- name: import_zod54.z.string(),
13916
- position: import_zod54.z.number().int().nonnegative()
14990
+ name: import_zod55.z.string(),
14991
+ position: import_zod55.z.number().int().nonnegative()
13917
14992
  });
13918
- var pipelineSchema = import_zod54.z.object({
14993
+ var pipelineSchema = import_zod55.z.object({
13919
14994
  ref: nsRef("pipeline"),
13920
- name: import_zod54.z.string(),
13921
- stages: import_zod54.z.array(stageSchema).min(1)
14995
+ name: import_zod55.z.string(),
14996
+ stages: import_zod55.z.array(stageSchema).min(1)
13922
14997
  });
13923
14998
  var GHL_FIELD_DATATYPES = [
13924
14999
  "TEXT",
@@ -13935,21 +15010,21 @@ var GHL_FIELD_DATATYPES = [
13935
15010
  "FILE_UPLOAD",
13936
15011
  "SIGNATURE"
13937
15012
  ];
13938
- var customFieldSchema = import_zod54.z.object({
15013
+ var customFieldSchema = import_zod55.z.object({
13939
15014
  ref: nsRef("field"),
13940
- name: import_zod54.z.string(),
13941
- dataType: import_zod54.z.enum(GHL_FIELD_DATATYPES),
13942
- model: import_zod54.z.enum(["contact", "opportunity"]).optional(),
13943
- options: import_zod54.z.array(import_zod54.z.string()).optional()
15015
+ name: import_zod55.z.string(),
15016
+ dataType: import_zod55.z.enum(GHL_FIELD_DATATYPES),
15017
+ model: import_zod55.z.enum(["contact", "opportunity"]).optional(),
15018
+ options: import_zod55.z.array(import_zod55.z.string()).optional()
13944
15019
  });
13945
- var tagSchema = import_zod54.z.object({
15020
+ var tagSchema = import_zod55.z.object({
13946
15021
  ref: nsRef("tag"),
13947
- name: import_zod54.z.string()
15022
+ name: import_zod55.z.string()
13948
15023
  });
13949
- var customValueSchema = import_zod54.z.object({
15024
+ var customValueSchema = import_zod55.z.object({
13950
15025
  ref: nsRef("cv"),
13951
- name: import_zod54.z.string(),
13952
- value: import_zod54.z.string().optional(),
15026
+ name: import_zod55.z.string(),
15027
+ value: import_zod55.z.string().optional(),
13953
15028
  filledBy: refSchema.optional()
13954
15029
  });
13955
15030
  var CALENDAR_TYPES = [
@@ -13959,89 +15034,89 @@ var CALENDAR_TYPES = [
13959
15034
  "collective",
13960
15035
  "service_booking"
13961
15036
  ];
13962
- var openHoursBlockSchema = import_zod54.z.object({
13963
- daysOfTheWeek: import_zod54.z.array(import_zod54.z.number().int().min(0).max(6)),
13964
- hours: import_zod54.z.array(
13965
- import_zod54.z.object({
13966
- openHour: import_zod54.z.number().int().min(0).max(23),
13967
- openMinute: import_zod54.z.number().int().min(0).max(59),
13968
- closeHour: import_zod54.z.number().int().min(0).max(23),
13969
- closeMinute: import_zod54.z.number().int().min(0).max(59)
15037
+ var openHoursBlockSchema = import_zod55.z.object({
15038
+ daysOfTheWeek: import_zod55.z.array(import_zod55.z.number().int().min(0).max(6)),
15039
+ hours: import_zod55.z.array(
15040
+ import_zod55.z.object({
15041
+ openHour: import_zod55.z.number().int().min(0).max(23),
15042
+ openMinute: import_zod55.z.number().int().min(0).max(59),
15043
+ closeHour: import_zod55.z.number().int().min(0).max(23),
15044
+ closeMinute: import_zod55.z.number().int().min(0).max(59)
13970
15045
  })
13971
15046
  )
13972
15047
  });
13973
- var calendarSchema = import_zod54.z.object({
15048
+ var calendarSchema = import_zod55.z.object({
13974
15049
  ref: nsRef("calendar"),
13975
- name: import_zod54.z.string(),
13976
- calendarType: import_zod54.z.enum(CALENDAR_TYPES),
13977
- openHours: import_zod54.z.array(openHoursBlockSchema).optional(),
13978
- availabilityType: import_zod54.z.number().int().optional(),
13979
- requiresStaff: import_zod54.z.boolean().optional()
15050
+ name: import_zod55.z.string(),
15051
+ calendarType: import_zod55.z.enum(CALENDAR_TYPES),
15052
+ openHours: import_zod55.z.array(openHoursBlockSchema).optional(),
15053
+ availabilityType: import_zod55.z.number().int().optional(),
15054
+ requiresStaff: import_zod55.z.boolean().optional()
13980
15055
  });
13981
- var formFieldSchema = import_zod54.z.discriminatedUnion("type", [
13982
- import_zod54.z.object({
13983
- type: import_zod54.z.literal("standard"),
13984
- key: import_zod54.z.string(),
13985
- required: import_zod54.z.boolean().optional()
15056
+ var formFieldSchema = import_zod55.z.discriminatedUnion("type", [
15057
+ import_zod55.z.object({
15058
+ type: import_zod55.z.literal("standard"),
15059
+ key: import_zod55.z.string(),
15060
+ required: import_zod55.z.boolean().optional()
13986
15061
  }),
13987
- import_zod54.z.object({
13988
- type: import_zod54.z.literal("custom"),
15062
+ import_zod55.z.object({
15063
+ type: import_zod55.z.literal("custom"),
13989
15064
  fieldRef: nsRef("field"),
13990
- required: import_zod54.z.boolean().optional()
15065
+ required: import_zod55.z.boolean().optional()
13991
15066
  })
13992
15067
  ]);
13993
- var formSchema = import_zod54.z.object({
15068
+ var formSchema = import_zod55.z.object({
13994
15069
  ref: nsRef("form"),
13995
- name: import_zod54.z.string(),
13996
- fields: import_zod54.z.array(formFieldSchema)
15070
+ name: import_zod55.z.string(),
15071
+ fields: import_zod55.z.array(formFieldSchema)
13997
15072
  });
13998
- var pageSchema = import_zod54.z.object({
15073
+ var pageSchema = import_zod55.z.object({
13999
15074
  ref: nsRef("page"),
14000
- name: import_zod54.z.string(),
14001
- role: import_zod54.z.string().optional(),
14002
- outline: import_zod54.z.string().optional(),
15075
+ name: import_zod55.z.string(),
15076
+ role: import_zod55.z.string().optional(),
15077
+ outline: import_zod55.z.string().optional(),
14003
15078
  formRef: nsRef("form").optional(),
14004
15079
  calendarRef: nsRef("calendar").optional()
14005
15080
  });
14006
15081
  var FUNNEL_TARGETS = ["ghl", "external"];
14007
15082
  var FUNNEL_HOSTS = ["cloudflare", "vercel"];
14008
- var funnelSchema = import_zod54.z.object({
15083
+ var funnelSchema = import_zod55.z.object({
14009
15084
  ref: nsRef("funnel"),
14010
- name: import_zod54.z.string(),
15085
+ name: import_zod55.z.string(),
14011
15086
  // Where the funnel is built. "ghl" (default) = funnel + named steps in GHL.
14012
15087
  // "external" = the subscriber builds + hosts the site themselves (Cloudflare/
14013
15088
  // Vercel) and wires its form back to this GHL sub-account (POWER-USER path —
14014
15089
  // see blueprint-funnel-targets-spec.md §9). The executor does NOT build or
14015
15090
  // deploy an external funnel; it surfaces the GHL-side wiring info.
14016
- target: import_zod54.z.enum(FUNNEL_TARGETS).optional(),
14017
- host: import_zod54.z.enum(FUNNEL_HOSTS).optional(),
15091
+ target: import_zod55.z.enum(FUNNEL_TARGETS).optional(),
15092
+ host: import_zod55.z.enum(FUNNEL_HOSTS).optional(),
14018
15093
  // external only
14019
- domain: import_zod54.z.string().optional(),
15094
+ domain: import_zod55.z.string().optional(),
14020
15095
  // external only
14021
- pages: import_zod54.z.array(pageSchema)
15096
+ pages: import_zod55.z.array(pageSchema)
14022
15097
  });
14023
- var emailAssetSchema = import_zod54.z.object({
15098
+ var emailAssetSchema = import_zod55.z.object({
14024
15099
  ref: nsRef("email"),
14025
- name: import_zod54.z.string(),
14026
- subject: import_zod54.z.string().optional(),
14027
- bodyOutline: import_zod54.z.string().optional(),
14028
- body: import_zod54.z.string().optional(),
14029
- mergeTags: import_zod54.z.array(import_zod54.z.string()).optional()
15100
+ name: import_zod55.z.string(),
15101
+ subject: import_zod55.z.string().optional(),
15102
+ bodyOutline: import_zod55.z.string().optional(),
15103
+ body: import_zod55.z.string().optional(),
15104
+ mergeTags: import_zod55.z.array(import_zod55.z.string()).optional()
14030
15105
  });
14031
- var smsAssetSchema = import_zod54.z.object({
15106
+ var smsAssetSchema = import_zod55.z.object({
14032
15107
  ref: nsRef("sms"),
14033
- name: import_zod54.z.string(),
14034
- bodyOutline: import_zod54.z.string().optional(),
14035
- body: import_zod54.z.string().optional(),
14036
- mergeTags: import_zod54.z.array(import_zod54.z.string()).optional()
15108
+ name: import_zod55.z.string(),
15109
+ bodyOutline: import_zod55.z.string().optional(),
15110
+ body: import_zod55.z.string().optional(),
15111
+ mergeTags: import_zod55.z.array(import_zod55.z.string()).optional()
14037
15112
  });
14038
- var waitUnit = import_zod54.z.enum(["minutes", "hours", "days"]);
15113
+ var waitUnit = import_zod55.z.enum(["minutes", "hours", "days"]);
14039
15114
  var branchActionOptions = [
14040
- import_zod54.z.object({ type: import_zod54.z.literal("add_contact_tag"), tagRef: nsRef("tag") }),
14041
- import_zod54.z.object({ type: import_zod54.z.literal("remove_contact_tag"), tagRef: nsRef("tag") }),
14042
- import_zod54.z.object({ type: import_zod54.z.literal("send_email"), emailRef: nsRef("email") }),
14043
- import_zod54.z.object({ type: import_zod54.z.literal("send_sms"), smsRef: nsRef("sms") }),
14044
- import_zod54.z.object({ type: import_zod54.z.literal("wait"), value: import_zod54.z.number().positive(), unit: waitUnit }),
15115
+ import_zod55.z.object({ type: import_zod55.z.literal("add_contact_tag"), tagRef: nsRef("tag") }),
15116
+ import_zod55.z.object({ type: import_zod55.z.literal("remove_contact_tag"), tagRef: nsRef("tag") }),
15117
+ import_zod55.z.object({ type: import_zod55.z.literal("send_email"), emailRef: nsRef("email") }),
15118
+ import_zod55.z.object({ type: import_zod55.z.literal("send_sms"), smsRef: nsRef("sms") }),
15119
+ import_zod55.z.object({ type: import_zod55.z.literal("wait"), value: import_zod55.z.number().positive(), unit: waitUnit }),
14045
15120
  // Appointment-relative wait ("wait until N BEFORE the appointment").
14046
15121
  // Only works when the workflow has an appointment in context (i.e. an
14047
15122
  // `appointment` trigger) — enforced by validateBuildPlan. Expands to GHL's
@@ -14050,85 +15125,85 @@ var branchActionOptions = [
14050
15125
  // (GHL stores whole minutes). Only "before" is emitted today — that's the
14051
15126
  // shape we captured + proved; "after" (post-appointment follow-up) is
14052
15127
  // deferred until its shape is captured from a real workflow.
14053
- import_zod54.z.object({
14054
- type: import_zod54.z.literal("wait_appointment"),
14055
- value: import_zod54.z.number().int().positive(),
15128
+ import_zod55.z.object({
15129
+ type: import_zod55.z.literal("wait_appointment"),
15130
+ value: import_zod55.z.number().int().positive(),
14056
15131
  unit: waitUnit
14057
15132
  }),
14058
- import_zod54.z.object({
14059
- type: import_zod54.z.literal("internal_notification"),
14060
- to: import_zod54.z.string(),
14061
- title: import_zod54.z.string(),
14062
- body: import_zod54.z.string()
15133
+ import_zod55.z.object({
15134
+ type: import_zod55.z.literal("internal_notification"),
15135
+ to: import_zod55.z.string(),
15136
+ title: import_zod55.z.string(),
15137
+ body: import_zod55.z.string()
14063
15138
  }),
14064
- import_zod54.z.object({
14065
- type: import_zod54.z.literal("update_contact_field"),
15139
+ import_zod55.z.object({
15140
+ type: import_zod55.z.literal("update_contact_field"),
14066
15141
  fieldRef: nsRef("field"),
14067
- value: import_zod54.z.string()
15142
+ value: import_zod55.z.string()
14068
15143
  }),
14069
- import_zod54.z.object({ type: import_zod54.z.literal("add_notes"), body: import_zod54.z.string() }),
14070
- import_zod54.z.object({
14071
- type: import_zod54.z.literal("task_notification"),
14072
- title: import_zod54.z.string(),
14073
- body: import_zod54.z.string().optional(),
14074
- dueDate: import_zod54.z.string().optional(),
14075
- assignedTo: import_zod54.z.string().optional()
15144
+ import_zod55.z.object({ type: import_zod55.z.literal("add_notes"), body: import_zod55.z.string() }),
15145
+ import_zod55.z.object({
15146
+ type: import_zod55.z.literal("task_notification"),
15147
+ title: import_zod55.z.string(),
15148
+ body: import_zod55.z.string().optional(),
15149
+ dueDate: import_zod55.z.string().optional(),
15150
+ assignedTo: import_zod55.z.string().optional()
14076
15151
  }),
14077
- import_zod54.z.object({ type: import_zod54.z.literal("remove_from_workflow"), workflowRef: nsRef("workflow") }),
14078
- import_zod54.z.object({ type: import_zod54.z.literal("add_to_workflow"), workflowRef: nsRef("workflow") }),
14079
- import_zod54.z.object({
14080
- type: import_zod54.z.literal("create_opportunity"),
15152
+ import_zod55.z.object({ type: import_zod55.z.literal("remove_from_workflow"), workflowRef: nsRef("workflow") }),
15153
+ import_zod55.z.object({ type: import_zod55.z.literal("add_to_workflow"), workflowRef: nsRef("workflow") }),
15154
+ import_zod55.z.object({
15155
+ type: import_zod55.z.literal("create_opportunity"),
14081
15156
  pipelineRef: nsRef("pipeline"),
14082
15157
  stageRef: nsRef("stage"),
14083
15158
  // Opportunity name (merge fields allowed). Defaults to the contact's name.
14084
15159
  // Required by GHL's create node; without it the create silently no-ops.
14085
- name: import_zod54.z.string().optional(),
15160
+ name: import_zod55.z.string().optional(),
14086
15161
  // Opportunity monetary value (the deal/sale dollar amount). A string so it
14087
15162
  // can be a literal ("2500") OR a merge field ("{{contact.package_value}}").
14088
15163
  // Optional — omitted → GHL leaves the value unset. Shape captured from Lux
14089
15164
  // Bio "14. Package Sale". Lux models the lifecycle by pipeline STAGE, not GHL
14090
15165
  // won/lost status, so a "won" opp = move to the closing stage WITH this value.
14091
- value: import_zod54.z.string().optional()
15166
+ value: import_zod55.z.string().optional()
14092
15167
  }),
14093
- import_zod54.z.object({
14094
- type: import_zod54.z.literal("update_opportunity"),
15168
+ import_zod55.z.object({
15169
+ type: import_zod55.z.literal("update_opportunity"),
14095
15170
  pipelineRef: nsRef("pipeline"),
14096
15171
  stageRef: nsRef("stage"),
14097
15172
  // Opportunity monetary value (see create_opportunity.value). Optional.
14098
- value: import_zod54.z.string().optional()
15173
+ value: import_zod55.z.string().optional()
14099
15174
  }),
14100
- import_zod54.z.object({
14101
- type: import_zod54.z.literal("goal_event"),
14102
- goalCondition: import_zod54.z.string(),
15175
+ import_zod55.z.object({
15176
+ type: import_zod55.z.literal("goal_event"),
15177
+ goalCondition: import_zod55.z.string(),
14103
15178
  // GHL's GoalAction enum (extracted 2026-05-18): continue | wait | exit.
14104
- action: import_zod54.z.enum(["exit", "continue", "wait"]).optional()
15179
+ action: import_zod55.z.enum(["exit", "continue", "wait"]).optional()
14105
15180
  })
14106
15181
  ];
14107
- var branchActionSchema = import_zod54.z.discriminatedUnion("type", branchActionOptions);
14108
- var findOpportunitySchema = import_zod54.z.object({
14109
- type: import_zod54.z.literal("find_opportunity"),
15182
+ var branchActionSchema = import_zod55.z.discriminatedUnion("type", branchActionOptions);
15183
+ var findOpportunitySchema = import_zod55.z.object({
15184
+ type: import_zod55.z.literal("find_opportunity"),
14110
15185
  pipelineRef: nsRef("pipeline"),
14111
- found: import_zod54.z.array(branchActionSchema).default([]),
14112
- notFound: import_zod54.z.array(branchActionSchema).default([])
15186
+ found: import_zod55.z.array(branchActionSchema).default([]),
15187
+ notFound: import_zod55.z.array(branchActionSchema).default([])
14113
15188
  });
14114
- var actionSchema = import_zod54.z.discriminatedUnion("type", [...branchActionOptions, findOpportunitySchema]);
15189
+ var actionSchema = import_zod55.z.discriminatedUnion("type", [...branchActionOptions, findOpportunitySchema]);
14115
15190
  var APPOINTMENT_STATUSES = ["new", "confirmed", "showed", "noshow", "cancelled", "invalid"];
14116
- var triggerSchema = import_zod54.z.object({
14117
- type: import_zod54.z.string(),
15191
+ var triggerSchema = import_zod55.z.object({
15192
+ type: import_zod55.z.string(),
14118
15193
  formRef: nsRef("form").optional(),
14119
15194
  tagRef: nsRef("tag").optional(),
14120
15195
  calendarRef: nsRef("calendar").optional(),
14121
15196
  pipelineRef: nsRef("pipeline").optional(),
14122
15197
  stageRef: nsRef("stage").optional(),
14123
15198
  // Required for a native `appointment` trigger (the status it fires on).
14124
- appointmentStatus: import_zod54.z.enum(APPOINTMENT_STATUSES).optional()
15199
+ appointmentStatus: import_zod55.z.enum(APPOINTMENT_STATUSES).optional()
14125
15200
  });
14126
- var workflowSchema = import_zod54.z.object({
15201
+ var workflowSchema = import_zod55.z.object({
14127
15202
  ref: nsRef("workflow"),
14128
- name: import_zod54.z.string(),
15203
+ name: import_zod55.z.string(),
14129
15204
  trigger: triggerSchema.optional(),
14130
- stopOnResponse: import_zod54.z.boolean().optional(),
14131
- actions: import_zod54.z.array(actionSchema).max(40)
15205
+ stopOnResponse: import_zod55.z.boolean().optional(),
15206
+ actions: import_zod55.z.array(actionSchema).max(40)
14132
15207
  // house rule: <=40 actions/workflow
14133
15208
  });
14134
15209
  var HANDOFF_OWNER_LEGACY = {
@@ -14136,35 +15211,35 @@ var HANDOFF_OWNER_LEGACY = {
14136
15211
  "JERRY-EXT": "OPERATOR-EXT",
14137
15212
  "SASHA": "TEAM"
14138
15213
  };
14139
- var handoffSchema = import_zod54.z.object({
15214
+ var handoffSchema = import_zod55.z.object({
14140
15215
  ref: nsRef("handoff"),
14141
- owner: import_zod54.z.enum(["OPERATOR-UI", "OPERATOR-EXT", "TEAM", "JERRY-UI", "JERRY-EXT", "SASHA"]).transform((o) => HANDOFF_OWNER_LEGACY[o] ?? o),
14142
- title: import_zod54.z.string(),
14143
- trigger: import_zod54.z.string().optional(),
14144
- instruction: import_zod54.z.string(),
15216
+ owner: import_zod55.z.enum(["OPERATOR-UI", "OPERATOR-EXT", "TEAM", "JERRY-UI", "JERRY-EXT", "SASHA"]).transform((o) => HANDOFF_OWNER_LEGACY[o] ?? o),
15217
+ title: import_zod55.z.string(),
15218
+ trigger: import_zod55.z.string().optional(),
15219
+ instruction: import_zod55.z.string(),
14145
15220
  produces: refSchema.nullable().optional(),
14146
- successCheck: import_zod54.z.string(),
14147
- blocks: import_zod54.z.array(import_zod54.z.string()).optional()
15221
+ successCheck: import_zod55.z.string(),
15222
+ blocks: import_zod55.z.array(import_zod55.z.string()).optional()
14148
15223
  });
14149
- var buildPlanSchema = import_zod54.z.object({
14150
- schemaVersion: import_zod54.z.string(),
14151
- planId: import_zod54.z.string(),
14152
- briefId: import_zod54.z.string(),
14153
- preset: import_zod54.z.string(),
14154
- summary: import_zod54.z.string().optional(),
14155
- pipelines: import_zod54.z.array(pipelineSchema).optional(),
14156
- customFields: import_zod54.z.array(customFieldSchema).optional(),
14157
- tags: import_zod54.z.array(tagSchema).optional(),
14158
- customValues: import_zod54.z.array(customValueSchema).optional(),
14159
- calendars: import_zod54.z.array(calendarSchema).optional(),
14160
- forms: import_zod54.z.array(formSchema).optional(),
14161
- funnels: import_zod54.z.array(funnelSchema).optional(),
14162
- emails: import_zod54.z.array(emailAssetSchema).optional(),
14163
- sms: import_zod54.z.array(smsAssetSchema).optional(),
14164
- workflows: import_zod54.z.array(workflowSchema).optional(),
14165
- handoffs: import_zod54.z.array(handoffSchema).optional(),
14166
- buildOrder: import_zod54.z.array(import_zod54.z.string()).optional(),
14167
- idMap: import_zod54.z.record(import_zod54.z.string()).optional()
15224
+ var buildPlanSchema = import_zod55.z.object({
15225
+ schemaVersion: import_zod55.z.string(),
15226
+ planId: import_zod55.z.string(),
15227
+ briefId: import_zod55.z.string(),
15228
+ preset: import_zod55.z.string(),
15229
+ summary: import_zod55.z.string().optional(),
15230
+ pipelines: import_zod55.z.array(pipelineSchema).optional(),
15231
+ customFields: import_zod55.z.array(customFieldSchema).optional(),
15232
+ tags: import_zod55.z.array(tagSchema).optional(),
15233
+ customValues: import_zod55.z.array(customValueSchema).optional(),
15234
+ calendars: import_zod55.z.array(calendarSchema).optional(),
15235
+ forms: import_zod55.z.array(formSchema).optional(),
15236
+ funnels: import_zod55.z.array(funnelSchema).optional(),
15237
+ emails: import_zod55.z.array(emailAssetSchema).optional(),
15238
+ sms: import_zod55.z.array(smsAssetSchema).optional(),
15239
+ workflows: import_zod55.z.array(workflowSchema).optional(),
15240
+ handoffs: import_zod55.z.array(handoffSchema).optional(),
15241
+ buildOrder: import_zod55.z.array(import_zod55.z.string()).optional(),
15242
+ idMap: import_zod55.z.record(import_zod55.z.string()).optional()
14168
15243
  }).strict();
14169
15244
  function collectDefinedRefs(plan) {
14170
15245
  const refs = /* @__PURE__ */ new Map();
@@ -15183,9 +16258,9 @@ function renderReport(plan, result, ctx) {
15183
16258
  }
15184
16259
  }
15185
16260
  for (const w of result.workflows) {
15186
- const gate = w.gatedBy.length ? ` \u2014 DRAFT, gated by ${w.gatedBy.join(", ")}` : ctx.publishWorkflows ? " \u2014 publish" : " \u2014 DRAFT";
16261
+ const gate2 = w.gatedBy.length ? ` \u2014 DRAFT, gated by ${w.gatedBy.join(", ")}` : ctx.publishWorkflows ? " \u2014 publish" : " \u2014 DRAFT";
15187
16262
  const split = w.splitInto > 1 ? ` (splits into ${w.splitInto} chained workflows, >${MAX_ACTIONS_PER_WORKFLOW} actions)` : "";
15188
- L.push(` [workflow] ${w.name}: ${w.nativeActions.length} actions${split}${gate}`);
16263
+ L.push(` [workflow] ${w.name}: ${w.nativeActions.length} actions${split}${gate2}`);
15189
16264
  }
15190
16265
  L.push("");
15191
16266
  L.push("\u2500\u2500 You must do these by hand (in order) \u2500\u2500");
@@ -15481,7 +16556,7 @@ async function executeBackbone(plan, deps, opts = {}) {
15481
16556
  return halt(form.ref, "form", `could not read custom fields to resolve form refs: ${msg(e)}`);
15482
16557
  }
15483
16558
  }
15484
- const byId = new Map(cfRecords.map((r) => [r.id, r]));
16559
+ const byId2 = new Map(cfRecords.map((r) => [r.id, r]));
15485
16560
  const resolved = [];
15486
16561
  let fieldHalt2;
15487
16562
  for (const ff of form.fields) {
@@ -15494,7 +16569,7 @@ async function executeBackbone(plan, deps, opts = {}) {
15494
16569
  fieldHalt2 = halt(form.ref, "form", `form "${form.name}" references ${ff.fieldRef} but that custom field was not built/resolved \u2014 cannot build the form`);
15495
16570
  break;
15496
16571
  }
15497
- const rec = byId.get(realId);
16572
+ const rec = byId2.get(realId);
15498
16573
  if (!rec) {
15499
16574
  fieldHalt2 = halt(form.ref, "form", `custom field ${ff.fieldRef} (id ${realId}) not found in this account when building form "${form.name}"`);
15500
16575
  break;
@@ -15749,16 +16824,16 @@ function msg(e) {
15749
16824
  }
15750
16825
 
15751
16826
  // src/tools/intake-to-build.ts
15752
- var customFieldItemSchema = import_zod55.z.object({
15753
- id: import_zod55.z.string(),
15754
- name: import_zod55.z.string(),
15755
- fieldKey: import_zod55.z.string(),
15756
- dataType: import_zod55.z.string(),
15757
- model: import_zod55.z.string().optional(),
15758
- parentId: import_zod55.z.string().optional(),
15759
- position: import_zod55.z.number().optional(),
15760
- dateAdded: import_zod55.z.string().optional(),
15761
- picklistOptions: import_zod55.z.array(import_zod55.z.string()).optional()
16827
+ var customFieldItemSchema = import_zod56.z.object({
16828
+ id: import_zod56.z.string(),
16829
+ name: import_zod56.z.string(),
16830
+ fieldKey: import_zod56.z.string(),
16831
+ dataType: import_zod56.z.string(),
16832
+ model: import_zod56.z.string().optional(),
16833
+ parentId: import_zod56.z.string().optional(),
16834
+ position: import_zod56.z.number().optional(),
16835
+ dateAdded: import_zod56.z.string().optional(),
16836
+ picklistOptions: import_zod56.z.array(import_zod56.z.string()).optional()
15762
16837
  }).passthrough();
15763
16838
  function parseCustomFields(raw) {
15764
16839
  const obj = raw && typeof raw === "object" ? raw : {};
@@ -16057,19 +17132,19 @@ ${text2.slice(0, 300)}`);
16057
17132
  // same-named funnel beyond it → duplicate). Dedup by id and stop when a page
16058
17133
  // adds nothing new — robust whether or not the endpoint honors `offset`.
16059
17134
  listFunnels: async () => {
16060
- const byId = /* @__PURE__ */ new Map();
17135
+ const byId2 = /* @__PURE__ */ new Map();
16061
17136
  const pageSize = 100;
16062
17137
  const maxFunnels = 5e3;
16063
17138
  for (let offset = 0; offset < maxFunnels; offset += pageSize) {
16064
17139
  const page = pickFunnels(await funnelApi("GET", `/funnel/list?locationId=${locationId2}&limit=${pageSize}&offset=${offset}&getStats=true`));
16065
17140
  let added = 0;
16066
- for (const f of page) if (!byId.has(f.id)) {
16067
- byId.set(f.id, f);
17141
+ for (const f of page) if (!byId2.has(f.id)) {
17142
+ byId2.set(f.id, f);
16068
17143
  added++;
16069
17144
  }
16070
17145
  if (page.length < pageSize || added === 0) break;
16071
17146
  }
16072
- return [...byId.values()];
17147
+ return [...byId2.values()];
16073
17148
  },
16074
17149
  createFunnel: async (name) => {
16075
17150
  const result = await funnelApi("POST", `/funnel/create?locationId=${locationId2}`, {
@@ -16167,7 +17242,7 @@ function registerIntakeToBuildTools(server2, client, builderClient) {
16167
17242
  "validate_brief",
16168
17243
  "Validate an Intake-to-Build Brief object against the \xA74 schema. Returns {valid, errors}. Use to check a normalized brief before handing it to the plan-generation skill.",
16169
17244
  {
16170
- brief: import_zod55.z.record(import_zod55.z.unknown()).describe("The Brief object to validate.")
17245
+ brief: import_zod56.z.record(import_zod56.z.unknown()).describe("The Brief object to validate.")
16171
17246
  },
16172
17247
  async ({ brief }) => validateBrief(brief)
16173
17248
  );
@@ -16176,7 +17251,7 @@ function registerIntakeToBuildTools(server2, client, builderClient) {
16176
17251
  "validate_build_plan",
16177
17252
  "Validate an Intake-to-Build Build Plan against the \xA75 schema AND check ref-integrity: every symbolic ref (pipeline.*, stage.*, tag.*, ...) must resolve to a defined object of the right type, and refs must be unique. Dead references are reported as errors here, before any build runs \u2014 the structural guard against 'an invalid ID silently kills downstream actions'. Returns {valid, errors, warnings, referencesScanned}.",
16178
17253
  {
16179
- plan: import_zod55.z.record(import_zod55.z.unknown()).describe("The Build Plan object to validate.")
17254
+ plan: import_zod56.z.record(import_zod56.z.unknown()).describe("The Build Plan object to validate.")
16180
17255
  },
16181
17256
  async ({ plan }) => validateBuildPlan(plan)
16182
17257
  );
@@ -16184,12 +17259,12 @@ function registerIntakeToBuildTools(server2, client, builderClient) {
16184
17259
  "apply_build_plan",
16185
17260
  `Take an APPROVED Blueprint \xA75 build plan + the CURRENT confirmed sub-account and build it. mode:"dry_run" (default) writes NOTHING \u2014 it resolves refs, expands each workflow's logical actions to native GHL JSON, runs the NEVER-CLOBBER existing-asset scan, and returns a two-part report. Run it FIRST. mode:"execute" performs LIVE writes for the CRM backbone (pipelines+stages, custom fields, tags, custom values), calendars, AND forms: never clobbers (same-named objects are bound to their existing id, never modified), verifies each create by read-back before resolving its ref, halts on the first failure returning the partial idMap, and is idempotent (re-run = no-op). Staff-requiring calendars (round_robin etc.) auto-build only when you are the sole account user (auto-assigns you as the team member); with 0 or 2+ users they're surfaced as a manual step, not auto-staffed to a guess. Forms build with their standard + custom fields (custom fieldRefs resolve to the real fields created earlier in the run). Funnels: a GHL funnel (target:"ghl", default) builds structurally (funnel + named steps; page content/HTML is a manual step \u2014 plans carry outlines); a funnel with target:"external" is NOT built or deployed here \u2014 the user builds + hosts the site themselves (Cloudflare/Vercel) and wires its form back to this GHL sub-account (surfaced as a manual wiring step). Workflows build as DRAFT with all their logical actions expanded to native GHL JSON (incl. opportunity create/move steps, re-enabled v3.41.0) and chained; a contact_tag trigger is built automatically, other trigger types are surfaced as a manual step; the operator reviews + publishes. Always confirms the active location and validates the plan before any write.`,
16186
17261
  {
16187
- plan: import_zod55.z.record(import_zod55.z.unknown()).describe("The approved \xA75 Build Plan object."),
16188
- mode: import_zod55.z.enum(["dry_run", "execute"]).optional().describe("dry_run (default) = resolve/expand/scan/report, no writes. execute = live writes (not yet enabled)."),
16189
- locationId: import_zod55.z.string().optional().describe("Target sub-account. MUST match the active location; if it differs the tool refuses (confirm/switch first)."),
16190
- metHandoffs: import_zod55.z.array(import_zod55.z.string()).optional().describe('Handoff refs the operator has already satisfied (e.g. ["handoff.a2p"]) \u2014 lifts their gate so dependent workflows are not held DRAFT.'),
16191
- publishWorkflows: import_zod55.z.boolean().optional().describe("If true, ungated workflows would be published instead of left DRAFT. Default false (DRAFT)."),
16192
- onConflict: import_zod55.z.enum(["skip", "abort"]).optional().describe("skip (default) = bind same-named existing objects and continue. abort = report conflicts as a halt.")
17262
+ plan: import_zod56.z.record(import_zod56.z.unknown()).describe("The approved \xA75 Build Plan object."),
17263
+ mode: import_zod56.z.enum(["dry_run", "execute"]).optional().describe("dry_run (default) = resolve/expand/scan/report, no writes. execute = live writes (not yet enabled)."),
17264
+ locationId: import_zod56.z.string().optional().describe("Target sub-account. MUST match the active location; if it differs the tool refuses (confirm/switch first)."),
17265
+ metHandoffs: import_zod56.z.array(import_zod56.z.string()).optional().describe('Handoff refs the operator has already satisfied (e.g. ["handoff.a2p"]) \u2014 lifts their gate so dependent workflows are not held DRAFT.'),
17266
+ publishWorkflows: import_zod56.z.boolean().optional().describe("If true, ungated workflows would be published instead of left DRAFT. Default false (DRAFT)."),
17267
+ onConflict: import_zod56.z.enum(["skip", "abort"]).optional().describe("skip (default) = bind same-named existing objects and continue. abort = report conflicts as a halt.")
16193
17268
  },
16194
17269
  async ({ plan, mode, locationId: locationId2, metHandoffs, publishWorkflows, onConflict }) => {
16195
17270
  try {
@@ -16392,9 +17467,9 @@ function registerIntakeToBuildTools(server2, client, builderClient) {
16392
17467
  "install_intake_form",
16393
17468
  "Install the canonical Intake-to-Build client-intake form into the CURRENT GHL location (whatever get_current_location returns). Account-agnostic, zero hardcoded IDs. Creates any missing intake custom fields (idempotent \u2014 reused on re-run), then builds the form with the proven GHL form-builder field shapes and verifies it. Returns {formId, fieldMap} \u2014 keep fieldMap; normalize_submission_to_brief uses it. Pass dryRun:true to preview what would be created without writing. Pass formId to update an existing intake form in place instead of creating a new one.",
16394
17469
  {
16395
- dryRun: import_zod55.z.boolean().optional().describe("Preview the fields/form that would be created without writing anything."),
16396
- formId: import_zod55.z.string().optional().describe("Update this existing form in place instead of creating a new one."),
16397
- formName: import_zod55.z.string().optional().describe(`Form name. Defaults to "${INTAKE_FORM_NAME}".`)
17470
+ dryRun: import_zod56.z.boolean().optional().describe("Preview the fields/form that would be created without writing anything."),
17471
+ formId: import_zod56.z.string().optional().describe("Update this existing form in place instead of creating a new one."),
17472
+ formName: import_zod56.z.string().optional().describe(`Form name. Defaults to "${INTAKE_FORM_NAME}".`)
16398
17473
  },
16399
17474
  async ({ dryRun, formId, formName }) => {
16400
17475
  try {
@@ -16482,10 +17557,10 @@ function registerIntakeToBuildTools(server2, client, builderClient) {
16482
17557
  "normalize_submission_to_brief",
16483
17558
  'Read an intake form submission and normalize it into a \xA74 Brief (briefSource:"intake_form"). Pass the formId; by default the most recent submission is used (or pass submissionId). The intakeKey->customFieldId map is taken from fieldMap if provided (the install_intake_form output, most robust), otherwise reconstructed from the live form. Returns {brief, validation, submissionId} \u2014 validation flags any missing required fields (e.g. an incomplete submission).',
16484
17559
  {
16485
- formId: import_zod55.z.string().describe("The intake form ID (from install_intake_form)."),
16486
- submissionId: import_zod55.z.string().optional().describe("Specific submission to normalize. Defaults to the most recent."),
16487
- fieldMap: import_zod55.z.record(import_zod55.z.string()).optional().describe("intakeKey -> customFieldId map from install_intake_form. Reconstructed from the form if omitted."),
16488
- preset: import_zod55.z.string().optional().describe("Override the preset. Defaults to one derived from business_type.")
17560
+ formId: import_zod56.z.string().describe("The intake form ID (from install_intake_form)."),
17561
+ submissionId: import_zod56.z.string().optional().describe("Specific submission to normalize. Defaults to the most recent."),
17562
+ fieldMap: import_zod56.z.record(import_zod56.z.string()).optional().describe("intakeKey -> customFieldId map from install_intake_form. Reconstructed from the form if omitted."),
17563
+ preset: import_zod56.z.string().optional().describe("Override the preset. Defaults to one derived from business_type.")
16489
17564
  },
16490
17565
  async ({ formId, submissionId, fieldMap, preset }) => {
16491
17566
  try {
@@ -16514,7 +17589,7 @@ function registerIntakeToBuildTools(server2, client, builderClient) {
16514
17589
  const formFull = await formApiRequest(bc, "GET", `/${formId}?locationId=${locationId2}`);
16515
17590
  resolvedMap = buildFieldMapFromFormFields(extractFormFields(formFull));
16516
17591
  }
16517
- const presetSchema2 = import_zod55.z.enum(["generic", "med_spa", "clinic_launch_a2p", "coach", "ecom", "agency"]).optional();
17592
+ const presetSchema2 = import_zod56.z.enum(["generic", "med_spa", "clinic_launch_a2p", "coach", "ecom", "agency"]).optional();
16518
17593
  const presetParsed = presetSchema2.safeParse(preset);
16519
17594
  const brief = normalizeSubmissionToBrief({
16520
17595
  others,
@@ -16580,7 +17655,8 @@ var internalApiTools = [
16580
17655
  [registerReputationTools, "reputation"],
16581
17656
  [registerEmailCampaignTools, "email-campaigns"],
16582
17657
  [registerEmailBuilderInternalTools, "email-builder"],
16583
- [registerMembershipTools, "memberships"]
17658
+ [registerMembershipTools, "memberships"],
17659
+ [registerPageStudioTools, "page-studio"]
16584
17660
  ];
16585
17661
  var VALIDATORS_MODULE = "validators";
16586
17662
  var DIAGNOSTICS_MODULE = "diagnostics";