const { useState, useEffect, useRef } = React;

// ============ shared icons (matches site) ============
const UIcon = {
  Arrow: (p) => (
    <svg viewBox="0 0 24 24" fill="none" {...p}>
      <path d="M5 12 H19 M13 6 L19 12 L13 18" stroke="currentColor" strokeWidth="1.8" strokeLinecap="square" strokeLinejoin="miter"/>
    </svg>
  ),
  Plus: (p) => (
    <svg viewBox="0 0 24 24" fill="none" {...p}>
      <line x1="12" y1="5" x2="12" y2="19" stroke="currentColor" strokeWidth="1.8"/>
      <line x1="5" y1="12" x2="19" y2="12" stroke="currentColor" strokeWidth="1.8"/>
    </svg>
  ),
  Close: (p) => (
    <svg viewBox="0 0 24 24" fill="none" {...p}>
      <line x1="6" y1="6" x2="18" y2="18" stroke="currentColor" strokeWidth="1.8"/>
      <line x1="18" y1="6" x2="6" y2="18" stroke="currentColor" strokeWidth="1.8"/>
    </svg>
  ),
  Menu: (p) => (
    <svg viewBox="0 0 24 24" fill="none" {...p}>
      <line x1="4" y1="6" x2="20" y2="6" stroke="currentColor" strokeWidth="1.8"/>
      <line x1="4" y1="12" x2="20" y2="12" stroke="currentColor" strokeWidth="1.8"/>
      <line x1="4" y1="18" x2="20" y2="18" stroke="currentColor" strokeWidth="1.8"/>
    </svg>
  ),
};

// ============ NAV ============
function Nav({ scrolled }) {
  const [menuOpen, setMenuOpen] = useState(false);
  useEffect(() => {
    document.body.style.overflow = menuOpen ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [menuOpen]);
  const closeMenu = () => setMenuOpen(false);
  const scrollTop = (e) => { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); closeMenu(); };
  return (
    <header className={`nav ${scrolled ? 'nav--solid' : 'nav--floating'}`}>
      <div className="nav__inner">
        <a href="/" className="nav__logo" aria-label="Ages Productions home">
          <img src="assets/logo-primary.png" alt="Ages Productions"/>
        </a>
        <nav className="nav__links">
          <a href="/" className="nav__link">Home</a>
          <a href="Ages Productions Media Workflow.html" className="nav__link">Media Workflow</a>
          <a href="Ages Productions Self-Shoot.html" className="nav__link">Self-Shoot Systems</a>
          <a href="Ages Productions About.html" className="nav__link">About</a>
          <a href="#" className="nav__link nav__link--active" onClick={(e) => { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); }}>Use Cases</a>
          <a href="Ages Productions Contact.html" className="nav__link">Contact</a>
        </nav>
        <div className="nav__cta"></div>
        <button className="nav__menu" aria-label={menuOpen ? "Close menu" : "Open menu"} aria-expanded={menuOpen} onClick={() => setMenuOpen(o => !o)}>
          {menuOpen
            ? <svg viewBox="0 0 24 24" width="22" height="22" fill="none"><line x1="6" y1="6" x2="18" y2="18" stroke="currentColor" strokeWidth="1.8"/><line x1="18" y1="6" x2="6" y2="18" stroke="currentColor" strokeWidth="1.8"/></svg>
            : <UIcon.Menu width="22" height="22"/>}
        </button>
      </div>
      <div className={`nav__drawer ${menuOpen ? 'nav__drawer--open' : ''}`} aria-hidden={!menuOpen}>
        <div className="nav__drawer-inner">
            <a href="/" className="nav__drawer-link" onClick={closeMenu}>Home</a>
            <a href="Ages Productions Media Workflow.html" className="nav__drawer-link" onClick={closeMenu}>Media Workflow</a>
            <a href="Ages Productions Self-Shoot.html" className="nav__drawer-link" onClick={closeMenu}>Self-Shoot Systems</a>
            <a href="Ages Productions About.html" className="nav__drawer-link" onClick={closeMenu}>About</a>
            <a href="#" className={`nav__drawer-link nav__drawer-link--active`} onClick={scrollTop}>Use Cases</a>
            <a href="Ages Productions Contact.html" className="nav__drawer-link" onClick={closeMenu}>Contact</a>
        </div>
      </div>
    </header>
  );
}

// ============ FOOTER ============
function Footer() {
  return (
    <footer className="footer">
      <div className="container footer__inner">
        <div className="footer__brand">
          <img src="assets/logo-primary.png" alt="Ages Productions" className="footer__logo"/>
          <p className="footer__tag">Field-to-post media workflow management for high-volume Reality TV productions.</p>
        </div>
        <div className="footer__cols">
          <div>
            <h6>SERVICES</h6>
            <a href="Ages Productions Media Workflow.html">Media Workflow</a>
            <a href="Ages Productions Self-Shoot.html">Self-Shoot Systems</a>
            <a href="Ages Productions Media Workflow.html#remote-cloud">Remote Delivery</a>
          </div>
          <div>
            <h6>COMPANY</h6>
            <a href="Ages Productions About.html">About</a>
            <a href="#" onClick={(e) => { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); }}>Use Cases</a>
            <a href="Ages Productions Contact.html">Contact</a>
          </div>
          <div>
            <h6>CONTACT</h6>
            <a href="Ages Productions Contact.html">Build a Media Plan</a>
            <span className="footer__loc">Miami · Worldwide</span>
          </div>
        </div>
      </div>
      <div className="footer__bar">
        <span>© 2026 Ages Productions. All rights reserved.</span>
        <span>v1.0 · Field → Post</span>
      </div>
    </footer>
  );
}

// ============ CASE DATA ============
// `hook` is custom-written summary copy to catch interest before expand.
const CASES = [
  {
    id: 'reality-ensemble',
    short: 'Reality Ensemble',
    type: 'Reality TV · Workflow redesign',
    title: 'From 24-Hour Bottlenecks to 8-Hour Ingest',
    hook: "A high-profile unscripted ensemble series was running 24-hour ingest shifts and still couldn't keep up. Ages Productions redesigned the field workflow around a single Mac Pro with specialized field storage — cutting daily ingest from approximately 24 hours to 8, ingesting up to 16 cards at once, and handling roughly 500 TB of original camera media across an 8-day stretch.",
    quick: [
      { num: '24h → 8h', label: 'ingest time' },
      { num: '16', label: 'cards in parallel' },
      { num: '~500 TB', label: 'OCM in 8 days' },
      { num: '2×', label: 'full field backups' },
    ],
    confidentiality: 'Client and show name withheld for confidentiality.',
    sections: [
      {
        label: ['SITUATION', '01'],
        body: (
          <React.Fragment>
            <p>An unscripted production company hired Ages Productions to provide media management support for the third season of a high-profile unscripted ensemble series.</p>
            <p>The production was already operating with an established field workflow: five iMac workstations connected to twelve 12-bay Areca RAID systems over Thunderbolt. The show generated media continuously from a large multi-camera setup.</p>
            <strong>Camera package</strong>
            <ul className="case__spec-list">
              <li>24 PTZ cameras (24/7, via Softron)</li>
              <li>8 Canon C300 Mark II</li>
              <li>4 Canon C70</li>
              <li>8 Panasonic BGH1 (interior car coverage)</li>
              <li>10 GoPros</li>
              <li>2 specialty gimbal cameras</li>
            </ul>
          </React.Fragment>
        ),
      },
      {
        label: ['CHALLENGE', '02'],
        body: (
          <React.Fragment>
            <p>The production ran on a 24-hour schedule with two data wranglers on 12-hour shifts, but the media inflow was still greater than the workflow could comfortably handle.</p>
            <ul className="case__bullets">
              <li>Transfers limited to one card at a time per machine</li>
              <li>Media from a single shoot day spread across five different drives</li>
              <li>Extra time spent moving footage again just to prepare shuttle drives for post</li>
              <li>Limited time for proper QC, logging, notes, and issue tracking</li>
              <li>Too much hardware being used without enough workflow efficiency</li>
            </ul>
            <p style={{marginTop:'16px'}}>The challenge was not only ingest speed. It was the need for a cleaner, faster, and more accountable media pipeline from set to post.</p>
          </React.Fragment>
        ),
      },
      {
        label: ['AGES’ ROLE', '03'],
        body: (
          <React.Fragment>
            <p>During the third season, Ages Productions helped optimize the production's existing workflow as much as possible within the limits of the current system.</p>
            <p>After seeing the bottlenecks firsthand, Ages recommended a redesigned field workflow for the following season. The goal was to <strong>reduce hardware complexity, centralize media, increase ingest speed, improve QC visibility, and create a smoother post-production handoff.</strong></p>
          </React.Fragment>
        ),
      },
      {
        label: ['SOLUTION & OUTCOME', '04'],
        body: (
          <React.Fragment>
            <p>For the fourth season, Ages Productions replaced the five-iMac, twelve-RAID setup with a customized field workflow built around <strong>a single Mac Pro with specialized high-speed field storage</strong> — fewer machines, more throughput, and one centralized place for media to live.</p>
            <p>The new system let the media team ingest <strong>up to 16 cards in parallel</strong> and cut daily ingest from roughly 24 hours to 8. Once footage was verified, it was organized onto Field Master drives and scheduled shuttle drives for delivery to post.</p>
            <p>Across the shoot, Ages Productions supported approximately <strong>500 TB of original camera media in 8 days</strong>, protected the full show with two complete field backups, and prepared an additional 500 TB of media for shuttle delivery to post.</p>
            <div className="case__stats" style={{gridTemplateColumns:'repeat(4, 1fr)'}}>
              <div className="case__stat">
                <span className="case__stat-num">24h→8h</span>
                <span className="case__stat-label">DAILY INGEST TIME</span>
              </div>
              <div className="case__stat">
                <span className="case__stat-num">~500<span>TB</span></span>
                <span className="case__stat-label">ORIGINAL CAMERA MEDIA · 8 DAYS</span>
              </div>
              <div className="case__stat">
                <span className="case__stat-num">2<span>×</span></span>
                <span className="case__stat-label">COMPLETE FIELD BACKUPS</span>
              </div>
              <div className="case__stat">
                <span className="case__stat-num">500<span>TB</span></span>
                <span className="case__stat-label">PREPARED FOR POST SHUTTLE</span>
              </div>
            </div>
            <p style={{marginTop:'18px'}}>Beyond the numbers, centralizing the pipeline freed up real time on the wrangler bench for <strong>QC, logging, issue tracking, and a cleaner post-production handoff.</strong></p>
            <p>The rebuild also shifted the production off long-term rental dependency, helping the company transition toward owning reusable high-capacity field storage for future seasons and other shows.</p>
          </React.Fragment>
        ),
      },
    ],
  },
  {
    id: 'esports-doc',
    short: 'Esports Documentary',
    type: 'Documentary · International event',
    title: 'A Lean Documentary Workflow Inside a Major International Esports Event',
    hook: "Eight weeks. A global esports event in Saudi Arabia. A small documentary team with editorial waiting back in Los Angeles, and roughly seven-day shipping in between. Ages Productions designed a lean field-to-cloud workflow that merged 16-channel Softron ISO recording with documentary ingest, kept rental costs in check, and delivered AVID-ready DNxHD LB files to remote post without waiting on shuttle drives.",
    quick: [
      { num: '~900 TB', label: 'media supported' },
      { num: '8 weeks', label: 'live event run' },
      { num: '3', label: 'buildings networked' },
      { num: '16ch', label: 'Softron ISO to field storage' },
    ],
    confidentiality: 'Client and project name withheld for confidentiality.',
    sections: [
      {
        label: ['SITUATION', '01'],
        body: (
          <React.Fragment>
            <p>A documentary production team was producing a global esports documentary series centered around a major international event in Saudi Arabia.</p>
            <p>The series included global story coverage and home-follow shoots, but Ages Productions was responsible for the documentary media workflow at the event itself.</p>
            <p>Because the event shoot would run for approximately eight weeks, the production needed a workflow that could handle large daily media volumes while still keeping the budget under control.</p>
            <p>The documentary team was also much smaller than the larger live-event production operation surrounding it, which included multiple vendors, technical departments, control rooms, and buildings.</p>
          </React.Fragment>
        ),
      },
      {
        label: ['CHALLENGE', '02'],
        body: (
          <React.Fragment>
            <p>The production needed to capture and manage several types of media at the same time:</p>
            <ul className="case__spec-list">
              <li>16-channel Softron MovieRecorder ISO</li>
              <li>3 Sony BURANO cameras (4K OCN)</li>
              <li>2 Sony FX3 cameras</li>
              <li>16 NDI stream recordings (separate building)</li>
            </ul>
            <p style={{marginTop:'16px'}}>From the beginning, it was clear that the Softron HD ISO recordings would generate significantly more data than the traditional camera footage. During the first season, the production averaged approximately <strong>10–12 hours of ISO recording per day.</strong></p>
            <p>The workflow also had to support post-production in Los Angeles while the event was taking place in Riyadh. Physical drive shipments could take approximately seven days by express shipping, so relying only on shuttle drives would slow down editorial access.</p>
            <p>The challenge was to build a workflow that could reduce daily ingest time, contain equipment costs, protect media with redundant backups, and deliver AVID-ready editorial files to post without waiting for physical drives.</p>
          </React.Fragment>
        ),
      },
      {
        label: ['AGES’ ROLE', '03'],
        body: (
          <React.Fragment>
            <p>Ages Productions helped design and operate a lean documentary media workflow that merged multiple technical needs into a more efficient system.</p>
            <p>Working with the Los Angeles rental house, Ages helped combine the 16-channel Softron MovieRecorder system with the documentary ingest station. This reduced the need for separate systems and helped contain rental costs across the eight-week event.</p>
            <p>Ages also provided a technician who could serve in a <strong>dual role: Softron operator + media manager.</strong> This gave production one person who understood both the recording side and the media-management side of the workflow.</p>
          </React.Fragment>
        ),
      },
      {
        label: ['SOLUTION', '04'],
        body: (
          <React.Fragment>
            <p>To reduce unnecessary ingest time, Ages designed the workflow so that Softron ISO recordings were written directly to high-speed field storage during capture. This avoided a large additional transfer step at the end of each day and created more time for proper media handling.</p>
            <ul className="case__bullets">
              <li>Softron ISO recordings written directly to field storage during capture</li>
              <li>Ingest and verification of Sony BURANO and FX3 camera media</li>
              <li>QC, logging, and issue tracking</li>
              <li>Automatic nightly backups to Field Master drives</li>
              <li>Weekly shuttle drives sent to post</li>
              <li>Automated transcoding to AVID DNxHD LB editorial files</li>
              <li>Cloud uploads of transcoded media for the Los Angeles post team</li>
            </ul>
            <p style={{marginTop:'16px'}}>Because the post team was based in Los Angeles, the cloud upload workflow was critical. It allowed editorial to begin working with AVID-ready files without waiting for physical drives to arrive from Saudi Arabia.</p>
          </React.Fragment>
        ),
      },
      {
        label: ['SEASON TWO', 'IMPROVEMENT'],
        body: (
          <React.Fragment>
            <p>For the second season, Ages Productions helped improve the workflow even further.</p>
            <p>The original setup included a separate machine in another building recording 16 NDI streams. That media also needed to be transcoded and uploaded within the same general turnaround window.</p>
            <p>To reduce physical movement of media between buildings, Ages worked with the event producer, vendors, and the event's IT department to create a network that allowed the documentary systems to communicate <strong>across three different buildings.</strong></p>
            <p>This improved workflow allowed media to be centralized into one main ingest system while still keeping local backups at each machine for safety. That redundancy mattered because power and network failures did happen during the event.</p>
            <p>The improved networked workflow also allowed the media manager to remotely access and monitor systems from the main control room, reducing the need to physically move between buildings just to check recording systems or media status.</p>
          </React.Fragment>
        ),
      },
      {
        label: ['IMPACT', '05'],
        body: (
          <React.Fragment>
            <p>Ages Productions helped a small documentary team operate efficiently inside a massive international esports event.</p>
            <p>The workflow gave production a practical balance of <strong>speed, redundancy, budget control, and remote editorial access.</strong></p>
            <p>Instead of treating documentary media management as a simple copy-and-backup task, Ages built a workflow that connected recording, ingest, backup, transcoding, upload, and remote monitoring into one lean media system.</p>
            <div className="case__stats">
              <div className="case__stat">
                <span className="case__stat-num">~900<span>TB</span></span>
                <span className="case__stat-label">MEDIA BACKED UP TO FIELD</span>
              </div>
              <div className="case__stat">
                <span className="case__stat-num">8<span>WK</span></span>
                <span className="case__stat-label">LIVE EVENT COVERAGE</span>
              </div>
              <div className="case__stat">
                <span className="case__stat-num">3<span></span></span>
                <span className="case__stat-label">BUILDINGS NETWORKED · S2</span>
              </div>
            </div>
            <ul className="case__bullets" style={{marginTop:'18px'}}>
              <li>Leaner setup that reduced ingest time, rental costs, and staffing overhead</li>
              <li>AVID-ready DNxHD LB files delivered to Los Angeles post via cloud, not shipping</li>
              <li>Redundant field backups with networked monitoring across three buildings</li>
              <li>Reliable operation through power and network failures during the live event</li>
            </ul>
          </React.Fragment>
        ),
      },
    ],
  },
  {
    id: 'mlb-doc',
    short: 'MLB Championship Doc',
    type: 'Sports doc · Travel-ready workflow',
    title: 'Travel-Ready Media Management for a Fast-Turnaround Sports Documentary',
    hook: "Following a professional baseball player through the League Championship Series and the World Series. Post needed footage within roughly one day, internet delivery wasn't an option because the post facility's bandwidth was already saturated, and the crew had to fly city to city. Ages Productions designed, sourced, built, and operated travel-ready media kits that scaled from carry-on for LCS to a checked-luggage system for the World Series, keeping the shuttle pipeline clean while the story unfolded in real time.",
    quick: [
      { num: '~1 day', label: 'post turnaround' },
      { num: '2 stages', label: 'carry-on → checked-luggage' },
      { num: '42', label: 'ISO beltpack recorders' },
      { num: '16ch', label: 'Softron broadcast capture' },
    ],
    confidentiality: 'Client and project name withheld for confidentiality.',
    sections: [
      {
        label: ['SITUATION', '01'],
        body: (
          <React.Fragment>
            <p>A documentary production team was filming a fast-turnaround sports series following a professional baseball player through the League Championship Series and the World Series.</p>
            <p>Because the project was scheduled to air soon after filming, post-production needed footage as quickly as possible. Depending on the city, post could sometimes receive drives the same day. In other cases, delivery depended on the fastest available FedEx option. Most of the time, the goal was for post to have the footage within approximately one day.</p>
            <p>Internet delivery was not a practical option because the post facility's bandwidth was limited by another active project. That made physical shuttle-drive delivery the most reliable path for fast editorial access.</p>
          </React.Fragment>
        ),
      },
      {
        label: ['CHALLENGE', '02'],
        body: (
          <React.Fragment>
            <p>The production had to move quickly between cities while keeping the media workflow portable, reliable, and clean. The camera and audio package scaled up significantly between the two stages of the series.</p>
            <strong>League Championship Series package</strong>
            <ul className="case__spec-list">
              <li>2 Sony VENICE 2</li>
              <li>2 Sony BURANO</li>
              <li>4 Sony FX6</li>
              <li>4 Sound Devices mixers</li>
            </ul>
            <strong style={{display:'block', marginTop:'22px'}}>World Series package (scaled up)</strong>
            <ul className="case__spec-list">
              <li>4 Sony VENICE 2</li>
              <li>4 Sony BURANO</li>
              <li>8 Sony FX6</li>
              <li>6 GoPros</li>
              <li>42 ISO beltpack recorders</li>
              <li>8 Sound Devices mixers</li>
            </ul>
            <p style={{marginTop:'16px'}}>The crew was small and everyone had to stay mobile. Each media manager had to begin offloading <strong>during the games</strong> — often starting halfway through — so shuttle drives could be ready immediately after the game or by the following morning. For LCS specifically, the whole kit needed to be compact enough for carry-on travel whenever possible.</p>
          </React.Fragment>
        ),
      },
      {
        label: ['RESULTS', '03'],
        body: (
          <React.Fragment>
            <p>Ages Productions designed, sourced, built, and operated the travel-ready kits for both stages of the series — two media managers split across the leagues for LCS, then converged as one team for the World Series when the production scale jumped.</p>
            <p>The <strong>LCS kit</strong> was a compact carry-on build using carefully selected off-the-shelf components. The <strong>World Series kit</strong> stepped up to a checked-luggage build with significantly more ingest performance to handle the larger media load, plus a Softron system added to record 16 broadcast feeds and camera angles.</p>
            <p>Either way, the kit let media managers begin ingesting and verifying during the games, organize for post, and have shuttle drives ready for same-day or next-day delivery — clean QC, logs, and metadata included.</p>
            <div className="case__stats" style={{gridTemplateColumns:'repeat(4, 1fr)'}}>
              <div className="case__stat">
                <span className="case__stat-num">~1<span>day</span></span>
                <span className="case__stat-label">POST TURNAROUND</span>
              </div>
              <div className="case__stat">
                <span className="case__stat-num">2<span>kits</span></span>
                <span className="case__stat-label">CARRY-ON → CHECKED-LUGGAGE</span>
              </div>
              <div className="case__stat">
                <span className="case__stat-num">42</span>
                <span className="case__stat-label">ISO BELTPACK RECORDERS · WS</span>
              </div>
              <div className="case__stat">
                <span className="case__stat-num">16<span>ch</span></span>
                <span className="case__stat-label">SOFTRON BROADCAST CAPTURE</span>
              </div>
            </div>
            <p style={{marginTop:'18px'}}>The result was a workflow <strong>portable enough to move city to city, powerful enough for high-resolution championship coverage, and organized enough to give post-production clean media inside a day</strong> whenever shipping allowed — without overbuilding the kit.</p>
          </React.Fragment>
        ),
      },
    ],
  },
];

// ============ CASE CARD ============
function CaseCard({ data, index, isOpen, onToggle }) {
  const ref = useRef(null);

  // When this card just opened, scroll it into view smoothly
  useEffect(() => {
    if (isOpen && ref.current) {
      const top = ref.current.getBoundingClientRect().top + window.scrollY - 90;
      window.scrollTo({ top, behavior: 'smooth' });
    }
  }, [isOpen]);

  const num = String(index + 1).padStart(2, '0');

  return (
    <article
      ref={ref}
      id={data.id}
      className={`case ${isOpen ? 'case--open' : ''}`}
    >
      <button
        className="case__head"
        onClick={onToggle}
        aria-expanded={isOpen}
        aria-controls={`${data.id}-detail`}
      >
        <div className="case__num">
          <span>CASE</span>
          <strong>/ {num}</strong>
        </div>
        <div className="case__body">
          <div className="case__type">{data.type}</div>
          <h2 className="case__title">{data.title}</h2>
          <p className="case__hook">{data.hook}</p>
          <div className="case__quick">
            {data.quick.map((q, i) => (
              <span className="case__quick-pill" key={i}>
                <strong>{q.num}</strong>{q.label}
              </span>
            ))}
          </div>
        </div>
        <div className="case__toggle">
          <span>{isOpen ? 'CLOSE' : 'READ FULL'}</span>
          <span className="case__toggle-icon" aria-hidden="true">
            <UIcon.Plus width="16" height="16"/>
          </span>
        </div>
      </button>

      <div id={`${data.id}-detail`} className="case__detail" aria-hidden={!isOpen}>
        <div className="case__detail-inner">
          <div className="case__detail-grid">
            {data.sections.map((s, i) => (
              <div className="case__section" key={i}>
                <div className="case__section-label">
                  <span>{s.label[1]}</span>
                  <strong>{s.label[0]}</strong>
                </div>
                <div className="case__section-body">
                  {s.body}
                </div>
              </div>
            ))}
            <div className="case__confidential">
              <span>{data.confidentiality}</span>
            </div>
            <div className="case__close-row">
              <button className="case__close" onClick={onToggle}>
                <UIcon.Close width="14" height="14"/>
                <span>COLLAPSE USE CASE</span>
              </button>
            </div>
          </div>
        </div>
      </div>
    </article>
  );
}

// ============ APP ============
function App() {
  const [scrolled, setScrolled] = useState(false);
  const [openIdx, setOpenIdx] = useState(null);

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 40);
    window.addEventListener('scroll', onScroll);
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  // Open via #hash if a case id is in the URL
  useEffect(() => {
    const hash = window.location.hash.replace('#', '');
    if (!hash) return;
    const i = CASES.findIndex(c => c.id === hash);
    if (i >= 0) setOpenIdx(i);
  }, []);

  const toggle = (i) => {
    setOpenIdx(prev => prev === i ? null : i);
  };

  return (
    <div className="app accent-balanced uc-page">
      <Nav scrolled={scrolled}/>

      <section className="uc-hero">
        <div className="uc-hero__bg" aria-hidden="true"></div>
        <div className="uc-hero__inner">
          <div>
            <div className="uc-hero__eyebrow">
              <span className="dot"></span>
              <span>USE CASES</span>
              <span style={{borderLeft:'1px solid rgba(255,255,255,0.2)', paddingLeft:'14px', color:'rgba(255,255,255,0.6)'}}>Field-to-post in production</span>
            </div>
            <h1 className="uc-hero__title">
              Real productions.<br/>
              <span className="uc-hero__title-accent">Real media loads.</span>
            </h1>
            <p className="uc-hero__lede">
              A closer look at how Ages Productions has redesigned, scaled and operated media workflows for high-volume unscripted, international documentary, and fast-turnaround sports productions — from broken multi-machine pipelines to carry-on travel kits.
            </p>
          </div>
          <div className="uc-hero__meta">
            <div className="uc-hero__meta-row">
              <span className="uc-hero__meta-k">USE CASES</span>
              <span className="uc-hero__meta-v"><span className="num">03<span>/03</span></span></span>
            </div>
            <div className="uc-hero__meta-row">
              <span className="uc-hero__meta-k">COMBINED MEDIA HANDLED</span>
              <span className="uc-hero__meta-v"><span className="num">~1,400<span>TB</span></span></span>
            </div>
            <div className="uc-hero__meta-row">
              <span className="uc-hero__meta-k">FORMATS</span>
              <span className="uc-hero__meta-v">REALITY · DOC · LIVE SPORTS</span>
            </div>
          </div>
        </div>
      </section>

      <nav className="uc-index" aria-label="Use case index">
        <div className="uc-index__inner">
          <span className="uc-index__label">[ INDEX ]</span>
          <ul className="uc-index__list">
            {CASES.map((c, i) => (
              <li key={c.id}>
                <button
                  className={`uc-index__btn ${openIdx === i ? 'uc-index__btn--active' : ''}`}
                  onClick={() => setOpenIdx(i)}
                >
                  <span className="uc-index__btn-num">{String(i+1).padStart(2,'0')}</span>
                  <span className="uc-index__btn-name">{c.short}</span>
                </button>
              </li>
            ))}
          </ul>
          {openIdx !== null && (
            <button
              className="uc-index__btn"
              onClick={() => setOpenIdx(null)}
              style={{borderColor:'var(--gray-line)'}}
            >
              <span>CLOSE ALL</span>
            </button>
          )}
        </div>
      </nav>

      <section className="uc-list">
        <div className="uc-list__inner">
          {CASES.map((c, i) => (
            <CaseCard
              key={c.id}
              data={c}
              index={i}
              isOpen={openIdx === i}
              onToggle={() => toggle(i)}
            />
          ))}
        </div>
      </section>

      <section className="uc-cta">
        <div className="uc-cta__inner">
          <div>
            <span className="section-label">[ NEXT STEP ]</span>
            <h2 className="uc-cta__title">
              Have a production with a media problem worth solving?
            </h2>
          </div>
          <div>
            <p className="uc-cta__lede">
              Whether it's a strained multi-machine workflow, an international live event, or a fast-turnaround travel show — Ages Productions can build a media plan around it.
            </p>
            <div className="uc-cta__buttons">
              <a href="Ages Productions Contact.html" className="btn btn--primary">
                <span>Build a Media Plan</span>
                <UIcon.Arrow width="18" height="18"/>
              </a>
              <a href="Ages Productions About.html" className="btn btn--ghost">
                <span>About Ages Productions</span>
              </a>
            </div>
          </div>
        </div>
      </section>

      <Footer/>
    </div>
  );
}

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