// Anologe — Careers: expandable role cards + apply flow

const ROLES = [
  {
    id: 'r01',
    code: 'R01',
    title: 'AI Operations Engineer',
    team: 'Workflows',
    location: 'Remote · EMEA',
    type: 'Permanent · Full‑time',
    comp: '£140k – £180k + equity',
    owner: 'Tomás Jensen',
    summary: 'Lead the agent + workflow surface area for two large engagements. You will own evals, observability, and the rollout of multi‑step automations into production stacks.',
    scope: [
      'Own 2–3 client engagements at any time',
      'Architect workflows in Temporal / Inngest with eval gates',
      'Build agent observability into Langfuse / Braintrust',
      'Mentor automation engineers on rollouts',
      'Author the workflow playbook (internal canon)'
    ],
    looking: [
      '6+ years in production ML / workflow engineering',
      'Shipped LLM features in revenue‑critical paths',
      'Comfortable owning on‑call for an AI system',
      'Writes well. Documents by default.'
    ]
  },
  {
    id: 'r02',
    code: 'R02',
    title: 'Revenue Operations Specialist',
    team: 'RevOps',
    location: 'London / Hybrid',
    type: 'Permanent · Full‑time',
    comp: '£110k – £150k + equity',
    owner: 'Eliot Marsden',
    summary: 'Operate end‑to‑end revenue systems for 3–4 engagements. Pipeline, forecasting, comp, and the warehouse layer underneath. You\'ll be the operator the client trusts.',
    scope: [
      'Install + run forecast cadence at 3–4 clients',
      'Own the schema and dedupe policy across engagements',
      'Build territory + routing automations',
      'Run quarterly business reviews with client leads',
      'Co‑author the RevOps runbook library'
    ],
    looking: [
      '5+ years in RevOps at a high‑growth SaaS',
      'Owned a forecast you\'d defend in front of a board',
      'Fluent in SFDC or HubSpot architecture',
      'SQL strong enough to read a warehouse model'
    ]
  },
  {
    id: 'r03',
    code: 'R03',
    title: 'Automation Engineer',
    team: 'Workflows',
    location: 'Remote · Global',
    type: 'Permanent · Full‑time',
    comp: '£120k – £160k + equity',
    owner: 'Sara Kępa',
    summary: 'Ship deterministic + AI workflow installations into client stacks. Routing, enrichment, billing recon, lifecycle programs — versioned, monitored, owned.',
    scope: [
      'Design + ship 4–6 workflow installs per year',
      'Own the eval harness + cost dashboards',
      'Build internal CLI for engagement scaffolding',
      'Be on‑call for client production flows',
      'Train client operators on handover'
    ],
    looking: [
      '4+ years building backend systems in production',
      'Hands‑on with Temporal, Inngest, n8n, or equivalent',
      'Has written code that handles money. Carefully.',
      'Comfortable on a pager.'
    ]
  },
  {
    id: 'r04',
    code: 'R04',
    title: 'Client Systems Manager',
    team: 'Operating',
    location: 'New York / Hybrid',
    type: 'Permanent · Full‑time',
    comp: '$170k – $220k + equity',
    owner: 'Naveen Okafor',
    summary: 'Run 4–5 client engagements as the operating lead. Scope, install milestones, weekly reviews, on‑call rota, handover. The client\'s single point of contact.',
    scope: [
      'Own 4–5 engagements end‑to‑end (NYC + EMEA)',
      'Run weekly operating review with each client',
      'Co‑sign all milestones with the lead engineer',
      'Manage handover at SLO',
      'Surface engagement risk to the partner team'
    ],
    looking: [
      '7+ years operating at internet‑first companies',
      'Has run ops for an early‑stage scale‑up',
      'Calm in front of an unhappy CFO',
      'Excellent written English; comfortable in Notion + Linear'
    ]
  }
];

function Chev({ open }) {
  return (
    <svg width="14" height="14" viewBox="0 0 14 14" style={{ transform: open ? 'rotate(180deg)' : 'rotate(0)', transition: 'transform 240ms' }}>
      <path d="M3 5 L7 9 L11 5" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

function RoleCard({ role, expanded, onToggle, onApply }) {
  return (
    <article className={`role ${expanded ? 'open' : ''}`}>
      <button className="role-row" onClick={onToggle} aria-expanded={expanded}>
        <span className="r-ix mono">{role.code}</span>
        <span className="r-title">
          <span className="r-name">{role.title}</span>
          <span className="r-team mono">{role.team.toUpperCase()}</span>
        </span>
        <span className="r-loc mono">{role.location}</span>
        <span className="r-comp mono">{role.comp.split('+')[0].trim()}</span>
        <span className="r-chev"><Chev open={expanded} /></span>
      </button>

      <div className="role-body" style={{ gridTemplateRows: expanded ? '1fr' : '0fr' }}>
        <div className="role-body-inner">
          <div className="r-detail-grid">
            <div className="r-summary">
              <div className="mono lbl">Surface area</div>
              <p>{role.summary}</p>
              <dl className="r-meta">
                <div><dt className="mono">Owner</dt><dd>{role.owner}</dd></div>
                <div><dt className="mono">Type</dt><dd>{role.type}</dd></div>
                <div><dt className="mono">Compensation</dt><dd>{role.comp}</dd></div>
              </dl>
            </div>
            <div>
              <div className="mono lbl">Scope</div>
              <ul className="r-list">
                {role.scope.map((s, i) => <li key={i}>{s}</li>)}
              </ul>
            </div>
            <div>
              <div className="mono lbl">We're looking for</div>
              <ul className="r-list">
                {role.looking.map((s, i) => <li key={i}>{s}</li>)}
              </ul>
            </div>
          </div>
          <div className="r-actions">
            <button className="btn primary" onClick={() => onApply(role)}>Start application <span className="arrow">→</span></button>
            <a className="btn ghost" href={`mailto:demo@anologe.co?subject=${encodeURIComponent('Re: ' + role.title + ' — refer a candidate')}`}>Refer someone</a>
            <span className="mono" style={{ fontSize: 11, color: 'var(--mute-1)', letterSpacing: '0.04em' }}>JD · 4 min read</span>
          </div>
        </div>
      </div>
    </article>
  );
}

function ApplyDialog({ role, onClose }) {
  const [form, setForm] = React.useState({ name: '', email: '', linkedin: '', why: '', last: '' });
  const [touched, setTouched] = React.useState({});
  const [submitted, setSubmitted] = React.useState(false);

  const err = {};
  if (!form.name.trim()) err.name = 'Required';
  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) err.email = 'Valid email required';
  if (form.linkedin && !/^https?:\/\//.test(form.linkedin)) err.linkedin = 'Include https://';
  if (form.why.trim().length < 40) err.why = 'At least 40 characters';
  if (form.last.trim().length < 30) err.last = 'At least 30 characters';

  const ok = Object.keys(err).length === 0;

  const submit = (e) => {
    e.preventDefault();
    setTouched({ name: true, email: true, linkedin: true, why: true, last: true });
    if (!ok) return;
    setSubmitted(true);
  };

  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = ''; };
  }, [onClose]);

  if (!role) return null;

  return (
    <div className="apply-overlay" onClick={onClose}>
      <div className="apply-modal" onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true">
        <div className="apply-head">
          <div>
            <div className="mono" style={{ fontSize: 11, color: 'var(--mute)', letterSpacing: '0.06em', textTransform: 'uppercase' }}>
              Application · {role.code}
            </div>
            <h3 style={{ marginTop: 6 }}>{role.title}</h3>
            <div className="mono" style={{ fontSize: 11, color: 'var(--mute-1)', letterSpacing: '0.04em', marginTop: 4 }}>
              {role.location} · {role.comp}
            </div>
          </div>
          <button className="apply-close" onClick={onClose} aria-label="Close">✕</button>
        </div>

        {submitted ? (
          <div className="apply-success">
            <div className="success-mark"><span className="dot" /></div>
            <h3 style={{ marginTop: 16 }}>Application received.</h3>
            <p style={{ color: 'var(--mute)', marginTop: 8, maxWidth: '48ch' }}>
              {role.owner} owns this role and will reply within 4 working days, regardless of outcome. We don't ghost.
            </p>
            <div className="mono" style={{ fontSize: 11, color: 'var(--mute-1)', marginTop: 18, padding: 12, background: 'var(--bg-1)', borderRadius: 3, letterSpacing: '0.04em' }}>
              REF · ANL‑{role.code}‑{Math.floor(Math.random() * 90000 + 10000)}
            </div>
            <button className="btn primary" style={{ marginTop: 18 }} onClick={onClose}>Close</button>
          </div>
        ) : (
          <form className="apply-form" onSubmit={submit} noValidate>
            <div className="apply-row">
              <div className="apply-field">
                <label className="label" htmlFor="ap-name">Your name</label>
                <input
                  id="ap-name"
                  className={`input ${touched.name && err.name ? 'invalid' : ''}`}
                  value={form.name}
                  onChange={(e) => setForm({ ...form, name: e.target.value })}
                  onBlur={() => setTouched({ ...touched, name: true })}
                  placeholder="Eliot Marsden"
                />
                {touched.name && err.name && <div className="field-error">{err.name}</div>}
              </div>
              <div className="apply-field">
                <label className="label" htmlFor="ap-email">Work email</label>
                <input
                  id="ap-email"
                  type="email"
                  className={`input ${touched.email && err.email ? 'invalid' : ''}`}
                  value={form.email}
                  onChange={(e) => setForm({ ...form, email: e.target.value })}
                  onBlur={() => setTouched({ ...touched, email: true })}
                  placeholder="you@company.co"
                />
                {touched.email && err.email && <div className="field-error">{err.email}</div>}
              </div>
            </div>

            <div className="apply-field">
              <label className="label" htmlFor="ap-linkedin">LinkedIn or portfolio (optional)</label>
              <input
                id="ap-linkedin"
                className={`input ${touched.linkedin && err.linkedin ? 'invalid' : ''}`}
                value={form.linkedin}
                onChange={(e) => setForm({ ...form, linkedin: e.target.value })}
                onBlur={() => setTouched({ ...touched, linkedin: true })}
                placeholder="https://linkedin.com/in/…"
              />
              {touched.linkedin && err.linkedin && <div className="field-error">{err.linkedin}</div>}
            </div>

            <div className="apply-field">
              <label className="label" htmlFor="ap-last">Last operating project</label>
              <textarea
                id="ap-last"
                className={`textarea ${touched.last && err.last ? 'invalid' : ''}`}
                rows="3"
                value={form.last}
                onChange={(e) => setForm({ ...form, last: e.target.value })}
                onBlur={() => setTouched({ ...touched, last: true })}
                placeholder="One paragraph. Concrete. What did you ship and what changed."
              />
              <div className="mono" style={{ fontSize: 11, color: 'var(--mute-1)', marginTop: 6 }}>
                {form.last.length} / 30 minimum
              </div>
              {touched.last && err.last && <div className="field-error">{err.last}</div>}
            </div>

            <div className="apply-field">
              <label className="label" htmlFor="ap-why">Why this role, specifically</label>
              <textarea
                id="ap-why"
                className={`textarea ${touched.why && err.why ? 'invalid' : ''}`}
                rows="3"
                value={form.why}
                onChange={(e) => setForm({ ...form, why: e.target.value })}
                onBlur={() => setTouched({ ...touched, why: true })}
                placeholder="Not Anologe in general — this specific surface area. 2–3 sentences."
              />
              <div className="mono" style={{ fontSize: 11, color: 'var(--mute-1)', marginTop: 6 }}>
                {form.why.length} / 40 minimum
              </div>
              {touched.why && err.why && <div className="field-error">{err.why}</div>}
            </div>

            <div className="apply-foot">
              <span className="mono" style={{ fontSize: 11, color: 'var(--mute)', letterSpacing: '0.04em' }}>
                We reply within 4 working days.
              </span>
              <div style={{ display: 'flex', gap: 10 }}>
                <button type="button" className="btn" onClick={onClose}>Cancel</button>
                <button type="submit" className="btn primary" disabled={!ok && Object.keys(touched).length > 0}>
                  Submit application <span className="arrow">→</span>
                </button>
              </div>
            </div>
          </form>
        )}
      </div>
    </div>
  );
}

function RolesApp() {
  const [openId, setOpenId] = React.useState('r01');
  const [applyRole, setApplyRole] = React.useState(null);

  return (
    <>
      <div className="roles">
        {ROLES.map((r) => (
          <RoleCard
            key={r.id}
            role={r}
            expanded={openId === r.id}
            onToggle={() => setOpenId(openId === r.id ? null : r.id)}
            onApply={(role) => setApplyRole(role)}
          />
        ))}
      </div>

      <div style={{ marginTop: 24, display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}>
        <span className="mono" style={{ fontSize: 12, color: 'var(--mute)', letterSpacing: '0.04em' }}>
          Don't see your role? Send a thoughtful note to <a href="mailto:demo@anologe.co" style={{ color: 'var(--ink)', borderBottom: '1px solid var(--ink)' }}>demo@anologe.co</a>.
        </span>
        <a href="mailto:demo@anologe.co" className="btn">General application <span className="arrow">→</span></a>
      </div>

      {applyRole && <ApplyDialog role={applyRole} onClose={() => setApplyRole(null)} />}

      <style>{`
        .roles { border: 1px solid var(--line); border-radius: var(--radius-card); background: var(--bg-card); overflow: hidden; }
        .role { border-bottom: 1px solid var(--line); }
        .role:last-child { border-bottom: 0; }
        .role-row {
          width: 100%;
          background: transparent;
          border: 0;
          padding: 22px 24px;
          display: grid;
          grid-template-columns: 60px 1fr 200px 180px 24px;
          align-items: center;
          gap: 16px;
          text-align: left;
          cursor: pointer;
          transition: background 200ms, padding 200ms;
        }
        .role-row:hover { background: #fcfcf9; }
        .role.open .role-row { background: #fcfcf9; }
        .r-ix { font-size: 11px; color: var(--mute-1); letter-spacing: 0.06em; }
        .r-title { display: flex; flex-direction: column; gap: 4px; }
        .r-name { font-family: var(--font-display); font-size: 22px; font-weight: 500; letter-spacing: -0.02em; color: var(--ink); }
        .r-team { font-size: 10.5px; color: var(--mute); letter-spacing: 0.08em; }
        .r-loc, .r-comp { font-size: 12px; color: var(--mute); letter-spacing: 0.04em; }
        .r-chev { color: var(--mute); justify-self: end; }
        .role-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 380ms cubic-bezier(0.2,0.8,0.2,1); }
        .role-body-inner { overflow: hidden; }
        .role.open .role-body-inner { border-top: 1px solid var(--line); }
        .r-detail-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 36px; padding: 28px 24px 16px; }
        .r-detail-grid .lbl { font-size: 11px; color: var(--mute); letter-spacing: 0.06em; text-transform: uppercase; margin-bottom: 12px; }
        .r-summary p { color: var(--ink-1); font-size: 15.5px; line-height: 1.55; max-width: 52ch; }
        .r-meta { display: flex; flex-direction: column; gap: 6px; margin-top: 18px; padding-top: 14px; border-top: 1px dashed var(--line); }
        .r-meta div { display: grid; grid-template-columns: 120px 1fr; font-size: 13px; }
        .r-meta dt { color: var(--mute); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; align-self: center; }
        .r-meta dd { margin: 0; color: var(--ink); font-family: var(--font-display); font-weight: 500; font-size: 14.5px; letter-spacing: -0.01em; }
        .r-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; font-size: 14px; color: var(--ink-1); }
        .r-list li { padding-left: 14px; position: relative; line-height: 1.5; }
        .r-list li::before { content: ''; position: absolute; left: 0; top: 9px; width: 6px; height: 1px; background: var(--mute); }
        .r-actions { display: flex; gap: 12px; align-items: center; padding: 20px 24px 28px; border-top: 1px solid var(--line); margin-top: 12px; flex-wrap: wrap; }

        @media (max-width: 980px) {
          .role-row { grid-template-columns: 50px 1fr 120px 24px; }
          .r-comp { display: none; }
          .r-detail-grid { grid-template-columns: 1fr; gap: 24px; }
        }
        @media (max-width: 600px) {
          .role-row { grid-template-columns: 1fr 24px; }
          .r-ix, .r-loc { display: none; }
        }

        .apply-overlay {
          position: fixed; inset: 0; z-index: 100;
          background: rgba(10, 10, 10, 0.45);
          backdrop-filter: blur(4px);
          display: flex; align-items: flex-start; justify-content: center;
          padding: 8vh 24px;
          overflow: auto;
        }
        .apply-modal {
          background: var(--bg-card);
          border: 1px solid var(--line-strong);
          border-radius: var(--radius-card);
          width: 100%;
          max-width: 680px;
          box-shadow: 0 30px 60px rgba(10,10,10,0.18);
          animation: modalIn 320ms cubic-bezier(0.2, 0.8, 0.2, 1);
        }
        @keyframes modalIn { from { transform: translateY(12px); opacity: 0; } to { transform: none; opacity: 1; } }
        .apply-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; padding: 24px 26px; border-bottom: 1px solid var(--line); }
        .apply-head h3 { font-size: 24px; }
        .apply-close { background: transparent; border: 1px solid var(--line); width: 32px; height: 32px; border-radius: 3px; cursor: pointer; color: var(--mute); }
        .apply-close:hover { color: var(--ink); background: var(--bg-1); }
        .apply-form { padding: 22px 26px 24px; display: flex; flex-direction: column; gap: 16px; }
        .apply-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
        .apply-foot { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 4px; padding-top: 16px; border-top: 1px solid var(--line); flex-wrap: wrap; }
        .apply-success { padding: 36px 26px 32px; text-align: center; }
        .success-mark { width: 56px; height: 56px; border-radius: 50%; background: var(--ink); display: inline-flex; align-items: center; justify-content: center; }
        .success-mark .dot { width: 14px; height: 14px; border-radius: 50%; background: var(--accent); }
        @media (max-width: 600px) { .apply-row { grid-template-columns: 1fr; } }
      `}</style>
    </>
  );
}

const rolesRoot = document.getElementById('roles-app');
if (rolesRoot) ReactDOM.createRoot(rolesRoot).render(<RolesApp />);
