/* Alchemy — shared LOCATION PAGE layout (owner-approved, final). Every location page (CLT, DTG, LRY, and any future site) renders this exact section order. A location supplies only data via the `loc` config object: Hero (More Than Offices & Outlets) → Address → Tiers to join → Meeting Rooms → Unique qualities → Pictures → Tour / Virtual Tour → Contact form Nothing here is per-location bespoke: to launch a new location, add a config and an html entry. The main website home page is separate and unchanged. */ const { Button, Tag, SectionHeading } = window.DS; const locWrap = { maxWidth: 'var(--container-wide)', margin: '0 auto', padding: '0 var(--gutter)' }; const goMain = (hash) => { window.location.href = window.alcUrl ? window.alcUrl('home', hash) : 'index.html' + (hash ? '#' + hash : ''); }; /* Virtual tour funnel, deep-linked to a location's walkthrough. */ const vtUrl = (key) => (window.alcUrl ? window.alcUrl('virtualTour', key) : 'VirtualTour.html#' + key); /* OfficeRnD storefront: buy a Partnership or book a room without talking to us first. */ const ORND_STORE = 'https://e-commerce.officernd.com/alchemy/dashboard?utm_source=alchemycowork.com&utm_medium=referral&language=en-us'; /* Button destinations come from the shared registry (links.jsx) so marketing can swap any URL in one place. Blank values fall back to the behaviour below. */ const linkFor = (loc, name) => (window.alcLink ? window.alcLink(loc.tourKey, name) : ''); const jumpTo = (id, offset = 70) => { const sc = document.getElementById('kit-scroll'); const t = document.getElementById(id); if (t && sc) sc.scrollTo({ top: t.offsetTop - offset, behavior: 'smooth' }); }; /* Partnership tiers — identical across every location (single source of truth). */ const LOCATION_TIERS = [ { name: 'Business Club', price: '$149', sub: '/mo · flexible plans', blurb: 'Best for getting started & flexible work.', features: ['24/7 open coworking access', 'Open seating', 'Phone booths for storage', 'Mailbox add-on', '4 meeting-room credits / mo', 'Community access & events'], highlight: false }, { name: 'Dedicated Desk', price: '$349', sub: '/mo · flexible plans', blurb: 'Best for a permanent home base.', features: ['24/7 access', 'Your dedicated desk', 'Locking cabinet with key', 'Mail included', '5 meeting-room credits / mo', 'Personalize your desk'], highlight: true }, { name: 'Private Office', price: 'Prices Vary', sub: 'month to month', blurb: 'Best for teams & established businesses.', features: ['24/7 access', 'Fully furnished office', 'Furnished storage', 'Mail included', '6 meeting-room credits / mo', 'Custom signage on your door'], highlight: false }, ]; /* ---------------------------------------------------------------- header --- */ function LocationHeader({ loc, onPrimary }) { const tourUrl = linkFor(loc, 'scheduleTour'); const [scrolled, setScrolled] = React.useState(false); React.useEffect(() => { const el = document.getElementById('kit-scroll'); const h = () => setScrolled((el ? el.scrollTop : window.scrollY) > 12); h(); (el || window).addEventListener('scroll', h); return () => (el || window).removeEventListener('scroll', h); }, []); const light = !scrolled; const linkStyle = { all: 'unset', cursor: 'pointer', fontFamily: 'var(--font-label)', fontWeight: 600, fontSize: '0.84rem', letterSpacing: '0.04em', textTransform: 'uppercase', padding: '0.5rem 0.85rem', color: light ? 'rgba(255,255,255,0.85)' : 'var(--stone-600)', }; const links = [['tiers', 'Ways to Join'], ['rooms', 'Meeting Rooms'], ['qualities', 'Why Here'], ['contact', 'Contact']]; return (
{'Alchemy {loc.badge && ( {loc.badge} )} {tourUrl ? : }
); } /* ------------------------------------------------------------------ hero --- */ /* Owner-approved headline + sub, identical on every location page. */ function LocationHero({ loc, onPrimary }) { const tourUrl = linkFor(loc, 'scheduleTour'); return (
{loc.heroImg ? (
) : (
)}
{loc.eyebrow}

More Than Offices & Outlets

{loc.heroSub}

{tourUrl ? : }
); } /* --------------------------------------------------------------- address --- */ function LocationAddress({ loc }) { const rows = [ ['Address', loc.address], ['Hours', loc.hours], ['Contact', loc.phone], ]; /* Optional area/context paragraph beneath the address strip (per location). */ return (
{rows.map(([k, v]) => (
{k} {v}
))}
{loc.areaInfo && (

{loc.areaInfo}

)}
); } /* ----------------------------------------------------------------- tiers --- */ function LocationTiers({ loc, onJoin }) { /* Tier list is shared; a location may override a single tier's price/features (e.g. Loray's Private Office is a flat $1200). */ const tiers = LOCATION_TIERS.map((t) => ({ ...t, ...((loc.tierOverrides || {})[t.name] || {}) })); const startNow = linkFor(loc, 'startNow') || ORND_STORE; return (
{tiers.map((t) => { const dark = t.highlight; return (

{t.name}

{dark && Popular}

{t.blurb}

{t.price} {t.sub}
    {t.features.map((f) => (
  • ✓{f}
  • ))}
{/* Straight-to-purchase path via the OfficeRnD storefront. */}
); })}
); } /* --------------------------------------------------------- meeting rooms --- */ function LocationRooms({ loc, onBookRoom }) { const rooms = loc.rooms || []; /* Locations whose bookable inventory isn't published yet show one generic block with an inquiry CTA — never a Book button that can't book. */ if (!rooms.length) { return (
{loc.roomsImg && (
)}
{loc.roomsNote && (

{loc.roomsNote}

)}
); } const cols = rooms.length >= 3 ? 3 : rooms.length; return (
{loc.roomsIntro && (

{loc.roomsIntro}

)}
{rooms.map((r) => (
{r.name}
{r.kind}

{r.name}

{r.body}

))}
); } /* ------------------------------------------------------ unique qualities --- */ function LocationQualities({ loc }) { return (
{loc.qualities.map(([t, d]) => (
{t} {d}
))}
); } /* -------------------------------------------------------------- pictures --- */ function LocationPictures({ loc }) { /* No photography for this location yet: leave the slot intentionally blank with a disclaimer rather than showing another location's rooms as if they were this one. */ if (!loc.gallery || !loc.gallery.length) { return (

Photography of {loc.name} is being shot now and will be published here. In the meantime, take the virtual tour or book a tour and we'll walk you through the space in person.

); } return (
{/* Photos and the walkthrough answer the same question, so keep them together. */}
{loc.gallery.map((src, i) => (
))}
); } /* -------------------------------------------------- tour / virtual tour --- */ function LocationTourBand({ loc, onTour }) { return (
{loc.tourImg && (
)}
{/* Every location's Virtual Tour button lands on the shared funnel page, deep-linked to that location's walkthrough. */}
); } /* ---------------------------------------------------------- contact form --- */ function LocationContact({ loc }) { return (
{[['Call', loc.phone], ['Email', 'team@alchemycowork.com'], ['Visit', loc.address]].map(([k, v]) => (
{k} {v}
))}
); } /* ------------------------------------------------------------ page shell --- */ function LocationPage({ loc, onBookRoom }) { const onPrimary = loc.onPrimary || (() => jumpTo('contact')); const onJoin = () => goMain('intake'); const bookRoom = onBookRoom || (() => jumpTo('contact')); return (
goMain()} />
); } Object.assign(window, { LocationPage, LOCATION_TIERS, locWrap, goMain, jumpTo });