/* Orinova Portal — pages11.jsx
   Mobile, the client side. 390 × 844, paper grammar, big serif
   headlines, big tap targets, one job per screen. Steve Jobs:
   say no to a hundred things.

     · MobileServicesIndex
     · MobileServiceDetail   (interior paint)
     · MobileColorStudio
     · MobileSchedule
     · MobileJobDetail
     · MobilePayBalance
     · MobileGallery
*/

/* ── Shared mobile chrome ──────────────────────────────────
   Status bar (clock + notch + signals), sticky top, sticky
   bottom tab bar. Same shape across every screen so the
   "phone" feels like a single app.
*/

function MStatusBar({ clock = '9:41' }) {
  return (
    <div className="m-statusbar">
      <div className="m-statusbar-clock">{clock}</div>
      <div className="m-statusbar-notch" />
      <div className="m-statusbar-icons">
        <span style={{ marginRight: 4 }}>5G</span>
        <span style={{ marginRight: 4 }}>●●●●</span>
        <span>100</span>
      </div>
    </div>
  );
}

function MTopBar({ back = '‹', title, action }) {
  return (
    <div className="m-topbar">
      <button className="m-back" aria-label="back">{back}</button>
      <div className="m-title">{title}</div>
      <div className="m-action">{action || ' '}</div>
    </div>
  );
}

function MTabBar({ active = 'job' }) {
  const tabs = [
    { id: 'job',  l: { es: 'OBRA',  en: 'JOB' } },
    { id: 'docs', l: { es: 'DOCS',  en: 'DOCS' } },
    { id: 'pay',  l: { es: 'PAGOS', en: 'PAY' } },
    { id: 'help', l: { es: 'AYUDA', en: 'HELP' } },
  ];
  const t = window.t;
  const { lang } = window.useLang();
  return (
    <div className="m-tabbar">
      {tabs.map((tab) => (
        <div key={tab.id} className={'m-tab ' + (active === tab.id ? 'is-active' : '')}>
          <div className="m-tab-dot" />
          {t(tab.l, lang)}
        </div>
      ))}
    </div>
  );
}

/* ── MOBILE · SERVICES INDEX ──────────────────────────────
   The catalog. Big serif headline, vertical card stack,
   no horizontal scroll tricks, no carousel.
*/

function MobileServicesIndex() {
  const t = window.t;
  const { lang } = window.useLang();
  const services = [
    { code: '01', name: { es: 'Pintura interior', en: 'Interior paint' }, range: '$480 – $6,200', dur: { es: '1–5 días', en: '1–5 days' } },
    { code: '02', name: { es: 'Pintura exterior', en: 'Exterior paint' }, range: '$3,200 – $14,500', dur: { es: '3–7 días', en: '3–7 days' } },
    { code: '03', name: { es: 'Drywall · reparación', en: 'Drywall · repair' }, range: '$180 – $1,800', dur: { es: '1–3 días', en: '1–3 days' } },
    { code: '04', name: { es: 'Gabinetes', en: 'Cabinets' }, range: '$1,200 – $4,800', dur: { es: '3–6 días', en: '3–6 days' } },
    { code: '05', name: { es: 'Acceso por cuerda · SPRAT', en: 'Rope access · SPRAT' }, range: { es: 'cotización', en: 'quote' }, dur: { es: '1–4 días', en: '1–4 days' } },
    { code: '06', name: { es: 'Estudio de color', en: 'Color studio' }, range: { es: 'sin costo', en: 'no charge' }, dur: { es: '30 min', en: '30 min' } },
  ];
  return (
    <div className="page m-page">
      <div className="page-scroll hide-scroll" style={{ paddingBottom: 80 }}>
        <MStatusBar />
        <MTopBar title="DreamValley" action={t({ es: 'BUSCAR', en: 'SEARCH' }, lang)} />
        <section style={{ padding: '22px 22px 4px' }}>
          <div className="codex" style={{ color: 'var(--ink-muted)' }}>
            {t({ es: 'SEIS OFICIOS · UNA CASA', en: 'SIX TRADES · ONE HOUSE' }, lang)}
          </div>
          <h1 className="display" style={{ fontSize: 36, lineHeight: 1.02, margin: '8px 0 14px', letterSpacing: '-0.02em' }}>
            {t({ es: 'Pídelo. Lo escribimos primero.', en: 'Ask. We write it first.' }, lang)}
          </h1>
        </section>

        <section style={{ padding: '0 22px' }}>
          {services.map((s) => (
            <div key={s.code} style={{
              padding: '18px 0',
              borderBottom: '1px solid var(--divider)',
              display: 'grid', gridTemplateColumns: '40px 1fr auto', gap: 12, alignItems: 'baseline',
            }}>
              <div className="codex tab" style={{ color: 'var(--terracotta)' }}>{s.code}</div>
              <div>
                <div style={{ fontFamily: 'var(--serif)', fontSize: 19, fontWeight: 500, lineHeight: 1.15 }}>{t(s.name, lang)}</div>
                <div className="codex" style={{ marginTop: 4, color: 'var(--ink-muted)' }}>
                  {typeof s.range === 'string' ? s.range : t(s.range, lang)} · {t(s.dur, lang)}
                </div>
              </div>
              <div className="codex" style={{ color: 'var(--ink-soft)' }}>›</div>
            </div>
          ))}
        </section>

        <section style={{ padding: '24px 22px 0' }}>
          <div className="m-card-dark">
            <div className="codex" style={{ opacity: 0.7 }}>{t({ es: 'NO ENCUENTRAS TU OFICIO', en: 'NOT SEEING YOUR TRADE' }, lang)}</div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 20, lineHeight: 1.25, marginTop: 8 }}>
              {t({
                es: 'Llámanos. Si no lo hacemos, te decimos quién sí.',
                en: 'Call us. If we don\u2019t, we name who does.'
              }, lang)}
            </div>
            <a className="btn btn-call" style={{ width: '100%', marginTop: 14, padding: '14px', fontSize: 15 }}>(951) 555-0148</a>
          </div>
        </section>

        <div style={{ height: 32 }} />
        <MTabBar active="docs" />
      </div>
    </div>
  );
}

/* ── MOBILE · SERVICE DETAIL ──────────────────────────────
   The drill-in. Stacked photo, 3 inclusions, price band,
   call/quote sticky CTA.
*/

function MobileServiceDetail() {
  const t = window.t;
  const { lang } = window.useLang();
  const { Slot } = window.OrinovaAtoms;
  return (
    <div className="page m-page">
      <div className="page-scroll hide-scroll" style={{ paddingBottom: 160 }}>
        <MStatusBar />
        <MTopBar title={t({ es: 'Pintura interior', en: 'Interior paint' }, lang)} action="01·06" />

        {/* hero */}
        <div style={{ padding: '14px 22px 0' }}>
          <Slot label="HERO" sub="finished room" slotId="m-service-hero" style={{ aspectRatio: '4 / 3', borderRadius: 14 }} />
        </div>

        <section style={{ padding: '20px 22px 0' }}>
          <div className="codex" style={{ color: 'var(--terracotta)' }}>SERVICE · 01 · DV·PAINT·INT</div>
          <h1 className="display" style={{ fontSize: 36, lineHeight: 1.02, margin: '8px 0 10px', letterSpacing: '-0.02em' }}>
            {t({ es: 'Casa entera o cuartos sueltos.', en: 'Whole-home or single rooms.' }, lang)}
          </h1>
          <p style={{ fontFamily: 'var(--serif)', fontSize: 15.5, lineHeight: 1.5, color: 'var(--ink-soft)', margin: 0 }}>
            {t({
              es: 'Preparación honesta. Dos manos. Limpieza al terminar. Tu inquilino puede quedarse en casa.',
              en: 'Honest prep. Two coats. Clean-up at the end. Your tenant can stay home.'
            }, lang)}
          </p>
        </section>

        {/* inclusions */}
        <section style={{ padding: '20px 22px 0' }}>
          <div className="codex" style={{ color: 'var(--ink-muted)' }}>{t({ es: 'QUÉ INCLUYE', en: 'WHAT\u2019S INCLUDED' }, lang)}</div>
          <div style={{ marginTop: 8 }}>
            {[
              { code: '01', t: { es: 'Preparación',  en: 'Prep' },      d: { es: 'plástico · enmascarado · parchado · primer', en: 'plastic · masking · patching · primer' } },
              { code: '02', t: { es: 'Dos manos',    en: 'Two coats' }, d: { es: 'marca y línea nombradas', en: 'brand and line named' } },
              { code: '03', t: { es: 'Limpieza',     en: 'Clean-up' },  d: { es: 'muebles regresan donde estaban', en: 'furniture goes back where it was' } },
            ].map((b, i) => (
              <div key={i} style={{ display: 'grid', gridTemplateColumns: '36px 1fr', gap: 10, padding: '12px 0', borderBottom: '1px solid var(--divider)' }}>
                <div className="codex" style={{ color: 'var(--terracotta)' }}>{b.code}</div>
                <div>
                  <div style={{ fontFamily: 'var(--serif)', fontSize: 16, fontWeight: 500 }}>{t(b.t, lang)}</div>
                  <div className="codex" style={{ marginTop: 2, color: 'var(--ink-muted)' }}>{t(b.d, lang)}</div>
                </div>
              </div>
            ))}
          </div>
        </section>

        {/* price band */}
        <section style={{ padding: '20px 22px 0' }}>
          <div className="m-card">
            <div className="codex" style={{ color: 'var(--ink-muted)' }}>{t({ es: 'RANGO TÍPICO · CUARTO COMPLETO', en: 'TYPICAL RANGE · WHOLE ROOM' }, lang)}</div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 32, marginTop: 6 }}>$480 – $780</div>
            <div className="codex" style={{ marginTop: 4, color: 'var(--ink-muted)' }}>{t({ es: 'TU ESTIMADO REAL EN 48H', en: 'YOUR REAL ESTIMATE IN 48H' }, lang)}</div>
          </div>
        </section>

        <div style={{ height: 40 }} />

        {/* sticky CTA */}
        <div className="m-cta">
          <a className="btn btn-call">
            {t({ es: 'Pedir estimado · gratis', en: 'Request estimate · free' }, lang)}
          </a>
        </div>
        <MTabBar active="docs" />
      </div>
    </div>
  );
}

/* ── MOBILE · COLOR STUDIO ───────────────────────────────
   Pick three. Live chip selector. Big confirm CTA.
*/

const M_CHIPS = [
  { name: 'Bone',         code: 'DE6213', hex: '#EFE6D2' },
  { name: 'Linen',        code: 'DE6196', hex: '#E4D6B7' },
  { name: 'Sand Trail',   code: 'DE6135', hex: '#D7BF95' },
  { name: 'Adobe',        code: 'DE6111', hex: '#B5895C' },
  { name: 'Riverbed',     code: 'DE6371', hex: '#8A7A66' },
  { name: 'Cinder',       code: 'DE6385', hex: '#5C544A' },
  { name: 'Slate',        code: 'DE6310', hex: '#3F4348' },
  { name: 'Olive',        code: 'DE5572', hex: '#5C6240' },
  { name: 'Sage',         code: 'DE5605', hex: '#A6AC8A' },
];

function MobileColorStudio() {
  const t = window.t;
  const { lang } = window.useLang();
  const [picked, setPicked] = React.useState(['Bone', 'Riverbed', 'Olive']);
  const toggle = (n) => setPicked(p =>
    p.includes(n) ? p.filter(x => x !== n) : (p.length >= 3 ? [p[1], p[2], n] : [...p, n])
  );

  return (
    <div className="page m-page">
      <div className="page-scroll hide-scroll" style={{ paddingBottom: 160 }}>
        <MStatusBar />
        <MTopBar title={t({ es: 'Estudio de color', en: 'Color studio' }, lang)} action={picked.length + '/3'} />

        <section style={{ padding: '22px 22px 0' }}>
          <div className="codex" style={{ color: 'var(--terracotta)' }}>STUDIO · 01 · DV·COLOR</div>
          <h1 className="display" style={{ fontSize: 32, lineHeight: 1.02, margin: '8px 0 10px', letterSpacing: '-0.02em' }}>
            {t({
              es: 'Toca tres. Te las pintamos en tu sala.',
              en: 'Tap three. We paint them in your living room.'
            }, lang)}
          </h1>
          <p style={{ fontFamily: 'var(--serif)', fontSize: 14.5, lineHeight: 1.5, color: 'var(--ink-soft)', margin: 0 }}>
            {t({
              es: 'Dunn-Edwards exclusivo. 2×2 ft de cada color, en placa, 48 horas, sin costo si firmas.',
              en: 'Dunn-Edwards exclusive. 2×2 ft of each on board, 48 hours, free if you book.'
            }, lang)}
          </p>
        </section>

        {/* chips */}
        <section style={{ padding: '20px 22px 0' }}>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
            {M_CHIPS.map((c) => {
              const on = picked.includes(c.name);
              return (
                <button key={c.code} onClick={() => toggle(c.name)} style={{
                  background: 'transparent', border: 0, padding: 0, cursor: 'pointer', textAlign: 'left',
                }}>
                  <div style={{
                    position: 'relative',
                    aspectRatio: '1 / 1',
                    background: c.hex,
                    borderRadius: 10,
                    border: on ? '2px solid var(--ink)' : '1px solid var(--divider)',
                    boxShadow: on ? '0 0 0 4px var(--paper)' : 'none',
                  }}>
                    {on && (
                      <span style={{
                        position: 'absolute', top: 6, right: 6,
                        background: 'var(--ink)', color: 'var(--paper)',
                        fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.14em',
                        padding: '2px 6px',
                      }}>{picked.indexOf(c.name) + 1}</span>
                    )}
                  </div>
                  <div style={{ marginTop: 6, fontFamily: 'var(--serif)', fontSize: 13.5, fontWeight: 500 }}>{c.name}</div>
                  <div className="codex" style={{ color: 'var(--ink-muted)' }}>{c.code}</div>
                </button>
              );
            })}
          </div>
        </section>

        {/* picked summary */}
        <section style={{ padding: '20px 22px 0' }}>
          <div className="codex" style={{ color: 'var(--ink-muted)' }}>{t({ es: 'TU SELECCIÓN', en: 'YOUR SELECTION' }, lang)}</div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10, marginTop: 8 }}>
            {[0, 1, 2].map(i => {
              const c = picked[i] && M_CHIPS.find(x => x.name === picked[i]);
              return (
                <div key={i} style={{ background: c ? c.hex : 'var(--paper-cream)', height: 60, borderRadius: 10, border: '1px solid var(--divider)' }} />
              );
            })}
          </div>
        </section>

        <div style={{ height: 30 }} />

        <div className="m-cta">
          <a className="btn btn-call" style={{ opacity: picked.length === 3 ? 1 : 0.7 }}>
            {t({ es: 'Agendar visita · gratis', en: 'Schedule visit · free' }, lang)}
          </a>
        </div>
        <MTabBar active="docs" />
      </div>
    </div>
  );
}

/* ── MOBILE · SCHEDULE ────────────────────────────────────
   Native-feeling date picker. Horizontal-scroll dates, two
   window pills, summary, confirm.
*/

function MobileSchedule() {
  const t = window.t;
  const { lang } = window.useLang();
  const ref = React.useMemo(() => {
    try {
      const q = new URLSearchParams(window.location.search);
      return q.get('ref') || '';
    } catch (e) {
      return '';
    }
  }, []);
  const base = React.useMemo(() => {
    const d = new Date();
    d.setHours(0, 0, 0, 0);
    d.setDate(d.getDate() + 1);
    return d;
  }, []);
  const days = React.useMemo(() => {
    const list = [];
    for (let i = 0; i < 10; i++) {
      const d = new Date(base);
      d.setDate(base.getDate() + i);
      const weekday = d.getDay();
      list.push({
        d: d.getDate(),
        iso: d.toISOString().slice(0, 10),
        label: {
          es: d.toLocaleDateString('es-MX', { weekday: 'short' }).slice(0, 3).toUpperCase(),
          en: d.toLocaleDateString('en-US', { weekday: 'short' }).toUpperCase(),
        },
        avail: weekday === 0 ? 'OFF' : (weekday === 6 ? 'AM' : (i % 5 === 2 ? 'AM' : 'AM·PM')),
      });
    }
    return list;
  }, [base]);
  const [pickD, setPickD] = React.useState(days[0] ? days[0].iso : '');
  const [pickW, setPickW] = React.useState('AM');
  const selected = React.useMemo(() => days.find((d) => d.iso === pickD), [days, pickD]);
  const headerMonth = React.useMemo(
    () => base.toLocaleDateString(lang === 'es' ? 'es-MX' : 'en-US', { month: 'short', year: 'numeric' }).toUpperCase(),
    [base, lang]
  );

  return (
    <div className="page m-page">
      <div className="page-scroll hide-scroll" style={{ paddingBottom: 160 }}>
        <MStatusBar />
        <MTopBar title={t({ es: 'Agendar visita', en: 'Schedule visit' }, lang)} action={headerMonth} />

        <section style={{ padding: '22px 22px 0' }}>
          <div className="codex" style={{ color: 'var(--terracotta)' }}>VISIT · 30–45 MIN · {t({ es: 'GRATIS', en: 'FREE' }, lang)}</div>
          <h1 className="display" style={{ fontSize: 30, lineHeight: 1.05, margin: '8px 0 10px', letterSpacing: '-0.02em' }}>
            {t({
              es: 'Tú escoges el día. Te damos la hora.',
              en: 'You pick the day. We name the hour.'
            }, lang)}
          </h1>
        </section>

        {/* horizontal day strip */}
        <section style={{ padding: '14px 0 0' }}>
          <div className="hide-scroll" style={{ display: 'flex', gap: 8, overflowX: 'auto', padding: '0 22px 6px' }}>
            {days.map((day) => {
              const open = day.avail !== 'OFF' && day.avail !== 'FULL';
              const on = pickD === day.iso && open;
              return (
                <button key={day.iso} type="button" disabled={!open} onClick={() => setPickD(day.iso)} style={{
                  flex: '0 0 auto',
                  width: 66, padding: '10px 0',
                  border: '1px solid ' + (on ? 'var(--ink)' : 'var(--divider-strong)'),
                  background: on ? 'var(--ink)' : 'var(--paper-form)',
                  color: on ? 'var(--paper)' : (open ? 'var(--ink)' : 'var(--ink-muted)'),
                  borderRadius: 14,
                  textAlign: 'center',
                  cursor: open ? 'pointer' : 'not-allowed',
                  opacity: open ? 1 : 0.5,
                  fontFamily: 'var(--mono)',
                }}>
                  <div style={{ fontSize: 9, letterSpacing: '0.16em', opacity: 0.8 }}>{t(day.label, lang)}</div>
                  <div style={{ fontFamily: 'var(--serif)', fontSize: 24, fontWeight: 500, lineHeight: 1, margin: '4px 0' }}>{day.d}</div>
                  <div style={{ fontSize: 8.5, letterSpacing: '0.14em' }}>{day.avail === 'OFF' ? (lang === 'es' ? 'CERR.' : 'CLOSED') : day.avail === 'FULL' ? (lang === 'es' ? 'LLENO' : 'FULL') : day.avail}</div>
                </button>
              );
            })}
          </div>
        </section>

        {/* time windows */}
        <section style={{ padding: '22px 22px 0' }}>
          <div className="codex" style={{ color: 'var(--ink-muted)' }}>{t({ es: 'VENTANA', en: 'TIME WINDOW' }, lang)}</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginTop: 8 }}>
            {[
              { id: 'AM', name: { es: 'Mañana', en: 'Morning' }, range: '8 – 11 AM', available: selected && selected.avail !== 'OFF' },
              { id: 'PM', name: { es: 'Tarde',  en: 'Afternoon' }, range: '1 – 4 PM', available: selected && selected.avail === 'AM·PM' },
            ].map((w) => {
              const on = pickW === w.id && w.available;
              return (
                <button key={w.id} type="button" disabled={!w.available} onClick={() => setPickW(w.id)} style={{
                  textAlign: 'left',
                  border: '1px solid ' + (on ? 'var(--ink)' : 'var(--divider-strong)'),
                  background: on ? 'var(--ink)' : 'var(--paper-form)',
                  color: on ? 'var(--paper)' : (w.available ? 'var(--ink)' : 'var(--ink-muted)'),
                  padding: '14px 16px', borderRadius: 12, cursor: w.available ? 'pointer' : 'not-allowed', opacity: w.available ? 1 : 0.45,
                }}>
                  <div style={{ fontFamily: 'var(--serif)', fontSize: 18 }}>{t(w.name, lang)}</div>
                  <div className="codex tab" style={{ marginTop: 4, opacity: 0.7 }}>{w.range}</div>
                </button>
              );
            })}
          </div>
        </section>

        {/* summary */}
        <section style={{ padding: '20px 22px 0' }}>
          <div className="m-card">
            <div className="codex" style={{ color: 'var(--ink-muted)' }}>{t({ es: 'TU VISITA', en: 'YOUR VISIT' }, lang)}</div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 22, marginTop: 6, lineHeight: 1.1 }}>
              {selected ? selected.iso : ''}
              <span style={{ color: 'var(--ink-muted)' }}> · {pickW === 'AM' ? '8 – 11 AM' : '1 – 4 PM'}</span>
            </div>
            <div className="codex" style={{ marginTop: 8 }}>ERICK R. · {t({ es: 'FUNDADOR', en: 'FOUNDER' }, lang)}</div>
          </div>
        </section>

        <div style={{ height: 32 }} />

        <form className="m-cta" data-dvt-form="schedule">
          <input type="hidden" name="ref" value={ref} />
          <input type="hidden" name="date" value={pickD} />
          <input type="hidden" name="window" value={pickW === 'AM' ? 'morning' : 'afternoon'} />
          <button type="submit" className="btn btn-primary" style={{ width: '100%' }}>
            {t({ es: 'Confirmar visita →', en: 'Confirm visit →' }, lang)}
          </button>
        </form>
        <MTabBar active="docs" />
      </div>
    </div>
  );
}

/* ── MOBILE · JOB DETAIL ──────────────────────────────────
   The live page during a job. Big code header, dark progress
   card, foreman call, timeline, change-order alert.
*/

function MobileJobDetailM() {
  const t = window.t;
  const { lang } = window.useLang();
  return (
    <div className="page m-page">
      <div className="page-scroll hide-scroll" style={{ paddingBottom: 80 }}>
        <MStatusBar />
        <MTopBar title="DV-0431" action={t({ es: 'COMPARTIR', en: 'SHARE' }, lang)} />

        <section style={{ padding: '18px 18px 0' }}>
          <div className="codex" style={{ color: 'var(--terracotta)' }}>{t({ es: 'EN PROGRESO · DÍA 2 DE 4', en: 'IN PROGRESS · DAY 2 OF 4' }, lang)}</div>
          <h1 className="display" style={{ fontSize: 30, lineHeight: 1.05, margin: '6px 0 4px', letterSpacing: '-0.02em' }}>1428 Magnolia</h1>
          <div className="codex">{t({ es: 'RIVERSIDE · PINTURA INTERIOR', en: 'RIVERSIDE · INTERIOR PAINT' }, lang)}</div>
        </section>

        {/* dark progress card */}
        <section style={{ padding: '14px 18px 0' }}>
          <div className="m-card-dark">
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 4 }}>
              {[
                { l: 'EST',   on: true },
                { l: 'FIRM',  on: true },
                { l: 'PROG',  on: true, now: true },
                { l: 'FIN',   on: false },
              ].map((s, i) => (
                <div key={i} style={{ textAlign: 'center' }}>
                  <div className="codex" style={{ color: s.on ? 'var(--paper-cream)' : 'rgba(245,240,232,0.4)', letterSpacing: '0.14em' }}>{s.l}</div>
                  <div style={{ fontFamily: 'var(--serif)', fontSize: 22, marginTop: 4, color: s.now ? 'var(--terracotta)' : (s.on ? 'var(--paper)' : 'rgba(245,240,232,0.35)') }}>{s.on ? (s.now ? '·' : '✓') : '·'}</div>
                </div>
              ))}
            </div>
            <div style={{ height: 1, background: 'rgba(245,240,232,0.18)', margin: '14px 0' }} />
            <div style={{ display: 'grid', gridTemplateColumns: '1fr auto', alignItems: 'baseline', gap: 12 }}>
              <div>
                <div className="codex" style={{ opacity: 0.7 }}>{t({ es: 'FOREMAN', en: 'FOREMAN' }, lang)}</div>
                <div style={{ fontFamily: 'var(--serif)', fontSize: 19, marginTop: 4 }}>Luis Ortega</div>
              </div>
              <a className="btn btn-call" style={{ padding: '8px 14px' }}>{t({ es: 'Llamar', en: 'Call' }, lang)}</a>
            </div>
          </div>
        </section>

        {/* numbers row */}
        <section style={{ padding: '18px 18px 0' }}>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
            {[
              { k: { es: 'TOTAL', en: 'TOTAL' }, v: '$4,820' },
              { k: { es: 'PAGADO', en: 'PAID' }, v: '$2,000' },
              { k: { es: 'SALDO', en: 'BALANCE' }, v: '$2,820', accent: true },
            ].map((m, i) => (
              <div key={i} className="m-card" style={{ padding: 14 }}>
                <div className="codex" style={{ color: 'var(--ink-muted)' }}>{t(m.k, lang)}</div>
                <div className="tab" style={{ fontFamily: 'var(--serif)', fontSize: 22, fontWeight: 500, marginTop: 4, color: m.accent ? 'var(--terracotta)' : 'var(--ink)' }}>{m.v}</div>
              </div>
            ))}
          </div>
        </section>

        {/* timeline */}
        <section style={{ padding: '22px 18px 0' }}>
          <div className="codex" style={{ color: 'var(--ink-muted)' }}>{t({ es: 'HOY · EN OBRA', en: 'TODAY · ON SITE' }, lang)}</div>
          <ul style={{ margin: '8px 0 0', padding: 0, listStyle: 'none' }}>
            {[
              { time: '7:30', body: { es: 'Luis llegó. Plástico tirado en sala y comedor.', en: 'Luis arrived. Plastic laid in living + dining.' }, now: false },
              { time: '9:48', body: { es: 'Primer aplicado en pared norte y este.', en: 'Primer applied to north and east walls.' }, now: false },
              { time: '11:15', body: { es: 'Foto del día subida — toca para ver.', en: 'Daily photo uploaded — tap to view.' }, now: true },
              { time: '13:00', body: { es: 'Pausa para almuerzo · regresan 1:30.', en: 'Lunch break · back at 1:30.' }, now: false },
            ].map((e, i) => (
              <li key={i} style={{ padding: '12px 0', borderBottom: '1px solid var(--divider)', display: 'grid', gridTemplateColumns: '52px 1fr', gap: 10 }}>
                <span className="codex tab" style={{ color: e.now ? 'var(--terracotta)' : 'var(--ink-muted)' }}>{e.time}</span>
                <span style={{ fontFamily: 'var(--serif)', fontSize: 14.5, lineHeight: 1.45, color: e.now ? 'var(--ink)' : 'var(--ink-soft)' }}>{t(e.body, lang)}</span>
              </li>
            ))}
          </ul>
        </section>

        <div style={{ height: 30 }} />
        <MTabBar active="job" />
      </div>
    </div>
  );
}

/* ── MOBILE · PAY BALANCE ────────────────────────────────
   The pay screen. One amount, three method tiles, one button.
*/

function MobilePayBalance() {
  const t = window.t;
  const { lang } = window.useLang();
  const [method, setMethod] = React.useState('ach');
  return (
    <div className="page m-page">
      <div className="page-scroll hide-scroll" style={{ paddingBottom: 160 }}>
        <MStatusBar />
        <MTopBar title={t({ es: 'Pagar saldo', en: 'Pay balance' }, lang)} action="DV-0431" />

        <section style={{ padding: '32px 22px 0', textAlign: 'center' }}>
          <div className="codex" style={{ color: 'var(--ink-muted)' }}>{t({ es: 'SALDO POR PAGAR', en: 'BALANCE DUE' }, lang)}</div>
          <div className="display tab" style={{ fontSize: 84, lineHeight: 1, margin: '6px 0 0', letterSpacing: '-0.04em' }}>
            $2,820
          </div>
          <div className="codex" style={{ marginTop: 8, color: 'var(--ink-muted)' }}>{t({ es: 'VENCE · 28 MAR · AL CIERRE', en: 'DUE · MAR 28 · AT CLOSE' }, lang)}</div>
        </section>

        <section style={{ padding: '32px 22px 0' }}>
          <div className="codex" style={{ color: 'var(--ink-muted)' }}>{t({ es: 'CÓMO QUIERES PAGAR', en: 'HOW WILL YOU PAY' }, lang)}</div>
          <div style={{ marginTop: 8 }}>
            {[
              { id: 'ach',   name: { es: 'ACH · cuenta de banco', en: 'ACH · bank account' }, note: { es: 'sin cargo', en: 'no fee' }, sub: '•••• 4422' },
              { id: 'card',  name: { es: 'Tarjeta · Visa', en: 'Card · Visa' },              note: { es: '+2.9%', en: '+2.9%' },     sub: '•••• 8810' },
              { id: 'check', name: { es: 'Cheque · al foreman', en: 'Check · to foreman' },   note: { es: 'sin cargo', en: 'no fee' }, sub: t({ es: 'al cierre', en: 'on close' }, lang) },
            ].map((m) => {
              const on = method === m.id;
              return (
                <button key={m.id} onClick={() => setMethod(m.id)} style={{
                  width: '100%', textAlign: 'left',
                  background: on ? 'var(--ink)' : 'var(--paper-form)',
                  color: on ? 'var(--paper)' : 'var(--ink)',
                  border: '1px solid ' + (on ? 'var(--ink)' : 'var(--divider-strong)'),
                  borderRadius: 12, padding: '14px 16px',
                  marginBottom: 8,
                  display: 'grid', gridTemplateColumns: '1fr auto', alignItems: 'center', gap: 12,
                  cursor: 'pointer',
                }}>
                  <div>
                    <div style={{ fontFamily: 'var(--serif)', fontSize: 17 }}>{t(m.name, lang)}</div>
                    <div className="codex" style={{ marginTop: 4, opacity: 0.7 }}>{m.sub}</div>
                  </div>
                  <div className="codex" style={{ opacity: on ? 0.8 : 0.7 }}>{t(m.note, lang)}</div>
                </button>
              );
            })}
          </div>
          <p style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 13.5, lineHeight: 1.5, color: 'var(--ink-muted)', marginTop: 12 }}>
            {t({
              es: 'No pagas hasta que firmes la caminata final. Si algo no quedó, no se cobra hasta arreglarlo.',
              en: 'Nothing is charged until you sign the walk-through. If anything\u2019s off, no charge until it\u2019s fixed.'
            }, lang)}
          </p>
        </section>

        <div className="m-cta">
          <a className="btn btn-primary">{t({ es: 'Pagar $2,820 →', en: 'Pay $2,820 →' }, lang)}</a>
        </div>
        <MTabBar active="pay" />
      </div>
    </div>
  );
}

/* ── MOBILE · GALLERY ────────────────────────────────────
   Vertical scrolling before/after pairs. Big, swipe-y.
*/

function MobileGallery() {
  const t = window.t;
  const { lang } = window.useLang();
  const { Slot } = window.OrinovaAtoms;
  const jobs = [
    { id: 'rpv-01', room: { es: 'Sala · Rancho Palos Verdes', en: 'Living · Rancho Palos Verdes' }, paint: 'DE6196 Linen', days: 3 },
    { id: 'rvs-02', room: { es: 'Cocina · Riverside',          en: 'Kitchen · Riverside' },        paint: 'DE6371 Riverbed', days: 4 },
    { id: 'cor-03', room: { es: 'Exterior · Corona',           en: 'Exterior · Corona' },          paint: 'DE6111 Adobe',    days: 6 },
  ];
  return (
    <div className="page m-page">
      <div className="page-scroll hide-scroll" style={{ paddingBottom: 80 }}>
        <MStatusBar />
        <MTopBar title={t({ es: 'Antes y después', en: 'Before & after' }, lang)} action={jobs.length + ' ' + t({ es: 'OBRAS', en: 'JOBS' }, lang)} />

        <section style={{ padding: '14px 22px 0' }}>
          <div className="codex" style={{ color: 'var(--terracotta)' }}>{t({ es: 'CASAS REALES · SIN PHOTOSHOP', en: 'REAL HOMES · NO PHOTOSHOP' }, lang)}</div>
          <h1 className="display" style={{ fontSize: 30, lineHeight: 1.05, margin: '8px 0 0', letterSpacing: '-0.02em' }}>
            {t({ es: 'Mismo encuadre. Misma luz.', en: 'Same frame. Same light.' }, lang)}
          </h1>
        </section>

        {jobs.map((j, i) => (
          <section key={j.id} style={{ padding: '20px 22px 0' }}>
            <div className="codex" style={{ color: 'var(--ink-muted)' }}>{String(i+1).padStart(2,'0')} · {t(j.room, lang).toUpperCase()}</div>
            <div style={{ marginTop: 8, position: 'relative' }}>
              <Slot label="BEFORE" sub={t({ es: 'antes', en: 'before' }, lang)} slotId={'m-ba-' + j.id + '-before'} style={{ aspectRatio: '4 / 5', borderRadius: 14 }} />
              <div style={{ position: 'absolute', top: 12, left: 12, background: 'var(--paper)', color: 'var(--ink)', padding: '2px 10px', fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase' }}>
                {t({ es: 'ANTES', en: 'BEFORE' }, lang)}
              </div>
            </div>
            <div style={{ marginTop: 10, position: 'relative' }}>
              <Slot label="AFTER" sub={t({ es: 'después', en: 'after' }, lang)} slotId={'m-ba-' + j.id + '-after'} style={{ aspectRatio: '4 / 5', borderRadius: 14 }} />
              <div style={{ position: 'absolute', top: 12, left: 12, background: 'var(--terracotta)', color: 'var(--paper)', padding: '2px 10px', fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase' }}>
                {t({ es: 'DESPUÉS', en: 'AFTER' }, lang)} · {j.paint}
              </div>
            </div>
            <div className="codex" style={{ marginTop: 10, color: 'var(--ink-muted)' }}>{j.days} {t({ es: 'DÍAS', en: 'DAYS' }, lang)} · {j.paint}</div>
          </section>
        ))}

        <div style={{ height: 30 }} />
        <MTabBar active="job" />
      </div>
    </div>
  );
}

window.OrinovaPages11 = {
  MobileServicesIndex,
  MobileServiceDetail,
  MobileColorStudio,
  MobileSchedule,
  MobileJobDetailM,
  MobilePayBalance,
  MobileGallery,
};
