/* global window */
// Per-service channel configurations + capacity bar data.
// Layered on top of SERVICES so we don't bloat data.jsx.

// Helper: render a GoGorilla 3D webp icon as a channel mark (used for
// generic categories like email/phone/video/"other"). Brand marks (Meta,
// TikTok, Google, etc.) stay as inline SVG below to preserve recognition.
const ggIcon = (src) => (
  <img src={src} alt="" className="channel-tile__webp" loading="lazy" />
);

// Brand mark image, full-color logo (PNG/WebP/SVG). Used for major platforms
// where users recognize the actual logo (Meta, TikTok, YouTube, etc.).
const brandImg = (src) => (
  <img src={src} alt="" className="channel-tile__brand" loading="lazy" />
);

// Inline SVG channel icons, sized 28×28, monochrome-friendly via fill="currentColor"
const CH_ICONS = {
  // Email envelope, for sales outbound + email channel, uses GG 3D webp
  email: ggIcon('assets/icons/ch-email.webp'),
  // LinkedIn brand mark
  linkedin: brandImg('assets/icons/channels/linkedin.png'),
  // Phone (handset) for cold-call channel, uses GG 3D webp
  phone: ggIcon('assets/icons/ch-phone.webp'),
  // 2026-05-30: ch-phone.webp is actually a message-bubble (SMS) graphic, so it
  // is reused for SMS.
  // 2026-06-05: 'calling' now uses the 3D Phone-icon.webp mark (replaces the
  // temporary inline handset SVG), matching the other channel icons.
  calling: ggIcon('assets/icons/Phone-icon.webp'),
  // Video outreach, uses GG 3D webp
  video: ggIcon('assets/icons/ch-video.webp'),
  // Meta brand mark (full color)
  meta: brandImg('assets/icons/channels/meta.png'),
  // 2026-06-12 (Nicole): official brand marks, uploaded and downscaled.
  facebook: brandImg('assets/icons/channels/facebook-f.png'),
  instagram: brandImg('assets/icons/channels/instagram.webp'),
  // TikTok brand mark (full color)
  tiktok: brandImg('assets/icons/channels/tiktok.webp'),
  // YouTube brand mark (full color)
  youtube: brandImg('assets/icons/channels/youtube.png'),
  'youtube-shorts': brandImg('assets/icons/channels/youtube-shorts.png'),
  // Pinterest brand mark (full color)
  pinterest: brandImg('assets/icons/channels/pinterest.png'),
  // X brand mark (full color)
  x: brandImg('assets/icons/channels/x.png'),
  // Snapchat brand mark (full color)
  snap: brandImg('assets/icons/channels/snap.png'),
  // WhatsApp brand mark (full color)
  whatsapp: brandImg('assets/icons/channels/whatsapp.png'),
  // Reddit brand mark, inline SVG (orange circle with white "r")
  reddit: (
    <svg viewBox="0 0 24 24" aria-hidden="true">
      <circle cx="12" cy="12" r="11" fill="#FF4500"/>
      <path d="M14.5 11c.7-.4 1.6-.4 2.2.2.7.7.7 1.8 0 2.5-.4.4-1 .6-1.5.5.05.3.07.6.07.9 0 2.4-2.5 4.4-5.6 4.4s-5.6-2-5.6-4.4c0-.3.02-.6.07-.9-.5.1-1.1-.1-1.5-.5-.7-.7-.7-1.8 0-2.5.6-.6 1.5-.6 2.2-.2 1-.7 2.4-1.1 3.9-1.2l.7-3.4c0-.1.1-.2.2-.2l2.5.5c.2-.4.6-.7 1.1-.7.7 0 1.2.5 1.2 1.2s-.5 1.2-1.2 1.2c-.7 0-1.2-.5-1.2-1.1l-2.2-.4-.6 3c1.5.06 2.9.5 3.9 1.2zm-7.5 2.5c0 .6.4 1 1 1s1-.4 1-1-.4-1-1-1-1 .4-1 1zm5 0c0 .6.4 1 1 1s1-.4 1-1-.4-1-1-1-1 .4-1 1zm-2.5 3.7c1.1 0 2-.3 2.6-.7.1-.1.1-.2 0-.3-.1-.1-.2-.1-.3 0-.5.4-1.3.6-2.3.6s-1.8-.2-2.3-.6c-.1-.1-.2-.1-.3 0-.1.1-.1.2 0 .3.6.4 1.5.7 2.6.7z" fill="#fff"/>
    </svg>
  ),
  // Quora brand mark
  quora: brandImg('assets/icons/channels/quora.svg'),
  // Google Ads brand mark (full color)
  google: brandImg('assets/icons/channels/googleads.webp'),
  // Microsoft (Bing) Ads brand mark (full color)
  microsoft: brandImg('assets/icons/channels/microsoft.png'),
  // Klaviyo (K-ish)
  klaviyo: (
    <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
      <path d="M12 3 2 8.5l1.4 2.4L12 6l8.6 4.9L22 8.5 12 3zm0 7-7.5 4.3 1.4 2.4L12 13l6.1 3.7 1.4-2.4L12 10z"/>
    </svg>
  ),
  // Mailchimp (M-monkey-ear simplified)
  mailchimp: (
    <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
      <path d="M12 2c2 0 3.7 1 4.4 2.6.7-.4 1.7-.4 2.4.2.8.7 1 1.9.5 2.9.7.6 1.2 1.5 1.2 2.6 0 1.4-.9 2.6-2.2 3 .3.7.5 1.6.5 2.6 0 3.4-2.6 6.1-7.7 6.1-5 0-7.6-2.7-7.6-6.1 0-3.7 3.4-6.6 6.5-8.6.5-.3 1-.6 1.5-.8C11.7 3.6 11.6 2 12 2zm-2.4 12.7c.1.4.5.7 1 .7s.9-.3 1-.7c0-.4-.3-.6-1-.6s-1.1.2-1 .6z"/>
    </svg>
  ),
  // HubSpot (sprocket)
  hubspot: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="13" cy="14" r="3.5"/>
      <path d="M13 10.5V5.5"/>
      <circle cx="17.5" cy="5" r="2"/>
      <path d="M10.5 14h-3.5"/>
      <circle cx="5" cy="14" r="1.5" fill="currentColor"/>
    </svg>
  ),
  // Braze (B-spark, generic)
  braze: (
    <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
      <path d="M5 4l3.5 3.5L5 11l3.5 3.5L5 18l3 3 7-7-3-3 3-3-7-7-3 3z"/>
    </svg>
  ),
  // 2026-05-31: content/deliverable-type marks (SMM, 3D CTV). Inline SVGs as
  // placeholders, currentColor so they pick up the tile colour. Bea to swap in
  // matching 3D webp marks later, same as the temporary 'calling' icon above.
  'static-photos': ggIcon('assets/icons/ch-photos.webp'),
  'short-form-video': ggIcon('assets/icons/ch-short-videos.webp'),
  'long-form-video': ggIcon('assets/icons/ch-video.webp'),
  'ctv': ggIcon('assets/icons/video.webp'),
  // Generic "more channels", uses GG 3D list webp
  more: ggIcon('assets/icons/ch-more.webp'),
};

// Channel option dictionary keyed by id, referenced from per-service configs.
// Each option: id, label, icon, brandColor (used for selected/hover accent)
const CHANNEL_OPTIONS = {
  // Sales/outbound
  'email':     { id: 'email',     label: 'Email Outbound',  icon: CH_ICONS.email,     color: '#D14728', tip: 'Personalised cold email sequences from warmed-up domains, written and managed by our team.' },
  'linkedin':  { id: 'linkedin',  label: 'LinkedIn',        icon: CH_ICONS.linkedin,  color: '#0A66C2', tip: 'Targeted LinkedIn connection requests and follow-ups to your ideal prospects.' },
  'phone':     { id: 'phone',     label: 'Phone',           icon: CH_ICONS.phone,     color: '#16a34a' },
  'sms':       { id: 'sms',       label: 'SMS',             icon: CH_ICONS.phone,     color: '#16a34a', tip: 'Short, compliant text follow-ups to warm prospects, used alongside email and calling to lift reply rates.' },
  'calling':   { id: 'calling',   label: 'Calling',         icon: CH_ICONS.calling,   color: '#16a34a', tip: 'Human cold calling by our in-house SDRs, sequenced with your other channels.' },
  'video':     { id: 'video',     label: 'Video outreach',  icon: CH_ICONS.video,     color: '#8b5cf6' },
  // Social platforms
  'meta':      { id: 'meta',      label: 'Meta',            icon: CH_ICONS.meta,      color: '#1877F2', tip: 'Meta (Facebook and Instagram), used to warm up and reach prospects alongside your direct outreach.' },
  'facebook':  { id: 'facebook',  label: 'Facebook',        icon: CH_ICONS.facebook,  color: '#1877F2' },
  'instagram': { id: 'instagram', label: 'Instagram',       icon: CH_ICONS.instagram, color: '#E1306C' },
  'tiktok':    { id: 'tiktok',    label: 'TikTok',          icon: CH_ICONS.tiktok,    color: '#000000' },
  'youtube':   { id: 'youtube',   label: 'YouTube',         icon: CH_ICONS.youtube,   color: '#FF0000' },
  'pinterest': { id: 'pinterest', label: 'Pinterest',       icon: CH_ICONS.pinterest, color: '#E60023' },
  'x':         { id: 'x',         label: 'X',               icon: CH_ICONS.x,         color: '#000000' },
  'snap':      { id: 'snap',      label: 'Snapchat',        icon: CH_ICONS.snap,      color: '#FFFC00' },
  'whatsapp':  { id: 'whatsapp',  label: 'WhatsApp',        icon: CH_ICONS.whatsapp,  color: '#25D366', tipTitle: 'WhatsApp follow-up', tip: 'We act as your executive assistant over WhatsApp, messaging prospects manually from a real device after your first email or call to keep the conversation going and reduce no-shows. Included as standard on Grow, Scale, and Enterprise.' },
  'reddit':    { id: 'reddit',    label: 'Reddit',          icon: CH_ICONS.reddit,    color: '#FF4500' },
  'quora':     { id: 'quora',     label: 'Quora',           icon: CH_ICONS.quora,     color: '#B92B27' },
  'linkedin-org': { id: 'linkedin-org', label: 'LinkedIn',  icon: CH_ICONS.linkedin,  color: '#0A66C2' },
  // Search / ads
  'google':    { id: 'google',    label: 'Google Ads',      icon: CH_ICONS.google,    color: '#4285F4' },
  'microsoft': { id: 'microsoft', label: 'Microsoft Ads',   icon: CH_ICONS.microsoft, color: '#737373' },
  // Email platforms
  'klaviyo':   { id: 'klaviyo',   label: 'Klaviyo',         icon: CH_ICONS.klaviyo,   color: '#1E1E1E' },
  'mailchimp': { id: 'mailchimp', label: 'Mailchimp',       icon: CH_ICONS.mailchimp, color: '#FFE01B' },
  'hubspot':   { id: 'hubspot',   label: 'HubSpot',         icon: CH_ICONS.hubspot,   color: '#FF7A59' },
  'braze':     { id: 'braze',     label: 'Braze',           icon: CH_ICONS.braze,     color: '#FFA800' },
  // Content & deliverable types (SMM, Content, 3D Animation)
  'static-photos':    { id: 'static-photos',    label: 'Static Photos',      icon: CH_ICONS['static-photos'],    color: '#0B1838' },
  'short-form-video': { id: 'short-form-video', label: 'Short-Form Videos',  icon: CH_ICONS['short-form-video'], color: '#0B1838' },
  'long-form-video':  { id: 'long-form-video',  label: 'Long-Form Videos',   icon: CH_ICONS['long-form-video'],  color: '#0B1838' },
  'youtube-shorts':   { id: 'youtube-shorts',   label: 'YouTube Shorts',     icon: CH_ICONS['youtube-shorts'], color: '#FF0000' },
  'ctv':              { id: 'ctv',              label: 'Connected TV (CTV)', icon: CH_ICONS['ctv'],              color: '#0B1838' },
  // Generic catch-all
  'more':      { id: 'more',      label: 'Other',           icon: CH_ICONS.more,      color: '#0B1838' },
};

// Per-service channel configs.
// `mode: 'included'`, show channels included in this tier (informational, no select)
// `mode: 'select'`  , user selects up to `max[tier]` channels from `options`.
//                      `options` may be either an array (same menu for all tiers) or
//                      an object keyed by tier id { starter:[...], grow:[...], scale:[...] }
//                      so the available menu can grow as tiers level up.
// `extras`, additional UI per service, e.g. paid-ads daily ad-spend input
const SERVICE_CHANNELS = {
  sales: {
    mode: 'select',
    helpInactive: 'Pick from the following channels',
    helpActive: 'Choose your outbound channels',
    options: {
      starter: ['email', 'linkedin'],
      grow:    ['email', 'sms', 'calling', 'whatsapp', 'linkedin', 'instagram'],
      // 2026-06-15 (Alexander): the warm-up channel reads Meta (paid Facebook
      // and Instagram ads that warm and retarget prospects), kept distinct from
      // the separately priced Instagram Outreach add-on (manual DMs, Scale and
      // Enterprise only, never pre-selected).
      scale:   ['email', 'sms', 'calling', 'whatsapp', 'meta', 'google', 'linkedin', 'instagram'],
      // enterprise inherits scale's menu
    },
    max: { starter: 2, grow: 6, scale: 8, enterprise: 8 },
  },
  'paid-ads': {
    mode: 'select',
    helpInactive: 'Pick from the following channels',
    helpActive: 'Choose your ad channel(s)',
    options: {
      starter: ['google', 'microsoft'],
      grow:    ['meta', 'tiktok', 'pinterest', 'linkedin'],
      scale:   ['google', 'meta', 'tiktok', 'pinterest', 'linkedin', 'microsoft'],
      // enterprise inherits scale's menu
    },
    max: { starter: 1, grow: 1, scale: 6, enterprise: 6 },
    // 2026-06-11 (Loom 38 items 2-3): Scale includes 2 channels, Enterprise 3
    // or more. Channels beyond the included count are chargeable on Scale only,
    // priced per commitment month below. Enterprise picks are proposal inputs
    // with no charge whilst pricing is bespoke.
    included: { scale: 2, enterprise: 3 },
    extraPrice: { '3': 495, '6': 395, '12': 295 },
    extras: { dailyAdSpend: true },
  },
  email: {
    mode: 'select',
    helpInactive: 'Channels included at this tier',
    helpActive: 'Channels included at your tier',
    options: {
      starter:    ['email'],
      grow:       ['email'],
      scale:      ['email', 'sms'],
      enterprise: ['email', 'sms'],
    },
    max: { starter: 1, grow: 1, scale: 2, enterprise: 2 },
  },
  smm: {
    mode: 'select',
    helpInactive: 'Content formats included at this tier',
    helpActive: 'Content formats included at your tier',
    options: {
      starter:    ['static-photos', 'short-form-video'],
      grow:       ['static-photos', 'short-form-video'],
      scale:      ['static-photos', 'short-form-video', 'long-form-video'],
      enterprise: ['static-photos', 'short-form-video', 'long-form-video'],
    },
    max: { starter: 2, grow: 2, scale: 3, enterprise: 3 },
  },
  content: {
    mode: 'select',
    helpInactive: 'Pick from the following channels',
    helpActive: 'Choose channels to produce content for',
    options: {
      starter:    ['meta', 'tiktok'],
      grow:       ['meta', 'tiktok', 'youtube-shorts'],
      scale:      ['meta', 'tiktok', 'pinterest', 'youtube-shorts'],
      enterprise: ['meta', 'tiktok', 'pinterest', 'youtube-shorts'],
    },
    max: { starter: 2, grow: 3, scale: 4, enterprise: 4 },
  },
  motion: {
    mode: 'select',
    helpInactive: 'Pick from the following channels',
    helpActive: 'Choose channels to produce motion content for',
    options: {
      starter:    ['meta', 'tiktok', 'pinterest', 'youtube', 'linkedin'],
      grow:       ['meta', 'tiktok', 'pinterest', 'youtube', 'linkedin'],
      scale:      ['meta', 'tiktok', 'pinterest', 'youtube', 'linkedin', 'ctv'],
      enterprise: ['meta', 'tiktok', 'pinterest', 'youtube', 'linkedin', 'ctv'],
    },
    max: { starter: 5, grow: 5, scale: 6, enterprise: 6 },
  },
};

// Capacity per service: status drives the bar fill + status pill + copy.
//   - 'open'    : ~30% fill, calm blue
//   - 'limited' : ~70% fill, blue→violet gradient
//   - 'full'    : 100% fill, amber gradient + waitlist copy
const SERVICE_CAPACITY = {
  sales:       { status: 'open', fill: 0.32, copy: 'We currently have capacity to onboard new clients for this service. We recommend scheduling a call soon to secure your place with our specialist team.' },
  'paid-ads':  { status: 'open', fill: 0.28, copy: 'We currently have capacity to onboard new clients for this service. We recommend scheduling a call soon to secure your place with our specialist team.' },
  email:       { status: 'open', fill: 0.30, copy: 'We currently have capacity to onboard new clients for this service. We recommend scheduling a call soon to secure your place with our specialist team.' },
  smm:         { status: 'open', fill: 0.34, copy: 'We currently have capacity to onboard new clients for this service. We recommend scheduling a call soon to secure your place with our specialist team.' },
  // 2026-06-11 (Loom 38 item 5): Content and 3D Animation are fully
  // waitlisted (every tier in waitlistTiers), so the grey capacity banner
  // carries the waiting-list story. The banner, not the tier pill, is the
  // waitlist signal, Enterprise pills read Bespoke Pricing instead.
  content:     { status: 'full', fill: 1, copy: 'This service is currently at capacity. Adding it reserves your place on the waiting list, and we email you as soon as a spot opens, typically within 2 to 4 weeks. Existing clients are prioritised, so you are likely to be onboarded faster if you already use another of our services.' },
  motion:      { status: 'full', fill: 1, copy: 'This service is currently at capacity. Adding it reserves your place on the waiting list, and we email you as soon as a spot opens, typically within 2 to 4 weeks. Existing clients are prioritised, so you are likely to be onboarded faster if you already use another of our services.' },
  whitelabel:  { status: 'open', fill: 0.22, copy: 'We currently have capacity to onboard new agency partners.' },
  fundraising: { status: 'open', fill: 0.30, copy: 'Open availability. Book a call to begin.' },
  'founders-portal': { status: 'open', fill: 0.18, copy: 'Open availability, instant onboarding.' },
};

const SERVICE_CHANNEL_TIPS = {
  // 2026-05-31: per-service channel tooltips. Same channel id can read
  // differently per service; falls back to CHANNEL_OPTIONS[cid].tip when a
  // service has no override (other services keep the shared tips).
  'sales': {
    // 2026-06-12 (Loom 44 0:32, 1:20): LinkedIn under SDG is a paid add-on at
    // £395 per profile a month, all-in (outreach costs, managed replies, and
    // meetings booked straight into the calendar).
    linkedin: { tipTitle: 'LinkedIn (Add-on)', tip: (<><span className="dis-tip__body" style={{display:'block'}}>Targeted LinkedIn connection requests, messages, and follow-ups to your ideal prospects. We send the messages and manage the responses on your behalf, with meetings booked straight into your calendar. This is an add-on at £395 per profile a month, under £100 a week, which includes outreach costs.</span><span className="dis-tip__body" style={{display:'block',marginTop:'0.55em'}}>LinkedIn allows roughly 100 to 200 connection requests a week per profile, so we recommend one profile for every 400 to 800 prospects you plan to reach each month.</span></>) },
    meta: { tipTitle: 'Meta ad warm-up', tip: (<><span className="dis-tip__body" style={{display:'block'}}>Paid Facebook and Instagram ads that warm up and retarget the prospects in your outbound sequence, so your brand is already familiar when your emails, calls, and messages land.</span><span className="dis-tip__body" style={{display:'block',marginTop:'0.55em'}}>This is a warm-up layer alongside your outreach, not a full paid-ads programme. For fully managed campaigns, our Paid Advertising service handles that.</span></>) },
    google: { tipTitle: 'Google Ads warm-up', tip: (<><span className="dis-tip__body" style={{display:'block'}}>Paid Google Search and display ads that warm up and retarget the prospects in your outbound sequence, so your brand is already familiar when your emails, calls, and messages land.</span><span className="dis-tip__body" style={{display:'block',marginTop:'0.55em'}}>This is a warm-up layer alongside your outreach, not a full paid-ads programme. For fully managed campaigns, our Paid Advertising service handles that.</span></>) },
    // 2026-06-12 (Loom 44 1:26): manual Instagram outreach, one managed
    // profile, an upsell on Scale and Enterprise.
    instagram: { tipTitle: 'Instagram Growth (Add-on)', tip: (<><span className="dis-tip__body" style={{display:'block'}}>A manual, human growth layer on Instagram. We follow and unfollow your prospects and use custom tools to track down decision-makers and find their personal profiles, then we engage with both their personal profiles and their company pages, interacting on their posts and sending considered DMs where appropriate.</span><span className="dis-tip__body" style={{display:'block',marginTop:'0.55em'}}>This is mainly top-of-funnel brand awareness, so that when we call or message them through your other channels they already recognise you rather than it being completely cold.</span></>) },
  },
  'paid-ads': {
    google:    { tipTitle: 'Google Ads',    tip: 'We plan and manage your Google Ads across Search, Performance Max, and retargeting, so you capture demand from people already searching. Management fee only, your ad spend goes directly to Google.' },
    microsoft: { tipTitle: 'Microsoft Ads', tip: 'We run and optimise your Microsoft Ads across Bing and its partner network, often a lower-cost route to high-intent search. Management fee only, your ad spend goes directly to Microsoft.' },
    meta:      { tipTitle: 'Meta Ads',      tip: 'We build and manage paid campaigns across Facebook and Instagram, from prospecting through to retargeting. Management fee only, your ad spend goes directly to Meta.' },
    tiktok:    { tipTitle: 'TikTok Ads',    tip: 'We plan and run paid TikTok campaigns with platform-native creative to reach new audiences. Management fee only, your ad spend goes directly to TikTok.' },
    pinterest: { tipTitle: 'Pinterest Ads', tip: 'We manage paid Pinterest campaigns to reach shoppers and planners with high buying intent. Management fee only, your ad spend goes directly to Pinterest.' },
    linkedin:  { tipTitle: 'LinkedIn Ads',  tip: 'We run paid LinkedIn campaigns, sponsored content and lead generation, to reach decision-makers by role and company. Management fee only, your ad spend goes directly to LinkedIn.' },
  },
  email: {
    email: { tipTitle: 'Email Marketing', tip: 'We run your full email programme, lifecycle flows, broadcasts, segmentation, and deliverability, on the platform you already use. Built and managed by our team.' },
    sms:   { tipTitle: 'SMS Marketing', tip: 'We add SMS broadcasts and automated flows to your opted-in list, run alongside email to lift engagement and revenue.' },
  },
  smm: {
    'static-photos':    { tip: 'Branded static posts and graphics, planned and published across your social channels.' },
    'short-form-video': { tip: 'Short-form video for reels, stories, and TikTok-style feeds, produced and scheduled into your calendar.' },
    'long-form-video':  { tip: 'Longer-form video for richer storytelling, edited and published to your channels.' },
  },
  content: {
    meta:             { tip: 'We produce content made for Facebook and Instagram, feed posts, stories, and reels, shaped to how each format performs.' },
    tiktok:           { tip: 'We produce short-form, platform-native TikTok content built around current formats and trends.' },
    'youtube-shorts': { tip: 'We produce YouTube Shorts, vertical short-form video built for discovery and watch time.' },
    pinterest:        { tip: 'We create Pinterest-ready visuals and pins designed to be saved and discovered.' },
  },
  motion: {
    meta:      { tip: 'We deliver your 3D animation in Facebook and Instagram formats, sized for feed, stories, and reels.' },
    tiktok:    { tip: 'We deliver vertical, platform-native cuts of your 3D animation for TikTok.' },
    pinterest: { tip: 'We deliver your 3D renders and animation as Pinterest-ready visuals.' },
    youtube:   { tip: 'We deliver your 3D animation as full-length films and Shorts for YouTube.' },
    linkedin:  { tip: 'We deliver your 3D animation in formats suited to LinkedIn and a professional audience.' },
    ctv:       { tip: 'We deliver your 3D animation as broadcast-quality spots for Connected TV, streaming and smart-TV placements.' },
  },
};

// 2026-06-19 (Alexander): channels flagged "recommended" per service — a small
// amber star badge on the tile nudges selection. SDG: LinkedIn + Instagram.
const RECOMMENDED_CHANNELS = {
  sales: ['linkedin', 'instagram'],
};
window.RECOMMENDED_CHANNELS = RECOMMENDED_CHANNELS;

window.SERVICE_CHANNELS = SERVICE_CHANNELS;
window.SERVICE_CAPACITY = SERVICE_CAPACITY;
window.CHANNEL_OPTIONS = CHANNEL_OPTIONS;
window.SERVICE_CHANNEL_TIPS = SERVICE_CHANNEL_TIPS;

// Resolve the channel ids for a given service + tier.
// - 'select' mode: returns options[tierId] (if per-tier object) or options (if array)
//                  Enterprise → scale fallback.
// - 'included' mode: returns perTier[tierId]
window.channelsForTier = function channelsForTier(serviceId, tierId) {
  const cfg = SERVICE_CHANNELS[serviceId];
  if (!cfg) return [];
  if (cfg.mode === 'select') {
    const opts = cfg.options;
    if (Array.isArray(opts)) return opts;
    if (opts && typeof opts === 'object') {
      return opts[tierId] || opts.scale || opts.grow || opts.starter || [];
    }
    return [];
  }
  if (cfg.mode === 'included') {
    const pt = cfg.perTier || {};
    return pt[tierId] || pt.starter || [];
  }
  return cfg.options || [];
};
