{
  "version": 3,
  "sources": ["config.js"],
  "sourcesContent": ["// ─────────────────────────────────────────────────────────────────────────\n// Public configuration for the account section.\n//\n// Everything in this file is PUBLIC by design and safe to commit / ship to\n// the browser: the Supabase anon key and the Stripe *publishable* key are\n// meant to be exposed client-side. Secrets (Stripe secret key, Supabase\n// service-role key, webhook signing secret) live ONLY in Cloudflare Pages\n// Function env vars / .dev.vars — never here.\n//\n// Fill these four values in before the account section will work.\n// ─────────────────────────────────────────────────────────────────────────\n\nexport const SUPABASE_URL = \"https://beqgojlmgnzypxrjgnzl.supabase.co\";\nexport const SUPABASE_ANON_KEY = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJlcWdvamxtZ256eXB4cmpnbnpsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODAyNTczOTksImV4cCI6MjA5NTgzMzM5OX0.-EAjXSbxJGLfv62KlH1DQ60j94587HEnMO6fVuxZkwM\";\n\nexport const STRIPE_PUBLISHABLE_KEY = \"pk_test_YOUR_PUBLISHABLE_KEY\";\n\n// Local testing only. When true, the dashboard shows a \"Dev · simulate states\"\n// panel that drives /api/dev-simulate. Derived from the hostname so it is ALWAYS\n// false in production and ALWAYS true on a local dev server — no flag to forget\n// to flip before deploy. The endpoint is independently guarded server-side by the\n// DEV_MODE env var, so the panel does nothing unless BOTH this and that are set.\nexport const DEV_MODE = typeof location !== \"undefined\" &&\n  /^(localhost|127\\.0\\.0\\.1|\\[::1\\]|.*\\.local)$/.test(location.hostname);\n\n/* Preview hosts, and PRIVATE LAN ADDRESSES.\n *\n * Lives here rather than in demo-fixture.js because it is the question asked\n * BEFORE the fixture is wanted: six pages used to import it from that module,\n * which meant every one of them pulled 68 KB of sample data into production just\n * to ask what hostname they were on. config.js is on every page's module graph\n * already (auth.js imports it), so asking here costs nothing and lets the fixture\n * itself load only when a preview actually asks for it.\n *\n * The list used to be pages.dev + localhost, which is every host a preview can\n * run on except the one that matters for a phone. `wrangler pages dev` on a\n * laptop is reachable from a handset on the same wifi at the laptop's LAN\n * address — but that address is 10.x / 192.168.x, so isDemoHost() said no and\n * the reader demanded a session. The result was that mobile work could be\n * measured in a headless viewport and never actually held, which is how a layout\n * ships that is technically correct and horrible in the hand.\n *\n * RFC1918 (10/8, 172.16/12, 192.168/16) and link-local (169.254/16) can never be\n * a public origin, so admitting them widens this to exactly the machines a\n * developer already has on their desk and nothing else. Production is a public\n * domain and still gets no fixture. See scripts/phone-preview.sh. */\nconst PRIVATE_HOST =\n  /^(10\\.|127\\.|169\\.254\\.|192\\.168\\.|172\\.(1[6-9]|2\\d|3[01])\\.)\\d/;\n\nexport const isDemoHost = () =>\n  /\\.pages\\.dev$/.test(location.hostname)\n  || [\"localhost\", \"127.0.0.1\"].includes(location.hostname)\n  || PRIVATE_HOST.test(location.hostname)\n  || location.hostname.endsWith(\".local\");   // Bonjour: <laptop>.local from an iPhone\n\n// ── AI Visibility Crawl (self-serve) — the CURRENT offer ─────────────────────────\n// One AI Visibility Crawl (internally an \"audit\") sold as three one-time SKUs. A pack\n// grants prepaid credits the customer spends whenever, on any URL. `kind` is the\n// checkout contract sent to POST /api/checkout; amounts are display-only and must\n// match the Stripe prices in STRIPE_PRICE_CRAWL_* (server-side). Single moved\n// 850→997 in the 2026-08-16 free-Foundations repricing; pack PRICES deliberately\n// stayed (decision 2026-08-15), so their effective discounts deepened:\n// 3×997=2991 → 2691 (~10% off, 897/crawl); 6×997=5982 → 4782 (~20% off, 797/crawl).\nexport const CRAWL = {\n  single: { kind: \"crawl_single\", credits: 1, amount: 997,  label: \"$997\" },\n  pack3:  { kind: \"crawl_pack3\",  credits: 3, amount: 2691, label: \"$2,691\", was: 2991, off: \"10%\", perCrawl: 897 },\n  pack6:  { kind: \"crawl_pack6\",  credits: 6, amount: 4782, label: \"$4,782\", was: 5982, off: \"20%\", perCrawl: 797 },\n};\nexport const CRAWL_ENABLED = true;\n\n// The Answers — the depth tier on top of the crawl. $299 bundled at order time\n// (single crawl only: 997 + 299 = 1,296), $495 released any time after\n// delivery; the $196 spread IS the bundle incentive. Display-only — the real\n// amounts live server-side in functions/api/checkout.js\n// (ANSWERS_ADDON_CENTS / ANSWERS_RELEASE_CENTS) and must match these.\nexport const ANSWERS = {\n  addon: 299,  addonLabel: \"$299\",\n  later: 495,  laterLabel: \"$495\",\n  bundle: 1296, bundleLabel: \"$1,296\",\n  save: 196,   saveLabel: \"Save $196\",\n};\n\n// Membership is hidden from the self-serve site (kept in code for existing\n// subscribers). Keep false unless MEMBERSHIP_ENABLED is also set server-side.\nexport const MEMBERSHIP_VISIBLE = false;\n\n// Self-serve plans shown on the dashboard. Each `priceId` is a Stripe Price\n// ID (starts with \"price_\"), NOT a product ID. Add as many as you sell\n// self-serve. The dashboard renders one card per entry.\n// NOTE (2026-07): membership/PRICING/PLANS below are the LEGACY model, hidden\n// from the new self-serve site (MEMBERSHIP_VISIBLE=false) but kept for existing\n// subscribers. New pricing lives in CRAWL above.\n// Value-ladder pricing. Foundations + Visibility are bundled as \"the audit\";\n// adding Actions completes the one-time program at $5,000. Paying the full\n// program upfront earns priority (faster) delivery; paying in two steps adds a\n// flat $250 convenience fee ($1,650 + $3,600 = $5,250). Re-audits are the\n// membership: $12,000 the first month, then $7,500/mo. A prior audit credits\n// in full toward that first month, so every member pays the same $12,000 to\n// start no matter the path (see functions/api/_shared.js → auditCreditCents).\n// (Presentation values — Stripe wiring of these amounts is the follow-up step.)\n// How many rounds of changes a customer can run on a foundation by themselves\n// before a strategist steps in. Shown to the customer on every round (\"Change\n// round 2 of 3\") so the end is never a surprise, and to the operator on the\n// requests card. genAI's auto-revision cap (MAX_REVISION_RETRIES) is the\n// machine's own retry budget and is separate from this.\nexport const REVISION_ROUNDS = 3;\n\nexport const PRICING = {\n  upfront: { total: 5000, label: \"$5,000\", note: \"Paid upfront · no fee · priority delivery\" },\n  staged: {\n    audit:   { amount: 1650, label: \"$1,650\", base: 1500, name: \"Foundations + Visibility\" },\n    actions: { amount: 3600, label: \"$3,600\", base: 3500, name: \"Actions\" },\n    total: 5250, splitFee: 250,\n  },\n  subscription: { amount: 7500, label: \"$7,500\", cadence: \"/mo\", name: \"Re-audits (membership)\" },\n  // First month of membership. Higher than the recurring rate; a prior audit's\n  // actual dollars credit against it (computed server-side at checkout), so the\n  // amount actually charged at upgrade is $12,000 minus what they've paid.\n  membershipFirst: { full: 12000, label: \"$12,000\", monthly: 7500 },\n  // Members order ADDITIONAL audits (a new site / product line / series, on top\n  // of the biweekly series their membership already includes) at a flat member\n  // price — Actions included, paid in one charge, no split-payment. Resolved\n  // server-side via STRIPE_PRICE_UPFRONT_MEMBER in functions/api/checkout.js.\n  memberUpfront: { amount: 1500, label: \"$1,500\" },\n  // Recurring per-brand add-on: fold an extra brand into the membership so it\n  // re-runs on cadence and bills monthly (vs a one-off audit). Display only —\n  // the actual recurring charge is the Stripe price in STRIPE_PRICE_ADDON_BRAND,\n  // and the feature stays hidden until that env var is set. Update this label to\n  // match whatever price you wire. (Placeholder amount.)\n  addon: { amount: 1500, label: \"$1,500\", cadence: \"/mo\" },\n};\n\n// Show the \"Add to my plan\" option at order time (members fold a new brand into\n// their subscription instead of a one-off). Flip to true ONLY once the recurring\n// add-on price exists (STRIPE_PRICE_ADDON_BRAND set server-side) — the Membership\n// page's per-brand toggle is gated server-side independently. Default off so the\n// option never promises recurring billing that isn't wired yet.\nexport const ADDON_ENABLED = false;\n\nexport const PLANS = [\n  {\n    name: \"Done-with-you\",\n    priceId: \"price_1Ti5b5DwTB71ddMSlORCP6J4\", // LIVE $7,500/mo (new account). Display/legacy only — the join resolves the price server-side via STRIPE_PRICE_SUBSCRIPTION.\n    price: \"$7,500\",\n    cadence: \"/month\",\n    blurb: \"Monthly audit, 30-day action plan, execution system, training, and Slack support.\",\n    featured: true,\n  },\n  // {\n  //   name: \"Another plan\",\n  //   priceId: \"price_xxx\",\n  //   price: \"$X\",\n  //   cadence: \"/month\",\n  //   blurb: \"…\",\n  // },\n];\n"],
  "mappings": "AAYO,aAAM,aAAe,2CACf,kBAAoB,mNAEpB,uBAAyB,+BAOzB,SAAW,OAAO,SAAa,KAC1C,+CAA+C,KAAK,SAAS,QAAQ,EAuBvE,MAAMA,EACJ,kEAEK,aAAM,WAAa,IACxB,gBAAgB,KAAK,SAAS,QAAQ,GACnC,CAAC,YAAa,WAAW,EAAE,SAAS,SAAS,QAAQ,GACrDA,EAAa,KAAK,SAAS,QAAQ,GACnC,SAAS,SAAS,SAAS,QAAQ,EAU3B,MAAQ,CACnB,OAAQ,CAAE,KAAM,eAAgB,QAAS,EAAG,OAAQ,IAAM,MAAO,MAAO,EACxE,MAAQ,CAAE,KAAM,cAAgB,QAAS,EAAG,OAAQ,KAAM,MAAO,SAAU,IAAK,KAAM,IAAK,MAAO,SAAU,GAAI,EAChH,MAAQ,CAAE,KAAM,cAAgB,QAAS,EAAG,OAAQ,KAAM,MAAO,SAAU,IAAK,KAAM,IAAK,MAAO,SAAU,GAAI,CAClH,EACa,cAAgB,GAOhB,QAAU,CACrB,MAAO,IAAM,WAAY,OACzB,MAAO,IAAM,WAAY,OACzB,OAAQ,KAAM,YAAa,SAC3B,KAAM,IAAO,UAAW,WAC1B,EAIa,mBAAqB,GAqBrB,gBAAkB,EAElB,QAAU,CACrB,QAAS,CAAE,MAAO,IAAM,MAAO,SAAU,KAAM,2CAA4C,EAC3F,OAAQ,CACN,MAAS,CAAE,OAAQ,KAAM,MAAO,SAAU,KAAM,KAAM,KAAM,0BAA2B,EACvF,QAAS,CAAE,OAAQ,KAAM,MAAO,SAAU,KAAM,KAAM,KAAM,SAAU,EACtE,MAAO,KAAM,SAAU,GACzB,EACA,aAAc,CAAE,OAAQ,KAAM,MAAO,SAAU,QAAS,MAAO,KAAM,wBAAyB,EAI9F,gBAAiB,CAAE,KAAM,KAAO,MAAO,UAAW,QAAS,IAAK,EAKhE,cAAe,CAAE,OAAQ,KAAM,MAAO,QAAS,EAM/C,MAAO,CAAE,OAAQ,KAAM,MAAO,SAAU,QAAS,KAAM,CACzD,EAOa,cAAgB,GAEhB,MAAQ,CACnB,CACE,KAAM,gBACN,QAAS,iCACT,MAAO,SACP,QAAS,SACT,MAAO,oFACP,SAAU,EACZ,CAQF",
  "names": ["PRIVATE_HOST"]
}
