/* global window */
/* ============================================================================
   Signals fixture — taken from a REAL customer workspace.

   The 27 signals below (ids, types, long descriptions, event counts) are lifted
   from a live tenant selling GTM/revenue tooling. Design against these
   proportions, not idealised ones — per the brief, the distribution is what
   makes or breaks the layout:

     27 signals            9 public · 12 jobs · 6 career
     1,442 event-matches   268 / 200 / 142 / 120 at the top …
     3 signals at ZERO     … 5 trickles under 15 …
     multi-match is normal one event can hit up to 7 signals at once

   THREE FIELDS ARE OURS, NOT PRODUCTION'S — flagged because each is a finding,
   not decoration:

     name    Production humanizes the slug, which yields "Gtm Ai Automation",
             "6sense Intent Adoption", "Series A B Funding". A real display name
             is needed; `id` keeps the slug, because that is what the SDR sees
             attached to an account elsewhere in the product.
     gist    Production HAS NO ONE-LINER. Cards clamp the long description to
             two lines, which is exactly why scanning fails today — every
             description opens with "Detects when the company…". The brief's
             job #1 (grasp the set in 30 seconds) needs a real one-sentence
             gist, so the redesign depends on these being authored.
     related The sibling signals each rule is defined AGAINST. The descriptions
             are full of "…not the first formal RevOps leadership hire" — those
             disambiguations point at real neighbours, and the brief asks
             whether they could be linkable. They can: this is the edge list.

   Events are GENERATED, deterministically (seeded PRNG — identical every load),
   because 1,442 hand-written matches is not a useful artefact. What is faithful
   is their SHAPE: per-signal counts hit the real numbers exactly, one event is
   shared across the signals it matched, titles run from four words to 300+
   characters, and dates spread over 14 months with a per-signal trend.

   Backwards-compatible with the old fixture: SIGNALS still carry
   { id, type, weight, detects, boundaries:{includes,excludes} } and
   SIGNAL_EVENTS is still keyed by signal id, so index.html renders unchanged.
   ========================================================================= */

const FAVICON = (host) => `https://www.google.com/s2/favicons?domain=${host}&sz=128`;

/* Events are dated relative to this, not the wall clock, so the fixture doesn't
   rot and screenshots stay reproducible. */
const TODAY = new Date("2026-07-14T12:00:00Z").getTime();
const DAY = 86400000;

/* ---------------------------------------------------------------------------
   The 27 signals. `detects` is verbatim from the live workspace — the density,
   the sub-clauses, the "not X, not Y, not Z" tails are all real. That prose is
   the reason the current page is unreadable, so it must not be tidied up here.
   ------------------------------------------------------------------------ */
const SIGNALS = [
  {
    id: "earning-call", name: "Earnings Call", type: "news", weight: 2, count: 9, trend: "steady",
    gist: "An exec says on an earnings call that go-to-market is held back by bad tooling — and commits to fixing it.",
    detects: "Detects earnings-call remarks in which executives explicitly say the company's pipeline creation, sales productivity, account prioritization, or revenue operations are constrained by outdated tools, fragmented data, or manual workflows, and state intent to fix it through AI, automation, or GTM systems modernization. Match the acknowledged GTM bottleneck plus a forward-looking commitment to address it on the earnings call, even if no specific rollout, displacement, formal program, financing event, or leadership appointment is yet announced.",
    related: ["gtm-ai-automation", "sales-tech-displacement", "funding-growth-pressure"],
    boundaries: {
      includes: [
        "e.g., a CRO telling analysts that pipeline generation is capped by manual prospecting, with automation coming",
        "e.g., a CFO attributing weak sales productivity to fragmented revenue data across disconnected systems",
        "e.g., an exec naming account prioritization as a bottleneck and committing to an AI-assisted fix",
        "e.g., prepared remarks describing a GTM systems modernization program starting next fiscal year",
        "e.g., an analyst Q&A answer conceding RevOps is manual today and will be rebuilt",
        "e.g., a CEO framing sales efficiency as the year's operating priority, tied explicitly to tooling",
      ],
      excludes: [
        "e.g., generic 'we're investing in AI' remarks with no GTM bottleneck named",
        "e.g., product-side AI announcements — the AI the company SELLS, not the AI it USES internally",
        "e.g., cost-cutting or headcount commentary with no tooling or workflow claim attached",
        "e.g., a bottleneck acknowledged with no forward-looking commitment to address it",
        "e.g., analyst speculation about the company's tooling rather than an executive statement",
        "e.g., an actual rollout being announced, which belongs to gtm-ai-automation",
        "e.g., dissatisfaction with a named vendor under review, which belongs to sales-tech-displacement",
        "e.g., growth pressure framed around a financing event, which belongs to funding-growth-pressure",
        "e.g., remarks from a customer or partner quoted on the call rather than the company itself",
      ],
    },
  },
  {
    id: "revops-leader-hiring", name: "RevOps Leader Hiring", type: "jobs", weight: 3, count: 35, trend: "rising",
    gist: "An open Director+ RevOps leadership role at a company that already has the function.",
    detects: "Detects active job postings for a dedicated Revenue Operations or equivalent leadership role at Director, Senior Director, VP, SVP, or Head level. Focus on roles that own broad revenue process, systems, analytics, and cross-functional GTM operations at an already established or not-explicitly-first function, but not roles explicitly framed as the first formal RevOps leadership hire, a broad first GTM leadership hire, or an SDR/BDR or outbound-function leadership hire.",
    related: ["first-revops-leader-hire", "revops-team-buildout", "outbound-leader-hire", "early-stage-gtm-buildout"],
    boundaries: {
      includes: [
        "e.g., Director of Revenue Operations",
        "e.g., VP, Revenue Operations",
        "e.g., Senior Director, Global Sales Operations",
        "e.g., Head of GTM Operations",
        "e.g., VP Commercial Operations, owning process, systems, and analytics",
        "e.g., SVP Revenue Operations with cross-functional GTM ownership",
        "e.g., Director, Revenue Strategy & Operations, reporting to the CRO",
      ],
      excludes: [
        "e.g., postings that say 'first RevOps leader' or 'build the function from scratch', which belong to first-revops-leader-hire",
        "e.g., Manager, Revenue Operations and other below-Director roles, which belong to revops-team-buildout",
        "e.g., Salesforce Administrator or CPQ Admin roles — systems admin, not revenue leadership",
        "e.g., Director of Sales (quota-carrying) with no operations ownership",
        "e.g., outbound or SDR leadership, which belongs to outbound-leader-hire",
        "e.g., a first company-wide GTM leader, which belongs to early-stage-gtm-buildout",
        "e.g., Marketing Operations leadership with no revenue-process ownership",
        "e.g., a filled appointment announced in the press, which belongs to revops-leader-job-change",
        "e.g., fractional, contract, or advisory RevOps listings",
        "e.g., agencies and consultancies hiring RevOps leaders for their clients",
      ],
    },
  },
  {
    id: "early-stage-gtm-buildout", name: "Early-Stage GTM Buildout", type: "jobs", weight: 3, count: 24, trend: "rising",
    gist: "The company is hiring its first salesperson or GTM leader — go-to-market is being built from nothing.",
    detects: "The company is hiring its first company-wide GTM leader or foundational seller—such as a first sales hire, founding AE, founding SDR, first Head of Sales, or first VP of Sales—indicating it is building a structured go-to-market motion for the first time. Match only company-level first hires, not first hires for a specific function-only ops build, outbound-only build, geography, territory, or regional launch.",
    related: ["founder-led-sales-transition", "first-revops-leader-hire", "outbound-team-buildout"],
    boundaries: {
      includes: [
        "e.g., Founding Account Executive",
        "e.g., First Sales Hire / First Seller",
        "e.g., Head of Sales — the company's first commercial leader",
        "e.g., VP of Sales at a company with a founder-led motion to date",
        "e.g., Founding SDR framed as building the motion, not joining one",
        "e.g., postings that say 'you will be our first commercial hire'",
      ],
      excludes: [
        "e.g., a first RevOps or sales-ops hire, which belongs to founder-led-sales-transition",
        "e.g., the first formal RevOps LEADER, which belongs to first-revops-leader-hire",
        "e.g., 'first AE in EMEA' — a geography-scoped first, not a company-level one",
        "e.g., a first outbound rep at a company that already sells, which belongs to outbound-team-buildout",
        "e.g., an established sales org backfilling a departed VP of Sales",
        "e.g., a second or third AE joining an existing team",
        "e.g., listings for a commercial co-founder",
        "e.g., Sales Engineer or Solutions roles supporting an existing motion",
        "e.g., companies past Series C where 'founding' is used loosely in the copy",
      ],
    },
  },
  {
    id: "outbound-sdr-scaling", name: "Outbound SDR Scaling", type: "jobs", weight: 2, count: 200, trend: "rising",
    gist: "Bulk hiring of SDRs and BDRs — an outbound engine that already exists is being scaled up.",
    detects: "Company is bulk hiring SDRs, BDRs, or outbound sales roles with emphasis on high-volume prospecting, multichannel sequencing, or personalization at scale. This signal indicates an existing or clearly expanding outbound motion being scaled through frontline rep headcount, not first-wave founding hires, region-launch coverage hires, stack-only mentions, or leadership hiring.",
    related: ["outbound-team-buildout", "outbound-leader-hire", "early-stage-gtm-buildout", "intent-platform-in-stack"],
    boundaries: {
      includes: [
        "e.g., Sales Development Representative (multiple openings)",
        "e.g., Business Development Representative, Outbound",
        "e.g., SDR, Enterprise Outbound — cohort start dates",
        "e.g., postings referencing high-volume prospecting quotas or sequencing at scale",
        "e.g., an SDR req open in three or more regions simultaneously",
        "e.g., Outbound Account Executive on an established outbound team",
        "e.g., 'we are doubling the SDR team this year' in the posting body",
      ],
      excludes: [
        "e.g., a company's first outbound rep, which belongs to outbound-team-buildout",
        "e.g., SDR Manager, Director of SDRs, or Head of Outbound, which belong to outbound-leader-hire",
        "e.g., a founding SDR at a pre-sales-team company, which belongs to early-stage-gtm-buildout",
        "e.g., postings that only NAME an outbound tool in the stack, which belong to intent-platform-in-stack",
        "e.g., a single SDR req opened to backfill an obvious departure",
        "e.g., inbound-only SDR roles working marketing-qualified leads",
        "e.g., 'SDR' roles that are really customer support or renewals",
        "e.g., region-launch coverage hires ('first SDR in APAC')",
        "e.g., Account Executive roles with no prospecting responsibility",
        "e.g., agencies and outsourced-SDR vendors hiring on a client's behalf",
      ],
    },
  },
  {
    id: "gtm-revops-outbound-initiative", name: "GTM RevOps Outbound Initiative", type: "jobs", weight: 3, count: 23, trend: "rising",
    gist: "A RevOps hire whose explicit job is to build a new outbound system — not to maintain the existing one.",
    detects: "Company is hiring Revenue Operations, Sales Operations, or GTM systems professionals with explicit responsibility to build, launch, or scale a new sales-owned outbound initiative, motion, or system. These roles signal active investment in structured outbound programs rather than maintenance of existing processes, existing-stack operation, general RevOps execution, or marketing-led ABM orchestration.",
    related: ["revops-team-buildout", "abm-signal-intelligence", "outbound-sdr-scaling", "gtm-engineer-hiring"],
    boundaries: {
      includes: [
        "e.g., Revenue Operations Manager, Outbound Systems — 'build our outbound engine'",
        "e.g., Sales Operations Lead tasked with launching a new outbound motion",
        "e.g., GTM Systems Manager owning sequencing, routing, and data for a new program",
        "e.g., RevOps roles explicitly scoped to 'stand up outbound from zero'",
        "e.g., Sales Ops hires attached to a named pipeline-generation initiative",
      ],
      excludes: [
        "e.g., general RevOps execution and BAU process ownership, which belongs to revops-team-buildout",
        "e.g., marketing-led ABM orchestration, which belongs to abm-signal-intelligence",
        "e.g., frontline SDR headcount, which belongs to outbound-sdr-scaling",
        "e.g., engineer-titled GTM automation roles, which belong to gtm-engineer-hiring",
        "e.g., roles that merely OPERATE an existing outbound stack",
        "e.g., Salesforce or HubSpot admin roles with no initiative attached",
        "e.g., Director+ RevOps leadership, which belongs to revops-leader-hiring",
        "e.g., forecasting, comp, or territory-planning analysts",
        "e.g., 'outbound' used to mean outbound logistics or shipping",
      ],
    },
  },
  {
    id: "abm-signal-intelligence", name: "ABM Signal Intelligence", type: "jobs", weight: 2, count: 75, trend: "steady",
    gist: "Marketing is hiring to build account-based targeting — intent data, buying committees, personalized outreach.",
    detects: "Company is building or scaling account-based marketing capabilities by hiring for ABM, demand generation, or marketing operations roles that emphasize marketing-led account-level targeting, intent data analysis, buying committee engagement, and personalized multi-stakeholder outreach, rather than merely operating an existing intent-tool stack, broad early-stage GTM formation, or building sales-owned outbound systems.",
    related: ["intent-platform-in-stack", "gtm-revops-outbound-initiative", "6sense-intent-adoption", "early-stage-gtm-buildout"],
    boundaries: {
      includes: [
        "e.g., ABM Manager / Account-Based Marketing Lead",
        "e.g., Demand Generation Manager with explicit account-level targeting scope",
        "e.g., Marketing Operations Manager owning intent-data analysis",
        "e.g., roles referencing buying-committee engagement or multi-threaded campaigns",
        "e.g., Field Marketing roles scoped to named-account programs",
        "e.g., 'build our ABM function' language in the posting body",
      ],
      excludes: [
        "e.g., postings that only list an intent tool in the stack, which belong to intent-platform-in-stack",
        "e.g., sales-owned outbound system building, which belongs to gtm-revops-outbound-initiative",
        "e.g., confirmed public use of 6sense specifically, which belongs to 6sense-intent-adoption",
        "e.g., broad first-GTM formation at a pre-sales company, which belongs to early-stage-gtm-buildout",
        "e.g., brand, content, or product-marketing roles with no account targeting",
        "e.g., performance and paid-media roles measured on MQLs",
        "e.g., Marketing Ops roles limited to email deliverability or CRM hygiene",
        "e.g., events and conference marketing coordinators",
        "e.g., agencies hiring ABM strategists to serve their clients",
      ],
    },
  },
  {
    id: "cro-appointment", name: "CRO Appointment", type: "news", weight: 3, count: 32, trend: "steady",
    gist: "The company announces it has hired a new top revenue leader.",
    detects: "Detects current announcements that the company has hired a new top revenue leader. Focus on C-level executives and the single highest commercial leader responsible for company-wide sales, revenue, or go-to-market performance.",
    related: ["external-cro-hire", "revenue-executive-joiner", "gtm-leadership-turnover"],
    boundaries: {
      includes: [
        "e.g., 'Acme names Jordan Vasquez as Chief Revenue Officer'",
        "e.g., Chief Commercial Officer appointments with company-wide revenue ownership",
        "e.g., President of Revenue or EVP Revenue named as the top commercial seat",
        "e.g., a CEO announcing the first CRO in the company's history",
        "e.g., a press release confirming a CRO start date",
      ],
      excludes: [
        "e.g., the same appointment seen as a people-move record, which belongs to external-cro-hire",
        "e.g., VP or SVP appointments below the top seat, which belong to gtm-leadership-turnover",
        "e.g., interim or acting CRO designations",
        "e.g., open CRO searches and executive-recruiter listings",
        "e.g., a CRO departure with no named successor",
        "e.g., board appointments and advisory roles",
        "e.g., regional revenue leaders (CRO, EMEA)",
        "e.g., a CRO at a portfolio company where this account is only the investor",
      ],
    },
  },
  {
    id: "gtm-ai-automation", name: "GTM AI Automation", type: "news", weight: 3, count: 41, trend: "rising",
    gist: "The company is publicly rolling out AI to automate its own sales and marketing workflows.",
    detects: "Detects news that the company is rolling out, expanding, or funding AI-driven automation for internal go-to-market workflows in sales, marketing, revenue operations, SDR/BDR, customer success, or account growth. Match announcements about using AI to automate prospecting, personalization, lead qualification, sequence execution, pipeline reactivation, lead routing, or upsell and renewal outreach, where a rollout, deployment, implementation, buyer/adopter decision, or financed implementation is explicit.",
    related: ["earning-call", "sales-tech-displacement", "6sense-intent-adoption"],
    boundaries: {
      includes: [
        "e.g., a case study describing an AI SDR deployed across the outbound team",
        "e.g., an announcement that AI lead scoring now routes all inbound demand",
        "e.g., a customer story about automating renewal outreach with AI",
        "e.g., a funded program to rebuild pipeline generation around AI agents",
        "e.g., an interview where the CRO describes a live AI prospecting rollout",
        "e.g., a partner announcement naming the company as the adopter",
      ],
      excludes: [
        "e.g., the AI features the company SELLS to its customers — product news, not internal adoption",
        "e.g., an intent to modernize stated on an earnings call, which belongs to earning-call",
        "e.g., a tool under review or being replaced, which belongs to sales-tech-displacement",
        "e.g., confirmed 6sense usage specifically, which belongs to 6sense-intent-adoption",
        "e.g., 'exploring AI' or 'evaluating vendors' with no deployment",
        "e.g., AI hiring plans with no rollout described",
        "e.g., thought-leadership bylines about AI in sales",
        "e.g., AI used in engineering, support, or back-office rather than GTM",
        "e.g., vendor press releases where the company is only a logo on a slide",
      ],
    },
  },
  {
    id: "intent-platform-in-stack", name: "Intent Platform in Stack", type: "jobs", weight: 1, count: 0, trend: "steady",
    gist: "A job posting names an intent or ABM platform as a tool the new hire will actually use.",
    detects: "Job postings that mention intent data platforms, account-based marketing (ABM) tools, or buyer-intent solutions as part of the company's current tech stack — indicating active use, not just familiarity. Focus on roles in marketing, demand generation, revenue operations, or sales that reference these tools as existing infrastructure the candidate will work with, rather than a mandate to build the ABM function itself, architect sales-owned outbound systems, drive bulk frontline outbound hiring, or broad Director+ leadership hiring.",
    related: ["abm-signal-intelligence", "6sense-intent-adoption", "gtm-revops-outbound-initiative", "revops-leader-hiring"],
    boundaries: {
      includes: [
        "e.g., 'You'll work in 6sense, Demandbase, and Salesforce daily'",
        "e.g., a RevOps posting listing Bombora intent feeds as existing infrastructure",
        "e.g., a demand-gen role requiring hands-on ZoomInfo Intent experience",
        "e.g., a sales role whose stack section names an ABM platform",
        "e.g., 'our stack: Outreach, 6sense, Clay, Salesforce'",
      ],
      excludes: [
        "e.g., a mandate to BUILD the ABM function, which belongs to abm-signal-intelligence",
        "e.g., publicly confirmed 6sense adoption in the press, which belongs to 6sense-intent-adoption",
        "e.g., building a new sales-owned outbound system, which belongs to gtm-revops-outbound-initiative",
        "e.g., bulk SDR hiring, which belongs to outbound-sdr-scaling",
        "e.g., Director+ leadership postings, which belong to revops-leader-hiring",
        "e.g., 'familiarity with intent tools is a plus' — a nice-to-have, not the current stack",
        "e.g., a vendor hiring for its own intent product team",
        "e.g., CRM-only stack mentions with no intent layer",
        "e.g., agency postings listing client tooling",
      ],
    },
  },
  {
    id: "revops-team-buildout", name: "RevOps Team Buildout", type: "jobs", weight: 2, count: 120, trend: "steady",
    gist: "Manager-level and below RevOps openings — the function is adding hands, not leaders.",
    detects: "Detects manager-level and below Revenue Operations, Sales Operations, and GTM Operations openings. Focus on operational roles responsible for process, systems, analytics, routing, forecasting support, and cross-functional GTM execution, but not dedicated systems-admin roles, explicit cleanup/repair mandates, first foundational early-stage ops hires, explicit ABM-build roles, or explicit new-outbound build mandates.",
    related: ["revops-leader-hiring", "gtm-engineer-hiring", "gtm-revops-outbound-initiative", "founder-led-sales-transition"],
    boundaries: {
      includes: [
        "e.g., Revenue Operations Manager",
        "e.g., Sales Operations Analyst",
        "e.g., GTM Operations Associate",
        "e.g., Deal Desk Analyst supporting forecasting and routing",
        "e.g., Revenue Operations Specialist, Territory & Quota",
        "e.g., Sales Ops Manager owning pipeline hygiene and reporting",
        "e.g., Manager, GTM Systems, on an existing RevOps team",
      ],
      excludes: [
        "e.g., Director+ RevOps leadership, which belongs to revops-leader-hiring",
        "e.g., engineer-titled automation roles, which belong to gtm-engineer-hiring",
        "e.g., roles scoped to build a new outbound system, which belong to gtm-revops-outbound-initiative",
        "e.g., a company's first ops hire, which belongs to founder-led-sales-transition",
        "e.g., dedicated Salesforce Administrator or CPQ Admin postings",
        "e.g., explicit 'clean up our Salesforce instance' repair mandates",
        "e.g., explicit ABM-build roles, which belong to abm-signal-intelligence",
        "e.g., Finance or FP&A analysts who touch revenue reporting",
        "e.g., Customer Success Operations with no GTM scope",
        "e.g., contract or fractional RevOps listings",
      ],
    },
  },
  {
    id: "gtm-engineer-hiring", name: "GTM Engineer Hiring", type: "jobs", weight: 3, count: 59, trend: "rising",
    gist: "The company is hiring engineers to automate revenue workflows — a GTM engineering function is forming.",
    detects: "Detects active job postings for IC-to-manager-level GTM engineering roles at the company, where the role is responsible for building or automating revenue workflows, outbound systems, GTM data infrastructure, or sales/marketing process orchestration. Match explicit engineer titles such as GTM Engineer, Go-to-Market Engineer, Growth Engineer, or Revenue Engineer, not director+ leadership roles, ops cleanup roles, general systems-admin roles, or customer-facing sales engineering roles.",
    related: ["revops-team-buildout", "gtm-revops-outbound-initiative", "revenue-systems-owner-change"],
    boundaries: {
      includes: [
        "e.g., GTM Engineer",
        "e.g., Go-to-Market Engineer, Outbound Automation",
        "e.g., Growth Engineer owning lifecycle and lead-flow automation",
        "e.g., Revenue Engineer building data pipelines for sales",
        "e.g., Manager, GTM Engineering, at a company standing up the function",
        "e.g., roles requiring Clay, n8n, or scripting against the CRM",
      ],
      excludes: [
        "e.g., Sales Engineer or Solutions Engineer — customer-facing, not internal automation",
        "e.g., Director+ GTM engineering leadership",
        "e.g., generic RevOps analyst work, which belongs to revops-team-buildout",
        "e.g., Salesforce Administrator and systems-admin postings",
        "e.g., 'clean up our data' repair mandates with no build scope",
        "e.g., Growth Engineer roles that are really product or frontend engineering",
        "e.g., Data Engineer roles serving analytics generally, not GTM",
        "e.g., Marketing Engineer roles limited to the website and landing pages",
      ],
    },
  },
  {
    id: "6sense-intent-adoption", name: "6sense Intent Adoption", type: "news", weight: 2, count: 0, trend: "steady",
    gist: "The company publicly confirms it is using 6sense today.",
    detects: "Current news, customer stories, webinars, partner announcements, or interviews that explicitly state the company is using 6sense today for intent data, ABM, account identification, account prioritization, or sales-and-marketing orchestration. Match only confirmed current use by the company, not job requirements, speculative evaluations, displacement discussions, broader AI-rollout stories, or vague stack references.",
    related: ["intent-platform-in-stack", "abm-signal-intelligence", "sales-tech-displacement", "gtm-ai-automation"],
    boundaries: {
      includes: [
        "e.g., a 6sense customer story naming the company",
        "e.g., a joint webinar where the company's marketing lead walks through their 6sense workflow",
        "e.g., an interview stating 'we run account prioritization in 6sense'",
        "e.g., a partner announcement confirming a live 6sense deployment",
        "e.g., a conference talk describing their 6sense-driven ABM program",
      ],
      excludes: [
        "e.g., a job posting listing 6sense in the stack, which belongs to intent-platform-in-stack",
        "e.g., building ABM capability generally, which belongs to abm-signal-intelligence",
        "e.g., evaluating or replacing 6sense, which belongs to sales-tech-displacement",
        "e.g., a broad AI-rollout story with no 6sense specifics, which belongs to gtm-ai-automation",
        "e.g., 'considering 6sense' or vendor-shortlist coverage",
        "e.g., 6sense's own corporate news where the company is not named as a user",
        "e.g., a competitor's takedown blog mentioning the company hypothetically",
        "e.g., historical usage described in the past tense",
      ],
    },
  },
  {
    id: "first-revops-leader-hire", name: "First RevOps Leader Hire", type: "jobs", weight: 3, count: 3, trend: "steady",
    gist: "An open Director+ role to build RevOps from scratch — the company has never had one.",
    detects: "Detects open Director-level and above roles where the company is hiring its first formal Revenue Operations leader. Match titles tied to Revenue Operations, Sales Operations, Commercial Operations, or GTM Operations leadership, especially when the posting explicitly describes building the function from scratch or making the first formal RevOps leadership hire.",
    related: ["revops-leader-hiring", "first-revops-leader", "founder-led-sales-transition", "early-stage-gtm-buildout"],
    boundaries: {
      includes: [
        "e.g., 'Director of Revenue Operations — our first RevOps hire'",
        "e.g., Head of GTM Operations, tasked with building the function from zero",
        "e.g., VP Revenue Operations at a company where RevOps has never existed",
        "e.g., postings that say 'you will define how we run revenue'",
        "e.g., First Commercial Operations Leader",
      ],
      excludes: [
        "e.g., a Director+ RevOps role at an established function, which belongs to revops-leader-hiring",
        "e.g., the same first-leader event seen as a people move, which belongs to first-revops-leader",
        "e.g., a first ops IC below Director, which belongs to founder-led-sales-transition",
        "e.g., a first GTM or sales leader, which belongs to early-stage-gtm-buildout",
        "e.g., a backfill for a departed RevOps leader",
        "e.g., 'first in region' RevOps leadership",
        "e.g., fractional or interim RevOps leadership",
        "e.g., 'greenfield' used loosely at a company that clearly already has RevOps",
      ],
    },
  },
  {
    id: "outbound-team-buildout", name: "Outbound Team Buildout", type: "jobs", weight: 3, count: 142, trend: "rising",
    gist: "First-wave SDR and prospecting hires — an outbound motion is being started, not scaled.",
    detects: "Detects manager-level and below individual-contributor job postings for early outbound and pipeline-generation roles. Focus on first-wave SDR, BDR, explicitly outbound AE, or prospecting roles that indicate the company is building a repeatable, company-wide outbound motion or very early outbound team, not bulk scaling an established engine, broad first-company GTM formation, staffing a specific geography, or hiring outbound leadership.",
    related: ["outbound-sdr-scaling", "outbound-leader-hire", "early-stage-gtm-buildout", "gtm-revops-outbound-initiative"],
    boundaries: {
      includes: [
        "e.g., the company's first SDR, at a business that sold inbound-only until now",
        "e.g., 'Founding BDR — build our outbound playbook'",
        "e.g., Outbound Account Executive on a newly formed team of two",
        "e.g., early prospecting roles where the posting says the motion is being established",
        "e.g., a first cohort of two or three SDRs hired together",
      ],
      excludes: [
        "e.g., bulk cohort hiring on an established engine, which belongs to outbound-sdr-scaling",
        "e.g., SDR and BDR leadership, which belongs to outbound-leader-hire",
        "e.g., a company-wide first commercial hire, which belongs to early-stage-gtm-buildout",
        "e.g., RevOps hires building the outbound SYSTEM, which belong to gtm-revops-outbound-initiative",
        "e.g., 'first SDR in DACH' — a geography hire at a company with outbound elsewhere",
        "e.g., inbound SDRs qualifying marketing leads",
        "e.g., a backfill for a departed SDR",
        "e.g., partner or channel development reps",
        "e.g., outbound roles at staffing agencies selling on behalf of clients",
      ],
    },
  },
  {
    id: "funding-growth-pressure", name: "Funding Growth Pressure", type: "news", weight: 3, count: 12, trend: "fading",
    gist: "A late-stage, flat, or down round that arrives with aggressive growth or efficiency mandates.",
    detects: "Detects that the company has recently announced a later-stage funding round, or a flat/down round, with aggressive growth mandates or efficiency pressure, creating urgency for systematic, scalable GTM execution to meet investor expectations. The financing event must be the primary news and the company must be the capital recipient.",
    related: ["growth-capital-received", "series-a-b-funding", "earning-call"],
    boundaries: {
      includes: [
        "e.g., a Series D raised at a flat valuation with efficiency commitments",
        "e.g., a down round paired with a public 'path to profitability' plan",
        "e.g., late-stage growth equity with named revenue targets attached",
        "e.g., coverage framing the round as investor pressure to scale GTM",
        "e.g., a recapitalization or restructuring financing with growth mandates",
      ],
      excludes: [
        "e.g., a clean Series A or B, which belongs to series-a-b-funding",
        "e.g., growth capital or IPO events with no pressure framing, which belong to growth-capital-received",
        "e.g., pressure described on an earnings call with no financing event, which belongs to earning-call",
        "e.g., rumored or 'in talks to raise' coverage",
        "e.g., the company INVESTING in another business",
        "e.g., debt facilities with no equity headline",
        "e.g., a parent company's raise where this account is a subsidiary mention",
        "e.g., secondary sales and employee tender offers",
      ],
    },
  },
  {
    id: "founder-led-sales-transition", name: "Founder-Led Sales Transition", type: "jobs", weight: 2, count: 13, trend: "steady",
    gist: "The first sales-ops or enablement hires appear — the founder is handing selling off to a real team.",
    detects: "Detects early-stage hiring that signals the prospect is building its first structured commercial infrastructure below the executive level, especially sales operations, revenue operations, sales systems, or sales enablement roles that typically appear as the GTM team becomes repeatable.",
    related: ["early-stage-gtm-buildout", "first-revops-leader-hire", "revops-team-buildout"],
    boundaries: {
      includes: [
        "e.g., the company's first Sales Operations Analyst",
        "e.g., a first Sales Enablement Manager at a 30-person company",
        "e.g., a first Revenue Operations Associate reporting to the founder",
        "e.g., Sales Systems Specialist hired to move deals out of spreadsheets",
        "e.g., postings describing 'putting structure behind founder-led sales'",
      ],
      excludes: [
        "e.g., a first seller or GTM leader, which belongs to early-stage-gtm-buildout",
        "e.g., a first Director+ RevOps leader, which belongs to first-revops-leader-hire",
        "e.g., ops hires at a company with an established RevOps team, which belong to revops-team-buildout",
        "e.g., Chief of Staff roles with incidental sales-ops duties",
        "e.g., Salesforce Admin postings at a mature org",
        "e.g., enablement roles at companies that already have an enablement team",
        "e.g., 'founder-led' used as culture copy at a 500-person company",
      ],
    },
  },
  {
    id: "sales-tech-displacement", name: "Sales Tech Displacement", type: "news", weight: 3, count: 0, trend: "steady",
    gist: "The company is publicly unhappy with a GTM tool and looking at alternatives — but hasn't switched yet.",
    detects: "Detects current news, interviews, case studies, or public comments indicating the prospect is reviewing alternatives to, expressing dissatisfaction with, or considering replacement of specific GTM tools or categories used by revenue teams, without a confirmed migration, sunset, switch, signed transition, settled current-adoption story, or explicit AI deployment announcement.",
    related: ["gtm-ai-automation", "6sense-intent-adoption", "earning-call"],
    boundaries: {
      includes: [
        "e.g., a RevOps lead saying publicly that their intent tool 'isn't earning its seat'",
        "e.g., a podcast where the CRO says they are re-evaluating the sales-engagement stack",
        "e.g., a post describing a bake-off between two GTM vendors",
        "e.g., commentary that a renewal is under review",
        "e.g., a conference talk criticizing a named tool the company currently runs",
      ],
      excludes: [
        "e.g., a completed migration or signed switch — the displacement already happened",
        "e.g., a confirmed live deployment, which belongs to gtm-ai-automation",
        "e.g., a settled current-use story, which belongs to 6sense-intent-adoption",
        "e.g., generic tooling complaints on an earnings call, which belong to earning-call",
        "e.g., a vendor's competitive blog speculating about the company",
        "e.g., an employee's personal opinion unconnected to the company's stack",
        "e.g., dissatisfaction with a non-GTM tool (HR, finance, engineering)",
        "e.g., anonymous review-site comments with no attribution",
      ],
    },
  },
  {
    id: "outbound-leader-hire", name: "Outbound Leader Hire", type: "jobs", weight: 3, count: 68, trend: "rising",
    gist: "An open Director+ role to lead outbound, business development, or pipeline generation.",
    detects: "Detects Director-level and above leadership openings responsible for outbound, business development, pipeline generation, or prospecting. Match roles specifically building or leading the SDR/BDR or outbound engine, not broad first-company GTM leadership, RevOps leadership, frontline rep hiring, or manager-level/team-lead roles.",
    related: ["outbound-sdr-scaling", "outbound-team-buildout", "revops-leader-hiring", "early-stage-gtm-buildout"],
    boundaries: {
      includes: [
        "e.g., Director of Sales Development",
        "e.g., VP, Business Development",
        "e.g., Head of Outbound",
        "e.g., Senior Director, Pipeline Generation",
        "e.g., VP of Global Sales Development, owning the SDR org",
      ],
      excludes: [
        "e.g., SDR Manager or Team Lead — below Director",
        "e.g., frontline SDR reqs, which belong to outbound-sdr-scaling or outbound-team-buildout",
        "e.g., RevOps leadership, which belongs to revops-leader-hiring",
        "e.g., a first company-wide GTM leader, which belongs to early-stage-gtm-buildout",
        "e.g., Director of Partnerships or Channel",
        "e.g., quota-carrying Sales Directors with no outbound org",
        "e.g., 'Head of Growth' roles that are really product growth",
        "e.g., an outbound leader appointment announced in the press rather than an open role",
      ],
    },
  },
  {
    id: "series-a-b-funding", name: "Series A/B Funding", type: "news", weight: 3, count: 7, trend: "steady",
    gist: "A clean Series A or B — capital raised to build out go-to-market.",
    detects: "Detects explicit current announcements that the prospect has raised a Series A or standard Series B financing round, or a seed extension clearly framed as funding to scale sales, marketing, or go-to-market. The event must be about the company receiving capital, not investing capital.",
    related: ["growth-capital-received", "funding-growth-pressure", "early-stage-gtm-buildout"],
    boundaries: {
      includes: [
        "e.g., 'Acme raises $18M Series A led by Benchmark'",
        "e.g., a standard Series B announcement with a named lead investor",
        "e.g., a seed extension explicitly earmarked for GTM hiring",
        "e.g., coverage confirming a closed A/B round with amount and investors",
      ],
      excludes: [
        "e.g., Series C and later, growth equity, or IPOs, which belong to growth-capital-received",
        "e.g., flat or down rounds with efficiency pressure, which belong to funding-growth-pressure",
        "e.g., rumored or 'in talks' coverage with no confirmed close",
        "e.g., the company leading an investment in someone else",
        "e.g., accelerator and pre-seed announcements",
        "e.g., grants, competitions, and non-dilutive awards",
        "e.g., a fund announcing a new vehicle rather than a company raise",
      ],
    },
  },
  {
    id: "growth-capital-received", name: "Growth Capital Received", type: "news", weight: 2, count: 24, trend: "steady",
    gist: "Late-stage capital or an IPO — big money in, minus the A/B and down-round cases.",
    detects: "Detects current announcements that the company has received external growth capital or gone public. Focus on explicit fundraises, equity financings, venture rounds, growth rounds, or IPO-related events involving the company as the recipient, excluding standard Series A and standard Series B rounds and excluding later-stage or down-round efficiency-pressure cases.",
    related: ["series-a-b-funding", "funding-growth-pressure"],
    boundaries: {
      includes: [
        "e.g., a Series C/D/E announcement at a strong valuation",
        "e.g., growth equity or private-equity investment into a private company",
        "e.g., an IPO pricing or direct listing",
        "e.g., a strategic investment from a corporate venture arm",
        "e.g., a pre-IPO crossover round",
      ],
      excludes: [
        "e.g., standard Series A and B rounds, which belong to series-a-b-funding",
        "e.g., flat and down rounds framed by efficiency pressure, which belong to funding-growth-pressure",
        "e.g., the company acquiring or investing in another business",
        "e.g., debt facilities with no equity headline",
        "e.g., rumored raises with no confirmed close",
        "e.g., secondary share sales with no new capital in",
        "e.g., a parent's raise where this account is only a subsidiary mention",
      ],
    },
  },
  {
    id: "gtm-leadership-turnover", name: "GTM Leadership Turnover", type: "news", weight: 2, count: 43, trend: "steady",
    gist: "A new GTM leader below the top seat, with a mandate to modernize how revenue runs.",
    detects: "Detects announcements of new GTM leadership appointments below the top commercial executive when the role has enterprise-wide or multi-business-unit scope to transform, modernize, or scale go-to-market operations. New GTM leaders typically need to demonstrate quick wins and often seek leverage through modern GTM infrastructure and automation.",
    related: ["cro-appointment", "revenue-executive-joiner", "revenue-systems-owner-change"],
    boundaries: {
      includes: [
        "e.g., 'Acme appoints SVP of Global Go-to-Market'",
        "e.g., a new EVP of Sales with a stated transformation mandate",
        "e.g., a VP GTM Strategy hired across multiple business units",
        "e.g., an appointment framed as modernizing the commercial engine",
      ],
      excludes: [
        "e.g., the top revenue seat, which belongs to cro-appointment",
        "e.g., the same move seen as a people-move record, which belongs to revenue-executive-joiner",
        "e.g., systems and CRM ownership appointments, which belong to revenue-systems-owner-change",
        "e.g., regional or single-segment leaders (VP Sales, EMEA)",
        "e.g., interim appointments and acting titles",
        "e.g., departures with no incoming leader named",
        "e.g., marketing-only leadership with no GTM scope",
        "e.g., board and advisory appointments",
      ],
    },
  },
  {
    id: "external-cro-hire", name: "External CRO Hire", type: "job_change", weight: 3, count: 19, trend: "steady",
    gist: "Someone joins from outside into the company's single top revenue seat.",
    detects: "Detects external hires into the prospect's single top, company-wide revenue leadership role. Watch for newly joined executives such as Chief Revenue Officer, Chief Commercial Officer, President of Revenue, or EVP Revenue only when explicitly described as the company's single top, company-wide revenue executive with end-to-end ownership of sales or commercial performance; skip internal promotions, interim roles, open searches, and lower-level or non-top sales leadership.",
    related: ["cro-appointment", "revenue-executive-joiner", "gtm-leadership-turnover"],
    boundaries: {
      includes: [
        "e.g., a CRO joining from another company",
        "e.g., a Chief Commercial Officer hired externally with end-to-end revenue ownership",
        "e.g., a President of Revenue arriving from a competitor",
        "e.g., an EVP Revenue explicitly described as the top commercial seat",
      ],
      excludes: [
        "e.g., an internal promotion into the CRO seat, which belongs to revenue-executive-joiner",
        "e.g., the press announcement of the same hire, which belongs to cro-appointment",
        "e.g., interim and acting CROs",
        "e.g., VP or SVP sales leaders below the top seat, which belong to gtm-leadership-turnover",
        "e.g., regional CROs (CRO, APAC)",
        "e.g., a CRO joining a portfolio company of this account",
        "e.g., an open CRO search with nobody hired",
        "e.g., advisory or fractional CRO engagements",
      ],
    },
  },
  {
    id: "revenue-systems-owner-change", name: "Revenue Systems Owner Change", type: "job_change", weight: 3, count: 36, trend: "rising",
    gist: "A new Director+ owner of the CRM and sales systems — the person who decides which tools stay.",
    detects: "Detects joins or promotions into Director+ roles that own the prospect's sales systems, CRM architecture, or business systems for GTM. Focus on leaders who primarily shape tooling decisions and workflow design rather than Revenue Operations program owners, top RevOps function leaders, inaugural first-ever RevOps leaders, individual contributors, or general IT staff.",
    related: ["revops-owner-joiner", "revops-leader-job-change", "first-revops-leader", "gtm-engineer-hiring"],
    boundaries: {
      includes: [
        "e.g., Director of Business Systems (GTM) joining the company",
        "e.g., VP, Sales Systems & CRM Architecture",
        "e.g., Head of GTM Systems promoted internally",
        "e.g., Director, Revenue Technology, owning the tooling roadmap",
      ],
      excludes: [
        "e.g., the top RevOps function owner, which belongs to revops-owner-joiner",
        "e.g., non-top RevOps program leaders, which belong to revops-leader-job-change",
        "e.g., a first-ever RevOps leader, which belongs to first-revops-leader",
        "e.g., individual contributors and admins (Salesforce Admin, CRM Analyst)",
        "e.g., general IT or corporate-systems leadership with no GTM scope",
        "e.g., an open systems-owner requisition rather than a person moving",
        "e.g., Data Platform leaders serving analytics broadly",
      ],
    },
  },
  {
    id: "revops-leader-job-change", name: "RevOps Leader Job Change", type: "job_change", weight: 2, count: 96, trend: "steady",
    gist: "A Director+ RevOps leader joins or is promoted — influential on tooling, but not the top owner.",
    detects: "Detects people moves where Director+ revenue operations, sales operations, or GTM operations leaders join the prospect or are promoted into a newly senior role, excluding clearly first-ever RevOps leaders, clearly single top company-wide RevOps ownership roles, and clearly systems-platform ownership roles. Watch for non-top program leaders likely to influence tooling, process design, and cross-functional revenue execution.",
    related: ["revops-owner-joiner", "first-revops-leader", "revenue-systems-owner-change", "revops-leader-hiring"],
    boundaries: {
      includes: [
        "e.g., Director of Revenue Operations, Americas, joining from another company",
        "e.g., Senior Director, Sales Operations, promoted internally",
        "e.g., VP GTM Operations for a single business unit",
        "e.g., a RevOps leader moving in with regional or divisional scope",
      ],
      excludes: [
        "e.g., the single top company-wide RevOps owner, which belongs to revops-owner-joiner",
        "e.g., an inaugural first-ever RevOps leader, which belongs to first-revops-leader",
        "e.g., systems and CRM platform ownership, which belongs to revenue-systems-owner-change",
        "e.g., an open Director+ RevOps requisition, which belongs to revops-leader-hiring",
        "e.g., managers and ICs below Director",
        "e.g., a RevOps leader LEAVING the company",
        "e.g., consultants and fractional RevOps leaders",
        "e.g., Marketing Ops leaders with no revenue-process scope",
      ],
    },
  },
  {
    id: "revops-owner-joiner", name: "RevOps Owner Joiner", type: "job_change", weight: 3, count: 62, trend: "rising",
    gist: "Someone takes the single top RevOps seat — the person who owns the function outright.",
    detects: "Detects people movements where a Director+ Revenue Operations, Sales Operations, or GTM Operations leader joins the company or is promoted into the single top, company-wide RevOps ownership role. Watch for buyer-persona roles that own the RevOps function, GTM process, systems, planning, and revenue execution infrastructure, excluding first-ever or inaugural RevOps leaders.",
    related: ["revops-leader-job-change", "first-revops-leader", "revenue-systems-owner-change"],
    boundaries: {
      includes: [
        "e.g., VP, Revenue Operations — the company's top RevOps seat",
        "e.g., Head of Revenue Operations joining with company-wide ownership",
        "e.g., Senior Director, GTM Operations, promoted to own the whole function",
        "e.g., a RevOps leader described as owning planning, systems, and execution end to end",
      ],
      excludes: [
        "e.g., an inaugural first-ever RevOps leader, which belongs to first-revops-leader",
        "e.g., divisional or regional RevOps leaders, which belong to revops-leader-job-change",
        "e.g., systems and CRM platform owners, which belong to revenue-systems-owner-change",
        "e.g., managers and ICs below Director",
        "e.g., an open requisition rather than a person moving",
        "e.g., a top RevOps leader departing",
        "e.g., Finance leaders who inherit revenue reporting",
      ],
    },
  },
  {
    id: "revenue-executive-joiner", name: "Revenue Executive Joiner", type: "job_change", weight: 2, count: 268, trend: "rising",
    gist: "A senior revenue exec joins or is promoted into a company-wide sales leadership seat.",
    detects: "Detects people movements where a senior revenue leader joins the company or is promoted into the prospect's global, cross-company top sales or commercial role, other than a discrete external CRO/CCO/President of Revenue/EVP Revenue hire handled separately. Watch for C-level, President, Head, EVP, SVP, and VP-level buyer personas with enterprise-wide responsibility for sales, revenue, and go-to-market performance; exclude any role limited to a geography, country, theater, region, segment, business unit, or clearly below-top seat.",
    related: ["external-cro-hire", "cro-appointment", "gtm-leadership-turnover"],
    boundaries: {
      includes: [
        "e.g., an internal promotion into Chief Revenue Officer",
        "e.g., SVP, Global Sales, with enterprise-wide ownership",
        "e.g., Head of Revenue joining with company-wide scope",
        "e.g., EVP Commercial promoted from within",
        "e.g., President, Global Field Operations",
      ],
      excludes: [
        "e.g., a discrete external CRO hire, which belongs to external-cro-hire",
        "e.g., the press-release view of the appointment, which belongs to cro-appointment",
        "e.g., transformation-mandate leaders below the top seat, which belong to gtm-leadership-turnover",
        "e.g., VP Sales, EMEA — or any geography-scoped seat",
        "e.g., segment leaders (VP, Mid-Market Sales)",
        "e.g., business-unit revenue leaders at a conglomerate",
        "e.g., executives departing the company",
        "e.g., board members with commercial backgrounds",
      ],
    },
  },
  {
    id: "first-revops-leader", name: "First RevOps Leader", type: "job_change", weight: 3, count: 31, trend: "steady",
    gist: "The company's first-ever RevOps leader starts — GTM infrastructure is being formalized for the first time.",
    detects: "Company hires or promotes its first senior, company-wide Revenue Operations leader at Director level or above, where the role appears to be a new function rather than a backfill. Focus on companies where this is the inaugural RevOps leader hire, signaling that GTM infrastructure is being formalized for the first time, not an existing function changing owners.",
    related: ["first-revops-leader-hire", "revops-owner-joiner", "revops-leader-job-change", "founder-led-sales-transition"],
    boundaries: {
      includes: [
        "e.g., 'joining as the company's first Head of Revenue Operations'",
        "e.g., a Director of RevOps starting where no RevOps function existed",
        "e.g., an internal promotion creating the RevOps function for the first time",
        "e.g., a profile update describing 'building RevOps from zero here'",
      ],
      excludes: [
        "e.g., the open requisition for the same role, which belongs to first-revops-leader-hire",
        "e.g., a top RevOps owner at an existing function, which belongs to revops-owner-joiner",
        "e.g., divisional RevOps leaders, which belong to revops-leader-job-change",
        "e.g., a first ops IC below Director, which belongs to founder-led-sales-transition",
        "e.g., a backfill where the predecessor is identifiable",
        "e.g., 'first RevOps leader in EMEA' — a regional first",
        "e.g., fractional or interim first leaders",
      ],
    },
  },
];

/* ---------------------------------------------------------------------------
   Event generation.

   Deterministic (seeded PRNG), so every reload produces identical data and
   screenshots stay reproducible. What it preserves from the real workspace:

     · per-signal counts hit the real numbers exactly (268, 200, 142, …, 3, 0)
     · events are SHARED across signals — one event can match up to 7, and the
       same event legitimately appears under each (`matched` lists them all)
     · per-match confidence, because an event can hit one rule at high
       confidence and another at medium
     · dates over ~14 months, skewed by each signal's trend, so 30-day counts
       and trend deltas carry information rather than noise
     · titles from four words to 300+ characters, because the real ones do
   ------------------------------------------------------------------------ */

/* mulberry32 — small, fast, seeded, so the fixture never shifts under us. */
function rng(seed) {
  return function () {
    seed |= 0; seed = (seed + 0x6D2B79F5) | 0;
    let t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}
const R = rng(20260714);
const pick = (arr) => arr[Math.floor(R() * arr.length)];
const pickN = (arr, n) => {
  const copy = arr.slice();
  const out = [];
  while (out.length < n && copy.length) out.push(copy.splice(Math.floor(R() * copy.length), 1)[0]);
  return out;
};

const ACCOUNTS = [
  ["Ramp", "ramp.com"], ["Vercel", "vercel.com"], ["Notion", "notion.so"], ["Airtable", "airtable.com"],
  ["Figma", "figma.com"], ["Datadog", "datadoghq.com"], ["MongoDB", "mongodb.com"], ["Stripe", "stripe.com"],
  ["Twilio", "twilio.com"], ["Snowflake", "snowflake.com"], ["Amplitude", "amplitude.com"], ["Segment", "segment.com"],
  ["Retool", "retool.com"], ["Linear", "linear.app"], ["Miro", "miro.com"], ["Asana", "asana.com"],
  ["Gong", "gong.io"], ["Outreach", "outreach.io"], ["Klaviyo", "klaviyo.com"], ["Braze", "braze.com"],
  ["Fivetran", "fivetran.com"], ["dbt Labs", "getdbt.com"], ["Confluent", "confluent.io"], ["Elastic", "elastic.co"],
  ["HashiCorp", "hashicorp.com"], ["GitLab", "gitlab.com"], ["Cloudflare", "cloudflare.com"], ["Okta", "okta.com"],
  ["PagerDuty", "pagerduty.com"], ["Zendesk", "zendesk.com"], ["Intercom", "intercom.com"], ["Calendly", "calendly.com"],
  ["Loom", "loom.com"], ["Webflow", "webflow.com"], ["Contentful", "contentful.com"], ["Algolia", "algolia.com"],
  ["Sentry", "sentry.io"], ["LaunchDarkly", "launchdarkly.com"], ["Temporal", "temporal.io"], ["Supabase", "supabase.com"],
  ["Neon", "neon.tech"], ["Clerk", "clerk.com"], ["WorkOS", "workos.com"], ["Modal", "modal.com"],
  ["Replit", "replit.com"], ["Postman", "postman.com"], ["Grafana Labs", "grafana.com"], ["Chronosphere", "chronosphere.io"],
  ["Census", "getcensus.com"], ["Hightouch", "hightouch.com"], ["Rippling", "rippling.com"], ["Deel", "deel.com"],
  ["Mercury", "mercury.com"], ["Brex", "brex.com"], ["Vanta", "vanta.com"], ["Drata", "drata.com"],
  ["Secureframe", "secureframe.com"], ["Coda", "coda.io"], ["Airbyte", "airbyte.com"], ["Chainguard", "chainguard.dev"],
];

const PUBLICATIONS = [
  "TechCrunch", "Business Insider", "Fortune", "Axios Pro Rata", "The Information", "Forbes",
  "PR Newswire", "Business Wire", "SaaStr", "Sifted", "Bloomberg", "Reuters",
];

const FIRST = ["Priya", "Marcus", "Elena", "Sam", "Jordan", "Ava", "Diego", "Naomi", "Tobias", "Fiona",
  "Rahul", "Grace", "Owen", "Leila", "Mateo", "Hannah", "Ibrahim", "Clara", "Nikhil", "Sofia",
  "Declan", "Yuki", "Amara", "Felix", "Nadia", "Caleb", "Ingrid", "Omar", "Ruth", "Viktor"];
const LAST = ["Raghavan", "Webb", "Duarte", "Oyelaran", "Vasquez", "Lindqvist", "Okafor", "Bianchi", "Nakamura", "Delgado",
  "Mensah", "Kovacs", "Ferreira", "Haddad", "Sorensen", "Iyer", "Novak", "Brennan", "Aluko", "Castillo",
  "Petrov", "Moreau", "Sandoval", "Kirby", "Osei", "Larsen", "Rossi", "Tan", "Whitfield", "Zhu"];

/* Title banks per signal, so an event's headline is plausible for the rule it
   matched. Some entries are deliberately enormous — real titles run past 300
   characters and the layout has to survive them. */
const JOB_TITLES = {
  "revops-leader-hiring": ["Director of Revenue Operations", "VP, Revenue Operations", "Senior Director, Global Sales Operations", "Head of GTM Operations", "VP Commercial Operations", "Director, Revenue Strategy & Operations", "SVP Revenue Operations, Worldwide Field Organization"],
  "early-stage-gtm-buildout": ["Founding Account Executive", "First Sales Hire", "Head of Sales", "VP of Sales (First Commercial Leader)", "Founding SDR", "Founding Enterprise Account Executive — you will be our first commercial hire, responsible for building the entire go-to-market motion from first principles, defining the ideal customer profile, writing the first playbook, closing the first fifty customers, and hiring the team that follows you"],
  "outbound-sdr-scaling": ["Sales Development Representative", "Business Development Representative, Outbound", "SDR, Enterprise Outbound", "BDR — High-Volume Prospecting", "Outbound Account Executive", "Sales Development Representative (Multiple Openings, Q3 Cohort)", "BDR, Multichannel Sequencing", "Senior Business Development Representative, Enterprise Outbound (EMEA & NAMER cohorts) — you will run high-volume multichannel sequences against a named account list of two hundred logos, personalize at scale with our AI tooling, partner with RevOps on routing and attribution, and help us double the size of the sales development organization over the next four quarters"],
  "gtm-revops-outbound-initiative": ["Revenue Operations Manager, Outbound Systems", "Sales Operations Lead — New Outbound Motion", "GTM Systems Manager, Pipeline Generation", "RevOps Manager — Build Our Outbound Engine"],
  "abm-signal-intelligence": ["ABM Manager", "Account-Based Marketing Lead", "Demand Generation Manager, Named Accounts", "Marketing Operations Manager — Intent Data", "Field Marketing Manager, Strategic Accounts"],
  "intent-platform-in-stack": ["Revenue Operations Analyst", "Demand Generation Manager", "Marketing Operations Specialist"],
  "revops-team-buildout": ["Revenue Operations Manager", "Sales Operations Analyst", "GTM Operations Associate", "Deal Desk Analyst", "Revenue Operations Specialist, Territory & Quota", "Sales Ops Manager, Pipeline Hygiene", "Manager, GTM Systems"],
  "gtm-engineer-hiring": ["GTM Engineer", "Go-to-Market Engineer, Outbound Automation", "Growth Engineer", "Revenue Engineer", "Manager, GTM Engineering"],
  "first-revops-leader-hire": ["Director of Revenue Operations — Our First RevOps Hire", "Head of GTM Operations (Build the Function)", "VP Revenue Operations — Greenfield"],
  "outbound-team-buildout": ["Founding BDR — Build Our Outbound Playbook", "First Sales Development Representative", "Outbound Account Executive (New Team)", "Early-Stage BDR, Pipeline Generation", "SDR — First Outbound Hire"],
  "founder-led-sales-transition": ["Sales Operations Analyst (First Ops Hire)", "Sales Enablement Manager", "Revenue Operations Associate", "Sales Systems Specialist"],
  "outbound-leader-hire": ["Director of Sales Development", "VP, Business Development", "Head of Outbound", "Senior Director, Pipeline Generation", "VP of Global Sales Development"],
};

const NEWS_TITLES = {
  "earning-call": [
    "{A} CFO tells analysts pipeline generation is 'capped by manual prospecting'",
    "On its Q2 call, {A} says fragmented revenue data is slowing sales productivity — and commits to a GTM systems overhaul",
    "{A} CEO: 'Our account prioritization is a spreadsheet problem, and we're fixing it with AI'",
    "{A} earnings call flags manual workflows as the constraint on sales efficiency, with an automation program promised for FY27",
    "{A} executives concede on the Q3 earnings call that revenue operations remain largely manual, that pipeline creation is constrained by fragmented data across three disconnected systems, and that the company will spend the coming fiscal year consolidating its go-to-market stack and introducing AI-assisted account prioritization in an effort to lift sales productivity",
  ],
  "cro-appointment": [
    "{A} names {P} as Chief Revenue Officer",
    "{A} appoints {P} Chief Commercial Officer",
    "{A} hires {P} as President of Revenue",
    "{A} taps {P} to lead global revenue as CRO",
    "{A} announces {P} as EVP Revenue, its top commercial seat",
  ],
  "gtm-ai-automation": [
    "{A} rolls out AI-assisted prospecting across its outbound team",
    "How {A} automated renewal outreach with AI agents",
    "{A} deploys AI lead scoring to route all inbound demand",
    "{A} funds a program to rebuild pipeline generation around AI",
    "{A} case study: AI sequencing cut SDR research time by 40% in a full rollout across the outbound org, with the RevOps team describing how account prioritization, personalization, and follow-up cadence were handed to AI agents over two quarters",
  ],
  "6sense-intent-adoption": [
    "{A} on running account prioritization in 6sense",
    "Customer story: how {A} uses 6sense for ABM orchestration",
  ],
  "funding-growth-pressure": [
    "{A} raises Series D at a flat valuation with efficiency commitments",
    "{A} closes down round as investors press for a path to profitability",
    "{A} takes late-stage growth capital tied to aggressive revenue targets",
  ],
  "sales-tech-displacement": [
    "{A} RevOps lead: 'our intent tool isn't earning its seat'",
    "{A} is re-evaluating its sales engagement stack, CRO says",
  ],
  "series-a-b-funding": [
    "{A} raises $18M Series A led by Benchmark",
    "{A} closes $32M Series B to scale go-to-market",
    "{A} extends its seed round to fund a first sales team",
  ],
  "growth-capital-received": [
    "{A} raises $120M Series D",
    "{A} takes growth equity investment at a $1.4B valuation",
    "{A} prices its IPO",
    "{A} closes $85M Series C led by ICONIQ",
  ],
  "gtm-leadership-turnover": [
    "{A} appoints {P} SVP of Global Go-to-Market",
    "{A} hires {P} as EVP Sales with a mandate to modernize the commercial engine",
    "{A} names {P} VP GTM Strategy across all business units",
  ],
};

const MOVE_ROLES = {
  "external-cro-hire": ["Chief Revenue Officer", "Chief Commercial Officer", "President of Revenue", "EVP Revenue"],
  "revenue-systems-owner-change": ["Director of Business Systems (GTM)", "VP, Sales Systems & CRM Architecture", "Head of GTM Systems", "Director, Revenue Technology"],
  "revops-leader-job-change": ["Director of Revenue Operations, Americas", "Senior Director, Sales Operations", "VP GTM Operations", "Director, Revenue Operations (EMEA)"],
  "revops-owner-joiner": ["VP, Revenue Operations", "Head of Revenue Operations", "Senior Director, GTM Operations"],
  "revenue-executive-joiner": ["Chief Revenue Officer", "SVP, Global Sales", "Head of Revenue", "EVP Commercial", "President, Global Field Operations", "Executive Vice President, Global Revenue & Commercial Operations, with enterprise-wide ownership of sales, customer success, partnerships, revenue operations, and go-to-market strategy across all regions and business units"],
  "first-revops-leader": ["Head of Revenue Operations (First)", "Director of Revenue Operations — First RevOps Leader"],
};

/* Trend shapes the date distribution: `rising` pulls matches into recent weeks,
   `fading` pushes them into old ones, `steady` sits flat. This is what makes a
   30-day trend delta mean something instead of being noise. */
const TREND_EXP = { rising: 2.4, steady: 1.0, fading: 0.42 };
const WINDOW_DAYS = 420;

function dateFor(trend) {
  const u = Math.pow(R(), 1 / TREND_EXP[trend]); // 0 = oldest, 1 = today
  const daysBack = Math.round((1 - u) * WINDOW_DAYS);
  return new Date(TODAY - daysBack * DAY).toISOString().slice(0, 10);
}

const conf = () => (R() < 0.62 ? "high" : "medium"); // real data is high|medium only

function titleFor(signal, account, person) {
  if (signal.type === "jobs") {
    return "Job posting: " + pick(JOB_TITLES[signal.id] || ["Revenue Operations Manager"]) + " — " + account;
  }
  if (signal.type === "news") {
    return pick(NEWS_TITLES[signal.id] || ["{A} announces a go-to-market program"])
      .replace(/\{A\}/g, account)
      .replace(/\{P\}/g, person);
  }
  const role = pick(MOVE_ROLES[signal.id] || ["VP, Revenue Operations"]);
  return R() < 0.62
    ? `${person} joins ${account} as ${role}`
    : `${person} is promoted to ${role} at ${account}`;
}

/* Multi-match: most events hit one signal, a long tail hits up to seven. */
const MULTI_WEIGHTS = [[1, 0.55], [2, 0.22], [3, 0.12], [4, 0.05], [5, 0.03], [6, 0.02], [7, 0.01]];
function drawMultiplicity(maxAvailable) {
  const r = R();
  let acc = 0;
  for (const [k, w] of MULTI_WEIGHTS) {
    acc += w;
    if (r <= acc) return Math.min(k, maxAvailable);
  }
  return 1;
}

const SIGNAL_EVENTS = {};
SIGNALS.forEach((s) => { SIGNAL_EVENTS[s.id] = []; });
const EVENTS = [];
let evSeq = 0;

/* One pass per source type: an event is a news article, a job posting, or a
   people move, so it can only ever match signals of its own type. Slots drain
   to exactly the real per-signal counts. */
["news", "jobs", "job_change"].forEach((type) => {
  const pool = SIGNALS.filter((s) => s.type === type);
  const remaining = {};
  pool.forEach((s) => { remaining[s.id] = s.count; });
  const alive = () => pool.filter((s) => remaining[s.id] > 0);

  while (alive().length > 0) {
    const live = alive();
    // Anchor on the signal with the most matches left, so the firehose never
    // ends up needing partners that have already drained to zero.
    live.sort((a, b) => remaining[b.id] - remaining[a.id]);
    const anchor = live[0];

    /* Co-matches are drawn ONLY from the anchor's neighbourhood — its declared
       neighbours, plus theirs. In the real workspace an event hits several
       signals precisely because those signals are defined against each other:
       one SDR posting is legitimately both "scaling an engine" and "building a
       team", which is what their excludes lists spend their length arguing
       about. Drawing partners at random would manufacture nonsense (a CRO
       appointment matching a Series B) and would make an "also matched" chip
       worthless. It also caps multiplicity honestly: the RevOps/outbound family
       is dense enough to produce 6- and 7-way matches, while the small news
       cluster tops out lower — which is the truth about this data. */
    const liveById = {};
    live.forEach((s) => { liveById[s.id] = s; });
    const hood = {};
    anchor.related.forEach((id) => {
      if (liveById[id] && id !== anchor.id) hood[id] = liveById[id];
      const second = SIGNALS.filter((s) => s.id === id)[0];
      if (second) {
        second.related.forEach((id2) => {
          if (liveById[id2] && id2 !== anchor.id) hood[id2] = liveById[id2];
        });
      }
    });
    const candidates = Object.keys(hood).map((id) => hood[id]);

    const k = Math.min(drawMultiplicity(live.length), candidates.length + 1);
    const partners = k > 1 ? pickN(candidates, k - 1) : [];
    const hits = [anchor].concat(partners);

    const acct = pick(ACCOUNTS);
    const person = pick(FIRST) + " " + pick(LAST);
    const ev = {
      id: "e" + (++evSeq),
      account: acct[0],
      host: acct[1],
      source: type,
      date: dateFor(anchor.trend),
      title: titleFor(anchor, acct[0], person),
      publication: type === "news" ? pick(PUBLICATIONS) : null,
      person: type === "job_change" ? person : null,
      matched: hits.map((s) => s.id),
    };
    EVENTS.push(ev);

    hits.forEach((s) => {
      remaining[s.id] -= 1;
      // Per-match confidence: the same event can be a high-confidence match for
      // one rule and a medium one for another.
      SIGNAL_EVENTS[s.id].push(Object.assign({}, ev, { confidence: conf() }));
    });
  }
});

// Most-recent-first, so consumers can slice without re-sorting.
Object.keys(SIGNAL_EVENTS).forEach((id) => {
  SIGNAL_EVENTS[id].sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));
});

/* The brief says design for 17 and check 10 and 30. 30 is the real 27 plus
   three clearly-marked filler signals, since no 30-signal workspace was to
   hand — they carry zero events, which also stress-tests a fuller empty tier. */
const FILLER = [
  { id: "partner-channel-buildout", name: "Partner Channel Buildout", type: "jobs", weight: 2, count: 0, trend: "steady", filler: true, gist: "The company is hiring to stand up a partner or channel sales motion.", detects: "Detects job postings for partner, channel, or alliances roles indicating the company is building an indirect revenue motion alongside its direct sales team.", related: ["early-stage-gtm-buildout"], boundaries: { includes: ["e.g., Director of Channel Sales"], excludes: ["e.g., direct-sales roles, which belong to early-stage-gtm-buildout"] } },
  { id: "pricing-packaging-change", name: "Pricing & Packaging Change", type: "news", weight: 1, count: 0, trend: "steady", filler: true, gist: "The company changes how it prices or packages — usually a GTM motion change underneath.", detects: "Detects announcements of pricing or packaging changes, including new tiers, usage-based models, or enterprise SKUs, which typically accompany a shift in go-to-market motion.", related: ["growth-capital-received"], boundaries: { includes: ["e.g., a shift to usage-based pricing"], excludes: ["e.g., routine discounting or promotions"] } },
  { id: "sales-enablement-leader", name: "Sales Enablement Leader", type: "job_change", weight: 1, count: 0, trend: "steady", filler: true, gist: "A Director+ enablement leader joins — someone who will standardize how reps sell.", detects: "Detects people moves into Director+ sales enablement leadership, where the incoming leader owns rep onboarding, playbooks, and the enablement tech stack.", related: ["revops-leader-job-change"], boundaries: { includes: ["e.g., Head of Sales Enablement joining"], excludes: ["e.g., RevOps leaders, which belong to revops-leader-job-change"] } },
];
FILLER.forEach((f) => { SIGNAL_EVENTS[f.id] = []; });

const META = {
  today: TODAY,
  signalCount: SIGNALS.length,
  eventCount: EVENTS.length,
  matchCount: Object.keys(SIGNAL_EVENTS).reduce((n, k) => n + SIGNAL_EVENTS[k].length, 0),
  /* Sized fixtures: SIZES[10] / [17] / [27] / [30]. */
  SIZES: {
    10: SIGNALS.slice(0, 10),
    17: SIGNALS.slice(0, 17),
    27: SIGNALS,
    30: SIGNALS.concat(FILLER),
  },
};

window.SIG_DATA = { SIGNALS, SIGNAL_EVENTS, EVENTS, FAVICON, META };
