/* global React */

/* ─── Media base. Wasabi bucket (1080p web tier + posters) ─────
   Masters live in /source/ but the site only serves /web/.
   To swap CDNs later, change CDN_BASE in one place.            */
const CDN_BASE = "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com";
const VID = (name) => `${CDN_BASE}/web/${name}`;
const POSTER = (name) => `${CDN_BASE}/posters/${name}`;

const VIDEO_SRC = {
  marfa:      VID("media-video-11.mp4"),
  lelabo:     VID("media-video-08.mp4"),
  shinola:    VID("media-video-07.mp4"),
  frette:     VID("media-video-02.mp4"),
  hudson:     VID("media-video-10.mp4"),
  northatlas: VID("instagram-video-04.mp4"),
};

/* Audio sources reuse the same web-tier mp4s, the audio track plays
   through <audio>, giving real playback for the music demo. */
const AUDIO_SRC = {
  evlp01: [
    { src: VID("media-video-02.mp4"), title: "I · North Atlas (Open)", duration: "—" },
    { src: VID("media-video-07.mp4"), title: "II · Field, Re-tuned",   duration: "—" },
    { src: VID("media-video-08.mp4"), title: "III · Slow Dawn",        duration: "—" },
    { src: VID("media-video-10.mp4"), title: "IV · A Room of Breath",  duration: "—" },
    { src: VID("media-video-11.mp4"), title: "V · The Marfa Cycle",    duration: "—" },
  ],
  evep02: [
    { src: VID("instagram-video-01.mp4"), title: "Sketch · 01", duration: "—" },
    { src: VID("instagram-video-02.mp4"), title: "Sketch · 02", duration: "—" },
    { src: VID("instagram-video-04.mp4"), title: "Loop · Hudson", duration: "—" },
  ],
  evfr25: [
    { src: VID("media-video-10.mp4"), title: "Mexico City · Field",    duration: "—" },
    { src: VID("media-video-11.mp4"), title: "Hudson Valley · Upright", duration: "—" },
  ],
  evs004: [
    { src: VID("media-video-08.mp4"), title: "North Atlas · Single", duration: "—" },
  ],
};

/* ─────────────────────────────────────────────────────────────────
   CATALOG, only what's actually for sale. Real product media.

   Three real products carried over from the production elevenviews.io store:
     1. Views Hoodie         — apparel, $75,  video media-video-07.mp4
     2. Views Classic Tee    — apparel, $50,  video media-video-01.mp4
     3. Pretty Girls Have    — music,   $10.99, Untitled.stream embed
        Wild Stories             + 3 m4a tracks (cover + audio in Vercel Blob)
   ───────────────────────────────────────────────────────────────── */
const ALBUM_PGHWS = {
  cover: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/albums/pretty-girls-have-wild-stories/album-cover-LYjkVGUbY5mNPCCcLYsRqpR3VqNlDW.png",
  tracks: [
    { n: 1, title: "Like That",        src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/albums/pretty-girls-have-wild-stories/01-like-that-QqohiA14NknzbUn6SMaeg1NWorIryG.m4a" },
    { n: 2, title: "Lost in the Game", src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/albums/pretty-girls-have-wild-stories/02-lost-in-the-game-ZKSLp9epfpBNVBRBTCkqrHPn2FBWMk.m4a" },
    { n: 3, title: "Her Stage",        src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/albums/pretty-girls-have-wild-stories/03-her-stage-y1gmHWzGnZt7XMVQx8XOf9n6Vetjqv.m4a" },
  ],
};

const CATALOG = [
  // Apparel, 2 SKUs, real product video for each
  {
    id: "ev-001", cat: "apparel", kind: "apparel",
    name: "Views Hoodie",
    subtitle: "Heavyweight cotton · embroidered Eleven Views monogram",
    price: 75, variants: ["Black / S", "Black / M", "Black / L", "Black / XL"],
    imgVariant: "deep", code: "EV-HD-001",
    badge: "New",
    video: VID("media-video-07.mp4"),
    poster: POSTER("media-video-07.jpg"),
    focal: "center top",
    desc: "A heavyweight cotton hoodie cut for layering. Boxy through the body, dropped shoulder, embroidered Eleven Views monogram at the chest. Garment-dyed in small batches.",
  },
  {
    id: "ev-002", cat: "apparel", kind: "apparel",
    name: "Views Classic Tee",
    subtitle: "Studio tee · soft cotton · Eleven Views script",
    price: 50, variants: ["Black / S", "Black / M", "Black / L", "Black / XL"],
    imgVariant: "warm", code: "EV-TEE-002",
    video: VID("media-video-01.mp4"),
    poster: POSTER("media-video-01.jpg"),
    focal: "center top",
    desc: "Soft mid-weight cotton in a clean studio cut. Boxy chest, tonal hem stitch, Eleven Views script at the chest. Made to wear in.",
  },
  // Music, real album. Card shows the cover image; PDP shows Untitled embed + audio.
  {
    id: "ev-003", cat: "music", kind: "music",
    name: "Pretty Girls Have Wild Stories",
    subtitle: "Album · digital · 3 tracks",
    artist: "Simeon Views",
    price: 10.99, variants: ["Digital · MP3", "Digital · WAV"],
    imgVariant: "deep", code: "EV-LP-003",
    badge: "Album",
    untitledId: "CUiMgZ7v5dEA", audioKey: "evlp01",
    cover: ALBUM_PGHWS.cover,
    tracks: ALBUM_PGHWS.tracks,
    desc: "Three songs by Simeon Views, the studio's own record. Recorded between sessions, mixed in the off hours, released without a campaign. Stream below or buy for the full files.",
  },
];

const CATEGORIES = [
  { key: "all",     label: "All" },
  { key: "apparel", label: "Apparel" },
  { key: "music",   label: "Music" },
];

const PRICE_BANDS = [
  { key: "any", label: "Any price" },
  { key: "u50", label: "Under $50", test: (p) => p < 50 },
  { key: "50-150", label: "$50–150", test: (p) => p >= 50 && p < 150 },
  { key: "150-300", label: "$150–300", test: (p) => p >= 150 && p < 300 },
  { key: "300+", label: "$300+", test: (p) => p >= 300 },
];

/* ─────────────────────────────────────────────────────────────────
   Services, outcomes, process, deliverables, pricing bands.
   Brief mandates: entry tier shows "starting at" band; deeper tiers say "Inquire."
   ───────────────────────────────────────────────────────────────── */
const SERVICES = {
  photography: {
    key: "photography",
    name: "Photography",
    tagline: "Image-making, in light and time.",
    lede: "Editorial-grade image for the brands that earn shelf space and column inches. We light, art-direct, and finish in-house.",
    icon: "cam",
    descriptors: ["Portrait", "Editorial", "Product / Lookbook"],
    blurb:
      "Operator-led, with a trusted bench of camera, grip, and post collaborators. We handle creative direction through final retouch in-studio, most projects deliver inside ten business days.",
    forWhom: ["Editorial publications and brand magazines", "Premium fashion, beauty, and home goods", "Founders and operators with a story worth telling"],
    outcomes: [
      "A library of frames you can use across web, retail, and press for two years.",
      "Cover-grade portraits that hold their own next to the editorial they sit in.",
      "Lookbooks that move the SKU and the brand at once.",
    ],
    process: [
      ["01", "Read", "We read the brief, the room, and three of your competitors. One call, one written response."],
      ["02", "Frame", "Mood, location, wardrobe, and shot list, locked before we touch a camera."],
      ["03", "Shoot", "On-location or in the studio. Same crew, every time."],
      ["04", "Finish", "Retouching by hand. Web and print masters delivered together."],
    ],
    tiers: [
      {
        key: "portrait",
        name: "Portrait Session",
        priceBand: "from $1,800",
        priceLabel: "Starting at",
        duration: "Half-day · 4 hours",
        deliver: "20 retouched files",
        highlights: ["Studio or on-location", "1 wardrobe change", "10-day delivery"],
        public: true,
      },
      {
        key: "events",
        name: "Editorial / Events",
        priceBand: "from $4,200",
        priceLabel: "Starting at",
        duration: "Full-day · 10 hours",
        deliver: "150+ retouched files",
        highlights: ["2-photographer crew", "Same-day previews", "Sneak-peek reel"],
        public: true,
      },
      {
        key: "lookbook",
        name: "Lookbook / Campaign",
        priceBand: "Inquire",
        priceLabel: "Six-figure productions",
        duration: "1–3 days",
        deliver: "40+ retouched files",
        highlights: ["Studio + creative direction", "Stylist + set on call", "Web + print masters"],
        public: false,
      },
    ],
  },
  video: {
    key: "video",
    name: "Video",
    tagline: "Stories that earn the cut.",
    lede: "We treat brand films like documentaries and social like editorials. One team, end-to-end, so the final cut feels like a single hand.",
    icon: "film",
    descriptors: ["Brand films", "Social / Short-form", "Music & culture"],
    blurb:
      "Director, DP, sound, edit, color, and original score, kept in-house from first call to delivery. We protect the cut.",
    forWhom: ["Brands launching a flagship moment", "Founders ready to put a story on camera", "Cultural institutions with a film to make"],
    outcomes: [
      "A hero film with the legs to run a year of paid and earned media.",
      "Social cuts that fit the algorithm without smelling like the algorithm.",
      "A score and grade your competitors can't shortcut.",
    ],
    process: [
      ["01", "Read", "Same first step as image, brief, references, a written response."],
      ["02", "Plan", "Treatment, board, location, crew. Locked at greenlight."],
      ["03", "Shoot", "Two-to-six day shoots, full crew, captured in the studio's standard pipeline."],
      ["04", "Finish", "Edit, sound design, score, color grade, every stage in our suite."],
    ],
    tiers: [
      {
        key: "social",
        name: "Social / Short-form",
        priceBand: "from $5,400",
        priceLabel: "Starting at",
        duration: "1–2 day shoot",
        deliver: "6 cuts · 15s–60s",
        highlights: ["Director + DP", "Stem audio", "Vertical + horizontal masters"],
        public: true,
      },
      {
        key: "brand",
        name: "Brand Film",
        priceBand: "Inquire",
        priceLabel: "Mid-five to mid-six figures",
        duration: "2–4 day shoot",
        deliver: "1 hero · 3 cuts",
        highlights: ["Original score", "Color in DaVinci", "Stills package included"],
        public: false,
      },
      {
        key: "longform",
        name: "Documentary / Long-form",
        priceBand: "Inquire",
        priceLabel: "Six-figure productions",
        duration: "4–10 day shoot",
        deliver: "1 film · 10–25 min",
        highlights: ["Full crew of seven", "On-location capture", "Theatrical-grade audio mix"],
        public: false,
      },
    ],
  },
  web: {
    key: "web",
    name: "Web & Brand",
    tagline: "Sites that read like the work.",
    lede: "We design and build sites the team actually uses, with brand systems that survive the next launch.",
    icon: "monitor",
    descriptors: ["Brand systems", "Landing pages", "Full sites & e-commerce"],
    blurb:
      "Figma to deploy under one roof. Branded CMS, editorial-grade typography, performance kept above 95 in Lighthouse. Every site comes with a 90-day post-launch tune-up.",
    forWhom: ["Brands rebuilding for a flagship moment", "DTC operators replacing a templated storefront", "Cultural orgs that need editorial control"],
    outcomes: [
      "A site that converts at the level your storytelling deserves.",
      "A brand system that holds for three years of campaigns and capsules.",
      "A CMS your editor will actually open on a Monday morning.",
    ],
    process: [
      ["01", "Read", "Audit the current site, competitors, and the funnel. One written response."],
      ["02", "Design", "Wireframe → high-fidelity → motion direction. Two design rounds, scoped."],
      ["03", "Build", "Webflow, Next.js, or Shopify, picked to fit the team, not the studio."],
      ["04", "Launch", "Migrate, ship, and stay on call for 90 days."],
    ],
    tiers: [
      {
        key: "landing",
        name: "Landing Page",
        priceBand: "from $7,500",
        priceLabel: "Starting at",
        duration: "3 weeks",
        deliver: "1 page, polished",
        highlights: ["Custom illustration", "Webflow / Next.js", "Lighthouse > 95"],
        public: true,
      },
      {
        key: "site",
        name: "Full Site",
        priceBand: "Inquire",
        priceLabel: "Mid-five figures",
        duration: "6–10 weeks",
        deliver: "5–12 pages",
        highlights: ["Branded CMS", "Editorial templates", "On-site copy direction"],
        public: false,
      },
      {
        key: "ecom",
        name: "E-commerce Build",
        priceBand: "Inquire",
        priceLabel: "Mid-to-high five figures",
        duration: "10–14 weeks",
        deliver: "Storefront + ops",
        highlights: ["Shopify / custom", "Inventory + analytics", "Launch campaign included"],
        public: false,
      },
    ],
  },
};

/* ─────────────────────────────────────────────────────────────────
   PACKAGES, curated, fixed-scope offerings sold direct.
   Three lanes: Nights · Designs · Moments.

   Every package can be added to cart; the price field is the
   non-refundable deposit. Booking page reads ?package=<id> to
   pre-fill the brief form with the package context.
   ───────────────────────────────────────────────────────────────── */
const PACKAGE_LANES = [
  { key: "nights",  label: "Nights",  blurb: "Live capture for evening events, performances, and recaps.", icon: "film" },
  { key: "designs", label: "Designs", blurb: "Brand-led look shoots, lookbooks, and editorial sets.",       icon: "cam" },
  { key: "moments", label: "Moments", blurb: "Personal commissions, portraits, milestones, recaps.",       icon: "heart" },
];

const PACKAGES = [
  // Nights
  {
    id: "pkg-night-recap", lane: "nights", code: "NIGHT-01",
    name: "Night Recap",
    subtitle: "Half-evening capture · 60-90s film + 20 stills",
    price: 750, deposit: 750, totalLabel: "$1,800 total · $750 deposit",
    duration: "Up to 4 hours on-site",
    deliver: "1× short film, 20 retouched stills, 7-day delivery",
    highlights: ["Single operator on site", "Vertical & horizontal cuts", "Music license included"],
    forWhom: ["Birthday parties · 18th, 21st, 30th, 40th, milestone", "Album release nights", "Private listening sessions"],
  },
  {
    id: "pkg-night-full", lane: "nights", code: "NIGHT-02",
    name: "Full Night Edit",
    subtitle: "All-evening capture · 2-3 min film + 50 stills + cutdown",
    price: 1500, deposit: 1500, totalLabel: "$4,200 total · $1,500 deposit",
    duration: "Up to 8 hours on-site",
    deliver: "Recap film, 50 retouched stills, social cutdowns, 14-day delivery",
    highlights: ["Two-camera coverage option", "Stills + film, one operator-led day", "Drive of selects within 48h"],
    forWhom: ["Weddings & receptions", "Sweet 16 / 21 / 30 anniversaries", "Brand launch parties"],
  },
  // Designs
  {
    id: "pkg-look-day", lane: "designs", code: "DESIGN-01",
    name: "One-Day Look Shoot",
    subtitle: "Three concepts captured in a single day",
    price: 900, deposit: 900, totalLabel: "$2,400 total · $900 deposit",
    duration: "1 day on-set, 7-day post",
    deliver: "30 retouched stills + 1× 30s motion cut",
    highlights: ["Studio or location", "3 concepts / wardrobe changes", "Stills + motion same day"],
    forWhom: ["Artists building a press kit", "DTC brands launching a season", "Athletes / creators with a campaign"],
  },
  {
    id: "pkg-lookbook-site", lane: "designs", code: "DESIGN-02",
    name: "Lookbook + Microsite",
    subtitle: "Two-day shoot + a dedicated landing page",
    price: 2200, deposit: 2200, totalLabel: "$6,800 total · $2,200 deposit",
    duration: "2 days on-set, 3-week build",
    deliver: "60 retouched stills, hero film, custom microsite",
    highlights: ["Editorial direction included", "Web build on Vercel", "Press-ready PDF kit"],
    forWhom: ["Capsule launches", "Album / EP rollouts", "Brand re-introductions"],
  },
  // Moments
  {
    id: "pkg-portrait", lane: "moments", code: "MOMENT-01",
    name: "Portrait Sitting",
    subtitle: "Half-day, 15 retouched portraits",
    price: 450, deposit: 450, totalLabel: "$1,200 total · $450 deposit",
    duration: "4 hours · studio or location",
    deliver: "15 retouched portraits, web + print masters",
    highlights: ["1 wardrobe change", "Web + print delivery", "10-day turnaround"],
    forWhom: ["Founders & operators", "Press kits", "Personal commissions"],
  },
  {
    id: "pkg-birthday-recap", lane: "moments", code: "MOMENT-02",
    name: "Birthday Recap",
    subtitle: "Half-day capture, recap film, and stills the family keeps",
    price: 600, deposit: 600, totalLabel: "$1,500 total · $600 deposit",
    duration: "Up to 5 hours on-site",
    deliver: "Recap film + 30 stills, family-keepable cut",
    highlights: ["Books months in advance with deposit", "Single operator", "Vertical recap for sharing"],
    forWhom: ["Sweet 16 / quinceañera / milestone", "Children's parties", "Anniversary dinners"],
  },
];

/* ─── Press / clients shown on the home and about pages ────────── */
const PRESS = [];
const CLIENTS = [];

/* ─────────────────────────────────────────────────────────────────
   Work, case studies. Each follows the problem → approach → result frame.
   ───────────────────────────────────────────────────────────────── */
/* ─── Real Eleven Views work — every entry has real captured media ──
   Order matters: WORK[0] is the lead case shown in mega-nav, on /work,
   and as next-up after every project. Yolanda's look-shoot leads.    */
const BLOB_WORK = "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work";

const _WORK_RAW = [
  {
    id: "young-ko-modomode",
    title: "Young K.O · modomode.army",
    client: "Young K.O",
    discipline: ["Web", "Brand", "Site build"],
    year: "2025",
    summary: "A full site build for Young K.O — a fan-site / brand home at modomode.army, designed and built by the studio end-to-end.",
    brand: {
      bg: "#050705",
      bgSoft: "#0a0d0a",
      accent: "#22c55e",
      accentLight: "#4ade80",
      gold: "#d4af37",
      text: "#e2e8e2",
      mono: "DM Mono, monospace",
      logo: null,
    },
    cover: {
      v: "deep",
      code: "EV-WK-YK",
      image: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/young-ko/youngko-hero-tlWlxQCTlRdLMezrafnaElCUj2hdeY.jpg",
      aspect: "16/10",
      focal: "center top",
    },
    role: "Brand · Web design · Build · Deploy",
    crew: "Studio · 1 build cycle",
    runtime: "Live · modomode.army",
    href: "https://modomode.army/",
    gallery: [
      { kind: "image", src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/young-ko/youngko-hero-tlWlxQCTlRdLMezrafnaElCUj2hdeY.jpg",     label: "modomode.army · home", aspect: "16/10" },
      { kind: "image", src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/young-ko/youngko-screen-01-EMaOv4eloY6sq7xQZ6EbMtK6orpTye.jpg", label: "modomode.army · scroll I",   aspect: "16/10" },
      { kind: "image", src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/young-ko/youngko-screen-02-ytsw0cBnsjFSRKCjZWrQow8WCCIHaI.jpg", label: "modomode.army · scroll II",  aspect: "16/10" },
      { kind: "image", src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/young-ko/youngko-screen-03-rUkJYbzDhKxsFZSBfQpf5l9IRiMXj5.jpg", label: "modomode.army · scroll III", aspect: "16/10" },
    ],
    problem:
      "Young K.O needed a brand home that read like the music — loud, confident, native to the internet, with room to grow into a fan-led world. A templated build wouldn't carry the tone.",
    approach:
      "A full site, designed and built end-to-end by the studio. Custom type, hand-laid sections, motion-led hero, performance-tuned for share traffic. Live at modomode.army.",
    result: [
      ["Live", "modomode.army"],
      ["Custom", "Designed end-to-end"],
      ["Brand", "Carries the music"],
    ],
    nextId: "akademy-ai",
  },
  {
    id: "akademy-ai",
    title: "The Akademy AI",
    client: "Akademiks",
    discipline: ["Web", "Brand", "Product"],
    year: "2025",
    summary: "An AI-driven education platform for Akademiks — wordmark, brand language, hero motion, and full member portal, designed and shipped by the studio.",
    brand: {
      bg: "#000000",
      bgSoft: "#11151C",
      accent: "#F80000",
      accentLight: "#ff3030",
      gold: "#F80000",
      text: "#ffffff",
      mono: "ui-monospace, monospace",
      logo: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/akademiks/wordmark-lzqyDt1HiOMmeTVDL1wCfJiKm8wtBd.svg",
    },
    cover: {
      v: "deep",
      code: "EV-WK-AK",
      video: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/akademiks/hero-wJAQnLUJsvryPRGRMvXWAyg73Q2peD.mp4",
      poster: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/akademiks/banner-e0XValpxi8lPaJ4cjC6ViIXLq2HvJ3.jpg",
      aspect: "16/9",
      focal: "center",
    },
    role: "Brand · Wordmark · Web design · Build · Hero motion",
    crew: "Studio · multi-cycle build",
    runtime: "Live · Akademiks platform",
    href: "https://akademy-ai.vercel.app",
    gallery: [
      { kind: "video", src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/akademiks/hero-wJAQnLUJsvryPRGRMvXWAyg73Q2peD.mp4",     label: "Hero motion · desktop", aspect: "16/9" },
      { kind: "image", src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/akademiks/banner-e0XValpxi8lPaJ4cjC6ViIXLq2HvJ3.jpg", label: "Brand banner", aspect: "21/9" },
      { kind: "image", src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/akademiks/logo-UDX8gu9QcoNSxtGoQXrGLlkixKYLKN.jpg",   label: "Logo lockup", aspect: "1/1" },
      { kind: "image", src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/akademiks/avatar-wJaNFnJeOrZ400IstwMhLxxWyWftla.jpg", label: "Avatar mark", aspect: "1/1" },
      { kind: "video", src: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/akademiks/hero-mobile-fkrsZfTJlvZ7X4rQVjDeIDhnEtyywx.mp4", label: "Hero motion · mobile cut", aspect: "9/16" },
    ],
    problem:
      "Akademiks needed a brand and a platform that didn't read like a course product. The room had to feel like the brand — fast, aggressive, native to the internet, with a logo the audience could already see.",
    approach:
      "Wordmark first. Hero motion second. Member portal built around them. Red-on-black core, custom type pairing, full motion language designed and delivered by the studio.",
    result: [
      ["Wordmark", "Designed in-studio"],
      ["Motion", "Hero film + mobile cut"],
      ["Platform", "Member portal, course flow"],
    ],
    nextId: "yolanda-rivera-look",
  },
  {
    id: "yolanda-rivera-look",
    title: "Yolanda Rivera · Look Shoot",
    client: "Yolanda Rivera",
    instagram: { model: "@yolylee.x", photographer: "@simeon.views" },
    discipline: ["Photography", "Editorial", "Look Shoot"],
    year: "2025",
    summary: "Three concepts captured back-to-back in a single day. One creative direction, one model, three sets that read like one cohesive editorial.",
    cover: {
      v: "warm",
      code: "EV-WK-YR",
      // Use the looping shoot video as the cover. focal:"center" keeps
      // the subject (mid-body) visible even when the wide frame crops top/bottom.
      video: `${BLOB_WORK}/yolanda-rivera/01-less-been-more-lately-Ztv8W7bbA89pDHBaU2NwiY5goJVFOP.mp4`,
      poster: `${BLOB_WORK}/yolanda-rivera/still-01-purest-00mUpsFDRWVTDxO4xqPSvzn2RjFvaP.jpg`,
      aspect: "9/16",
      focal: "center 35%",
    },
    role: "Direction · DP · Photography · Edit",
    crew: "Simeon · Yolanda · 1 day on set",
    runtime: "Look reel · 1 day",
    gallery: [
      { kind: "video", src: `${BLOB_WORK}/yolanda-rivera/01-less-been-more-lately-Ztv8W7bbA89pDHBaU2NwiY5goJVFOP.mp4`, label: "Less Been More Lately", aspect: "9/16" },
      { kind: "video", src: `${BLOB_WORK}/yolanda-rivera/02-valentines-look-qQSF5KFUbU5rTKqCGRVphHxIGPERxb.mp4`, label: "Valentine look", aspect: "9/16" },
      { kind: "image", src: `${BLOB_WORK}/yolanda-rivera/still-01-purest-00mUpsFDRWVTDxO4xqPSvzn2RjFvaP.jpg`, label: "The Purest of Inspiration · plate I",   aspect: "4/5" },
      { kind: "image", src: `${BLOB_WORK}/yolanda-rivera/still-02-purest-zD0JEmermKsT5p9OYtWqIM3SxRKlec.jpg`, label: "The Purest of Inspiration · plate II",  aspect: "4/5" },
      { kind: "image", src: `${BLOB_WORK}/yolanda-rivera/still-03-purest-JachhQDvC9Vjb0OzJnQmjHJbZx3N1F.jpg`, label: "The Purest of Inspiration · plate III", aspect: "4/5" },
    ],
    problem:
      "A look shoot needed to do three things in one day: build a press kit, feed the social channel for a quarter, and read like an editorial spread. The studio had Yolanda for one day; the work had to come back finished.",
    approach:
      "Three concepts, three setups, one operator-led day. Stills and motion captured side-by-side on a single body, edited the same week, delivered as a vertical-first look reel plus a stills set captioned for press.",
    result: [
      ["03", "Concepts captured · 1 day on set"],
      ["02", "Vertical edits, social-ready"],
      ["03", "Editorial stills · The Purest of Inspiration"],
    ],
    nextId: "uzi-night",
  },
  {
    id: "uzi-night",
    title: "Uzi Pulled Up · Sold-Out Night",
    client: "Eleven Views",
    discipline: ["Live capture", "Event recap", "Film"],
    year: "2024",
    summary: "A sold-out night, every section packed. Vertical capture of the moment Uzi pulled up — the room, the section, the room watching the section.",
    cover: {
      v: "deep",
      code: "EV-WK-UZ",
      video: `${BLOB_WORK}/uzi-pulled-up-M1485yDz7vUTJTVwY9Co7VaKcW4uUe.mp4`,
      aspect: "9/16",
      focal: "center top",
    },
    role: "Live capture · Edit · Color",
    crew: "Simeon · 1 night on the floor",
    runtime: "Recap · 0:45",
    gallery: [
      { kind: "video", src: `${BLOB_WORK}/uzi-pulled-up-M1485yDz7vUTJTVwY9Co7VaKcW4uUe.mp4`, label: "Sold-out night recap", aspect: "9/16" },
    ],
    problem:
      "Capture a single sold-out night without staging a single frame. The room had to read as the room. The cut had to ship before the venue posted theirs.",
    approach:
      "One operator on the floor, vertical, available light, mixed with the house. Cut and color the same week.",
    result: [
      ["1 night", "Captured solo"],
      ["Sold out", "Every section, packed"],
      ["48 hr", "Edit-to-post turnaround"],
    ],
    nextId: "birthday-section",
  },
  {
    id: "birthday-section",
    title: "Birthday Section · Replay",
    client: "Eleven Views",
    discipline: ["Birthday recap", "Live capture", "Edit"],
    year: "2024",
    summary: "Birthday section recap. The studio's signature offering — a film a family keeps for the rest of their lives, captured in one evening.",
    cover: {
      v: "warm",
      code: "EV-WK-BD",
      video: `${BLOB_WORK}/birthday-section-replay-JX9FqfQy3RAvrIKN8ElULbL42qkEKd.mp4`,
      aspect: "9/16",
      focal: "center top",
    },
    role: "Live capture · Edit",
    crew: "Simeon · 1 evening",
    runtime: "Recap · 0:35",
    gallery: [
      { kind: "video", src: `${BLOB_WORK}/birthday-section-replay-JX9FqfQy3RAvrIKN8ElULbL42qkEKd.mp4`, label: "Birthday section replay", aspect: "9/16" },
    ],
    problem:
      "Capture an evening that mattered to one family in a way that holds up in fifteen years. Quietly. Without making the room about the camera.",
    approach:
      "Single operator. Available light. A short cut delivered the next week, plus the full take archived for the family.",
    result: [
      ["1 evening", "On-site capture"],
      ["1 week", "Edit-to-deliver"],
      ["Forever", "What the family keeps"],
    ],
    nextId: "yolanda-rivera-look",
  },
];

/* Reorder so Yolanda's look shoot leads. Falls back to original order
   if the lead id isn't present.                                      */
const _LEAD_ID = "yolanda-rivera-look";
const _LEAD = _WORK_RAW.find((w) => w.id === _LEAD_ID);
const WORK = _LEAD
  ? [_LEAD, ..._WORK_RAW.filter((w) => w.id !== _LEAD_ID)]
  : _WORK_RAW;

const WORK_FILTERS = [
  { key: "all", label: "All" },
  { key: "film", label: "Film & Video", match: (p) => p.discipline.some(d => /Film|Video|Score/.test(d)) },
  { key: "photo", label: "Photography", match: (p) => p.discipline.some(d => /Photo|Lookbook/.test(d)) },
  { key: "web", label: "Web & Brand", match: (p) => p.discipline.some(d => /Web|Brand|E-commerce|Print/.test(d)) },
];

/* ─────────────────────────────────────────────────────────────────
   FAQ
   ───────────────────────────────────────────────────────────────── */
const FAQ = [
  {
    group: "Working with the studio",
    items: [
      ["How do you take on new work?", "Through the inquiry form, by email, or by referral. We read every brief by hand and write back within one working day."],
      ["What's the typical engagement length?", "Two weeks for a portrait, ten weeks for a full site, four months for a documentary. The booking flow gives you a real estimate before we talk."],
      ["Do you work with in-house teams?", "Often, we work alongside in-house creative leads on roughly half of our engagements, and we're comfortable plugging into existing review pipelines."],
      ["Where are you based?", "We are a remote, distributed studio, we travel for the right brief, and most of our work is shot on location."],
    ],
  },
  {
    group: "Pricing & contracts",
    items: [
      ["Why do some tiers say 'Inquire'?", "Six-figure productions vary too widely to publish a band that's honest. We send a fixed-fee proposal within three days of a kickoff call."],
      ["Do you take on retainers?", "Yes, usually a quarterly retainer with a defined deliverable cadence. Retainers start at $18k/quarter."],
      ["What rights are licensed?", "Everything we shoot is licensed for unlimited use across owned channels for two years, with paid extensions thereafter. Buyouts available."],
      ["Do you require deposits?", "50% on greenlight, 50% on delivery for fixed-fee work. Retainers are billed monthly in advance."],
    ],
  },
  {
    group: "Store",
    items: [
      ["Where do orders ship from?", "the studio. Most pieces leave the studio within 3–5 business days."],
      ["What's the return window?", "30 days for unworn apparel and accessories. Music and digital goods are non-refundable but always re-downloadable."],
      ["Do you restock?", "Some pieces, sometimes. Most are made in numbered runs and stay sold out, we'd rather make the next thing than reprint the last."],
      ["International shipping?", "Yes. DDP available in 28 countries. Duties and taxes are calculated at checkout."],
    ],
  },
];

/* ─────────────────────────────────────────────────────────────────
   MEDIA MANIFEST, single source of truth for every visual slot.

   Every section of the site reads its imagery from this object.
   To swap a clip / photo, just change the `file` value below, no
   page-level edits needed. Every slot also carries:
     • kind   — "image" | "video"
     • aspect, recommended aspect ratio for new uploads
     • role   — semantic tag, also used as the auto-routing key when
                a new file is dropped into /assets/media/_inbox

   The `MEDIA_FILTERS` table at the bottom maps filename patterns to
   a slot key, so when a new clip lands matching a known pattern the
   site can auto-pick it up (used by the upcoming /admin uploader).
   ───────────────────────────────────────────────────────────────── */
const MEDIA_BASE = CDN_BASE;            // Wasabi base, see CDN_BASE above
const LOCAL_IMG  = "/assets/media";       // small still images stay local; root-absolute so deep-linked routes resolve correctly
const MEDIA = {
  home: {
    hero: {
      kind: "video",
      role: "home.hero",
      aspect: "16/9",
      file: VID("instagram-video-01.mp4"),
      poster: POSTER("instagram-video-01.jpg"),
      note: "Cinematic loop behind the headline 'Brands worth looking at twice.'",
    },
    services: {
      photography: {
        kind: "image",
        role: "service.photography.cover",
        aspect: "4/3",
        file: `${LOCAL_IMG}/images/projects/purest-inspiration-01.jpg`,
        focal: "center 25%",
        note: "Photography service card, portrait still — focal bias up so the face stays in the 4:3 frame.",
      },
      video: {
        kind: "video",
        role: "service.video.cover",
        aspect: "4/3",
        file: VID("media-video-08.mp4"),
        poster: POSTER("media-video-08.jpg"),
        focal: "center top",
        note: "Video service card, short looping clip.",
      },
      web: {
        kind: "image",
        role: "service.web.cover",
        aspect: "4/3",
        file: "https://hd709m3aorgvkjdg.public.blob.vercel-storage.com/work/young-ko/youngko-hero-tlWlxQCTlRdLMezrafnaElCUj2hdeY.jpg",
        focal: "center top",
        note: "Web & Brand service card uses the live Young K.O / modomode.army site as proof-of-work.",
      },
    },
    featuredFilm: {
      kind: "video",
      role: "home.featuredFilm",
      aspect: "16/10",
      file: VID("instagram-video-04.mp4"),
      poster: POSTER("instagram-video-04.jpg"),
      note: "'Selected work' split, the marquee case study film.",
    },
    store: [
      { kind: "video", role: "store.product", aspect: "4/5", file: VID("media-video-02.mp4"), poster: POSTER("media-video-02.jpg") },
      { kind: "video", role: "store.product", aspect: "4/5", file: VID("media-video-09.mp4"), poster: POSTER("media-video-09.jpg") },
      { kind: "video", role: "store.product", aspect: "4/5", file: VID("media-video-11.mp4"), poster: POSTER("media-video-11.jpg") },
      { kind: "image", role: "store.product", aspect: "4/5", file: `${LOCAL_IMG}/images/projects/purest-inspiration-02.jpg` },
    ],
  },
  work: {
    "yoyo-lee-lookshoot": {
      cover: { kind: "video", role: "work.cover", aspect: "16/10", file: VID("instagram-video-04.mp4"), poster: POSTER("instagram-video-04.jpg") },
    },
  },
  about: {
    founder: { kind: "image", role: "about.founder", aspect: "4/5", file: `${LOCAL_IMG}/images/projects/purest-inspiration-03.jpg` },
  },
  music: {
    /* Music is rendered through the Untitled.stream embed.  Track IDs live on
       each CATALOG item (mu-01..mu-04) under the `untitledId` field, drop
       the ID from the share URL (e.g. https://untitled.stream/embed/<ID>). */
    provider: "untitled.stream",
    embedHeights: { card: 280, pdp: 520 },
    notes: "Set CATALOG[<musicItem>].untitledId = '<id>' to switch a card from placeholder to embedded player.",
  },
};

/* Filename → slot routing.  When a new file lands in /assets/media/_inbox,
   the first pattern that matches sends it to that slot.            */
const MEDIA_FILTERS = [
  { pattern: /^purest-inspiration-01/i,        slot: "home.services.photography" },
  { pattern: /^purest-inspiration-02/i,        slot: "home.store.3" },
  { pattern: /^purest-inspiration-03/i,        slot: "about.founder" },
  { pattern: /^instagram-video-01/i,           slot: "home.hero" },
  { pattern: /^instagram-video-04/i,           slot: "home.featuredFilm" },
  { pattern: /^media-video-(02|07|08|10|11)/i, slot: "home.store.*" },
  { pattern: /^media-video-/i,                 slot: "home.featuredFilm" },
  { pattern: /yoyo|yo[-_ ]yo|yo lee/i,         slot: "work.yoyo-lee-lookshoot.cover" },
  { pattern: /\.(jpg|jpeg|png|webp)$/i,        slot: "home.services.photography" },
  { pattern: /\.(mp4|mov|webm)$/i,             slot: "home.featuredFilm" },
];

/* ─── Site IA, used by mega-nav and mobile drawer ─────────────── */
const NAV = [
  { key: "home", label: "Home" },
  { key: "work", label: "Work" },
  { key: "services", label: "Services" },
  { key: "intelligence", label: "Intelligence" },
  { key: "store", label: "Store" },
  { key: "booking", label: "Book" },
  { key: "about", label: "Studio" },
  { key: "contact", label: "Contact" },
];

window.CATALOG = CATALOG;
window.CATEGORIES = CATEGORIES;
window.PRICE_BANDS = PRICE_BANDS;
window.SERVICES = SERVICES;
window.PRESS = PRESS;
window.CLIENTS = CLIENTS;
window.WORK = WORK;
window.WORK_FILTERS = WORK_FILTERS;
window.FAQ = FAQ;
window.NAV = NAV;
window.MEDIA = MEDIA;
window.MEDIA_FILTERS = MEDIA_FILTERS;
window.PACKAGES = PACKAGES;
window.PACKAGE_LANES = PACKAGE_LANES;
window.AUDIO_SRC = AUDIO_SRC;
window.VIDEO_SRC = VIDEO_SRC;
