/* global React, window, document */
//
// signed-out-sidebar.jsx — the portal preview rail on the PUBLIC calculator.
// 2026-08-07. Ships DARK behind window.GG_FEATURE_SOS. Preview with ?sos=1.
//
// WHAT THIS IS. On app.gogorilla.com a visitor is never signed in, by Alexander's
// own definition of the host (LOOM 16 at 24:56, "app is just this, pre-login state").
// After they pick a client type, a portal-style rail slides in from the left so they
// can see the shape of the product they would be signing into. Grow is the calculator
// they are already standing on, so it is real. Everything else is a blurred glimpse
// behind a sign-in prompt, which is the difference Alexander draws against Mercor at
// LOOM 16 02:09, where a click "just goes straight to sign in" and he wants a blur
// "giving you like a glimpse of what you can expect".
//
// THE RAILS. Only ONE of the three has a live source of truth.
//   PARTNER is copied item for item from the portal. THE SOURCE OF TRUTH IS
//   lib/account/freelancer-nav.ts IN aonslow/gogorilla-platform, the FREELANCER_NAV array,
//   confirmed against the running portal at portal.gogorilla.com/partners on 7 August:
//   Home, Opportunities, My Projects, Grow, Referrals, Earnings, Profile.
//   RE-SYNC RULE, same shape as the service-teasers one. This is a MIRROR of another repo,
//   and a mirror drifts. If FREELANCER_NAV changes, this changes. Note that array also
//   carries a Services item which is NOT in the live rail because its flag is off, so read
//   the flags as well as the labels before copying anything across.
//   THE REAL FIX IS AN ENDPOINT, NOT A TIGHTER MIRROR. Two repos, and this one has no build
//   step, so a .tsx component cannot be imported here however much we would like it to be.
//   The portal exposing FREELANCER_NAV as public JSON, the way it already exposes prices,
//   would make a rename there propagate here with no deploy. Asked for in the 7 August note.
//   DO NOT EDIT THESE LABELS TO TASTE. The preview exists to look like the real thing, and a
//   mismatch is caught by the user at the exact moment they sign in. If the portal renames
//   something, this follows it, never the other way round.
//   FOUNDER is designed, not mirrored, because that sidebar does not exist yet (LOOM 15 at
//   08:16). Its shape follows the Founders Engine design-inheritance law: Home and Find
//   Investors are founders-specific, everything else inherits the partner rail.
//   INVESTOR is designed too, and the portal is on hold (LOOM 15 at 07:51). Its items are
//   derived from the live pricing page's own feature groups at /pricing/investor-portal.
//
// NO WAITING LIST BADGES IN THE RAIL. Ruled by Nicole 7 August. The investor tier cards in
// the calculator already say it, so a badge on every rail item is the third telling of the
// same fact. It is said once, in the overlay, where it is the call to action rather than
// decoration. Locked items use a padlock in all three variants, which is one visual language
// and is Alexander's own (LOOM 9 at 19:32 and 39:35, "maybe we have a padlock over it").

(function () {
  'use strict';

  var e = React.createElement;

  // *** NEVER RENDER WHEN EMBEDDED. THIS CHECK COMES FIRST AND BEATS BOTH THE FLAG AND
  // THE PREVIEW PARAM, ON PURPOSE. *** Inside the portal Grow tab the host already has its
  // own rail, so rendering ours would put two sidebars side by side. It is also simply
  // wrong on its own terms: this is a SIGNED-OUT preview of a portal, and anybody seeing
  // the embedded calculator is signed into that portal already. Same reasoning as the
  // checkout call to action, where being embedded IS the signed-in signal.
  //
  // window.GG_EMBED is the contract the host sets before our scripts load, per
  // assets/embed-manifest.v1.json. GG_EMBED_CONTRACT is NOT the signal, we set that
  // ourselves and it is always present.
  //
  // Raised by Nicole on 7 August before the flag was ever flipped, which is the only
  // reason it never shipped as a defect.
  function isEmbedded() {
    try { return !!(window.GG_EMBED && typeof window.GG_EMBED === 'object'); }
    catch (err) { return false; }
  }

  function enabled() {
    try {
      if (isEmbedded()) return false;
      if (window.GG_FEATURE_SOS === true) return true;
      return new URLSearchParams(window.location.search || '').get('sos') === '1';
    } catch (err) { return false; }
  }

  // ── ICONS. THESE ARE THE PORTAL'S OWN, NOT LOOK-ALIKES. ──────────────────
  // Extracted verbatim from lucide-static, the same icon set FreelancerRail.tsx
  // imports from lucide-react, and mapped with the SAME KEYS that file uses:
  //   home: Home · explore: Compass · clients: Users · grow: TrendingUp
  //   referrals: Share2 · addservice: Package · earnings: PoundSterling
  //   profile: UserRound
  // search and portfolio are the two the portal has no entry for, because the
  // founder and investor rails do not exist there yet. Same family, so they do
  // not read as borrowed from somewhere else.
  //
  // WHY COPIES AND NOT AN IMPORT. lucide-react is a node module and this repo
  // has no build step, so there is nothing here that could resolve it. Copying
  // the paths is the closest thing to using the component itself, and it is a
  // mirror like the rail labels are, so the same re-sync rule applies.
  var ICON_PATHS = {
      "home": [
          {
              "t": "path",
              "a": {
                  "d": "M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"
              }
          }
      ],
      "explore": [
          {
              "t": "circle",
              "a": {
                  "cx": "12",
                  "cy": "12",
                  "r": "10"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"
              }
          }
      ],
      "clients": [
          {
              "t": "path",
              "a": {
                  "d": "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "M16 3.128a4 4 0 0 1 0 7.744"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "M22 21v-2a4 4 0 0 0-3-3.87"
              }
          },
          {
              "t": "circle",
              "a": {
                  "cx": "9",
                  "cy": "7",
                  "r": "4"
              }
          }
      ],
      "grow": [
          {
              "t": "path",
              "a": {
                  "d": "M16 7h6v6"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "m22 7-8.5 8.5-5-5L2 17"
              }
          }
      ],
      "referrals": [
          {
              "t": "circle",
              "a": {
                  "cx": "18",
                  "cy": "5",
                  "r": "3"
              }
          },
          {
              "t": "circle",
              "a": {
                  "cx": "6",
                  "cy": "12",
                  "r": "3"
              }
          },
          {
              "t": "circle",
              "a": {
                  "cx": "18",
                  "cy": "19",
                  "r": "3"
              }
          },
          {
              "t": "line",
              "a": {
                  "x1": "8.59",
                  "x2": "15.42",
                  "y1": "13.51",
                  "y2": "17.49"
              }
          },
          {
              "t": "line",
              "a": {
                  "x1": "15.41",
                  "x2": "8.59",
                  "y1": "6.51",
                  "y2": "10.49"
              }
          }
      ],
      "addservice": [
          {
              "t": "path",
              "a": {
                  "d": "M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "M12 22V12"
              }
          },
          {
              "t": "polyline",
              "a": {
                  "points": "3.29 7 12 12 20.71 7"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "m7.5 4.27 9 5.15"
              }
          }
      ],
      "earnings": [
          {
              "t": "path",
              "a": {
                  "d": "M18 7c0-5.333-8-5.333-8 0"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "M10 7v14"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "M6 21h12"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "M6 13h10"
              }
          }
      ],
      "profile": [
          {
              "t": "circle",
              "a": {
                  "cx": "12",
                  "cy": "8",
                  "r": "5"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "M20 21a8 8 0 0 0-16 0"
              }
          }
      ],
      "search": [
          {
              "t": "path",
              "a": {
                  "d": "m21 21-4.34-4.34"
              }
          },
          {
              "t": "circle",
              "a": {
                  "cx": "11",
                  "cy": "11",
                  "r": "8"
              }
          }
      ],
      "portfolio": [
          {
              "t": "path",
              "a": {
                  "d": "M21 12c.552 0 1.005-.449.95-.998a10 10 0 0 0-8.953-8.951c-.55-.055-.998.398-.998.95v8a1 1 0 0 0 1 1z"
              }
          },
          {
              "t": "path",
              "a": {
                  "d": "M21.21 15.89A10 10 0 1 1 8 2.83"
              }
          }
      ]
  };

  function Icon(name) {
    var kids = (ICON_PATHS[name] || []).map(function (n, i) {
      return e(n.t, Object.assign({ key: i }, n.a));
    });
    return e('svg', {
      className: 'gg-sos__icon', viewBox: '0 0 24 24', fill: 'none',
      stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round',
      strokeLinejoin: 'round', 'aria-hidden': 'true'
    }, kids);
  }

  // PanelLeft / PanelLeftClose, the two lucide glyphs FreelancerRail imports for the
  // toggle. Drawn here rather than imported because this repo has no bundler.
  function PanelIcon(open) {
    var kids = [
      e('rect', { key: 'r', width: 18, height: 18, x: 3, y: 3, rx: 2 }),
      e('path', { key: 'p', d: 'M9 3v18' })
    ];
    if (open) kids.push(e('path', { key: 'c', d: 'm16 15-3-3 3-3' }));
    return e('svg', {
      className: 'gg-sos__toggleicon', viewBox: '0 0 24 24', fill: 'none',
      stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round',
      strokeLinejoin: 'round', 'aria-hidden': 'true'
    }, kids);
  }

  // COLLAPSED STATE IS DELIBERATELY NOT PERSISTED, AND THIS IS THE ONE PLACE THIS
  // COMPONENT DIVERGES FROM FreelancerRail ON PURPOSE. DO NOT "FIX" IT BACK.
  //
  // The portal persists the choice per browser under gg:customerSidebarCollapsed, via
  // CustomerLayoutContext, and that is right there: the visitor is signed in, and
  // collapsing the rail costs them nothing they cannot get back from any page.
  //
  // Here the rail IS the conversion surface. It is the only thing on the public
  // calculator that shows a signed-out visitor what they would be signing into.
  // Remembering a collapse would mean somebody who folded it away once never sees it
  // again on that browser, which quietly removes the reason the preview exists.
  //
  // So the state lives in React and nowhere else. It survives moving between steps,
  // because this component stays mounted, and it resets to expanded on every fresh
  // load. Nicole, 7 August.

  function Padlock() {
    return e('span', { className: 'gg-sos__lock', 'aria-hidden': 'true' },
      e('svg', { viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2.2, strokeLinecap: 'round', strokeLinejoin: 'round' },
        e('rect', { x: 5, y: 11, width: 14, height: 9, rx: 2 }),
        e('path', { d: 'M8 11V8a4 4 0 0 1 8 0v3' })));
  }

  // ── The rails. `kind` drives the blurred skeleton, never the copy. ──
  var RAILS = {
    // COPIED FROM THE LIVE PORTAL. Do not edit to taste.
    // TABS ADDED 7 AUG 2026, and they are a MIRROR exactly as the labels above are.
    // Source is the tabs[] of each entry in FREELANCER_NAV, lib/account/freelancer-nav.ts
    // in aonslow/gogorilla-platform, and every one was additionally confirmed page by page
    // against the running portal on 7 August. SAME RE-SYNC RULE AS THE RAIL LABELS: if a tab
    // is renamed there it is renamed here, never the other way round. Two names in that file
    // are load-bearing and have each already been corrected once, so do not tidy them.
    // Earnings is "Client work" and NEVER "Task earnings", and My Projects tab two is "Board"
    // and never "Projects". Grow carries none because Grow is the live item and never opens
    // a glimpse.
    agency: [
      { id: 'home',     label: 'Home',          icon: 'home',     kind: 'dash',
        tabs: ['Overview', 'Tasks'] },
      { id: 'opps',     label: 'Opportunities', icon: 'explore',  kind: 'list',
        tabs: ['Account management', 'One-off projects', 'Talent network', 'My interests'] },
      { id: 'projects', label: 'My Projects',   icon: 'clients', kind: 'board',
        tabs: ['Active', 'Board', 'Assets', 'Meeting prep'] },
      { id: 'grow',     label: 'Grow',          icon: 'grow',     kind: 'live' },
      { id: 'refer',    label: 'Referrals',     icon: 'referrals', kind: 'list',
        tabs: ['My referrals', 'Refer a candidate'] },
      { id: 'earn',     label: 'Earnings',      icon: 'earnings',    kind: 'dash',
        tabs: ['Overview', 'Client work', 'Referrals', 'Payouts'] },
      { id: 'profile',  label: 'Profile',       icon: 'profile',  kind: 'form',
        tabs: ['About & specialisms', 'Portfolio', 'Rates & availability'] }
    ],
    // FOUNDER AND INVESTOR CARRY NO TABS, DELIBERATELY. Neither portal exists, so there is
    // no tabs[] to mirror and anything written here would be invented. Nicole, 7 August:
    // use the portal source rather than guessing. The rails themselves are designed rather
    // than mirrored, which is already recorded at the top of this file, but a rail label is
    // one word whilst a tab bar asserts an entire information architecture. When those
    // sidebars are built, mirror them the same way and delete this note.
    founder: [
      { id: 'home',     label: 'Home',           icon: 'home',     kind: 'dash' },
      { id: 'projects', label: 'My Projects',    icon: 'clients', kind: 'board' },
      { id: 'grow',     label: 'Grow',           icon: 'grow',     kind: 'live' },
      { id: 'invest',   label: 'Find Investors', icon: 'search',   kind: 'list' },
      { id: 'refer',    label: 'Referrals',      icon: 'referrals', kind: 'list' },
      { id: 'billing',  label: 'Billing',        icon: 'earnings',    kind: 'dash' },
      { id: 'profile',  label: 'Profile',        icon: 'profile',  kind: 'form' }
    ],
    investor: [
      { id: 'home',      label: 'Home',          icon: 'home',     kind: 'dash' },
      { id: 'founders',  label: 'Find Founders', icon: 'search',   kind: 'list' },
      { id: 'grow',      label: 'Grow',          icon: 'grow',     kind: 'live' },
      { id: 'portfolio', label: 'Portfolio',     icon: 'portfolio',      kind: 'board' },
      { id: 'refer',     label: 'Referrals',     icon: 'referrals', kind: 'list' },
      { id: 'billing',   label: 'Billing',       icon: 'earnings',    kind: 'dash' },
      { id: 'profile',   label: 'Profile',       icon: 'profile',  kind: 'form' }
    ]
  };

  // One line per page, so the overlay says what is behind the blur rather than
  // repeating the page name back at the visitor.
  var BLURB = {
    home:      'Your dashboard, next steps, and what needs your attention.',
    opps:      'Roles we are recruiting for, with rates and requirements.',
    projects:  'Every project you are running, on one board.',
    invest:    'Investors matched to your stage, sector, and raise.',
    founders:  'Founders actively raising, matched to your thesis.',
    portfolio: 'Your portfolio companies and how they are tracking.',
    refer:     'Refer a business or a candidate, and track what you have sent us.',
    earn:      'What you have earned, what is pending, and when it pays out.',
    billing:   'Your plan, invoices, and payment method.',
    profile:   'Your details, and how you appear to everyone else.'
  };

  function Skeleton(kind) {
    var rows = [];
    if (kind === 'board') {
      for (var c = 0; c < 3; c++) {
        var cards = [];
        for (var i = 0; i < 3; i++) cards.push(e('div', { key: i, className: 'gg-sos__sk-card' }));
        rows.push(e('div', { key: c, className: 'gg-sos__sk-col' },
          e('div', { className: 'gg-sos__sk-colhead' }), cards));
      }
      return e('div', { className: 'gg-sos__sk gg-sos__sk--board' }, rows);
    }
    if (kind === 'list') {
      for (var r = 0; r < 5; r++) rows.push(e('div', { key: r, className: 'gg-sos__sk-row' },
        e('div', { className: 'gg-sos__sk-avatar' }),
        e('div', { className: 'gg-sos__sk-lines' },
          e('div', { className: 'gg-sos__sk-line' }),
          e('div', { className: 'gg-sos__sk-line gg-sos__sk-line--short' })),
        e('div', { className: 'gg-sos__sk-pill' })));
      return e('div', { className: 'gg-sos__sk' }, rows);
    }
    if (kind === 'form') {
      for (var f = 0; f < 5; f++) rows.push(e('div', { key: f, className: 'gg-sos__sk-field' },
        e('div', { className: 'gg-sos__sk-line gg-sos__sk-line--short' }),
        e('div', { className: 'gg-sos__sk-input' })));
      return e('div', { className: 'gg-sos__sk gg-sos__sk--form' }, rows);
    }
    var tiles = [];
    for (var t = 0; t < 4; t++) tiles.push(e('div', { key: t, className: 'gg-sos__sk-tile' }));
    return e('div', { className: 'gg-sos__sk' },
      e('div', { className: 'gg-sos__sk-tiles' }, tiles),
      e('div', { className: 'gg-sos__sk-wide' }));
  }

  // THE INNER TAB BAR. Every page in the portal has one and this preview had none,
  // which was the largest structural difference between the glimpse and the real thing.
  // It renders INSIDE gg-sos__blur so it reads as part of the page being glimpsed rather
  // than as chrome we bolted on, which is also where it sits in the portal. Shape follows
  // AccountTabNav, a pill row with the first tab active. No page title above it on purpose:
  // the real h1 differs from the rail label on two pages and is personalised on Home, so
  // writing one here would be inventing copy for a surface we are only mirroring.
  function TabBar(item) {
    var tabs = item && item.tabs;
    if (!tabs || !tabs.length) return null;
    return e('div', { className: 'gg-sos__sk-tabs' },
      tabs.map(function (label, i) {
        return e('span', {
          key: label,
          className: 'gg-sos__sk-tab' + (i === 0 ? ' is-on' : '')
        }, label);
      }));
  }

  function SignedOutSidebar(props) {
    var state = props && props.state ? props.state : {};
    var clientTypeId = state.clientTypeId || null;
    var openId = React.useState(null);
    var open = openId[0], setOpen = openId[1];

    var on = enabled() && !!clientTypeId;

    // COLLAPSIBLE SINCE 7 Aug 2026, mirroring FreelancerRail.tsx which gained this the
    // same day. It hides FULLY rather than narrowing to icons, which is the portal's
    // choice and its reason applies here too: the calculator wants the whole width.
    var colBag = React.useState(false);   // always expanded on load, see the note above
    var collapsed = colBag[0], setCollapsed = colBag[1];
    var railRef = React.useRef(null);

    // Shift the calculator right whilst the rail is showing. Done as a class on the
    // mount element so no JSX restructuring is needed and the rail can be removed
    // cleanly. gg-scope IS the mount element, see the embed contract.
    React.useEffect(function () {
      var host = document.querySelector('.gg-scope');
      if (!host) return;
      if (on) host.classList.add('gg-sos-on'); else host.classList.remove('gg-sos-on');
      if (on && collapsed) host.classList.add('gg-sos-collapsed');
      else host.classList.remove('gg-sos-collapsed');
      return function () {
        try { host.classList.remove('gg-sos-on'); host.classList.remove('gg-sos-collapsed'); } catch (err) {}
      };
    }, [on, collapsed]);

    // aria-hidden and inert whilst closed, so a collapsed rail is not a set of invisible
    // tab stops. Verbatim intent from FreelancerRail. inert is set on the node rather than
    // passed as a prop, because this React does not forward it.
    React.useEffect(function () {
      var el = railRef.current; if (!el) return;
      if (collapsed) { el.setAttribute('inert', ''); el.setAttribute('aria-hidden', 'true'); }
      else { el.removeAttribute('inert'); el.removeAttribute('aria-hidden'); }
    }, [collapsed]);

    // A client type change closes any open glimpse, so the overlay never survives
    // into a pathway whose rail does not contain that page.
    React.useEffect(function () { setOpen(null); }, [clientTypeId]);

    if (!on) return null;

    var rail = RAILS[clientTypeId] || RAILS.agency;
    var isInvestor = clientTypeId === 'investor';
    var item = open ? rail.filter(function (x) { return x.id === open; })[0] : null;

    return e('div', { className: 'gg-sos' },
      // THE RAIL IS A PLAIN PANEL AND THE GLASS PILL IS THE SELECTED ITEM. Read off
      // FreelancerRail.tsx: the aside is "bg-white/70 backdrop-blur-[8px] border-r
      // border-slate-200/80 w-24", and it is the ACTIVE LINK that carries
      // thin-glass-frame. An earlier pass here put the frame on the rail itself,
      // which is the same component in the wrong place.
      e('nav', { className: 'gg-sos__rail', id: 'gg-sos-rail', ref: railRef, 'aria-label': 'Portal preview' },
        // THE HEAD, and it is the PORTAL'S OWN FILE rather than a copy. It serves with
        // access-control-allow-origin star, so linking it live means a rebrand there
        // lands here with no deploy. Same reasoning as asking them to serve the nav.
        e('div', { className: 'gg-sos__brand' },
          e('img', {
            className: 'gg-sos__brandimg',
            src: 'https://portal.gogorilla.com/brand/gogorilla-head.png',
            alt: '', 'aria-hidden': 'true', loading: 'lazy', decoding: 'async'
          })),
        rail.map(function (it) {
          var live = it.kind === 'live';
          return e('button', {
            key: it.id, type: 'button',
            // SELECTED TAKES thin-glass-frame, verbatim from FreelancerRail.tsx:
            //   active ? 'thin-glass-frame text-slate-900'
            //          : 'text-slate-600 hover:bg-blue-50 hover:text-slate-900'
            // Selected here means whichever page the visitor is looking at, so it is
            // Grow until they open a glimpse and then it follows them.
            className: 'gg-sos__item' + (live ? ' is-live' : '')
              + ((open ? open === it.id : live) ? ' is-selected thin-glass-frame' : ''),
            'aria-current': live && !open ? 'page' : undefined,
            // TWO WAYS BACK TO GROW, Nicole 7 August: click Grow itself, or the
            // Back to Grow link in the glimpse. So Grow is a real control rather than
            // a decorative highlight, and clicking it closes whatever is open.
            onClick: function () { setOpen(live ? null : it.id); }
          },
            e('span', { className: 'gg-sos__iconwrap' }, Icon(it.icon), live ? null : Padlock()),
            e('span', { className: 'gg-sos__label' }, it.label));
        })),

      // THE TOGGLE, and it lives OUTSIDE the rail for the portal's own reason: a control
      // inside the rail disappears with it and there is then no way back. It slides with
      // the rail so it always sits just inside the content edge, and THE ICON STATES THE
      // RESULT OF PRESSING IT rather than the current state.
      e('button', {
        type: 'button',
        className: 'gg-sos__toggle',
        onClick: function () {
          setCollapsed(function (prev) { return !prev; });
        },
        'aria-expanded': !collapsed,
        'aria-controls': 'gg-sos-rail',
        title: collapsed ? 'Expand sidebar' : 'Collapse sidebar'
      }, PanelIcon(!collapsed), e('span', { className: 'gg-sos__sr' }, collapsed ? 'Expand sidebar' : 'Collapse sidebar')),

      item ? e('div', { className: 'gg-sos__glimpse', role: 'dialog', 'aria-modal': 'false', 'aria-label': item.label },
        e('div', { className: 'gg-sos__blur' }, TabBar(item), Skeleton(item.kind)),
        // glass-frame is the 22px sibling of the rail's 14px one, again the
        // calculator's own class. A hand-built card beside real glass reads as a
        // different product.
        e('div', { className: 'gg-sos__prompt glass-frame' },
          e('span', { className: 'gg-sos__promptlock' }, Padlock()),
          e('h3', { className: 'gg-sos__prompttitle' }, item.label),
          e('p', { className: 'gg-sos__promptbody' }, BLURB[item.id] || ''),
          isInvestor
            ? e('p', { className: 'gg-sos__promptnote' }, 'The Investor Portal has not launched yet.')
            : null,
          // THE SIGN-IN CTA IS WIRED. Nicole, 7 August: it goes to portal.gogorilla.com/login.
          // Worth knowing what that page actually is, because the label undersells it. There
          // is NO PASSWORD. Entering an email mints a magic link, so for somebody with no
          // account this is account creation and sign-in in one step, which is why it can sit
          // behind a button that says sign up.
          //
          // *** IT IS GATED TODAY AND THE GATE IS SILENT. *** POST /api/v1/auth/magic-link is
          // wrapped in FEATURE_MAGIC_LINK_AUTO_INVITE. With the flag off it returns 200 with
          // sent: true AND SENDS NOTHING, deliberately, so the response cannot be used to
          // enumerate accounts. The cost is that a real person gets a check-your-email screen
          // and no email. Raised with the portal on 7 August. If this CTA appears to do
          // nothing, that is where to look first, not here.
          //
          // The other two are deliberately NOT wired yet and must not be guessed at. The
          // investor waiting list has no destination decided, and Book a call has no chosen
          // event for founders or investors, only the freelancer assessment call which is the
          // wrong meeting for both. Dead is better than wrong here.
          e('div', { className: 'gg-sos__actions' },
            // btn btn--primary IS THE NEXT BUTTON, the same gradient the calculator
            // uses to move you through the flow, and btn--ghost is the grey pill
            // beside it. Nicole, 7 August. gg-sos__cta now only makes them fill the
            // card width, it carries no colour of its own any more.
            isInvestor
              ? e('button', { type: 'button', className: 'btn btn--primary gg-sos__cta' }, 'Join the waiting list')
              : e('a', {
                  className: 'btn btn--primary gg-sos__cta',
                  href: 'https://portal.gogorilla.com/login',
                  // NEW TAB, Nicole 7 August. The visitor has a quote in progress on
                  // this page and a same-tab navigation throws it away.
                  target: '_blank', rel: 'noopener noreferrer'
                }, 'Sign up to explore our platform'),
            // BOOK A CALL, wired 7 August to the team link Nicole supplied. NEW TAB
            // rather than a Cal.com overlay: this is already an overlay, and stacking
            // a second one on top of it is the friction the glimpse exists to avoid.
            // Her own instinct, and it also keeps the quote alive on this page.
            e('a', {
              className: 'btn btn--ghost gg-sos__cta',
              href: 'https://cal.com/team/gogorilla/call',
              target: '_blank', rel: 'noopener noreferrer'
            }, 'Book a call')),
          e('button', {
            // NOT "Back to Grow". Grow is portal vocabulary and this visitor has
            // never been in the portal, so it names the thing they are actually
            // standing on. Nicole raised it, 7 August.
            type: 'button', className: 'gg-sos__back', onClick: function () { setOpen(null); }
          }, 'Back to the pricing calculator'))) : null
    );
  }

  window.SignedOutSidebar = SignedOutSidebar;
})();
