/* ============== SOCIAL TAG, APP ============== */
const { useState, useEffect, useRef } = React;

/* ---- Reveal-on-scroll ---- */
function useReveal() {
 useEffect(() => {
 const io = new IntersectionObserver(
 (entries) => {
 entries.forEach((e) => {
 if (e.isIntersecting) {
 e.target.classList.add('in');
 io.unobserve(e.target);
 }
 });
 },
 { threshold: 0.12, rootMargin: '0px 0px -40px 0px' }
 );
 document.querySelectorAll('.reveal').forEach((el) => io.observe(el));
 return () => io.disconnect();
 });
}

/* ---- SVG icons ---- */
const YouTubeIcon = () => (
 <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
 <path d="M23.5 6.2c-.3-1-1.1-1.8-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6c-1 .3-1.8 1.1-2.1 2.1C0 8.1 0 12 0 12s0 3.9.5 5.8c.3 1 1.1 1.8 2.1 2.1 1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6c1-.3 1.8-1.1 2.1-2.1.5-1.9.5-5.8.5-5.8s0-3.9-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z"/>
 </svg>
);
const InstagramIcon = () => (
 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" aria-hidden="true">
 <rect x="3" y="3" width="18" height="18" rx="5" />
 <circle cx="12" cy="12" r="4" />
 <circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none" />
 </svg>
);
const SpotifyIcon = () => (
 <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
 <path d="M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.5 17.31a.75.75 0 01-1.03.25c-2.82-1.72-6.37-2.11-10.55-1.16a.75.75 0 11-.33-1.46c4.57-1.04 8.5-.58 11.66 1.34.36.22.47.69.25 1.03zm1.47-3.27a.94.94 0 01-1.29.31c-3.23-1.99-8.16-2.56-11.99-1.4a.94.94 0 11-.55-1.79c4.37-1.34 9.8-.69 13.51 1.58.44.27.58.85.32 1.3zm.13-3.41C15.32 8.39 8.7 8.17 5.05 9.28a1.13 1.13 0 01-.66-2.16c4.2-1.28 11.51-1.03 16.05 1.66a1.13 1.13 0 01-1.16 1.94z"/>
 </svg>
);
const TwitterIcon = () => (
 <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
 <path d="M17.53 3H20.5l-6.5 7.43L21.75 21h-6l-4.7-6.14L5.65 21H2.68l6.95-7.94L1.95 3h6.15l4.25 5.62L17.53 3zm-1.05 16.18h1.65L7.6 4.73H5.83l10.65 14.45z"/>
 </svg>
);

/* Nav + Footer live in site-chrome.js (loaded by every HTML page).
   They are injected outside the React root so there's a single source
   of truth shared between React-driven and static pages. */

/* ---- Hero ---- */
const TRUSTED_LOGOS = [
 { name: 'OpenArt', file: 'openart', h: 32 },
 { name: 'Anthropic', file: 'anthropic', h: 38 },
 { name: 'ChatGPT', file: 'chatgpt', h: 34, bright: true },
 { name: 'Google', file: 'google', h: 44, large: true },
 { name: 'Meta', file: 'meta', h: 36, bright: true },
 { name: 'Adobe', file: 'adobe', h: 38 },
 { name: 'Figma', file: 'figma', h: 42 },
 { name: 'Framer', file: 'framer', h: 32 },
 { name: 'Notion', file: 'notion', h: 44 },
 { name: 'PayPal', file: 'paypal', h: 36 },
 { name: 'Mastercard', file: 'mastercard', h: 44, dim: true },
 { name: 'Apple', file: 'apple', h: 44 },
 { name: 'Intel', file: 'intel', h: 40 },
 { name: 'AMD', file: 'amd', h: 30 },
 { name: 'Samsung Ai', file: 'samsung-ai', h: 30 },
 { name: 'OnePlus', file: 'oneplus', h: 40, bright: true },
 { name: 'BenQ', file: 'benq', h: 36 },
 { name: 'Hostinger', file: 'hostinger', h: 42, large: true },
 { name: 'Zapier', file: 'zapier', h: 30 },
 { name: 'Gamma', file: 'gamma', h: 48, large: true },
 { name: 'Manus', file: 'manus', h: 40 },
 { name: 'Artlist', file: 'artlist', h: 32 },

 { name: 'Audo', file: 'audo', h: 44 },
 { name: 'Gemini', file: 'gemini', h: 44 },
 { name: 'Wayin AI', file: 'wayin', h: 32 },
 { name: 'Milvus', file: 'milvus', h: 44, large: true },
 { name: 'Neuro', file: 'neuro', h: 32 },
 { name: 'Filmora', file: 'filmora', h: 46, dim: true },
 { name: 'Truecaller', file: 'truecaller', h: 44 },
 { name: 'WisprFlow', file: 'wisprflow', h: 30 },
 { name: 'Freepik', file: 'freepik', h: 32 },
 { name: 'CNN', file: 'cnn', h: 30 },
 { name: 'X', file: 'x', h: 36 },
 { name: 'ICICI Bank', file: 'icici', h: 44, bright: true },
 { name: 'JioHotstar', file: 'jiohotstar', h: 44, large: true },
 { name: 'Thums Up', file: 'thums-up', h: 46, large: true },
];

// Split the roster across two marquee rows.
const TRUSTED_ROW_ONE = TRUSTED_LOGOS.slice(0, Math.ceil(TRUSTED_LOGOS.length / 2));
const TRUSTED_ROW_TWO = TRUSTED_LOGOS.slice(Math.ceil(TRUSTED_LOGOS.length / 2));

function BrandLogo({ logo }) {
 return (
 <span className={`brand-logo${logo.bright ? ' brand-logo--bright' : ''}${logo.dim ? ' brand-logo--dim' : ''}${logo.large ? ' brand-logo--large' : ''}`} title={logo.name}>
 <img
 className="brand-logo__img"
 src={`assets/logos/marquee/${logo.file}.png`}
 alt={logo.name}
 loading="lazy"
 draggable="false"
 />
 </span>
 );
}

function Hero() {
 return (
 <section className="sec sec--dark hero" id="hero">
 <div className="hero-bg">
 <div className="hero-bg__image" />
 <div className="hero-bg__beam hero-bg__beam--left" />
 <div className="hero-bg__beam hero-bg__beam--center" />
 <div className="hero-bg__beam hero-bg__beam--right" />
 <div className="hero-bg__floor" />
 <div className="hero-bg__vignette" />
 </div>
 <div className="hero-inner">
 <div className="hero-eyebrow reveal">
 <span className="dot" />
 A new-age media company · est. for brands who lead
 </div>
 <h1 className="hero-title serif reveal" data-d="1">
 Where <span className="it">brands</span> find their voice.<br />
 And <span className="it">creators</span> amplify it.
 </h1>
 <p className="hero-sub reveal" data-d="2">
 We don't just do "influencer marketing."<br />
 We build <span className="it">brand influence</span> through creators who own distribution.
 </p>
 <div className="hero-ctas reveal" data-d="3">
 <a href="#case-studies" className="btn btn-ghost">
 See our work <span className="arrow">→</span>
 </a>
 </div>
 </div>
 <div className="trusted reveal" data-d="4">
 <div className="trusted-inner">
 <div className="trusted-label">Trusted by category-defining brands</div>
 </div>
 <div className="marquee">
 <div className="marquee-track">
 {[...TRUSTED_ROW_ONE, ...TRUSTED_ROW_ONE].map((b, i) => (
 <BrandLogo key={i} logo={b} />
 ))}
 </div>
 </div>
 <div className="marquee">
 <div className="marquee-track marquee-track--reverse">
 {[...TRUSTED_ROW_TWO, ...TRUSTED_ROW_TWO].map((b, i) => (
 <BrandLogo key={i} logo={b} />
 ))}
 </div>
 </div>
 </div>
 </section>
 );
}

/* ---- Offer ---- */
const OFFERS = [
 {
 n: 'i',
 img: 'assets/offers/creator-marketing.png?v=2',
 alt: 'Creator marketing',
 title: <>Creator <span className="it">marketing</span></>,
 desc: 'We match your brand with creators whose audiences actually convert. From strategy to execution, we run campaigns that feel authentic.',
 },
 {
 n: 'ii',
 img: 'assets/offers/talent-management.png?v=2',
 alt: 'Talent management',
 title: <>Talent <span className="it">management</span></>,
 desc: 'We represent and grow creators end-to-end: brand deals, negotiations and positioning. You create; we handle the business of building your name.',
 },
 {
 n: 'iii',
 img: 'assets/offers/narrative-building.png?v=2',
 alt: 'Narrative building',
 title: <>Narrative <span className="it">building</span></>,
 desc: 'We shape how the world sees you. Through PR, storytelling, and strategic visibility, we craft the narrative that earns trust, press, and the right kind of attention.',
 },
 {
 n: 'iv',
 img: 'assets/offers/consulting.png?v=2',
 alt: 'Consulting',
 title: <>Consulting</>,
 desc: 'We sit with founders and teams to solve influence, growth, and positioning challenges. Practical, data-backed strategy tailored to where you are and where you want to go.',
 },
];

function WhatWeOffer() {
 const gridRef = useRef(null);
 const [activeIdx, setActiveIdx] = useState(0);

 useEffect(() => {
 const el = gridRef.current;
 if (!el) return;
 const onScroll = () => {
 const cards = el.querySelectorAll('.offer-card');
 if (!cards.length) return;
 const left = el.scrollLeft;
 let best = 0;
 let bestDist = Infinity;
 cards.forEach((c, i) => {
 const d = Math.abs(c.offsetLeft - left);
 if (d < bestDist) { bestDist = d; best = i; }
 });
 setActiveIdx(best);
 };
 el.addEventListener('scroll', onScroll, { passive: true });
 return () => el.removeEventListener('scroll', onScroll);
 }, []);

 const scrollToCard = (i) => {
 const el = gridRef.current;
 if (!el) return;
 const card = el.querySelectorAll('.offer-card')[i];
 if (card) el.scrollTo({ left: card.offsetLeft, behavior: 'smooth' });
 };

 return (
 <section className="sec sec--light" id="offer">
 <div className="sec-inner">
 <div className="section-label reveal">
 <span className="num">02</span>
 <span>What we offer</span>
 <span className="line" />
 </div>
 <h2 className="section-title reveal" data-d="1">
 A studio for <span className="it">brand influence</span>.<br />
 Not a media buy.
 </h2>
 <p className="section-sub reveal" data-d="2">
 Four disciplines, one team. We help legacy brands meet modern media, and we help modern brands stay in culture.
 </p>
 <div className="offer-grid" ref={gridRef}>
 {OFFERS.map((o, i) => (
 <div className="offer-card reveal" key={i} data-d={(i % 3) + 1}>
 <div className="offer-card__media">
 <img src={o.img} alt={o.alt} loading="lazy" draggable="false" />
 </div>
 <div className="offer-card__copy">
 <span className="idx">{o.n}</span>
 <p>{o.desc}</p>
 </div>
 </div>
 ))}
 </div>
 <div className="offer-dots" role="tablist" aria-label="What we offer navigation">
 {OFFERS.map((_, i) => (
 <button
 key={i}
 type="button"
 className={`offer-dot${i === activeIdx ? ' is-active' : ''}`}
 aria-label={`Go to card ${i + 1}`}
 aria-current={i === activeIdx ? 'true' : undefined}
 onClick={() => scrollToCard(i)}
 />
 ))}
 </div>
 </div>
 </section>
 );
}

/* ---- Roster ---- */
const ROSTER_CATS = [
 <>All <span className="it">creators</span></>,
 'Podcasters',
 <>Lifestyle <span className="it">&amp;</span> beauty</>,
 'Tech & business',
 'Food',
 'Sports & fitness',
 'Comedy',
 <>Culture <span className="it">&amp; voice</span></>,
];

/* Each creator: photo, niche pill (below photo), name, location, socials,
 and a list of brand campaigns shown on hover (each brand opens a campaign URL).
 `featured: true` → shown on the homepage (also driven by HOMEPAGE_ALL_ORDER / HOMEPAGE_EXCLUSIVE_ORDER).
 `exclusive: true` → renders the Exclusive badge and shows in the Exclusive tab. */
const ROSTER = [
 // ----- Featured (homepage) -----
 {
 name: 'Raj Shamani', loc: 'Mumbai', niche: 'Founder · Figuring Out',
 photo: 'assets/creators/raj.jpg', featured: true,
 youtube: { handle: '@RajShamani', count: '5.2M' },
 instagram: { handle: '@rajshamani', count: '2.4M' },
 campaigns: [
 { brand: 'CRED', url: '#case/cred-raj' },
 { brand: 'Zerodha', url: '#case/zerodha-raj' },
 { brand: 'Spotify', url: '#case/spotify-raj' },
 ],
 },
 {
 name: 'Think School', loc: 'Bangalore', niche: 'Business storytelling',
 photo: 'assets/creators/think.jpg', featured: true,
 youtube: { handle: '@ThinkSchool', count: '4.1M' },
 instagram: { handle: '@think.school', count: '610K' },
 campaigns: [
 { brand: 'Zerodha', url: '#case/zerodha-thinkschool' },
 { brand: 'Notion', url: '#case/notion-thinkschool' },
 { brand: 'Tata 1mg', url: '#case/tata1mg-thinkschool' },
 ],
 },
 {
 name: 'Ansh Mehra', loc: 'Mumbai', niche: 'Marketing & storytelling',
 company: 'Founder of The Cutting Edge School',
 photo: 'assets/creators/ansh.jpg', featured: true, exclusive: true,
 instagram: { handle: '@anshmehra.in', count: '238K' },
 youtube: { handle: '@CuttingEdgeSchool', count: '664K' },
 campaigns: [
 { brand: 'Mamaearth', url: '#case/mamaearth-ansh' },
 { brand: 'BoldCare', url: '#case/boldcare-ansh' },
 { brand: 'Notion', url: '#case/notion-ansh' },
 ],
 },
 {
 name: 'Anik Jain', loc: 'Delhi', niche: 'Tech & opinion',
 company: 'Founder of Anik Jain Design',
 photo: 'assets/creators/anik.jpg', exclusive: true,
 instagram: { handle: '@anikjaindesign', count: '455K' },
 youtube: { handle: '@anikjaindesign', count: '170K' },
 campaigns: [
 { brand: 'OnePlus', url: '#case/oneplus-anik' },
 { brand: 'BenQ', url: '#case/benq-anik' },
 { brand: 'CRED', url: '#case/cred-anik' },
 ],
 },
 {
 name: 'CA Rachana Ranade', loc: 'Pune', niche: 'Finance & investing',
 photo: 'assets/creators/rachana.jpg', featured: true,
 youtube: { handle: '@CARachanaRanade', count: '5.0M' },
 instagram: { handle: '@ca_rachanaranade', count: '710K' },
 campaigns: [
 { brand: 'Zerodha', url: '#case/zerodha-rachana' },
 { brand: 'ICICI Direct', url: '#case/icicidirect-rachana' },
 { brand: 'Smallcase', url: '#case/smallcase-rachana' },
 ],
 },
 {
 name: 'Zeel Jain', loc: 'Mumbai', niche: 'Lifestyle & travel',
 company: 'Founder of Know AI',
 photo: 'assets/creators/zeel.jpg', featured: true, exclusive: true,
 instagram: { handle: '@zeeeljain', count: '72K' },
 campaigns: [],
 },

 // ----- Full roster (also shown on the work / roster page) -----
 {
 name: 'Ishan Sharma', loc: 'Bangalore', niche: 'Tech & business',
 photo: 'assets/creators/ishaan.jpg',
 instagram: { handle: '@ishansharma7390', count: '1.1M' },
 youtube: { handle: '@IshanSharma7390', count: '2M' },
 campaigns: [
 { brand: 'Notion', url: '#case/notion-ishan' },
 { brand: 'Hostinger', url: '#case/hostinger-ishan' },
 { brand: 'Skillshare', url: '#case/skillshare-ishan' },
 ],
 },
 {
 name: 'Varun Mayya', loc: 'Dubai', niche: 'Founder · AI & tech',
 photo: 'assets/creators/varun-mayya.jpg',
 instagram: { handle: '@thevarunmayya', count: '1.2M' },
 youtube: { handle: '@VarunMayya', count: '950K' },
 campaigns: [
 { brand: 'Notion', url: '#case/notion-varun' },
 { brand: 'OpenAI', url: '#case/openai-varun' },
 { brand: 'Linear', url: '#case/linear-varun' },
 ],
 },
 {
 name: 'Varun Aggarwal', loc: 'Delhi', niche: 'Tech & PC builds',
 photo: 'assets/creators/varun-aggarwal.jpg',
 instagram: { handle: '@varun760', count: '180K' },
 campaigns: [
 { brand: 'Intel', url: '#case/intel-varuna' },
 { brand: 'AMD', url: '#case/amd-varuna' },
 { brand: 'BenQ', url: '#case/benq-varuna' },
 ],
 },
 {
 name: 'Manav Kwatra', loc: 'Mumbai', niche: 'Comedy & sketch',
 photo: 'assets/creators/manav.jpg', exclusive: true,
 instagram: { handle: '@manavisuals', count: '11K' },
 youtube: { handle: '@manavisuals', count: '110K' },
 campaigns: [],
 },
 {
 name: 'Tharun Naik', loc: 'Bangalore', niche: 'Tech reviews',
 photo: 'assets/creators/tharun-naik.png',
 youtube: { handle: '@TharunSpeaks', count: '610K' },
 instagram: { handle: '@tharunnaik.0', count: '180K' },
 campaigns: [
 { brand: 'OnePlus', url: '#case/oneplus-tharun' },
 { brand: 'Realme', url: '#case/realme-tharun' },
 ],
 },
 {
 name: 'Somrat Dutta', loc: 'Kolkata', niche: 'Podcaster · Culture',
 photo: 'assets/creators/somrat.jpg', exclusive: true,
 youtube: { handle: '@SomratDutta', count: '380K' },
 instagram: { handle: '@somrat.creates', count: '140K' },
 campaigns: [
 { brand: 'Audible', url: '#case/audible-somrat' },
 { brand: 'Spotify', url: '#case/spotify-somrat' },
 ],
 },
 {
 name: 'Aryaman Vir', loc: 'Bangalore', niche: 'Founder · Builder',
 photo: 'assets/creators/aryaman.png',
 youtube: { handle: '@AryamanVir', count: '180K' },
 instagram: { handle: '@aryamanvir', count: '80K' },
 campaigns: [
 { brand: 'Notion', url: '#case/notion-aryaman' },
 { brand: 'Linear', url: '#case/linear-aryaman' },
 ],
 },
 {
 name: 'Manan Sharma', loc: 'Delhi', niche: 'Comedy & shorts',
 photo: 'assets/creators/manan.png',
 instagram: { handle: '@manansharma', count: '320K' },
 youtube: { handle: '@MananSharma', count: '120K' },
 campaigns: [
 { brand: 'Zomato', url: '#case/zomato-manan' },
 { brand: 'Bira 91', url: '#case/bira-manan' },
 ],
 },
 {
 name: 'Raul John Aju', niche: 'CEO of Project 47x',
 photo: 'assets/creators/kid-creator.jpg',
 instagram: { handle: '@raul_the_rockstar', count: '' },
 campaigns: [],
 },

 // ----- AI Roster (from SocialTag AI Creator Roster) -----
 { name: 'Vaibhav Sisinty', company: 'Founder of Growth School',
 photo: 'assets/creators/vaibhav.jpeg',
 instagram: { handle: '@vaibhavsisinty', count: '1M' },
 youtube: { handle: '@vaibhavsisinty', count: '' },
 campaigns: [] },
 { name: 'Avinash Mada',
 instagram: { handle: '@meetavinash', count: '540K' },
 youtube: { handle: '@avinashmada', count: '55K' },
 campaigns: [] },
 { name: 'Aarti Samant', company: 'Founder of Sort your Marketing',
 photo: 'assets/creators/aarti.jpeg',
 instagram: { handle: '@thesortedgirl', count: '393K' },
 campaigns: [] },
 { name: 'Nikhil Pawar', company: 'Founder of Dope Motions',
 photo: 'assets/creators/nikhil.jpg',
 instagram: { handle: '@dope.motions', count: '746K' },
 youtube: { handle: '@dopemotions', count: '652K' },
 campaigns: [] },
 { name: '100x Engineers',
 instagram: { handle: '@100xengineers', count: '712K' },
 campaigns: [] },
 { name: 'Khushika Pahwa', company: 'Founder of Fond of Designs',
 photo: 'assets/creators/khushika.jpg',
 featured: true, exclusive: true,
 instagram: { handle: '@tickleandme', count: '168K' },
 campaigns: [] },
 { name: 'Jadhesh',
 photo: 'assets/creators/jadhesh.jpeg',
 instagram: { handle: '@jadheshvp', count: '287K' },
 youtube: { handle: 'channel/UCum_VwlI3a742x7HLKyrG4A', count: '' },
 campaigns: [] },
 { name: 'Ritika', company: 'Founder of Learn AI with Ritika',
 youtube: { handle: '@LearnAIwithRitika', count: '182K' },
 campaigns: [] },
 { name: 'Vishnu Vijayan', company: 'Founder of 11fps.ai',
 photo: 'assets/creators/vishnu.jpg',
 instagram: { handle: '@v.i.s.h.ai', count: '213K' },
 campaigns: [] },
 { name: 'Saptarshi',
 photo: 'assets/creators/sapta.jpg',
 instagram: { handle: '@saptarshiux', count: '427K' },
 youtube: { handle: '@saptarshipr', count: '157K' },
 campaigns: [] },
 { name: 'Akshat Tongia',
 photo: 'assets/creators/akshat.jpg',
 instagram: { handle: '@theakshattongia', count: '219K' },
 youtube: { handle: 'c/akshattongia', count: '' },
 campaigns: [] },
 { name: 'Saksham Gaur', company: 'Founder of Metro Media House',
 photo: 'assets/creators/saksham-gaur.png',
 exclusive: true,
 instagram: { handle: '@whysaksham', count: '175K' },
 campaigns: [] },
 { name: 'Ayushman Pandita',
 photo: 'assets/creators/pandita.jpg',
 instagram: { handle: '@ayushman.pandita', count: '418K' },
 youtube: { handle: '@AyushmanPandita', count: '791K' },
 campaigns: [] },
 { name: 'Adrien Ninet',
 instagram: { handle: '@adrien.ninet', count: '525K' },
 campaigns: [] },
 { name: 'Nathan Hodgson',
 instagram: { handle: '@nathanhodgson.ai', count: '109K' },
 campaigns: [] },
 { name: 'Nick Saraev',
 instagram: { handle: '@nick_saraev', count: '368K' },
 campaigns: [] },
 { name: 'Iron Coding',
 instagram: { handle: '@iron.coding', count: '214K' },
 campaigns: [] },
 { name: 'Malva AI',
 youtube: { handle: '@malvaAI', count: '57K' },
 campaigns: [] },
 { name: 'Rishi Udapurkar',
 photo: 'assets/creators/rishi.jpg',
 instagram: { handle: '@rishiudapurkar', count: '36K' },
 youtube: { handle: '@RishiiUdapurkar', count: '31K' },
 campaigns: [] },
 { name: 'Mohit Nagore',
 photo: 'assets/creators/mohit.jpg',
 instagram: { handle: '@mohitnagore.ai', count: '145K' },
 campaigns: [] },
 { name: 'Sahil Verma',
 photo: 'assets/creators/sahil.png',
 instagram: { handle: '@sahilverma.ai', count: '584K' },
 campaigns: [] },
 { name: 'Swarnima',
 instagram: { handle: '@swarnima.ai', count: '78K' },
 campaigns: [] },
 { name: 'Ashutosh Pratihast',
 photo: 'assets/creators/ashutosh.jpg',
 instagram: { handle: '@ashutoshpratihast', count: '448K' },
 campaigns: [] },
 { name: 'Shraddha Pawar',
 instagram: { handle: '@shraddha.dsgn', count: '154K' },
 campaigns: [] },
 { name: 'Kunwar', company: 'Founder of EcomJet',
 instagram: { handle: '@the_ecomjet', count: '308K' },
 campaigns: [] },
 { name: 'Aevy TV',
 instagram: { handle: '@aevytvdaily', count: '299K' },
 youtube: { handle: '@aevytv', count: '1.4M' },
 campaigns: [] },
 { name: 'AI Adventure',
 instagram: { handle: '@aiadventureryt', count: '105K' },
 campaigns: [] },
 { name: 'Tirth Patel',
 photo: 'assets/creators/tirth.jpeg',
 instagram: { handle: '@tirthpatel00', count: '185K' },
 campaigns: [] },
 { name: 'Abhinav Sayshi',
 instagram: { handle: '@abhinavsayshi', count: '101K' },
 campaigns: [] },
 { name: 'Toshi',
 instagram: { handle: '@designwithtoshi', count: '520K' },
 campaigns: [] },
];

const TONE_GRADIENTS = {
 rose: 'linear-gradient(160deg, #5a3340 0%, #a05a78 45%, #1a0d12 100%)',
 cobalt: 'linear-gradient(160deg, #1f3258 0%, #4870a8 45%, #0a1020 100%)',
 rust: 'linear-gradient(160deg, #5a3018 0%, #a85a2c 45%, #1a0d05 100%)',
 olive: 'linear-gradient(160deg, #303a1a 0%, #687a36 45%, #0d1208 100%)',
 amber: 'linear-gradient(160deg, #5a3a18 0%, #ad7530 45%, #1a1005 100%)',
 navy: 'linear-gradient(160deg, #18253f 0%, #324a72 45%, #050a18 100%)',
 plum: 'linear-gradient(160deg, #402550 0%, #7a4790 45%, #100618 100%)',
};

function SocialLink({ kind, handle, count }) {
 const Icon = { youtube: YouTubeIcon, instagram: InstagramIcon, spotify: SpotifyIcon, twitter: TwitterIcon }[kind];
 const url = {
 youtube: `https://youtube.com/${handle.replace('@','@')}`,
 instagram: `https://instagram.com/${handle.replace('@','')}`,
 spotify: `https://open.spotify.com/show/${handle.replace('@','')}`,
 twitter: `https://x.com/${handle.replace('@','')}`,
 }[kind];
 return (
 <a className="creator__social" href={url} target="_blank" rel="noreferrer" aria-label={`${kind} ${handle}`} onClick={(e) => e.stopPropagation()}>
 <Icon />
 <span>{count}</span>
 </a>
 );
}

function CreatorCard({ c }) {
 return (
 <article className="creator">
 <div className="creator__media">
 {c.exclusive && <span className="creator__exclusive-badge">Exclusive</span>}
 {c.photo ? (
 <img
 className="creator__photo creator__photo--img"
 src={c.photo}
 alt={c.name}
 loading="lazy"
 draggable="false"
 />
 ) : (
 <div className="creator__photo" style={{ background: TONE_GRADIENTS[c.tone] || '#222' }} />
 )}

 {c.campaigns && c.campaigns.length > 0 && (
 <div className="creator__campaigns">
 <div className="creator__campaigns-label">Featured campaigns</div>
 <div className="creator__brands">
 {c.campaigns.map((b, i) => (
 <a key={i} className="creator__brand" href={b.url} onClick={(e) => e.stopPropagation()}>
 {b.brand} <span className="arrow">↗</span>
 </a>
 ))}
 </div>
 </div>
 )}
 </div>

 <div className="creator__body">
 <div className="creator__name">{c.name}</div>
 <div className="creator__location">{c.company || c.loc}</div>

 <div className="creator__socials">
 {c.youtube && <SocialLink kind="youtube" handle={c.youtube.handle} count={c.youtube.count} />}
 {c.instagram && <SocialLink kind="instagram" handle={c.instagram.handle} count={c.instagram.count} />}
 {c.spotify && <SocialLink kind="spotify" handle={c.spotify.handle} count={c.spotify.count} />}
 {c.twitter && <SocialLink kind="twitter" handle={c.twitter.handle} count={c.twitter.count} />}
 </div>
 </div>
 </article>
 );
}

const HOMEPAGE_ALL_ORDER = [
 'Varun Mayya', 'Think School', 'Ansh Mehra', 'Raj Shamani',
 'Zeel Jain', 'Khushika Pahwa', 'Ishan Sharma', 'Manan Sharma',
];
const HOMEPAGE_EXCLUSIVE_ORDER = [
 'Khushika Pahwa', 'Zeel Jain', 'Ansh Mehra', 'Anik Jain',
 'Saksham Gaur', 'Somrat Dutta', 'Manav Kwatra',
];

/* ---- Creator faces (homepage roster) ----
   A staggered row of circular grayscale faces with a connector line to each
   name + handle, inspired by the reference roster wall. Only these creators
   are shown; faces without a photo render an initials circle. */
const CREATOR_FACES = [
 { name: 'Ansh Mehra', photo: 'assets/creators/ansh.jpg', handle: '@anshmehra.in' },
 { name: 'Anik Jain', photo: 'assets/creators/anik.jpg', handle: '@anikjaindesign' },
 { name: 'Abhijay Arora', photo: 'assets/creators/abhijay.jpg', handle: '@abhijayarora_', url: 'https://www.instagram.com/abhijayarora_/?hl=en' },
 { name: 'Khushika Pahwa', photo: 'assets/creators/khushika.jpg', handle: '@tickleandme' },
 { name: 'Ayushman Pandita', photo: 'assets/creators/pandita.jpg', handle: '@ayushman.pandita' },
 { name: 'Zeel Jain', photo: 'assets/creators/zeel.jpg', handle: '@zeeeljain' },
 { name: 'Somrat Dutta', photo: 'assets/creators/somrat.jpg', handle: '@somrat.creates' },
 { name: 'Akshat Tongia', photo: 'assets/creators/akshat.jpg', handle: '@theakshattongia' },
 { name: 'Saksham Gaur', photo: 'assets/creators/saksham-gaur.png', handle: '@whysaksham' },
 { name: 'Rishi Udapurkar', photo: 'assets/creators/rishi.jpg', handle: '@rishiudapurkar' },
 { name: 'Ananya Bagri', photo: 'assets/creators/ananya.jpg', handle: '@ananyabagri', url: 'https://www.instagram.com/ananyabagri' },
 { name: 'Manav Kwatra', photo: 'assets/creators/manav.jpg', handle: '@manavisuals' },
];

function FaceItem({ c, up }) {
 const initials = c.name.split(' ').map((w) => w[0]).slice(0, 2).join('');
 const href = c.url || (c.handle ? `https://instagram.com/${c.handle.replace(/^@/, '')}` : null);
 const label = (
 <div className="cf-label">
 <div className="cf-name">{c.name}</div>
 {c.handle && <div className="cf-handle">{c.handle}</div>}
 </div>
 );
 const connector = <div className="cf-connector" />;
 const face = (
 <span className="cf-face">
 {c.photo
 ? <img src={c.photo} alt={c.name} loading="lazy" draggable="false" />
 : <span className="cf-initials">{initials}</span>}
 </span>
 );
 const labelGroup = (
 <div className="cf-label-group">
 {up ? <>{label}{connector}</> : <>{connector}{label}</>}
 </div>
 );
 const inner = up ? <>{labelGroup}{face}</> : <>{face}{labelGroup}</>;
 const cls = `cf-item ${up ? 'cf-item--up' : 'cf-item--down'}`;
 return href
 ? <a className={cls} href={href} target="_blank" rel="noreferrer" aria-label={c.name}>{inner}</a>
 : <div className={cls}>{inner}</div>;
}

function CreatorFaces() {
 return (
 <section className="sec sec--dark creator-faces" id="roster">
 <div className="sec-inner">
 <div className="section-label reveal">
 <span className="num">03</span>
 <span>Creative roster</span>
 <span className="line" />
 </div>
 <h2 className="section-title reveal" data-d="1">
 Creators who <span className="it">own</span> distribution.
 </h2>
 <p className="section-sub reveal" data-d="2">
 A creative bench of voices shaping opinion across India: AI, tech, business and culture.
 </p>
 <div className="cf-row reveal" data-d="3">
 {CREATOR_FACES.map((c, i) => (
 <FaceItem key={c.name} c={c} up={i % 2 === 1} />
 ))}
 </div>
 </div>
 </section>
 );
}

function CreativeRoster() {
 const [active, setActive] = useState(0);
 const [tab, setTab] = useState('all');
 const showAll = typeof window !== 'undefined' && window.__FULL_ROSTER__ === true;

 let list;
 if (showAll) {
 list = tab === 'exclusive' ? ROSTER.filter((c) => c.exclusive) : ROSTER;
 } else {
 const order = tab === 'exclusive' ? HOMEPAGE_EXCLUSIVE_ORDER : HOMEPAGE_ALL_ORDER;
 list = order.map((n) => ROSTER.find((c) => c.name === n)).filter(Boolean);
 }

 return (
 <section className="sec sec--dark" id="roster">
 <div className="sec-inner">
 <div className="section-label reveal">
 <span className="num">03</span>
 <span>Creative roster</span>
 <span className="line" />
 </div>
 <h2 className="section-title reveal" data-d="1">
 Creators who <span className="it">own</span> distribution.
 </h2>
 <p className="section-sub reveal" data-d="2">
 A creative bench of voices shaping opinion across India, across AI, tech, and leading enterprises and businesses.
 </p>

 <div className="roster-tabs reveal" data-d="3">
 <button
 className={`roster-tab ${tab === 'all' ? 'active' : ''}`}
 onClick={() => setTab('all')}
 >All creators</button>
 <button
 className={`roster-tab ${tab === 'exclusive' ? 'active' : ''}`}
 onClick={() => setTab('exclusive')}
 >Exclusive</button>
 </div>

 {showAll && (
 <div className="roster-cats reveal" data-d="3">
 {ROSTER_CATS.map((c, i) => (
 <button
 key={i}
 className={`roster-cat ${i === active ? 'active' : ''}`}
 onClick={() => setActive(i)}
 >{c}</button>
 ))}
 </div>
 )}

 <div className="roster-grid">
 {list.map((c, i) => (
 <div className="reveal" data-d={(i % 4) + 1} key={c.name}>
 <CreatorCard c={c} />
 </div>
 ))}
 </div>

 {!showAll && (
 <div className="roster-more reveal">
 <a href="Creative Roster.html" className="btn btn-ghost">
 See the full roster <span className="arrow">→</span>
 </a>
 </div>
 )}
 </div>
 </section>
 );
}

/* ---- Case studies ---- */
/* Case studies — each maps to a brand cover (assets/case-covers) and the
   creators we collaborated with. Creator `img` points at assets/creators/*;
   set img:null to leave an initials-placeholder slot until a photo is added. */
const CASES = [
  {
    brand: 'ChatGPT',
    featured: true,
    tag: 'Awareness · Adoption',
    cover: 'assets/case-covers/openai-cover.png',
    vp: 'vp-7',
    url: 'case-studies/chatgpt.html',
    headline: <>We made AI <span className="it">impossible</span> to ignore.</>,
    sub: 'When AI became mainstream, we made utility go viral.',
    stats: [
      { v: '1M+', l: 'Views & impressions' },
      { v: '50K+', l: 'Interactions' },
    ],
    creators: [
      { name: 'Khushika', img: 'assets/creators/khushika.jpg' },
      { name: 'Rishi Udapurkar', img: 'assets/creators/rishi.jpg' },
      { name: 'Vishnu Vijayan', img: 'assets/creators/vishnu.jpg' },
      { name: 'Anik Jain', img: 'assets/creators/anik.jpg' },
    ],
  },
  {
    brand: 'Emergent',
    tag: 'Trust · Credibility',
    cover: 'assets/case-covers/emergent-cover.png',
    vp: 'vp-6',
    url: 'case-studies/emergent.html',
    headline: <>Building <span className="it">trust</span> in a category built on hype.</>,
    sub: 'We helped builders connect with builders.',
    stats: [
      { v: '10M+', l: 'Views across phases' },
      { v: '50K+', l: 'Interactions' },
    ],
    creators: [
      { name: 'Akshat', img: 'assets/creators/akshat.jpg' },
      { name: 'Khushika', img: 'assets/creators/khushika.jpg' },
      { name: 'Ayushman Pandita', img: 'assets/creators/pandita.jpg' },
      { name: 'Saksham', img: 'assets/creators/saksham.jpg' },
      { name: 'Jadhesh', img: 'assets/creators/jadhesh.jpg' },
      { name: 'Zeel', img: 'assets/creators/zeel.jpg' },
      { name: 'Mohit Nagore', img: 'assets/creators/mohit.jpg' },
      { name: 'Rishi Udapurkar', img: 'assets/creators/rishi.jpg' },
      { name: 'Vishnu Vijayan', img: 'assets/creators/vishnu.jpg' },
      { name: 'Anik Jain', img: 'assets/creators/anik.jpg' },
      { name: 'Tirth', img: 'assets/creators/tirth.jpeg' },
      { name: 'Ansh Mehra', img: 'assets/creators/ansh.jpg' },
    ],
  },
  {
    brand: 'Higgsfield',
    tag: 'Cinematic AI',
    cover: 'assets/case-covers/higgsfield-cover.png',
    vp: 'vp-5',
    url: 'case-studies/higgsfield.html',
    headline: <>Create what <span className="it">couldn't</span> be created before.</>,
    sub: 'We turned AI filmmaking into scroll-stopping entertainment.',
    stats: [
      { v: '2M+', l: 'Organic views' },
      { v: '100K+', l: 'Interactions' },
    ],
    creators: [
      { name: 'Anik Jain', img: 'assets/creators/anik.jpg' },
      { name: 'Ansh Mehra', img: 'assets/creators/ansh.jpg' },
      { name: 'Jadhesh', img: 'assets/creators/jadhesh.jpg' },
      { name: 'Somrat Dutta', img: 'assets/creators/somrat.jpg' },
      { name: 'Vishnu Vijayan', img: 'assets/creators/vishnu.jpg' },
    ],
  },
  {
    brand: 'Hostinger',
    tag: 'Multi-phase',
    cover: 'assets/case-covers/hostinger-cover.png',
    vp: 'vp-6',
    url: 'case-studies/hostinger.html',
    headline: <>Every great business starts with a <span className="it">tab open</span> somewhere.</>,
    sub: 'We turned ambition into action.',
    stats: [
      { v: '10M+', l: 'Reach' },
      { v: '1M+', l: 'Cross-platform' },
      { v: '174K+', l: 'Top organic post' },
    ],
    creators: [
      { name: 'Dope Motions', img: null },
      { name: 'Ishan Sharma', img: 'assets/creators/ishaan.jpg' },
      { name: 'Ayushman Pandita', img: 'assets/creators/pandita.jpg' },
      { name: 'Manav Kwatra', img: 'assets/creators/manav.jpg' },
      { name: 'Varun Mayya', img: 'assets/creators/varun-mayya.jpg' },
    ],
  },
  {
    brand: 'Wondershare',
    tag: 'Workflow · Productivity',
    cover: 'assets/case-covers/wondershare-cover.png',
    vp: 'vp-3',
    url: 'case-studies/wondershare.html',
    headline: <>Behind every great creator is a <span className="it">better workflow</span>.</>,
    sub: 'We made productivity feel creative.',
    stats: [
      { v: '5M+', l: 'Cross-platform performance' },
    ],
    creators: [
      { name: 'Somrat Dutta', img: 'assets/creators/somrat.jpg' },
      { name: 'Manav Kwatra', img: 'assets/creators/manav.jpg' },
      { name: 'Ayushman Pandita', img: 'assets/creators/pandita.jpg' },
      { name: 'Anik Jain', img: 'assets/creators/anik.jpg' },
    ],
  },
  {
    brand: 'TopView',
    tag: 'Performance · AI',
    cover: 'assets/case-covers/topview-cover.png',
    vp: 'vp-2',
    url: 'case-studies/topview.html',
    headline: <>The best ads <span className="it">don't feel</span> like ads.</>,
    sub: 'We made performance marketing look effortless.',
    stats: null,
    creators: [
      { name: 'Ansh Mehra', img: 'assets/creators/ansh.jpg' },
      { name: 'Somrat Dutta', img: 'assets/creators/somrat.jpg' },
      { name: 'Rishi Udapurkar', img: 'assets/creators/rishi.jpg' },
      { name: 'Anik Jain', img: 'assets/creators/anik.jpg' },
      { name: 'Manav Kwatra', img: 'assets/creators/manav.jpg' },
      { name: 'Ayushman Pandita', img: 'assets/creators/pandita.jpg' },
    ],
  },
  {
    brand: 'OpenArt',
    tag: 'AI Creative',
    cover: 'assets/case-covers/openart-cover.png',
    vp: 'vp-4',
    url: null,
    headline: <>When <span className="it">creativity</span> meets computation.</>,
    sub: 'We transformed prompts into possibilities.',
    stats: null,
    creators: [
      { name: 'Ansh Mehra', img: 'assets/creators/ansh.jpg' },
      { name: 'Vishnu Vijayan', img: 'assets/creators/vishnu.jpg' },
      { name: 'Ayushman Pandita', img: 'assets/creators/pandita.jpg' },
    ],
  },
];

const csInitials = (name) =>
  name.split(' ').filter(Boolean).slice(0, 2).map((w) => w[0]).join('').toUpperCase();

function CaseStudies() {
  const MAX_AVATARS = 6;
  return (
    <section className="sec sec--light" id="case-studies">
      <div className="sec-inner">
        <div className="section-label reveal">
          <span className="num">04</span>
          <span>Case studies</span>
          <span className="line" />
        </div>
        <h2 className="section-title reveal" data-d="1">
          Helping brands <span className="it">tell their story</span>.
        </h2>
        <p className="section-sub reveal" data-d="2">
          Real campaigns with measurable impact.
        </p>
        <div className="csx-grid">
          {CASES.slice(0, 3).map((c, i) => {
            const Wrapper = c.url ? 'a' : 'article';
            const wrapProps = c.url ? { href: c.url } : {};
            const shown = c.creators.slice(0, MAX_AVATARS);
            const extra = c.creators.length - shown.length;
            return (
              <Wrapper
                key={c.brand}
                className="csx reveal"
                data-d={(i % 3) + 1}
                {...wrapProps}
              >
                <div className="csx__cover">
                  {c.cover ? (
                    <img className="csx__cover-img" src={c.cover} alt={`${c.brand} campaign`} loading="lazy" />
                  ) : (
                    <div className={`csx__cover-fallback ${c.vp}`} />
                  )}
                  <div className="csx__scrim" />
                  <div className="csx__cover-top">
                    <span className="csx__tag">{c.tag}</span>
                    {c.url && (
                      <span className="csx__view">View campaign <span className="arr">→</span></span>
                    )}
                  </div>
                  <div className="csx__brand">{c.brand} <span className="csx__brand-x">×</span> SocialTag</div>
                </div>
                <div className="csx__body">
                  {c.stats ? (
                    <div className="csx__stats">
                      {c.stats.map((s, j) => (
                        <div className="csx__stat" key={j}>
                          <div className="csx__stat-v serif">{s.v}</div>
                          <div className="csx__stat-l">{s.l}</div>
                        </div>
                      ))}
                    </div>
                  ) : (
                    <div className="csx__soon"><span className="csx__soon-dot" /> Results coming soon</div>
                  )}
                  <div className="csx__creators">
                    <div className="csx__avatars">
                      {shown.map((cr, k) => (
                        <span className="csx__avatar" key={k} title={cr.name} style={{ zIndex: shown.length - k }}>
                          {cr.img ? (
                            <img src={cr.img} alt={cr.name} loading="lazy" />
                          ) : (
                            <span className="csx__avatar-fallback">{csInitials(cr.name)}</span>
                          )}
                        </span>
                      ))}
                      {extra > 0 && <span className="csx__avatar csx__avatar--more">+{extra}</span>}
                    </div>
                    <div className="csx__creators-label">
                      {c.creators.length} creator{c.creators.length > 1 ? 's' : ''} we collaborated with
                    </div>
                  </div>
                </div>
              </Wrapper>
            );
          })}
        </div>

        <div className="case-more reveal">
          <a href="Work.html" className="btn btn-ghost">
            Read more case studies <span className="arrow">→</span>
          </a>
        </div>
      </div>
    </section>
  );
}

/* ============== WORK PAGE (simple, card grid) ============== */
/* Title + subtitle + animated stat ribbon, then a clean grid of case-study
   cards. Each card opens the brand's full case study. */

const WORK_CASES = [
  {
    brand: 'Hostinger',
    title: 'Turning aspiration into the first line of code',
    category: 'Multi-phase creator campaign',
    year: '2025-26',
    cover: 'assets/case-covers/hostinger-cover.png',
    url: 'case-studies/hostinger.html',
  },
  {
    brand: 'Higgsfield',
    title: 'Putting generative video on every Indian creator\'s timeline',
    category: 'Creator-led product launch',
    year: '2025',
    cover: 'assets/case-covers/higgsfield-cover.png',
    url: 'case-studies/higgsfield.html',
  },
  {
    brand: 'Emergent',
    title: 'Build for the world: six phases of founder-led innovation',
    category: 'Multi-phase creator campaign',
    year: '2025-26',
    cover: 'assets/case-covers/emergent-cover.png',
    url: 'case-studies/emergent.html',
  },
  {
    brand: 'ChatGPT',
    title: 'India\'s creator class meets the world\'s biggest model',
    category: 'Always-on creator series',
    year: '2024-26',
    cover: 'assets/case-covers/openai-cover.png',
    url: 'case-studies/chatgpt.html',
  },
  {
    brand: 'Topview',
    title: 'Short-form analytics, told by people who live in short-form',
    category: 'Founder-led narrative',
    year: '2025',
    cover: 'assets/case-covers/topview-cover.png',
    url: 'case-studies/topview.html',
  },
  {
    brand: 'Wondershare',
    title: 'Editor reviews that actually move SKUs',
    category: 'Performance + brand',
    year: '2024-25',
    cover: 'assets/case-covers/wondershare-cover.png',
    url: 'case-studies/wondershare.html',
  },
  {
    brand: 'OpenArt',
    title: 'When creativity meets computation',
    category: 'AI creative · creator-led',
    year: '2026',
    cover: 'assets/case-covers/openart-cover.png',
    vp: 'vp-4',
    url: 'case-studies/openart.html',
  },
  {
    brand: 'Solid',
    title: 'Letting builders prove an AI app builder ships real code',
    category: 'Creator-led product launch',
    year: '2025-26',
    cover: 'assets/case-covers/solid-cover.png',
    vp: 'vp-2',
    url: 'case-studies/solid.html',
  },
];

/* Stats showcase — real site numbers. `sub` is short descriptor copy added to
   fill the card's subtext slot (the site had only the heading); edit freely.
   `tilt` drives the hand-placed rotation (alternating direction). */
const HOME_STATS = [
  { v: 2.3, decimals: 1, suffix: 'B+', heading: 'Aggregate views', sub: 'Across every campaign, every platform.', tilt: -4 },
  { v: 850, decimals: 0, suffix: '+', heading: 'Brands shipped with', sub: 'From startups to category leaders.', tilt: 3 },
  { v: 6, decimals: 0, suffix: '+', heading: 'Years in the game', sub: 'Shipping influence that lasts.', tilt: -3 },
];

const STX_MOBILE_QUERY = '(max-width: 768px)';

function formatStat(value, decimals) {
  if (decimals > 0) return value.toFixed(decimals);
  return Math.round(value).toLocaleString();
}

/* One stat card. When `animate` is true it counts up from 0 with an
   ease-out cubic via requestAnimationFrame once `run` (in-view) is set.
   When false it renders the final value immediately (mobile / reduced-motion). */
function StatCard({ s, index, animate, run, className }) {
  const [val, setVal] = useState(animate ? 0 : s.v);

  useEffect(() => {
    if (!animate) { setVal(s.v); return; }
    if (!run) { setVal(0); return; }
    let raf;
    const dur = 1900;
    const startAt = performance.now() + index * 140;
    const tick = (t) => {
      if (t < startAt) { raf = requestAnimationFrame(tick); return; }
      const p = Math.min(1, (t - startAt) / dur);
      const eased = 1 - Math.pow(1 - p, 3); // ease-out
      setVal(s.v * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
      else setVal(s.v);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [animate, run, s.v, index]);

  return (
    <article className={'stx-card' + (className ? ' ' + className : '')} style={{ '--tilt': s.tilt + 'deg' }}>
      <div className="stx-card__num">
        {formatStat(val, s.decimals)}<span className="stx-card__suffix">{s.suffix}</span>
      </div>
      <h3 className="stx-card__heading">{s.heading}</h3>
      <span className="stx-card__divider" aria-hidden="true" />
      <p className="stx-card__sub">{s.sub}</p>
    </article>
  );
}

function HomeStats() {
  const sectionRef = useRef(null);
  const trackRef = useRef(null);
  const [inView, setInView] = useState(false);
  const [isMobile, setIsMobile] = useState(false);
  const [reduceMotion, setReduceMotion] = useState(false);

  // Desktop vs mobile behavior switch via matchMedia.
  useEffect(() => {
    if (!window.matchMedia) return;
    const mq = window.matchMedia(STX_MOBILE_QUERY);
    const apply = () => setIsMobile(mq.matches);
    apply();
    mq.addEventListener('change', apply);
    return () => mq.removeEventListener('change', apply);
  }, []);

  // Respect prefers-reduced-motion — skip the count-up entirely.
  useEffect(() => {
    if (!window.matchMedia) return;
    const mq = window.matchMedia('(prefers-reduced-motion: reduce)');
    const apply = () => setReduceMotion(mq.matches);
    apply();
    mq.addEventListener('change', apply);
    return () => mq.removeEventListener('change', apply);
  }, []);

  // Trigger the desktop count-up when the section scrolls into view.
  useEffect(() => {
    const el = sectionRef.current;
    if (!el) return;
    const io = new IntersectionObserver(
      (entries) => entries.forEach((e) => { if (e.isIntersecting) setInView(true); }),
      { threshold: 0.3 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);

  // Mobile popover stack: drive all three cards from ONE scroll-progress value.
  // A tall track holds a sticky stage; as the stage stays pinned, progress goes
  // 0→1 and each card slides up to stack. Because every card reads the same
  // progress, they move as a single unit — the front card can't desync/detach
  // (the failure mode of three independent position:sticky cards on mobile).
  useEffect(() => {
    if (!isMobile) return;
    const track = trackRef.current;
    if (!track) return;
    const stage = track.querySelector('.stx-stack__stage');
    const cards = Array.prototype.slice.call(track.querySelectorAll('.stx-card--stack'));
    if (!stage || cards.length === 0) return;
    const TILT = [-5, 3, -3];           // per-card rotation (deg)
    // Progress window each card slides in over. The windows are sequential with a
    // gap between them (card 2 finishes at 0.40, card 3 doesn't start until 0.55)
    // so each card fully lands — and sits visible for a beat — before the next one
    // begins covering it. Card 3 finishes by 0.90, leaving a short end "hold".
    const ENTER = [[0, 0], [0.05, 0.40], [0.55, 0.90]];
    const SLIDE = 460;                  // px each card travels up from below into the stack
    let raf = 0;
    const update = () => {
      raf = 0;
      const dist = Math.max(1, track.offsetHeight - stage.offsetHeight);
      let p = -track.getBoundingClientRect().top / dist;
      if (reduceMotion) p = 1;          // reduced motion → show the finished stack, no scrub
      p = Math.min(1, Math.max(0, p));
      for (let i = 0; i < cards.length; i++) {
        const a = ENTER[i][0], b = ENTER[i][1];
        const lp = b <= a ? 1 : Math.min(1, Math.max(0, (p - a) / (b - a)));
        const ty = (1 - lp) * SLIDE;
        cards[i].style.transform =
          'translate(-50%, -50%) translateY(' + ty.toFixed(1) + 'px) rotate(' + TILT[i] + 'deg)';
      }
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(update); };
    update();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, [isMobile, reduceMotion]);

  const animateDesktop = !isMobile && !reduceMotion;

  return (
    <section ref={sectionRef} className="sec sec--light home-stats-sec">
      <div className="sec-inner">
        {/* Desktop: three rotated, overlapping cards that count up in view. */}
        <div className="stx stx--desktop" aria-hidden={isMobile ? 'true' : undefined}>
          {HOME_STATS.map((s, i) => (
            <StatCard key={s.heading} s={s} index={i} animate={animateDesktop} run={inView} />
          ))}
        </div>
      </div>

      {/* Mobile: scroll-driven popover stack. The tall track keeps the sticky
          stage pinned while you scroll; a single scroll-progress value (see the
          effect above) slides each card up to stack. All three cards are locked
          to that one value, so they move as a unit and the front card can't
          detach. Static values, no count-up. */}
      <div className="stx-stack" aria-hidden={!isMobile ? 'true' : undefined}>
        <div className="stx-stack__track" ref={trackRef}>
          <div className="stx-stack__stage">
            {HOME_STATS.map((s, i) => (
              <StatCard key={s.heading} s={s} index={i} animate={false} run={false} className="stx-card--stack" />
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function WorkPage() {
  return (
    <React.Fragment>
      <section className="sec sec--dark wpx-hero" data-screen-label="01 Work hero">
        <div className="sec-inner">
          <div className="section-label reveal">
            <span className="num">04</span>
            <span>Our work</span>
            <span className="line" />
          </div>

          <h1 className="wpx-hero__title serif reveal" data-d="1">
            We don't send <span className="it">decks</span>.<br />
            We send <span className="it">results</span>.
          </h1>

          <p className="wpx-hero__sub reveal" data-d="2">
            A review of campaigns we shipped. Every number you see is the one we delivered, not the one we pitched.
          </p>
        </div>
      </section>

      <section className="sec sec--dark wpx-cases" data-screen-label="02 Case studies">
        <div className="sec-inner">
          <div className="wpx-grid">
            {WORK_CASES.map((c, i) => (
              <a
                key={c.brand}
                href={c.url}
                className="wpx-card reveal"
                data-d={(i % 3) + 1}
              >
                <div className="wpx-card__cover">
                  {c.cover ? (
                    <img src={c.cover} alt={c.brand + ' cover'} loading="lazy" />
                  ) : (
                    <div className={`wpx-card__cover-fallback ${c.vp || 'vp-4'}`}>
                      <span>{c.brand}</span>
                    </div>
                  )}
                </div>
                <div className="wpx-card__body">
                  <div className="wpx-card__meta">
                    <span>{c.category}</span>
                    <span className="dot" />
                    <span>{c.year}</span>
                  </div>
                  <div className="wpx-card__brand">{c.brand} × SocialTag</div>
                  <h3 className="wpx-card__title serif">{c.title}</h3>
                </div>
              </a>
            ))}
          </div>
        </div>
      </section>
    </React.Fragment>
  );
}


/* ---- Press + testimonials ---- */
const PRESS = [
 {
 name: 'MediaNews4U',
 logo: 'assets/logos/press/medianews4u.png',
 headline: 'SocialTag rebrands to build deeper media partnerships with tech and AI brands',
 url: 'https://www.medianews4u.com/socialtag-rebrands-to-build-deeper-media-partnerships-with-tech-and-ai-brands/',
 },
 {
 name: 'Passionate in Marketing',
 logo: 'assets/logos/press/passionate-in-marketing.jpg',
 headline: 'SocialTag rebrands with a sharper focus on tech, AI and design-first brands',
 url: 'https://www.passionateinmarketing.com/socialtag-rebrands-with-a-sharper-focus-on-tech-ai-and-design-first-brands-continues-to-manage-indias-most-credible-creator-voices/',
 },
 {
 name: 'Marketing Mind',
 logo: 'assets/logos/press/marketing-mind.jpg',
 headline: 'SocialTag rebrands with strategic focus on tech, AI and design categories',
 url: 'https://marketingmind.in/socialtag-rebrands-with-strategic-focus-on-tech-ai-and-design-categories/',
 },
 {
 name: 'Social Samosa',
 logo: 'assets/logos/press/social-samosa.png',
 headline: 'SocialTag rebrands, focus on tech, AI, design storytelling',
 url: 'https://www.socialsamosa.com/industry-updates/socialtag-rebrands-focus-tech-ai-design-storytelling-11179874',
 },
];

const TESTIMONIALS = [
 {
 quote: <>SocialTag didn't sell us a creator list, they <span className="it">designed</span> a year of brand presence for us. The difference shows in every metric.</>,
 name: 'Aanya Krishnan',
 role: 'CMO · Consumer beauty brand',
 initial: 'A',
 },
 {
 quote: <>The team understands the <span className="it">difference</span> between attention and influence. That's rare. Our podcast play with them is now our most efficient channel.</>,
 name: 'Rohit Bhalla',
 role: 'Head of growth · Fintech',
 initial: 'R',
 },
 {
 quote: <>They handle creators with care and brands with rigour. The combination is what most agencies <span className="it">cannot</span> do.</>,
 name: 'Devika Menon',
 role: 'Brand director · Heritage retail',
 initial: 'D',
 },
];

/* Horizontal mobile carousel: tracks the centred card on scroll and
   auto-advances every `interval` ms (only when the container actually
   scrolls — i.e. on mobile). Pauses while the user is interacting. */
function useCarousel(itemSelector, interval = 3200) {
 const ref = useRef(null);
 const [activeIdx, setActiveIdx] = useState(0);

 useEffect(() => {
 const el = ref.current;
 if (!el) return;
 const onScroll = () => {
 const cards = el.querySelectorAll(itemSelector);
 if (!cards.length) return;
 const viewCenter = el.scrollLeft + el.clientWidth / 2;
 let best = 0;
 let bestDist = Infinity;
 cards.forEach((c, i) => {
 const cardCenter = c.offsetLeft + c.offsetWidth / 2;
 const d = Math.abs(cardCenter - viewCenter);
 if (d < bestDist) { bestDist = d; best = i; }
 });
 setActiveIdx(best);
 };
 el.addEventListener('scroll', onScroll, { passive: true });
 return () => el.removeEventListener('scroll', onScroll);
 }, [itemSelector]);

 const centerTarget = (el, card) =>
 Math.max(0, card.offsetLeft - (el.clientWidth - card.offsetWidth) / 2);

 const scrollToCard = (i) => {
 const el = ref.current;
 if (!el) return;
 const card = el.querySelectorAll(itemSelector)[i];
 if (card) el.scrollTo({ left: centerTarget(el, card), behavior: 'smooth' });
 };

 useEffect(() => {
 const el = ref.current;
 if (!el) return;
 let paused = false;
 const onEnter = () => { paused = true; };
 const onLeave = () => { paused = false; };
 el.addEventListener('pointerenter', onEnter);
 el.addEventListener('pointerleave', onLeave);
 el.addEventListener('touchstart', onEnter, { passive: true });
 el.addEventListener('touchend', onLeave, { passive: true });
 const id = setInterval(() => {
 if (paused) return;
 if (el.scrollWidth - el.clientWidth < 8) return; // not a scroller (desktop)
 const cards = el.querySelectorAll(itemSelector);
 if (!cards.length) return;
 const next = (activeIdx + 1) % cards.length;
 const card = cards[next];
 if (card) el.scrollTo({ left: centerTarget(el, card), behavior: 'smooth' });
 }, interval);
 return () => {
 clearInterval(id);
 el.removeEventListener('pointerenter', onEnter);
 el.removeEventListener('pointerleave', onLeave);
 el.removeEventListener('touchstart', onEnter);
 el.removeEventListener('touchend', onLeave);
 };
 }, [activeIdx, itemSelector, interval]);

 return { ref, activeIdx, scrollToCard };
}

function Press() {
 const press = useCarousel('.press-cell');
 const testi = useCarousel('.testi');

 return (
 <section className="sec sec--dark" id="press">
 <div className="sec-inner">
 <div className="section-label reveal">
 <span className="num">05</span>
 <span>As featured in</span>
 <span className="line" />
 </div>
 <h2 className="section-title reveal" data-d="1" style={{ marginBottom: 56 }}>
 Leading publications<br />
 have <span className="it">covered our work</span>.
 </h2>
 <div className="press-strip reveal" data-d="3" ref={press.ref}>
 {PRESS.map((p, i) => (
 <a
 className="press-cell"
 key={i}
 href={p.url}
 target="_blank"
 rel="noopener noreferrer"
 aria-label={`${p.name}, ${p.headline}`}
 >
 <div className="press-cell__plate">
 <img src={p.logo} alt={p.name} loading="lazy" />
 </div>
 <span className="press-cell__cta">Read article <span className="arr">→</span></span>
 </a>
 ))}
 </div>
 <div className="press-dots" role="tablist" aria-label="Publications navigation">
 {PRESS.map((_, i) => (
 <button
 key={i}
 type="button"
 className={`press-dot${i === press.activeIdx ? ' is-active' : ''}`}
 aria-label={`Go to publication ${i + 1}`}
 aria-current={i === press.activeIdx ? 'true' : undefined}
 onClick={() => press.scrollToCard(i)}
 />
 ))}
 </div>

 <div className="section-label reveal" style={{ marginTop: 20 }}>
 <span className="num">·</span>
 <span>What partners say</span>
 <span className="line" />
 </div>
 <h2 className="section-title reveal" data-d="1" style={{ fontSize: 'clamp(36px, 4.4vw, 64px)', marginBottom: 56 }}>
 We bridge <span className="it">the gap</span> between legacy companies and modern media.
 </h2>
 <div className="testi-grid" ref={testi.ref}>
 {TESTIMONIALS.map((t, i) => (
 <figure key={i} className="testi reveal" data-d={i + 1}>
 <div className="quote-mark">"</div>
 <blockquote>{t.quote}</blockquote>
 <figcaption className="author">
 <div className="avatar">{t.initial}</div>
 <div className="author-info">
 <div className="name">{t.name}</div>
 <div className="role">{t.role}</div>
 </div>
 </figcaption>
 </figure>
 ))}
 </div>
 <div className="testi-dots" role="tablist" aria-label="Testimonials navigation">
 {TESTIMONIALS.map((_, i) => (
 <button
 key={i}
 type="button"
 className={`press-dot${i === testi.activeIdx ? ' is-active' : ''}`}
 aria-label={`Go to testimonial ${i + 1}`}
 aria-current={i === testi.activeIdx ? 'true' : undefined}
 onClick={() => testi.scrollToCard(i)}
 />
 ))}
 </div>
 </div>
 </section>
 );
}

/* ---- About ---- */
const ABOUT_STATS = [
 { v: '350+', l: 'Clients' },
 { v: '10,000+', l: 'Campaigns' },
 { v: '100+', l: 'Team members' },
 { v: '6+', l: 'Years in the game' },
];

const FOUNDER_NOTE = [
 "I started SocialTAG because I saw a gap nobody was filling. Tech companies building genuinely incredible products were hiring agencies that didn't understand the first thing about their buyer. The creators they picked had reach but no relevance. The content looked good but converted nothing. And the agency called it a success because the impressions looked nice in a deck.",
 "I'm from Manipur. I built this in Mumbai with no industry connections, no family business, no fallback. Just one bet: that credibility converts better than clout. That a creator who actually uses Figma will outsell a creator who's never opened it. That tech audiences deserve better than recycled influencer playbooks.",
 "That bet paid off. 850+ brands later, Adobe, Figma, Notion, Miro, Replit, HeyGen. Creators like Raj Shamani, Sharan Hegde, Rachna Ranade, Varun Mayya trusting us with their partnerships. And still, every major client found us through word of mouth.",
 "I don't think creator marketing is a \u201Cchannel.\u201D It's the distribution layer that will define the next decade. If you're building something real, I'd love to help you tell that story.",
];

function About() {
 return (
 <React.Fragment>
 {/* HERO IMAGE — full-bleed, edge to edge */}
 <section className="about-cover" data-screen-label="01 Studio">
 <img
 className="about-cover__img"
 src="assets/about-cover.jpg"
 alt="The SocialTag studio, Andheri West, Mumbai"
 loading="eager"
 />
 </section>

 {/* ABOUT US */}
 <section className="about-studio sec--dark" data-screen-label="02 About us">
 <div className="about-inner">
 <div className="section-label reveal">
 <span className="num">01</span>
 <span>About us</span>
 <span className="line" />
 </div>
 <div className="studio-grid">
 <div className="studio-copy reveal" data-d="1">
 <p>
 We're a new age media company built on a simple belief: influencer
 marketing, done right, is measurable, durable, and worth investing in.
 </p>
 <p>
 We help brands build real influence, the kind that compounds over time.
 Since 2021, our team has worked across influencer marketing, talent
 management, narrative building, and consulting, with deep specialisation
 in AI, tech, and design influencers. We've partnered with companies
 shaping what comes next, from OpenAI, Figma, and Adobe to Emami, Jio, and
 several other brands.
 </p>
 <p>
 What sets us apart isn't reach. It's intelligence. We bring strategy,
 data, and a consultant-led approach to every engagement, so the influence
 we build doesn't just spike, it lasts.
 </p>
 <p>
 Based in Mumbai. Building influence that means something.
 </p>
 </div>
 <figure className="studio-image reveal" data-d="2">
 <img src="assets/team-meeting.jpg" alt="The SocialTag team at the studio" loading="lazy" />
 </figure>
 </div>
 </div>
 </section>

 {/* FOUNDER NOTE */}
 <section className="about-founder sec--dark" data-screen-label="04 Note from the founder">
 <div className="about-inner">
 <div className="section-label reveal">
 <span className="num">02</span>
 <span>Note from the founder</span>
 <span className="line" />
 </div>
 <div className="founder-grid">
 <div className="founder-portrait reveal" data-d="1">
 <img src="assets/founder-anushree.jpg" alt="Anushree Jain, Founder of SocialTag" loading="lazy" />
 <div className="founder-socials">
 <a href="https://www.linkedin.com/in/anushreejain-/" target="_blank" rel="noopener noreferrer" aria-label="Anushree Jain on LinkedIn" className="founder-social">
 <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M20.45 20.45h-3.55v-5.57c0-1.33-.02-3.03-1.85-3.03-1.85 0-2.13 1.45-2.13 2.94v5.66H9.36V9h3.41v1.56h.05c.48-.9 1.64-1.85 3.38-1.85 3.61 0 4.27 2.38 4.27 5.47v6.27zM5.34 7.43a2.06 2.06 0 1 1 0-4.12 2.06 2.06 0 0 1 0 4.12zM7.12 20.45H3.56V9h3.56v11.45z" /></svg>
 </a>
 <a href="https://www.instagram.com/anushreejain.in/" target="_blank" rel="noopener noreferrer" aria-label="Anushree Jain on Instagram" className="founder-social">
 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="5" /><circle cx="12" cy="12" r="4" /><circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none" /></svg>
 </a>
 </div>
 <div className="founder-portrait__caption">
 <div className="name">Anushree Jain</div>
 <div className="role">Founder, SocialTag</div>
 </div>
 </div>
 <div className="founder-letter reveal" data-d="2">
 {FOUNDER_NOTE.map((p, i) => (
 <p key={i}>{p}</p>
 ))}
 <div className="founder-letter__sig-only">
 <div className="sig">Anushree</div>
 </div>
 </div>
 </div>
 </div>
 </section>
 </React.Fragment>
 );
}

/* ---- Work With Us (Brand / Creator forms) ---- */
function WorkWithUs() {
 const initial = (() => {
 if (typeof window === 'undefined') return 'brand';
 const p = new URLSearchParams(window.location.search).get('role');
 return p === 'creator' ? 'creator' : 'brand';
 })();
 const [role, setRole] = useState(initial);
 const [loaded, setLoaded] = useState(false);
 const iframeRef = useRef(null);

 useEffect(() => {
 setLoaded(false);
 const t = setTimeout(() => setLoaded(true), 200);
 return () => clearTimeout(t);
 }, [role]);

 // Make dynamicHeight actually work. Tally's own loadEmbeds() skips iframes that
 // already have a src, so it never attaches the resizer — which is why the frame
 // used to stay at its fixed CSS height with a big empty band below the form.
 // Instead we attach iframe-resizer (exposed globally by Tally's embed.js) to our
 // frame directly, so it fits the frame to the form exactly at any width. The CSS
 // heights remain only as a fallback for when the embed script can't load.
 useEffect(() => {
 let instances = null, id = null, stop = null;
 const attach = () => {
 const el = iframeRef.current;
 if (!el || typeof window.iFrameResize !== 'function') return false;
 try { instances = window.iFrameResize({ checkOrigin: false, heightCalculationMethod: 'lowestElement' }, el); } catch (e) {}
 return true;
 };
 if (!attach()) {
 id = setInterval(() => { if (attach()) { clearInterval(id); id = null; } }, 300);
 stop = setTimeout(() => { if (id) clearInterval(id); }, 6000);
 }
 return () => {
 if (id) clearInterval(id);
 if (stop) clearTimeout(stop);
 try { if (instances && instances[0] && instances[0].iFrameResizer) instances[0].iFrameResizer.close(); } catch (e) {}
 };
 }, [role]);

 // Tally embed forms (brand brief + creator application).
 const FORMS = {
 brand: 'https://tally.so/embed/obpzNM?alignLeft=1&hideTitle=1&dynamicHeight=1&formEventsForwarding=1&transparentBackground=1',
 creator: 'https://tally.so/embed/Ekgrrr?alignLeft=1&hideTitle=1&transparentBackground=1&dynamicHeight=1&formEventsForwarding=1',
 };

 const COPY = {
 brand: {
 eyebrow: 'For brands',
 title: <>Let's turn your <span className="it">brand</span> into a media house.</>,
 sub: 'Tell us about your product, your audience and the kind of attention you\'re after. We\'ll come back within 48 hours, as soon as possible, with a roster.',
 bullets: ['Strategy + creator selection', 'Production + campaign management', 'Reach, watch-time and ROI reporting'],
 },
 creator: {
 eyebrow: 'For creators',
 title: <>Join the <span className="it">roster</span>.</>,
 sub: 'We work with creators who care about the craft. Drop your work, your numbers and the kind of brands you actually want to make things with.',
 bullets: ['Long-term brand partnerships', 'Production + edit support', 'Transparent rates, paid on time'],
 },
 };

 const c = COPY[role];

 return (
 <section className="wwu-section">
 <div className="wwu-inner">
 <div className="section-label reveal">
 <span className="num">07</span>
 <span>Work with us</span>
 <span className="line" />
 </div>

 <div className="wwu-head">
 <div className="wwu-head__copy">
 <h1 className="wwu-title reveal" data-d="1">{c.title}</h1>
 <p className="wwu-sub reveal" data-d="2">{c.sub}</p>
 <ul className="wwu-bullets reveal" data-d="3">
 {c.bullets.map((b, i) => (
 <li key={i}><span className="bul" />{b}</li>
 ))}
 </ul>
 </div>

 <div className="wwu-toggle-card reveal" data-d="2">
 <div className="wwu-toggle-card__label">Who are you?</div>
 <div className="wwu-toggle" role="tablist" aria-label="Select your role">
 <span className={`wwu-toggle__pill ${role === 'creator' ? 'right' : ''}`} aria-hidden="true" />
 <button
 type="button"
 role="tab"
 aria-selected={role === 'brand'}
 className={`wwu-toggle__btn ${role === 'brand' ? 'active' : ''}`}
 onClick={() => setRole('brand')}
 >
 I'm a <span className="it">brand</span>
 </button>
 <button
 type="button"
 role="tab"
 aria-selected={role === 'creator'}
 className={`wwu-toggle__btn ${role === 'creator' ? 'active' : ''}`}
 onClick={() => setRole('creator')}
 >
 I'm a <span className="it">creator</span>
 </button>
 </div>
 <p className="wwu-toggle-card__hint">
 {role === 'brand'
 ? 'Looking to run a campaign or work with creators.'
 : 'Looking to be part of the SocialTag roster.'}
 </p>
 </div>
 </div>

 <div className="wwu-form-shell reveal" data-d="3">
 <div className="wwu-form-shell__body">
 {!loaded && <div className="wwu-form-loading">Loading form…</div>}
 <iframe
 key={role}
 ref={iframeRef}
 title={role === 'brand' ? 'Brand inquiry form' : 'Creator application form'}
 src={FORMS[role]}
 className={`wwu-iframe wwu-iframe--${role}`}
 frameBorder="0"
 onLoad={() => setLoaded(true)}
 />
 </div>
 </div>
 </div>
 </section>
 );
}

/* ---- Blogs ---- */
const BLOGS = [
 {
 title: <>A complete guide to <span className="it">Instagram collaborations</span> in 2026.</>,
 desc: 'How the Collab feature actually works, why it outperforms ads, what to pay creators, and how to plan a collab that earns attention without demanding it.',
 url: 'blogs/instagram-collaborations-guide-2026.html',
 image: 'assets/blog-covers/instagram-collaborations-2026.png?v=2',
 badge: 'Instagram playbook',
 read: '11 min',
 date: 'May 2026',
 tone: 'rust',
 },
 {
 title: <>How to use <span className="it">Instagram Reels</span> to scale your brand in 2026.</>,
 desc: 'Relatability beats perfection. Hooks decide everything. And one good 15-second reel can do what crores of traditional advertising can\'t.',
 url: 'blogs/instagram-reels-2026.html',
 image: 'assets/blog-covers/instagram-reels-2026.png',
 badge: 'Marketing playbook',
 read: '7 min',
 date: 'May 2026',
 tone: 'rose',
 },
 {
 title: <>The right <span className="it">type of influencer</span> for each marketing funnel stage.</>,
 desc: 'Macro for awareness. Micro for trust. Nano for conversion. The creator who helps your brand go viral isn\'t always the one who closes the sale.',
 url: 'blogs/influencer-marketing-funnel.html',
 image: 'assets/blog-covers/influencer-marketing-funnel.png',
 badge: 'Influencer marketing',
 read: '6 min',
 date: 'May 2026',
 tone: 'olive',
 },
 {
 title: <>Influencer marketing strategy, the <span className="it">common mistakes</span> brands still make.</>,
 desc: 'Audiences spot forced influencer campaigns from a mile away. Six reasons most campaigns waste money, and how to fix each one.',
 url: 'blogs/influencer-marketing-mistakes.html',
 image: 'assets/blog-covers/influencer-marketing-mistakes.png',
 badge: 'Brand strategy',
 read: '8 min',
 date: 'May 2026',
 tone: 'rust',
 },
 {
 title: <>12 free <span className="it">AI tools</span> creators &amp; brands are obsessed with in 2026.</>,
 desc: 'ChatGPT, Gemini, Perplexity, Canva AI, NotebookLM, Gamma, Fireflies, Topview, Kling, Runway, Luma, Evoto, the 2026 stack everyone is quietly using.',
 url: 'blogs/ai-tools-creators-brands-2026.html',
 image: 'assets/blog-covers/ai-tools-creators-brands-2026.png',
 badge: 'AI & tools',
 read: '9 min',
 date: 'May 2026',
 tone: 'plum',
 },
 {
 title: <>25 <span className="it">AI tools</span> every business needs in 2026.</>,
 desc: 'Foundations, automation, marketing, video, research, code, CRM. The real 25-tool stack the fastest-moving companies are quietly running on.',
 url: 'blogs/25-ai-tools-for-business-2026.html',
 image: 'assets/blog-covers/25-ai-tools-for-business-2026.png',
 badge: 'AI for business',
 read: '14 min',
 date: 'May 2026',
 tone: 'cobalt',
 },
 {
 title: <>Why <span className="it">Instagram</span> is the headquarters of influencer marketing in 2026.</>,
 desc: 'Reels changed everything. Communities replaced followers. And IG quietly became the biggest marketing ecosystem on the internet.',
 url: 'blogs/why-instagram-influencer-marketing-2026.html',
 image: 'assets/blog-covers/why-instagram-influencer-marketing-2026.png',
 badge: 'Instagram',
 read: '7 min',
 date: 'May 2026',
 tone: 'rose',
 },
 {
 title: <>How brands hit <span className="it">1M+ app installs</span> with influencer marketing.</>,
 desc: 'Apps don\'t go viral through ads. They scale when creators make them part of routines, trends and recommendations. The 2026 install playbook.',
 url: 'blogs/app-installs-influencer-marketing.html',
 image: 'assets/blog-covers/app-installs-influencer-marketing.png',
 badge: 'App growth',
 read: '8 min',
 date: 'May 2026',
 tone: 'navy',
 },
];

function Blogs() {
 return (
 <section className="sec sec--dark" id="blogs">
 <div className="sec-inner">
 <div className="section-label reveal">
 <span className="num">06</span>
 <span>Journal</span>
 <span className="line" />
 </div>
 <h2 className="section-title reveal" data-d="1">
 Notes from the <span className="it">studio</span>.
 </h2>
 <p className="section-sub reveal" data-d="2">
 Playbooks, opinions and field notes on creators, attention and internet culture, written by the people building campaigns inside SocialTag.
 </p>

 <div className="blog-grid">
 {BLOGS.map((b, i) => (
 <a key={b.url} href={b.url} className={`blog-card reveal blog-card--${b.tone}`} data-d={(i % 3) + 1}>
 <div className="blog-card__thumb">
 {b.image && <img className="blog-card__thumb-img" src={b.image} alt="" loading="lazy" />}
 <span className="blog-card__badge">{b.badge}</span>
 </div>
 <div className="blog-card__body">
 <div className="blog-card__meta">{b.date} · {b.read} read</div>
 <h3 className="blog-card__title">{b.title}</h3>
 <p className="blog-card__desc">{b.desc}</p>
 <span className="blog-card__cta">Read article <span className="arrow">→</span></span>
 </div>
 </a>
 ))}
 </div>
 </div>
 </section>
 );
}

/* ---- App ----
   Nav + Footer are rendered by site-chrome.js, outside the React root.
   App() only owns the main content for whichever page is currently loaded. */
function App() {
 useReveal();
 if (typeof window !== 'undefined' && window.__WORK_PAGE__) {
 return <WorkPage />;
 }
 if (typeof window !== 'undefined' && window.__BLOGS_PAGE__) {
 return <Blogs />;
 }
 if (typeof window !== 'undefined' && window.__WORK_WITH_US_PAGE__) {
 return <WorkWithUs />;
 }
 if (typeof window !== 'undefined' && window.__ABOUT_PAGE__) {
 return <About />;
 }
 return (
 <React.Fragment>
 <Hero />
 <HomeStats />
 <WhatWeOffer />
 <CreatorFaces />
 <CaseStudies />
 <Press />
 </React.Fragment>
 );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
