/*
 * Audit Me - landing page
 * Reimplemented from the Claude Design export "AuditMe.dc.html".
 * State model, copy, styling and interactions mirror the original DC component.
 */

const INK = '#16233F';
const CREAM = '#F5F1E8';
const RED = '#F0505E';
const YELLOW = '#F2C94C';

const MONO = "'IBM Plex Mono', monospace";
const DISPLAY = "'Montserrat', sans-serif";
const BODY = "'Public Sans', sans-serif";

// Apply admin-editable SEO to the document head at runtime. Note: this updates
// the browser title + tags for users and JS-running crawlers (Google); social
// scrapers read the static <head> in index.html (change that via redeploy).
function setMetaTag(attr, key, content) {
  if (content == null || content === '') return;
  let el = document.head.querySelector('meta[' + attr + '="' + key + '"]');
  if (!el) { el = document.createElement('meta'); el.setAttribute(attr, key); document.head.appendChild(el); }
  el.setAttribute('content', content);
}
function applySeo(seo) {
  if (!seo) return;
  if (seo.title) document.title = seo.title;
  setMetaTag('name', 'description', seo.description);
  setMetaTag('name', 'keywords', seo.keywords);
  setMetaTag('property', 'og:title', seo.og_title || seo.title);
  setMetaTag('property', 'og:description', seo.og_description || seo.description);
  setMetaTag('property', 'og:image', seo.og_image);
  setMetaTag('name', 'twitter:title', seo.og_title || seo.title);
  setMetaTag('name', 'twitter:description', seo.og_description || seo.description);
  setMetaTag('name', 'twitter:image', seo.og_image);
}

// Heuristic eligibility check on the free-text location: is it in the US or Canada?
// Matches a country name, a US state, or a Canadian province (full name or code).
function isUSorCanada(loc) {
  const norm = ' ' + String(loc || '').toLowerCase().replace(/[^a-z]+/g, ' ').replace(/\s+/g, ' ').trim() + ' ';
  const tokens = norm.trim() ? norm.trim().split(' ') : [];
  const has = (arr) => arr.some((t) => tokens.indexOf(t) !== -1);

  // Country signals
  const countryPhrases = [' usa ', ' u s a ', ' u s ', ' united states ', ' america ', ' canada '];
  if (countryPhrases.some((p) => norm.indexOf(p) !== -1)) return true;
  if (has(['us', 'usa', 'can', 'canada', 'america'])) return true;

  // US state + Canadian province 2-letter codes
  const codes = ['al', 'ak', 'az', 'ar', 'ca', 'co', 'ct', 'de', 'fl', 'ga', 'hi', 'id', 'il', 'in', 'ia', 'ks', 'ky', 'la', 'me', 'md', 'ma', 'mi', 'mn', 'ms', 'mo', 'mt', 'ne', 'nv', 'nh', 'nj', 'nm', 'ny', 'nc', 'nd', 'oh', 'ok', 'or', 'pa', 'ri', 'sc', 'sd', 'tn', 'tx', 'ut', 'vt', 'va', 'wa', 'wv', 'wi', 'wy', 'dc', 'on', 'qc', 'bc', 'ab', 'mb', 'sk', 'ns', 'nb', 'nl', 'pe', 'pei', 'nt', 'yt', 'nu'];
  if (has(codes)) return true;

  // US state + Canadian province full names (multi-word supported)
  const names = ['alabama', 'alaska', 'arizona', 'arkansas', 'california', 'colorado', 'connecticut', 'delaware', 'florida', 'georgia', 'hawaii', 'idaho', 'illinois', 'indiana', 'iowa', 'kansas', 'kentucky', 'louisiana', 'maine', 'maryland', 'massachusetts', 'michigan', 'minnesota', 'mississippi', 'missouri', 'montana', 'nebraska', 'nevada', 'new hampshire', 'new jersey', 'new mexico', 'new york', 'north carolina', 'north dakota', 'ohio', 'oklahoma', 'oregon', 'pennsylvania', 'rhode island', 'south carolina', 'south dakota', 'tennessee', 'texas', 'utah', 'vermont', 'virginia', 'washington', 'west virginia', 'wisconsin', 'wyoming', 'ontario', 'quebec', 'british columbia', 'alberta', 'manitoba', 'saskatchewan', 'nova scotia', 'new brunswick', 'newfoundland', 'labrador', 'prince edward island', 'northwest territories', 'yukon', 'nunavut'];
  if (names.some((n) => norm.indexOf(' ' + n + ' ') !== -1)) return true;

  return false;
}

// ---- Video upload limits ----
const MAX_VIDEO_MB = 100;        // standard max file size
const MAX_VIDEO_SECONDS = 90;    // max duration
const MAX_VIDEO_LONG = 1920;     // Full HD (1080p) long edge
const MAX_VIDEO_SHORT = 1080;    // Full HD short edge

// Validate a chosen video against the limits. Resolves { ok, error }.
function validateVideoFile(file) {
  return new Promise((resolve) => {
    if (!file) return resolve({ ok: false, error: 'Please choose a video file.' });
    const mb = file.size / (1024 * 1024);
    if (mb > MAX_VIDEO_MB) {
      return resolve({ ok: false, error: 'Video is too large (' + mb.toFixed(0) + ' MB). Maximum is ' + MAX_VIDEO_MB + ' MB.' });
    }
    const url = URL.createObjectURL(file);
    const v = document.createElement('video');
    v.preload = 'metadata';
    let done = false;
    const finish = (res) => { if (done) return; done = true; try { URL.revokeObjectURL(url); } catch (_) {} resolve(res); };
    const timer = setTimeout(() => finish({ ok: false, error: "Couldn't read this video. Please try a different file (MP4 recommended)." }), 15000);
    v.onloadedmetadata = () => {
      clearTimeout(timer);
      const dur = v.duration;
      const w = v.videoWidth || 0, h = v.videoHeight || 0;
      const longEdge = Math.max(w, h), shortEdge = Math.min(w, h);
      if (Number.isFinite(dur) && dur > MAX_VIDEO_SECONDS + 0.5) {
        return finish({ ok: false, error: 'Video is too long (' + Math.round(dur) + 's). Maximum is ' + MAX_VIDEO_SECONDS + ' seconds.' });
      }
      if (longEdge && (longEdge > MAX_VIDEO_LONG || shortEdge > MAX_VIDEO_SHORT)) {
        return finish({ ok: false, error: 'Video resolution is too high (' + w + '×' + h + '). Maximum is Full HD (1080p).' });
      }
      finish({ ok: true });
    };
    v.onerror = () => { clearTimeout(timer); finish({ ok: false, error: "Couldn't read this video. Please try a different file (MP4 recommended)." }); };
    v.src = url;
  });
}

// Supabase client for uploading the applicant's video directly to storage.
const _pubCfg = window.PUBLIC_CONFIG || {};
const sbPublic = (window.supabase && _pubCfg.SUPABASE_URL && _pubCfg.SUPABASE_ANON_KEY)
  ? window.supabase.createClient(_pubCfg.SUPABASE_URL, _pubCfg.SUPABASE_ANON_KEY)
  : null;

// ---- shared style fragments -------------------------------------------------
const btnBase = {
  fontFamily: MONO, fontWeight: 700, borderRadius: 999, cursor: 'pointer', border: 'none',
};
const btnPrimary = { ...btnBase, background: RED, color: CREAM };
const btnDark = { ...btnBase, background: INK, color: CREAM };
const btnGhost = { ...btnBase, background: 'transparent', color: INK, border: '2px solid ' + INK };

const h2Style = {
  fontFamily: DISPLAY, fontWeight: 900, fontSize: 'clamp(36px,6vw,64px)',
  textTransform: 'uppercase',
};
const sectionPad = 'clamp(56px,9vw,80px) clamp(16px,5vw,64px)';
const dottedBg = {
  backgroundImage:
    'radial-gradient(rgba(22,35,63,0.05) 1px, transparent 1px), repeating-linear-gradient(to bottom, transparent 0 39px, rgba(22,35,63,0.07) 39px 40px)',
  backgroundSize: '3px 3px, 100% 40px',
};

class App extends React.Component {
  constructor(props) {
    super(props);
    this.rootRef = React.createRef();
    this.reducedMotion =
      typeof window !== 'undefined' && window.matchMedia &&
      window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    this.hasStartedCount = false;
    this.state = {
      revealedIds: {},
      revealedPhrases: { r1: false, r2: false },
      activeStep: null,
      completedSteps: [false, false, false, false],
      countValue: 0,
      showStamp: false,
      pastHero: false,
      footerVisible: false,
      barDismissed: false,
      formStep: 1,
      openFaq: null,
      submitted: false,
      submitting: false,
      submitStatus: '',
      submitError: '',
      videoError: '',
      videoChecking: false,
      disqualified: false,
      form: {
        over18Yes: false, over18No: false, eligibleYes: false, eligibleNo: false,
        name: '', email: '', phone: '', location: '', handle: '',
        summary: '', story: '', videoFileName: '',
        roastYes: false, roastNo: false, offLimits: '', anythingElse: '', consent: false,
      },
      errors: {},
      social: { instagram: '', x: '', youtube: '', tiktok: '' },
      socialIcons: {},
    };
  }

  // Social links, custom icons and SEO are editable from the admin panel.
  loadSocialLinks() {
    const cfg = window.PUBLIC_CONFIG || {};
    if (!cfg.SUPABASE_URL || !cfg.SUPABASE_ANON_KEY) return; // not configured - keep defaults
    fetch(cfg.SUPABASE_URL.replace(/\/+$/, '') + '/rest/v1/settings?key=in.(social_links,social_icons,seo)&select=key,value', {
      headers: { apikey: cfg.SUPABASE_ANON_KEY, Authorization: 'Bearer ' + cfg.SUPABASE_ANON_KEY },
    })
      .then((r) => (r.ok ? r.json() : null))
      .then((rows) => {
        if (!rows) return;
        const byKey = {};
        rows.forEach((r) => { byKey[r.key] = r.value; });
        this.setState((s) => ({
          social: Object.assign({}, s.social, byKey.social_links || {}),
          socialIcons: Object.assign({}, s.socialIcons, byKey.social_icons || {}),
        }));
        if (byKey.seo) applySeo(byKey.seo);
      })
      .catch(() => { /* non-critical */ });
  }

  componentDidMount() {
    this.loadSocialLinks();
    const root = this.rootRef.current;
    if (!root) return;

    const revealObs = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          const id = entry.target.getAttribute('data-reveal-id');
          if (id) {
            this.setState((s) => ({ revealedIds: { ...s.revealedIds, [id]: true } }));
            revealObs.unobserve(entry.target);
          }
        }
      });
    }, { threshold: 0.2 });
    root.querySelectorAll('[data-reveal-id]').forEach((el) => revealObs.observe(el));
    this.revealObs = revealObs;

    const heroEl = root.querySelector('[data-hero-sentinel]');
    if (heroEl) {
      this.heroObs = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          const past = !entry.isIntersecting && entry.boundingClientRect.top < 0;
          this.setState({ pastHero: past });
        });
      }, { threshold: 0 });
      this.heroObs.observe(heroEl);
    }

    const countEl = root.querySelector('[data-count-sentinel]');
    if (countEl) {
      this.countObs = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting && !this.hasStartedCount) {
            this.hasStartedCount = true;
            this.animateCount();
            this.countObs.disconnect();
          }
        });
      }, { threshold: 0.4 });
      this.countObs.observe(countEl);
    }

    const stepEls = root.querySelectorAll('[data-step-index]');
    if (stepEls.length) {
      this.stepObs = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            const idx = parseInt(entry.target.getAttribute('data-step-index'), 10);
            this.setState((s) => ({ completedSteps: s.completedSteps.map((v, i) => i <= idx) }));
          }
        });
      }, { threshold: 0.5, rootMargin: '-35% 0px -35% 0px' });
      stepEls.forEach((el) => this.stepObs.observe(el));
    }

    const footerEl = root.querySelector('[data-footer-sentinel]');
    if (footerEl) {
      this.footerObs = new IntersectionObserver((entries) => {
        entries.forEach((entry) => this.setState({ footerVisible: entry.isIntersecting }));
      }, { threshold: 0 });
      this.footerObs.observe(footerEl);
    }
  }

  componentWillUnmount() {
    ['revealObs', 'heroObs', 'countObs', 'stepObs', 'footerObs'].forEach((k) => {
      if (this[k]) this[k].disconnect();
    });
  }

  animateCount() {
    if (this.reducedMotion) {
      this.setState({ countValue: 500, showStamp: true });
      return;
    }
    const duration = 1100;
    const start = performance.now();
    const tick = (now) => {
      const t = Math.min(1, (now - start) / duration);
      const eased = 1 - Math.pow(1 - t, 3);
      this.setState({ countValue: Math.round(eased * 500) });
      if (t < 1) requestAnimationFrame(tick);
      else setTimeout(() => this.setState({ showStamp: true }), 150);
    };
    requestAnimationFrame(tick);
  }

  scrollTo(id) {
    const el = document.getElementById(id);
    if (!el) return;
    if (typeof window.smoothScrollTo === 'function') {
      const y = el.getBoundingClientRect().top + window.scrollY;
      window.smoothScrollTo(y);
    } else {
      el.scrollIntoView({ behavior: this.reducedMotion ? 'auto' : 'smooth', block: 'start' });
    }
  }

  updateField(field, value) {
    this.setState((s) => ({ form: { ...s.form, [field]: value }, errors: { ...s.errors, [field]: false } }));
  }

  setBoolField(yesField, noField, val) {
    this.setState((s) => ({
      form: { ...s.form, [yesField]: val === 'yes', [noField]: val === 'no' },
      errors: { ...s.errors, [yesField.replace('Yes', '')]: false },
    }));
  }

  validateStep1() {
    const f = this.state.form;
    const errors = {};
    if (!f.over18Yes && !f.over18No) errors.over18 = true;
    if (!f.eligibleYes && !f.eligibleNo) errors.eligible = true;
    this.setState({ errors });
    if (Object.keys(errors).length) return false;
    if (f.over18No || f.eligibleNo) { this.setState({ disqualified: true }); return false; }
    return true;
  }

  validateStep2() {
    const f = this.state.form;
    const errors = {};
    if (!f.name.trim()) errors.name = true;
    if (!/^\S+@\S+\.\S+$/.test(f.email)) errors.email = true;
    if (!f.phone.trim()) errors.phone = true;
    if (!f.location.trim()) errors.location = true;
    this.setState({ errors });
    if (Object.keys(errors).length) return false;
    // Location must be in the US or Canada.
    //if (!isUSorCanada(f.location)) { this.setState({ disqualified: true }); return false; }
    return true;
  }

  validateStep3() {
    const f = this.state.form;
    const errors = {};
    if (!f.summary.trim()) errors.summary = true;
    if (!f.story.trim()) errors.story = true;
    this.setState({ errors });
    return Object.keys(errors).length === 0;
  }

  validateStep4() {
    const ok = !!this.state.form.videoFileName;
    this.setState({ errors: { videoFile: !ok } });
    return ok;
  }

  validateStep5() {
    const f = this.state.form;
    const errors = {};
    if (!f.roastYes && !f.roastNo) errors.roast = true;
    this.setState({ errors });
    return Object.keys(errors).length === 0;
  }

  validateStep6() {
    const ok = this.state.form.consent;
    this.setState({ errors: { consent: !ok } });
    return ok;
  }

  submitForm() {
    if (this.state.submitting) return;
    if (!this.validateStep6()) return;
    this.setState({ submitting: true, submitError: '', submitStatus: '' });
    this._runSubmit();
  }

  async _runSubmit() {
    try {
      // Upload the video first (so the admin can download it later); we send
      // only its storage path onward. Cloudflare R2 is used when configured
      // (server returns a presigned PUT); otherwise fall back to Supabase.
      let videoPath = null;
      const file = this._videoFile;
      if (file) {
        this.setState({ submitStatus: 'Uploading video…' });
        let usedR2 = false;
        try {
          const r = await fetch('/api/video-upload-url', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ filename: file.name, contentType: file.type || 'video/mp4' }),
          });
          if (r.ok) {
            const { url, key } = await r.json();
            const put = await fetch(url, { method: 'PUT', body: file, headers: { 'Content-Type': file.type || 'video/mp4' } });
            if (!put.ok) throw new Error('Video upload failed (' + put.status + ').');
            videoPath = 'r2:' + key;
            usedR2 = true;
          }
          // non-OK (e.g. 501 not configured) → fall through to Supabase
        } catch (e) {
          if (usedR2) throw e; // R2 was in use and genuinely failed
          // R2 was offered but the direct PUT failed (usually a missing CORS
          // rule on the bucket for this origin) - fall back to Supabase.
          console.warn('[audit-me] R2 upload unavailable, using Supabase instead:', (e && e.message) || e);
        }
        if (!usedR2 && sbPublic) {
          const safe = file.name.replace(/[^\w.\-]+/g, '_').slice(-80);
          const path = 'applications/' + Date.now() + '-' + Math.random().toString(36).slice(2, 8) + '-' + safe;
          const { error: upErr } = await sbPublic.storage
            .from('application-videos')
            .upload(path, file, { contentType: file.type || 'video/mp4', upsert: false });
          if (upErr) throw new Error('Video upload failed: ' + upErr.message);
          videoPath = path;
        }
      }

      this.setState({ submitStatus: 'Submitting…' });
      const payload = Object.assign({}, this.state.form, { video_path: videoPath });
      const res = await fetch('/api/apply', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
      if (!res.ok) {
        const body = await res.json().catch(() => ({}));
        throw new Error(body.error || ('Request failed (' + res.status + ').'));
      }
      // Success → send the applicant to the dedicated thank-you page.
      window.location.href = '/thank-you';
    } catch (err) {
      this.setState({
        submitting: false,
        submitStatus: '',
        submitError: (err && err.message) || 'Something went wrong. Please try again.',
      });
    }
  }

  render() {
    const s = this.state;
    const f = s.form;
    const revealed = s.revealedIds;

    const auditItems = [
      'Overspending, debt, or money disappearing',
      'A big financial risk or win',
      'Career confusion or a turning point',
      'Relationship or lifestyle decisions',
      'Self-sabotage, broken routines, or new discipline',
      'Any phase that changed how you live, spend, or think',
    ];

    const benefitTexts = [
      'Get featured on a real show',
      'Receive $500 if selected to appear',
      'Get an honest audit of your money or life',
      'Turn a big moment - good or bad - into a story that actually lands',
    ];
    const benefits = benefitTexts.map((text, i) => {
      const n = String(i + 1).padStart(2, '0');
      const r = !!revealed['benefit-' + n];
      return { n, text, opacity: r ? 1 : 0, transform: r ? 'translateY(0)' : 'translateY(14px)' };
    });

    const stepData = [
      { title: 'Apply for Audit Me', desc: 'Start your application below.' },
      { title: 'We may reach out', desc: 'If your story stands out, our team may contact you for the next step.' },
      { title: 'Get featured, get paid', desc: 'Selected stories are featured on Audit Me, and guests who appear on the show receive $500.' },
    ];
    const completedCount = s.completedSteps.filter(Boolean).length;
    const stepLineHeight = (completedCount / 4 * 100) + '%';

    const honestyLen = f.story.length;
    const honestyLabel = honestyLen < 40 ? 'Too vague' : honestyLen < 150 ? 'Getting real' : "Now we're talking";
    const honestyPercent = Math.min(100, Math.round((honestyLen / 220) * 100));

    const faqData = [
      ['Who can apply for Audit Me?', 'Anyone in the United States or Canada who is at least 20 years old can apply.'],
      ['What kind of stories are you looking for?', 'Real stories about money, life choices, pressure, wins, mistakes, or turning points.'],
      ['Do I need to share exact numbers or private details?', 'No. Share what you’re comfortable sharing - we care more about the story than forcing every detail.'],
      ['Do I have to be camera-ready or “good on camera” to apply?', 'No. You just need a real story and the willingness to tell it honestly.'],
      ['Is Audit Me a roast show?', 'No. It’s honest, direct, and funny at times, but it is not meant to humiliate people.'],
      ['Do featured guests get paid, and is there any cost to apply?', 'Yes, selected guests who appear on the show receive $500, and applying is free.'],
    ];

    const footerTargets = [
      ['Overview', 'hero'], ['What Is Audit Me', 'what-is'], ['What We Audit', 'what-we-audit'],
      ['Why Apply', 'why-apply'], ['How It Works', 'how-it-works'], ['FAQs', 'faqs'], ['Apply', 'apply'],
    ];

    const scrollToForm = () => this.scrollTo('apply');
    const scrollToWhatWeAudit = () => this.scrollTo('what-we-audit');

    const barVisible = s.pastHero && !s.barDismissed && !s.submitted && !s.footerVisible;
    const formVisible = !s.submitted && !s.disqualified;

    const toggleBtn = (active, activeBg) => ({
      flex: 1, fontFamily: MONO, fontWeight: 700, fontSize: 14, padding: 12,
      borderRadius: 6, border: '2px solid ' + INK, cursor: 'pointer',
      background: active ? activeBg : 'transparent',
      color: active ? CREAM : INK,
    });
    const inputStyle = {
      width: '100%', boxSizing: 'border-box', fontSize: 16, padding: '12px 14px',
      borderRadius: 6, border: '2px solid ' + INK, fontFamily: BODY,
    };
    const textareaStyle = { ...inputStyle, padding: 14, resize: 'vertical', lineHeight: 1.5 };
    const labelMono = { fontSize: 13, fontFamily: MONO, display: 'block', marginBottom: 6 };
    const stepTitle = { fontFamily: DISPLAY, fontWeight: 800, fontSize: 20, textTransform: 'uppercase', margin: 0 };
    const err = (msg) => <p role="alert" style={{ color: RED, fontSize: 13, margin: '6px 0 0' }}>{msg}</p>;
    const backBtn = (onClick) => (
      <button type="button" onClick={onClick} style={{ ...btnGhost, fontSize: 15, padding: '14px 24px' }}><svg style={{verticalAlign:'middle' }} xmlns="http://www.w3.org/2000/svg" height="18px" viewBox="0 -960 960 960" width="18px" fill="rgb(22, 35, 63)"><path d="m313-440 224 224-57 56-320-320 320-320 57 56-224 224h487v80H313Z"/></svg> Back</button>
    );
    const continueBtn = (onClick) => (
      <button type="button" onClick={onClick} style={{ ...btnDark, fontSize: 15, padding: '14px 28px' }}>Continue <svg style={{verticalAlign:'middle' }} xmlns="http://www.w3.org/2000/svg" height="18px" viewBox="0 -960 960 960" width="18px" fill="#fff"><path d="M647-440H160v-80h487L423-744l57-56 320 320-320 320-57-56 224-224Z"/></svg></button>
    );

    return (
      <div ref={this.rootRef} style={{
        '--accent': RED, '--accent-soft': 'rgba(227,54,41,0.14)',
        fontFamily: BODY, color: INK, background: CREAM, position: 'relative', overflowX: 'clip',
      }}>

        {/* HEADER */}
        <header style={{
          position: 'sticky', top: 0, zIndex: 40, background: '#F5F1E8ee', backdropFilter: 'blur(6px)',
          borderBottom: '1px solid rgba(22,35,63,0.15)', display: 'flex', alignItems: 'center',
          justifyContent: 'space-between', gap: 16, padding: '14px clamp(16px,4vw,48px)', flexWrap: 'wrap',
        }}>
          <img src="assets/logo.png" alt="Audit Me" style={{ height: 34, width: 'auto', display: 'block' }} />
          <button type="button" onClick={scrollToForm} style={{ ...btnDark, fontSize: 13, padding: '10px 20px' }}>Apply for Audit Me</button>
        </header>

        {/* HERO */}
        <section id="hero" data-screen-label="Hero" style={{
          padding: 'clamp(48px,10vw,80px) clamp(16px,5vw,64px) clamp(56px,9vw,96px)', textAlign: 'center',
          display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 28, position: 'relative',
        }}>
          <span style={{
            fontFamily: MONO, fontSize: 13, letterSpacing: '0.12em', textTransform: 'uppercase',
            border: '1px solid ' + INK, borderRadius: 999, padding: '6px 16px', background: YELLOW,
          }}>Selected guests receive $500</span>
          <h1 style={{
            fontFamily: DISPLAY, fontWeight: 900, fontSize: 'clamp(40px, 16vw, 148px)', lineHeight: 1.05,
            margin: 0, paddingBottom: '0.08em', textTransform: 'uppercase', letterSpacing: '-0.01em', whiteSpace: 'nowrap',
          }}>Audit Me</h1>
          <p style={{ maxWidth: 640, fontSize: 'clamp(18px,2.2vw,22px)', margin: 0, fontWeight: 600 }}>
            If your story is selected, we'll feature it on Audit Me. Guests who appear on the show will receive $500.
          </p>
          <p style={{ maxWidth: 620, fontSize: 16, margin: 0, color: 'rgba(22,35,63,0.75)' }}>
            A show where real people get their money, habits, and life choices audited on camera - honestly, publicly, and with humor.
          </p>
          <p style={{ maxWidth: 600, fontSize: 15, margin: 0, color: 'rgba(22,35,63,0.75)', fontFamily: MONO }}>
            Tell us what really happened - good or bad - and if your story stands out, we may bring it to the show.
          </p>
          <div style={{ display: 'flex', gap: 14, flexWrap: 'wrap', justifyContent: 'center', marginTop: 8 }}>
            <button type="button" onClick={scrollToForm} style={{ ...btnPrimary, fontSize: 15, padding: '16px 30px' }}>Apply for Audit Me</button>
            <button type="button" onClick={scrollToWhatWeAudit} style={{ ...btnGhost, fontSize: 15, padding: '14px 28px' }}>Tell Your Story</button>
          </div>
          <div data-hero-sentinel="" style={{ position: 'absolute', bottom: 0, height: 1, width: 1 }}></div>
        </section>

        {/* WHAT IS AUDIT ME */}
        <section id="what-is" data-screen-label="What Is Audit Me" style={{
          padding: sectionPad, ...dottedBg, maxWidth: 900, margin: '0 auto',
        }}>
          <h2 style={{ ...h2Style, margin: '0 0 24px' }}>What Is Audit Me?</h2>
          <p data-reveal-id="whatis-body" style={{
            fontSize: 18, lineHeight: 1.6, margin: '0 0 20px',
            opacity: revealed['whatis-body'] ? 1 : 0,
            transform: revealed['whatis-body'] ? 'translateY(0)' : 'translateY(16px)',
            transition: 'opacity .6s ease, transform .6s ease',
          }}>
            <strong>Audit Me </strong>is a show where real people unpack the <strong>financial decisions</strong> that changed their lives.
            <p>From life-changing investments and career risks to failed businesses, debt, missed opportunities, and hard-earned comebacks, every episode explores the choices that shaped someone's financial journey.</p>
            Because the most valuable financial advice doesn't always come from experts. Sometimes, it comes from someone who's lived it.
          </p>
        </section>

        {/* WHAT WE AUDIT */}
        <section id="what-we-audit" data-screen-label="What We Audit" style={{ padding: sectionPad, maxWidth: 900, margin: '0 auto' }}>
          <h2 style={{ ...h2Style, margin: '0 0 18px' }}>What We Audit</h2>
          <p style={{ fontSize: 17, lineHeight: 1.6, margin: '0 0 28px', color: 'rgba(22,35,63,0.85)' }}>
            Audit Me is for people whose money, habits, or life choices have given them a story worth telling - whether it went wrong, went right, or just got very real. That could mean:
          </p>
          <div style={{ display: 'flex', flexDirection: 'column', marginBottom: 28 }}>
            {auditItems.map((item, i) => (
              <div key={i} style={{ display: 'flex', alignItems: 'baseline', gap: 16, padding: '14px 0', borderTop: '1px solid rgba(22,35,63,0.18)' }}>
                <span style={{ width: 8, height: 8, borderRadius: 999, background: RED, flexShrink: 0, alignSelf: 'center' }}></span>
                <span style={{ fontSize: 16.5 }}>{item}</span>
              </div>
            ))}
          </div>
          <p style={{ fontSize: 17, lineHeight: 1.6, margin: '0 0 28px', fontWeight: 600 }}>
            If you have a chapter you already tell your friends about - and you're willing to talk about it on camera - this is where it goes.
          </p>
          <button type="button" onClick={scrollToForm} style={{ ...btnPrimary, fontSize: 15, padding: '14px 28px' }}>Apply for Audit Me</button>
        </section>

        {/* WHY APPLY */}
        <section id="why-apply" data-screen-label="Why Apply" style={{ padding: sectionPad, maxWidth: 900, margin: '0 auto' }}>
          <h2 style={{ ...h2Style, margin: '0 0 8px' }}>Why Apply?</h2>
          <p style={{ fontSize: 20, fontWeight: 700, margin: '0 0 18px' }}>Because anyone can give you vague advice. A proper audit is different.</p>
          <p style={{ fontSize: 16, lineHeight: 1.6, margin: '0 0 36px', color: 'rgba(22,35,63,0.8)' }}>
            Audit Me is for people who already know their story has weight - a mistake, a win, a risk, or a phase that changed things - and are willing to put it on the table. The upside is turning that moment into something bigger: a clear story, a real episode, and a chance for other people to see themselves in what you went through.
          </p>
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            {benefits.map((b) => (
              <div key={b.n} data-reveal-id={'benefit-' + b.n} style={{
                display: 'flex', alignItems: 'baseline', gap: 20, padding: '18px 0',
                borderTop: '1px solid rgba(22,35,63,0.2)', opacity: b.opacity, transform: b.transform,
                transition: 'opacity .5s ease, transform .5s ease',
              }}>
                <span style={{ fontFamily: MONO, fontSize: 14, color: 'var(--accent)', fontWeight: 700, flexShrink: 0 }}>{b.n}</span>
                <span style={{ fontSize: 18, fontWeight: 600 }}>{b.text}</span>
              </div>
            ))}
          </div>
        </section>

        {/* HOW IT WORKS */}
        <section id="how-it-works" data-screen-label="How Audit Me Works" style={{ padding: sectionPad, ...dottedBg }}>
          <div style={{ maxWidth: 720, margin: '0 auto' }}>
            <h2 style={{ ...h2Style, margin: '0 0 36px', textAlign: 'center' }}>How Audit Me Works</h2>
            <div style={{ position: 'relative', paddingLeft: 28 }}>
              <div style={{ position: 'absolute', left: 6, top: 6, bottom: 6, width: 3, background: 'rgba(22,35,63,0.15)', borderRadius: 2 }}></div>
              <div style={{ position: 'absolute', left: 6, top: 6, width: 3, background: RED, borderRadius: 2, height: stepLineHeight, transition: 'height .5s ease' }}></div>
              {stepData.map((d, i) => {
                const n = String(i + 1).padStart(2, '0');
                const done = s.completedSteps[i];
                const open = s.activeStep === i;
                return (
                  <div key={i} data-step-index={i}
                    onClick={() => this.setState((st) => ({ activeStep: st.activeStep === i ? null : i }))}
                    style={{
                      background: CREAM, border: '2px solid ' + INK, borderRadius: 4, padding: '18px 20px',
                      marginBottom: 16, cursor: 'pointer', boxShadow: done ? '3px 3px 0 ' + RED : 'none',
                    }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
                      <span style={{ fontFamily: MONO, fontWeight: 700, fontSize: 15, color: done ? RED : INK }}>{n}</span>
                      <span style={{ fontFamily: DISPLAY, fontWeight: 800, fontSize: 20, textTransform: 'uppercase', flex: 1 }}>{d.title}</span>
                      <span style={{ fontSize: 20, lineHeight:0.8, transform: open ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform .25s ease' }}><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M480-344 240-584l56-56 184 184 184-184 56 56-240 240Z"/></svg></span>
                      {done && (
                        <span aria-label="completed" style={{
                          width: 20, height: 20, borderRadius: 999, background: RED, color: CREAM, fontSize: 12,
                          display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 700,
                        }}>✓</span>
                      )}
                    </div>
                    {open && (
                      <p style={{ margin: '12px 0 0', paddingTop: 12, borderTop: '1px dashed rgba(22,35,63,0.3)', fontSize: 15, lineHeight: 1.55 }}>{d.desc}</p>
                    )}
                  </div>
                );
              })}
            </div>
          </div>
        </section>

        {/* $500 SECTION */}
        <section id="the-250" data-screen-label="$500 Reveal" style={{
          background: INK, color: CREAM, padding: 'clamp(64px,10vw,140px) clamp(16px,5vw,64px)', textAlign: 'center',
        }}>
          <h2 style={{
            fontFamily: DISPLAY, fontWeight: 900, fontSize: 'clamp(28px,4vw,42px)', lineHeight: 1.2,
            textTransform: 'uppercase', margin: '0 0 40px',
          }}>Selected Guests Receive $500</h2>
          <div data-count-sentinel="" style={{ position: 'relative', display: 'inline-block', margin: '0 auto 28px' }}>
            <div style={{ fontFamily: DISPLAY, fontWeight: 900, fontSize: 'clamp(80px,18vw,220px)', lineHeight: 1.15, paddingBottom: '0.05em', color: YELLOW }}>${s.countValue}</div>
            {s.showStamp && (
              <div style={{
                position: 'absolute', top: '50%', left: '50%',
                transform: 'translate(-50%,-50%) rotate(-10deg)',
                animation: this.reducedMotion ? 'none' : 'stampThump 0.6s ease-out forwards',
                border: '6px solid ' + RED, borderRadius: 10, color: RED, fontFamily: MONO, fontWeight: 700,
                fontSize: 'clamp(28px,5vw,52px)', letterSpacing: '0.06em', padding: '6px 22px', background: 'rgba(22,35,63,0.85)',
              }}>PAID</div>
            )}
          </div>
          <p style={{ maxWidth: 560, margin: '0 auto 18px', fontSize: 17, lineHeight: 1.6, color: 'rgba(245,241,232,0.85)' }}>
            Guests who are selected and appear on Audit Me will receive $500 as participant payment for the episode.
          </p>
          <p style={{ fontFamily: MONO, fontSize: 13, color: 'rgba(245,241,232,0.55)', maxWidth: 480, margin: '0 auto' }}>
            Applying does not guarantee selection, but if your story is chosen and you are featured on the show, you will be paid.
          </p>
        </section>

        {/* HOST */}
        <section id="host" data-screen-label="Host" style={{
          padding: sectionPad, maxWidth: 980, margin: '0 auto', position: 'relative',
        }}>
          <div className="host-portrait" style={{ position: 'relative' }}>
            <div style={{ position: 'relative', aspectRatio: '4/5', border: '3px solid ' + INK, borderRadius: 4, overflow: 'hidden' }}>
              <img src="assets/host.png" alt="Saroosh, Host" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
              <div style={{ position: 'absolute', top: '14%', left: '8%', width: '60%', height: '46%', border: '3px solid ' + RED, borderRadius: '50%', transform: 'rotate(-8deg)', pointerEvents: 'none' }}></div>
            </div>
            <div style={{
              position: 'absolute', top: -16, right: -10, border: '3px solid ' + RED, color: RED, fontFamily: MONO,
              fontWeight: 700, fontSize: 13, letterSpacing: '0.08em', padding: '4px 10px', transform: 'rotate(8deg)', opacity: 0.85,
            }}>AUDITED</div>
          </div>
          <div>
            <h2 style={{ fontFamily: DISPLAY, fontWeight: 900, fontSize: 'clamp(32px,5vw,52px)', textTransform: 'uppercase', margin: '0 0 18px' }}>Hosted by Saroosh</h2>
            <p style={{ fontSize: 17, lineHeight: 1.6, margin: 0 }}>
              Hosted by Saroosh, who brings a direct eye, sharp humor, and zero interest in pretending everything is fine. He asks the questions most people avoid, keeps the conversation honest, and makes sure the audit feels real, not rehearsed.
            </p>
          </div>
        </section>

        {/* FAQS */}
        <section id="faqs" data-screen-label="FAQs" style={{ padding: sectionPad, maxWidth: 780, margin: '0 auto' }}>
          <h2 style={{ ...h2Style, margin: '0 0 32px', textAlign: 'center' }}>FAQs</h2>
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            {faqData.map(([q, a], i) => {
              const open = s.openFaq === i;
              return (
                <div key={i} style={{ borderTop: '1px solid rgba(22,35,63,0.2)' }}>
                  <button type="button"
                    onClick={() => this.setState((st) => ({ openFaq: st.openFaq === i ? null : i }))}
                    aria-expanded={open}
                    style={{
                      width: '100%', textAlign: 'left', background: 'transparent', border: 'none', outline: 'none',
                      cursor: 'pointer', padding: '18px 0', display: 'flex', alignItems: 'center',
                      justifyContent: 'space-between', gap: 16, fontSize: 17, fontWeight: 700, fontFamily: BODY, color: INK,
                    }}>
                    <span>{q}</span>
                    <span style={{ fontSize: 20, lineHeight:0.8, flexShrink: 0, transform: open ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform .25s ease' }}><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M480-344 240-584l56-56 184 184 184-184 56 56-240 240Z"/></svg></span>
                  </button>
                  {open && (
                    <p style={{ margin: '0 0 20px', fontSize: 15.5, lineHeight: 1.6, color: 'rgba(22,35,63,0.8)', animation: 'fadeInUp .3s ease' }}>{a}</p>
                  )}
                </div>
              );
            })}
          </div>
        </section>

        {/* APPLY FORM */}
        <section id="apply" data-screen-label="Apply" style={{ padding: sectionPad, maxWidth: 720, margin: '0 auto' }}>
          <h2 style={{ ...h2Style, margin: '0 0 8px', textAlign: 'center' }}>Apply for Audit Me</h2>
          <p style={{ textAlign: 'center', fontSize: 16, margin: '0 0 8px' }}>Tell us the story you keep coming back to - about your money, your life, or both.</p>
          <p style={{ textAlign: 'center', fontSize: 15, color: 'rgba(22,35,63,0.7)', margin: '0 0 8px' }}>Be specific. Be real. Don't polish it for us.</p>
          <p style={{ textAlign: 'center', fontSize: 15, color: 'rgba(22,35,63,0.7)', margin: '0 0 36px' }}>If something in that chapter feels big, messy, risky, funny, or important, we want to see it.</p>

          {s.submitted && (
            <div aria-live="polite" style={{
              animation: 'receiptIn .5s ease', border: '2px solid ' + INK, background: '#fff', padding: 32,
              fontFamily: MONO, boxShadow: '8px 8px 0 rgba(22,35,63,0.15)', position: 'relative',
            }}>
              <div style={{ position: 'absolute', top: 18, right: 18, border: '4px solid ' + RED, color: RED, fontWeight: 700, fontSize: 15, letterSpacing: '0.06em', padding: '4px 10px', transform: 'rotate(-8deg)' }}>RECEIVED</div>
              <p style={{ margin: '0 0 6px', fontSize: 13, color: 'rgba(22,35,63,0.6)' }}>AUDIT ME - APPLICATION RECEIPT</p>
              <h3 style={{ fontFamily: DISPLAY, fontWeight: 800, fontSize: 28, textTransform: 'uppercase', margin: '4px 0 20px' }}>Application Received</h3>
              <div style={{ borderTop: '1px dashed rgba(22,35,63,0.4)', paddingTop: 16, display: 'flex', flexDirection: 'column', gap: 8, fontSize: 14 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>Name</span><span>{f.name}</span></div>
                <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>Email</span><span>{f.email}</span></div>
              </div>
              <p style={{ margin: '20px 0 0', fontSize: 13, color: 'rgba(22,35,63,0.65)' }}>We review every application. If your story stands out, our team will reach out.</p>
            </div>
          )}

          {s.disqualified && (
            <div style={{ border: '2px solid ' + INK, background: '#fff', padding: 28, textAlign: 'center' }}>
              <p style={{ fontFamily: MONO, fontSize: 14, margin: '0 0 8px', textTransform: 'uppercase', letterSpacing: '0.06em', color: RED }}>Not Eligible</p>
              <p style={{ fontSize: 15.5, margin: 0 }}>Audit Me currently requires applicants to be 18+ and legally able to sign a media release and receive payment in the US or Canada.</p>
            </div>
          )}

          {formVisible && (
            <div>
              <div style={{ display: 'flex', gap: 5, marginBottom: 28 }}>
                {[1, 2, 3, 4, 5, 6].map((n) => (
                  <div key={n} style={{ flex: 1, height: 6, borderRadius: 3, background: s.formStep >= n ? INK : 'rgba(22,35,63,0.15)' }}></div>
                ))}
              </div>
              <div aria-live="polite" style={{ fontFamily: MONO, fontSize: 12, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'rgba(22,35,63,0.6)', marginBottom: 18 }}>Step {s.formStep} of 6</div>

              {s.formStep === 1 && (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 18, animation: 'fadeInUp .35s ease' }}>
                  <p style={stepTitle}>Eligibility</p>
                  <div>
                    <label style={{ fontSize: 14, display: 'block', marginBottom: 8, fontWeight: 600 }}>Are you 18 or older?</label>
                    <div style={{ display: 'flex', gap: 10 }}>
                      <button type="button" aria-pressed={f.over18Yes} onClick={() => this.setBoolField('over18Yes', 'over18No', 'yes')} style={toggleBtn(f.over18Yes, INK)}>Yes</button>
                      <button type="button" aria-pressed={f.over18No} onClick={() => this.setBoolField('over18Yes', 'over18No', 'no')} style={toggleBtn(f.over18No, RED)}>No</button>
                    </div>
                    {s.errors.over18 && err('Please answer this question.')}
                  </div>
                  <div>
                    <label style={{ fontSize: 14, display: 'block', marginBottom: 8, fontWeight: 600 }}>Are you legally able to sign a media release and receive payment in the US or Canada?</label>
                    <div style={{ display: 'flex', gap: 10 }}>
                      <button type="button" aria-pressed={f.eligibleYes} onClick={() => this.setBoolField('eligibleYes', 'eligibleNo', 'yes')} style={toggleBtn(f.eligibleYes, INK)}>Yes</button>
                      <button type="button" aria-pressed={f.eligibleNo} onClick={() => this.setBoolField('eligibleYes', 'eligibleNo', 'no')} style={toggleBtn(f.eligibleNo, RED)}>No</button>
                    </div>
                    {s.errors.eligible && err('Please answer this question.')}
                  </div>
                  <button type="button" onClick={() => { if (this.validateStep1()) this.setState({ formStep: 2 }); }} style={{ ...btnDark, alignSelf: 'flex-end', fontSize: 15, padding: '14px 28px' }}>Continue <svg style={{verticalAlign:'middle' }} xmlns="http://www.w3.org/2000/svg" height="18px" viewBox="0 -960 960 960" width="24px" fill="#fff"><path d="M647-440H160v-80h487L423-744l57-56 320 320-320 320-57-56 224-224Z"/></svg></button>
                </div>
              )}

              {s.formStep === 2 && (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 18, animation: 'fadeInUp .35s ease' }}>
                  <p style={stepTitle}>Basic Info</p>
                  <div>
                    <label htmlFor="f-name" style={labelMono}>Full name</label>
                    <input id="f-name" type="text" value={f.name} onChange={(e) => this.updateField('name', e.target.value)} style={inputStyle} />
                    {s.errors.name && err('Please enter your name.')}
                  </div>
                  <div>
                    <label htmlFor="f-email" style={labelMono}>Email</label>
                    <input id="f-email" type="email" value={f.email} onChange={(e) => this.updateField('email', e.target.value)} style={inputStyle} />
                    {s.errors.email && err('Enter a valid email address.')}
                  </div>
                  <div>
                    <label htmlFor="f-phone" style={labelMono}>Phone number</label>
                    <input id="f-phone" type="tel" value={f.phone} onChange={(e) => this.updateField('phone', e.target.value)} style={inputStyle} />
                    {s.errors.phone && err('Please enter your phone number.')}
                  </div>
                  <div>
                    <label htmlFor="f-location" style={labelMono}>City, State/Province</label>
                    <input id="f-location" type="text" placeholder="e.g., Toronto, ON, Canada" value={f.location} onChange={(e) => this.updateField('location', e.target.value)} style={inputStyle} />
                    {s.errors.location && err('Please enter your location.')}
                  </div>
                  <div>
                    <label htmlFor="f-handle" style={labelMono}>Instagram/TikTok handle (optional)</label>
                    <input id="f-handle" type="text" value={f.handle} onChange={(e) => this.updateField('handle', e.target.value)} style={inputStyle} />
                  </div>
                  <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8 }}>
                    {backBtn(() => this.setState({ formStep: 1 }))}
                    {continueBtn(() => { if (this.validateStep2()) this.setState({ formStep: 3 }); })}
                  </div>
                </div>
              )}

              {s.formStep === 3 && (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 18, animation: 'fadeInUp .35s ease' }}>
                  <p style={stepTitle}>The Story</p>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                    <label htmlFor="f-summary" style={{ fontSize: 13, fontFamily: MONO }}>Summarize the story you want to bring to Audit Me in one or two sentences.</label>
                    <textarea id="f-summary" rows="3" maxLength={500} value={f.summary} onChange={(e) => this.updateField('summary', e.target.value)} style={textareaStyle}></textarea>
                    {s.errors.summary && <p role="alert" style={{ color: RED, fontSize: 13, margin: 0 }}>Please summarize your story.</p>}
                  </div>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                    <label htmlFor="f-story" style={{ fontSize: 13, fontFamily: MONO }}>What makes this story worth featuring - what happened, and what was the outcome or turning point?</label>
                    <textarea id="f-story" rows="8" maxLength={500} value={f.story} onChange={(e) => this.updateField('story', e.target.value)} style={textareaStyle}></textarea>
                    {s.errors.story && <p role="alert" style={{ color: RED, fontSize: 13, margin: 0 }}>Tell us a bit about what's going on.</p>}
                    <div>
                      <div style={{ height: 8, borderRadius: 4, background: 'rgba(22,35,63,0.12)', overflow: 'hidden' }}>
                        <div style={{ height: '100%', width: honestyPercent + '%', background: 'var(--accent)', transition: 'width .3s ease' }}></div>
                      </div>
                      <p style={{ fontFamily: MONO, fontSize: 12, margin: '6px 0 0', color: 'rgba(22,35,63,0.65)' }}>Honesty meter: {honestyLabel}</p>
                    </div>
                  </div>
                  <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8 }}>
                    {backBtn(() => this.setState({ formStep: 2 }))}
                    {continueBtn(() => { if (this.validateStep3()) this.setState({ formStep: 4 }); })}
                  </div>
                </div>
              )}

              {s.formStep === 4 && (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 18, animation: 'fadeInUp .35s ease' }}>
                  <p style={stepTitle}>Camera Check</p>
                  <div>
                    <label htmlFor="f-video-input" style={{ fontSize: 14, fontWeight: 600, display: 'block', marginBottom: 8 }}>Upload a 60–90 second video telling your story directly to camera.</label>
                    <p style={{ fontFamily: MONO, fontSize: 12, color: RED, margin: '0 0 6px' }}>Non-negotiable - this shows whether you, not just the story, will work on screen.</p>
                    <p style={{ fontFamily: MONO, fontSize: 12, color: 'rgba(22,35,63,0.6)', margin: '0 0 10px' }}>Max 90 seconds · up to Full HD (1080p) · up to 100 MB · MP4 recommended.</p>
                    <label htmlFor="f-video-input" style={{
                      display: 'flex', alignItems: 'center', justifyContent: 'center', border: '2px dashed ' + INK,
                      borderRadius: 6, padding: 28, cursor: 'pointer', textAlign: 'center', fontFamily: MONO, fontSize: 14,
                      background: 'rgba(22,35,63,0.03)',
                    }}>
                      {s.videoChecking ? 'Checking video…' : (f.videoFileName ? 'Selected: ' + f.videoFileName : 'Click to choose a video file')}
                    </label>
                    <input id="f-video-input" type="file" accept="video/*"
                      onChange={(e) => {
                        const file = e.target.files && e.target.files[0];
                        if (!file) { this._videoFile = null; this.setState((st) => ({ form: { ...st.form, videoFileName: '' }, videoError: '' })); return; }
                        this._videoFile = null;
                        this.setState((st) => ({ form: { ...st.form, videoFileName: '' }, videoChecking: true, videoError: '', errors: { ...st.errors, videoFile: false } }));
                        validateVideoFile(file).then((r) => {
                          if (r.ok) {
                            this._videoFile = file;
                            this.setState((st) => ({ form: { ...st.form, videoFileName: file.name }, videoChecking: false, videoError: '' }));
                          } else {
                            this._videoFile = null;
                            this.setState((st) => ({ form: { ...st.form, videoFileName: '' }, videoChecking: false, videoError: r.error }));
                          }
                        });
                      }}
                      style={{ position: 'absolute', width: 1, height: 1, overflow: 'hidden', opacity: 0 }} />
                    {s.videoError && <p role="alert" style={{ color: RED, fontSize: 13, margin: '8px 0 0' }}>{s.videoError}</p>}
                    {!s.videoError && s.errors.videoFile && <p role="alert" style={{ color: RED, fontSize: 13, margin: '8px 0 0' }}>A video is required to submit.</p>}
                  </div>
                  <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8 }}>
                    {backBtn(() => this.setState({ formStep: 3 }))}
                    {continueBtn(() => { if (this.validateStep4()) this.setState({ formStep: 5 }); })}
                  </div>
                </div>
              )}

              {s.formStep === 5 && (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 18, animation: 'fadeInUp .35s ease' }}>
                  <p style={stepTitle}>Comfort &amp; Consent</p>
                  <div>
                    <label style={{ fontSize: 14, display: 'block', marginBottom: 8, fontWeight: 600 }}>Are you comfortable being teased or roasted, in a friendly way, about this story on camera?</label>
                    <div style={{ display: 'flex', gap: 10 }}>
                      <button type="button" aria-pressed={f.roastYes} onClick={() => this.setBoolField('roastYes', 'roastNo', 'yes')} style={toggleBtn(f.roastYes, INK)}>Yes</button>
                      <button type="button" aria-pressed={f.roastNo} onClick={() => this.setBoolField('roastYes', 'roastNo', 'no')} style={toggleBtn(f.roastNo, INK)}>No</button>
                    </div>
                    {s.errors.roast && err('Please answer this question.')}
                  </div>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                    <label htmlFor="f-offlimits" style={{ fontSize: 14, fontWeight: 600 }}>Is there anything you'd want kept off-limits if you're selected?</label>
                    <textarea id="f-offlimits" rows="4" maxLength={500} value={f.offLimits} onChange={(e) => this.updateField('offLimits', e.target.value)} style={textareaStyle}></textarea>
                  </div>
                  <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8 }}>
                    {backBtn(() => this.setState({ formStep: 4 }))}
                    {continueBtn(() => { if (this.validateStep5()) this.setState({ formStep: 6 }); })}
                  </div>
                </div>
              )}

              {s.formStep === 6 && (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 18, animation: 'fadeInUp .35s ease' }}>
                  <p style={stepTitle}>Close</p>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                    <label htmlFor="f-anything" style={{ fontSize: 13, fontFamily: MONO }}>Anything else you'd like us to know before we review your submission? (optional)</label>
                    <textarea id="f-anything" rows="4" maxLength={500} value={f.anythingElse} onChange={(e) => this.updateField('anythingElse', e.target.value)} style={textareaStyle}></textarea>
                  </div>
                  <label style={{ display: 'flex', alignItems: 'flex-start', gap: 10, fontSize: 14, cursor: 'pointer' }}>
                    <input type="checkbox" checked={f.consent} onChange={(e) => this.updateField('consent', e.target.checked)} style={{ marginTop: 3, width: 18, height: 18, flexShrink: 0 }} />
                    <span>I understand that applying does not guarantee selection, and that if selected, I will be asked to sign a consent/release form and will receive $500 for my appearance.</span>
                  </label>
                  {s.errors.consent && <p role="alert" style={{ color: RED, fontSize: 13, margin: 0 }}>Consent is required to submit.</p>}
                  {s.submitError && <p role="alert" style={{ color: RED, fontSize: 13, margin: 0 }}>{s.submitError}</p>}
                  <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8 }}>
                    {backBtn(() => this.setState({ formStep: 5 }))}
                    <button type="button" disabled={s.submitting} onClick={() => this.submitForm()} style={{ ...btnPrimary, fontSize: 15, padding: '14px 28px', opacity: s.submitting ? 0.7 : 1, cursor: s.submitting ? 'wait' : 'pointer' }}>{s.submitting ? (s.submitStatus || 'Submitting…') : 'Submit Application'}</button>
                  </div>
                </div>
              )}
            </div>
          )}
        </section>

        {/* FOOTER */}
        <footer data-footer-sentinel="" style={{ background: INK, color: CREAM, padding: 'clamp(40px,7vw,72px) clamp(16px,5vw,64px) 32px' }}>
          <div style={{ maxWidth: 1180, margin: '0 auto', display: 'flex', flexWrap: 'wrap', gap: 32, justifyContent: 'space-between' }}>
            <div style={{ maxWidth: 340 }}>
              <img src="assets/logo.png" alt="Audit Me" style={{ height: 32, width: 'auto', display: 'block', marginBottom: 10, filter: 'brightness(0) invert(1)' }} />
              <p style={{ fontSize: 14.5, color: 'rgba(245,241,232,0.7)', lineHeight: 1.5, margin: '0 0 14px' }}>Audit Me - real stories, sharp audits, and honest conversations.</p>
              <span style={{ fontFamily: MONO, fontSize: 12, border: '1px solid rgba(245,241,232,0.4)', borderRadius: 999, padding: '5px 12px', display: 'inline-block' }}>Selected guests receive $500</span>
            </div>
            <nav aria-label="Footer" style={{ display: 'flex', flexDirection: 'column', gap: 8, fontFamily: MONO, fontSize: 14 }}>
              {footerTargets.map(([label, id]) => (
                <a key={id} href="#" className="footer-link" onClick={(e) => { e.preventDefault(); this.scrollTo(id); }} style={{ color: 'rgba(245,241,232,0.8)', textDecoration: 'none' }}>{label}</a>
              ))}
            </nav>
            <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
              <a href={s.social.instagram || '#'} target={s.social.instagram ? '_blank' : undefined} rel="noopener noreferrer" aria-label="Instagram" className="social-link" style={socialStyle}>
                {s.socialIcons.instagram ? <img src={s.socialIcons.instagram} alt="" style={socialImgStyle} /> : (
                  <span style={{ width: 17, height: 17, border: '1.6px solid ' + CREAM, borderRadius: 6, position: 'relative' }}>
                    <span style={{ position: 'absolute', top: '50%', left: '50%', width: 8, height: 8, border: '1.6px solid ' + CREAM, borderRadius: 999, transform: 'translate(-50%,-50%)' }}></span>
                    <span style={{ position: 'absolute', top: 1, right: 1, width: 2.5, height: 2.5, borderRadius: 999, background: CREAM }}></span>
                  </span>
                )}
              </a>
              <a href={s.social.x || '#'} target={s.social.x ? '_blank' : undefined} rel="noopener noreferrer" aria-label="X" className="social-link" style={socialStyle}>
                {s.socialIcons.x ? <img src={s.socialIcons.x} alt="" style={socialImgStyle} /> : (
                  <span style={{ position: 'relative', width: 15, height: 15 }}>
                    <span style={{ position: 'absolute', top: '50%', left: '50%', width: 17, height: 1.8, background: CREAM, transform: 'translate(-50%,-50%) rotate(45deg)' }}></span>
                    <span style={{ position: 'absolute', top: '50%', left: '50%', width: 17, height: 1.8, background: CREAM, transform: 'translate(-50%,-50%) rotate(-45deg)' }}></span>
                  </span>
                )}
              </a>
              <a href={s.social.youtube || '#'} target={s.social.youtube ? '_blank' : undefined} rel="noopener noreferrer" aria-label="YouTube" className="social-link" style={socialStyle}>
                {s.socialIcons.youtube ? <img src={s.socialIcons.youtube} alt="" style={socialImgStyle} /> : (
                  <span style={{ width: 20, height: 14, border: '1.6px solid ' + CREAM, borderRadius: 4, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    <span style={{ width: 0, height: 0, borderTop: '4px solid transparent', borderBottom: '4px solid transparent', borderLeft: '6px solid ' + CREAM, marginLeft: 2 }}></span>
                  </span>
                )}
              </a>
              <a href={s.social.tiktok || '#'} target={s.social.tiktok ? '_blank' : undefined} rel="noopener noreferrer" aria-label="TikTok" className="social-link" style={socialStyle}>
                {s.socialIcons.tiktok ? <img src={s.socialIcons.tiktok} alt="" style={socialImgStyle} /> : (
                  <svg width="16" height="16" viewBox="0 0 24 24" fill={CREAM} aria-hidden="true">
                    <path d="M16.5 3c.3 2.1 1.6 3.6 3.7 3.9v2.5c-1.2.1-2.4-.2-3.6-.9v5.9c0 3.4-2.6 5.9-5.8 5.6a5.4 5.4 0 0 1-4.9-5.3c0-3.2 2.9-5.7 6.1-5.2v2.7c-.5-.2-1-.2-1.5-.1-1.2.3-2 1.4-1.9 2.7a2.4 2.4 0 0 0 4.8-.2V3h3.1z"/>
                  </svg>
                )}
              </a>
            </div>
          </div>
        </footer>

        {/* STICKY APPLY BAR */}
        <div role="region" aria-label="Apply reminder" style={{
          position: 'fixed', left: 0, right: 0, bottom: 0, zIndex: 50,
          transform: barVisible ? 'translateY(0)' : 'translateY(140%)', transition: 'transform .35s ease',
          background: INK, color: CREAM, borderTop: '3px solid ' + RED, padding: '14px clamp(16px,4vw,32px)',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16, flexWrap: 'wrap',
        }}>
          <span style={{ fontFamily: MONO, fontSize: 14 }}>Selected guests receive $500 → Apply for Audit Me</span>
          <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
            <button type="button" onClick={scrollToForm} style={{ ...btnPrimary, fontSize: 14, padding: '10px 20px' }}>Apply Now</button>
            <button type="button" aria-label="Dismiss" onClick={() => this.setState({ barDismissed: true })} style={{ background: 'transparent', border: 'none', color: CREAM, fontSize: 20, cursor: 'pointer', lineHeight: 1 }}>×</button>
          </div>
        </div>
      </div>
    );
  }
}

const socialStyle = {
  width: 40, height: 40, borderRadius: 999, border: '1px solid rgba(245,241,232,0.4)',
  display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative',
};
const socialImgStyle = { width: 20, height: 20, objectFit: 'contain', display: 'block' };

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