// audit.jsx — The Busywork Audit. Standalone lead-magnet page.
// Math is Daniel's own ranking framework: annual hours x cost-of-error weight.
const { useState: useStateA, useRef: useRefA, useMemo: useMemoA } = React;

const UNITS = [
  { id: "day", perYear: 260 },
  { id: "week", perYear: 52 },
  { id: "month", perYear: 12 }
];

const ERROR_IDS = ["low", "medium", "high"];
const ERROR_WEIGHTS = { low: 1, medium: 3, high: 5 };

// One FTE-month of capacity, used to translate hours into something an owner feels.
const HOURS_PER_FTE_MONTH = 173.33;
const MAX_TASKS = 5;

const num = (v) => {
  const n = parseFloat(v);
  return Number.isFinite(n) ? n : 0;
};
const fmtMoney = (n) => "$" + Math.round(n).toLocaleString("en-US");
const fmtNum = (n) => Math.round(n).toLocaleString("en-US");

let taskSeq = 0;
const newTask = () => ({
  id: ++taskSeq,
  name: "",
  freq: "",
  unit: "week",
  minutes: "",
  people: "1",
  errorCost: "medium"
});

const isComplete = (t) =>
  t.name.trim() !== "" && num(t.freq) > 0 && num(t.minutes) > 0 && num(t.people) > 0;

function computeTask(t, rate) {
  const unit = UNITS.find((u) => u.id === t.unit) || UNITS[1];
  const weight = ERROR_WEIGHTS[t.errorCost] || ERROR_WEIGHTS.low;
  const annualHours = num(t.freq) * unit.perYear * (num(t.minutes) / 60) * num(t.people);
  return {
    id: t.id,
    name: t.name.trim(),
    errorCost: t.errorCost,
    annualHours,
    annualCost: annualHours * rate,
    score: annualHours * weight
  };
}

// Word order for "N hours a year · [level] cost of error" flips in Spanish
// ("costo de error alto" reads naturally; "alto costo de error" doesn't).
function errorCostLine(t, lang, hours, errorId) {
  const level = t("audit.error." + errorId).toLowerCase();
  const hoursPart = fmtNum(hours) + " " + t("audit.breakdown.hoursayear");
  return lang === "es"
    ? hoursPart + " · " + t("audit.breakdown.costoferror") + " " + level
    : hoursPart + " · " + level + " " + t("audit.breakdown.costoferror");
}

function taskCountLabel(t, n) {
  return n === 1 ? t("audit.task.singular") : t("audit.task.plural");
}

// ────────────────────────────────────────────────────────────
// Header / footer chrome
// ────────────────────────────────────────────────────────────
function MiniHeader({ lang, setLang }) {
  return (
    <header style={{ borderBottom: "1px solid var(--slate)" }}>
      <div style={{
        maxWidth: 1000, margin: "0 auto", padding: "20px 28px",
        display: "flex", alignItems: "center", justifyContent: "space-between", gap: 24
      }}>
        <a href="/" aria-label="Soptix home" style={{ display: "flex", alignItems: "center" }}>
          <SoptixLogo height={20} />
        </a>
        <div style={{ display: "flex", alignItems: "center", gap: 20 }}>
          <a href="/" style={{
            fontFamily: "'Space Grotesk', sans-serif", fontWeight: 500, fontSize: 12,
            letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--mist)", opacity: 0.7
          }}>Soptix.com</a>
          <LangSwitcher lang={lang} setLang={setLang} />
        </div>
      </div>
    </header>
  );
}

function MiniFooter({ t }) {
  return (
    <footer style={{ borderTop: "1px solid var(--slate)", marginTop: 80 }}>
      <div style={{
        maxWidth: 1000, margin: "0 auto", padding: "28px",
        display: "flex", alignItems: "center", gap: 12,
        fontSize: 13, color: "var(--mist-faint)"
      }}>
        <span>{t("audit.footer.tag")}</span>
      </div>
    </footer>
  );
}

// ────────────────────────────────────────────────────────────
// Task row
// ────────────────────────────────────────────────────────────
function TaskRow({ task, index, onChange, onRemove, canRemove, t }) {
  const set = (k) => (e) => onChange(task.id, k, e.target.value);
  const placeholder = t("audit.placeholder." + ((index % 5) + 1));

  return (
    <div style={{
      border: "1px solid var(--slate)",
      background: "var(--graphite)",
      padding: 20,
      marginBottom: 14
    }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
        <span style={{
          fontFamily: "'JetBrains Mono', ui-monospace, monospace", fontSize: 10,
          fontWeight: 500, letterSpacing: "0.14em", color: "var(--mist-faint)"
        }}>{t("audit.task.label")} {String(index + 1).padStart(2, "0")}</span>
        {canRemove && (
          <button
            type="button"
            onClick={() => onRemove(task.id)}
            aria-label={t("audit.task.remove.aria") + " " + (index + 1)}
            style={{
              background: "none", border: "none", color: "var(--mist-faint)",
              fontSize: 12, letterSpacing: "0.08em", textTransform: "uppercase",
              fontWeight: 500, cursor: "pointer", padding: 0
            }}
          >{t("audit.task.remove")}</button>
        )}
      </div>

      <div className="task-grid">
        <div className="span-2">
          <label className="lbl" htmlFor={"name-" + task.id}>{t("audit.task.name.label")}</label>
          <input
            id={"name-" + task.id}
            className="fld"
            type="text"
            maxLength={80}
            placeholder={placeholder}
            value={task.name}
            onChange={set("name")}
          />
        </div>
        <div>
          <label className="lbl" htmlFor={"freq-" + task.id}>{t("audit.task.freq.label")}</label>
          <input
            id={"freq-" + task.id}
            className="fld" type="number" min="0" step="any" inputMode="decimal"
            placeholder="3" value={task.freq} onChange={set("freq")}
          />
        </div>
        <div>
          <label className="lbl" htmlFor={"unit-" + task.id}>{t("audit.task.per.label")}</label>
          <select id={"unit-" + task.id} className="fld" value={task.unit} onChange={set("unit")}>
            {UNITS.map((u) => <option key={u.id} value={u.id}>{t("audit.unit." + u.id)}</option>)}
          </select>
        </div>
        <div>
          <label className="lbl" htmlFor={"mins-" + task.id}>{t("audit.task.mins.label")}</label>
          <input
            id={"mins-" + task.id}
            className="fld" type="number" min="0" step="any" inputMode="decimal"
            placeholder="20" value={task.minutes} onChange={set("minutes")}
          />
        </div>
      </div>

      <div style={{
        display: "flex", flexWrap: "wrap", alignItems: "flex-end",
        gap: 24, marginTop: 16
      }}>
        <div style={{ width: 90 }}>
          <label className="lbl" htmlFor={"people-" + task.id}>{t("audit.task.people.label")}</label>
          <input
            id={"people-" + task.id}
            className="fld" type="number" min="1" step="1" inputMode="numeric"
            value={task.people} onChange={set("people")}
          />
        </div>
        <div style={{ flex: "1 1 260px", minWidth: 240 }}>
          <span className="lbl">{t("audit.task.error.label")}</span>
          <div style={{ display: "flex", gap: 8 }}>
            {ERROR_IDS.map((id) => {
              const on = task.errorCost === id;
              return (
                <button
                  key={id}
                  type="button"
                  onClick={() => onChange(task.id, "errorCost", id)}
                  aria-pressed={on}
                  title={t("audit.error." + id + ".hint")}
                  style={{
                    flex: 1,
                    padding: "10px 6px",
                    background: on ? "var(--blue)" : "var(--obsidian)",
                    color: on ? "var(--obsidian)" : "var(--mist-dim)",
                    border: "1px solid " + (on ? "var(--blue)" : "var(--slate)"),
                    fontWeight: 600, fontSize: 12, letterSpacing: "0.06em",
                    textTransform: "uppercase", cursor: "pointer",
                    transition: "all 0.15s ease"
                  }}
                >{t("audit.error." + id)}</button>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Gated breakdown
// ────────────────────────────────────────────────────────────
function Breakdown({ rows, byCost, locked, t, lang }) {
  const max = Math.max.apply(null, rows.map((r) => r.annualCost).concat([1]));
  const first = rows[0];
  const priciest = byCost[0];
  const diverges = first && priciest && first.id !== priciest.id;

  return (
    <div style={{
      filter: locked ? "blur(7px)" : "none",
      pointerEvents: locked ? "none" : "auto",
      userSelect: locked ? "none" : "auto",
      transition: "filter 0.4s ease"
    }} aria-hidden={locked}>
      <h2 style={{
        fontSize: 20, fontWeight: 600, margin: "0 0 4px", letterSpacing: "-0.01em"
      }}>{t("audit.breakdown.h")}</h2>
      <p style={{ margin: "0 0 24px", color: "var(--mist-dim)", fontSize: 14 }}>
        {t("audit.breakdown.sub")}
      </p>

      {byCost.map((r) => (
        <div key={r.id} style={{ marginBottom: 18 }}>
          <div style={{
            display: "flex", justifyContent: "space-between", alignItems: "baseline",
            gap: 16, marginBottom: 7
          }}>
            <span style={{ fontWeight: 500, fontSize: 15 }}>{r.name}</span>
            <span style={{
              fontFamily: "'JetBrains Mono', ui-monospace, monospace",
              fontSize: 14, fontWeight: 500, whiteSpace: "nowrap"
            }}>{fmtMoney(r.annualCost)}</span>
          </div>
          <div style={{ height: 6, background: "var(--slate)" }}>
            <div style={{
              height: "100%",
              width: Math.max((r.annualCost / max) * 100, 2) + "%",
              background: "var(--blue)"
            }} />
          </div>
          <div style={{ marginTop: 6, fontSize: 12, color: "var(--mist-faint)" }}>
            {errorCostLine(t, lang, r.annualHours, r.errorCost)}
          </div>
        </div>
      ))}

      <div style={{
        border: "1px solid var(--slate)",
        borderLeft: "2px solid var(--blue)",
        background: "var(--graphite)",
        padding: 24,
        marginTop: 32
      }}>
        <Eyebrow>{t("audit.automatefirst.eyebrow")}</Eyebrow>
        <h3 style={{ fontSize: 22, fontWeight: 600, margin: "14px 0 12px", letterSpacing: "-0.01em" }}>
          {first ? first.name : ""}
        </h3>
        {diverges ? (
          <p style={{ margin: 0, color: "var(--mist-dim)", fontSize: 15, lineHeight: 1.6 }}>
            {lang === "es" ? (
              <React.Fragment>
                Tu tarea más costosa es {priciest.name}, con {fmtMoney(priciest.annualCost)} al año.
                Pero {first.name} es la que hay que resolver primero. Consume menos horas, pero un
                error ahí sale caro, así que cada equivocación se suma silenciosamente al costo del
                tiempo. Ordena por horas multiplicadas por el costo de equivocarte, y el ganador casi
                nunca es el que habrías imaginado.
              </React.Fragment>
            ) : (
              <React.Fragment>
                Your most expensive task is {priciest.name} at {fmtMoney(priciest.annualCost)} a year.
                But {first.name} is the one to fix first. It costs fewer raw hours, and a mistake there
                is expensive, so every error you make quietly adds to the bill on top of the time.
                Rank by hours multiplied by the cost of getting it wrong, and the winner is almost never
                the one you would have guessed.
              </React.Fragment>
            )}
          </p>
        ) : (
          <p style={{ margin: 0, color: "var(--mist-dim)", fontSize: 15, lineHeight: 1.6 }}>
            {lang === "es" ? (
              <React.Fragment>
                Esta tarea es a la vez la más costosa y la más riesgosa. Solo en tiempo te cuesta{" "}
                {first ? fmtMoney(first.annualCost) : ""} al año, antes de contar lo que sale un error.
                Por eso es el punto de partida más claro.
              </React.Fragment>
            ) : (
              <React.Fragment>
                This one is both your most expensive task and your riskiest. It costs you{" "}
                {first ? fmtMoney(first.annualCost) : ""} a year in time alone, before counting what a
                mistake costs. That makes it the clearest place to start.
              </React.Fragment>
            )}
          </p>
        )}
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Email gate
// ────────────────────────────────────────────────────────────
function EmailGate({ onUnlock, payload, t, lang }) {
  const [firstName, setFirstName] = useStateA("");
  const [lastName, setLastName] = useStateA("");
  const [email, setEmail] = useStateA("");
  const [honey, setHoney] = useStateA("");
  const [busy, setBusy] = useStateA(false);
  const [err, setErr] = useStateA("");

  const submit = async (e) => {
    e.preventDefault();
    if (busy) return;
    if (firstName.trim() === "") {
      setErr(t("audit.gate.err.firstname"));
      return;
    }
    if (lastName.trim() === "") {
      setErr(t("audit.gate.err.lastname"));
      return;
    }
    if (!/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email.trim())) {
      setErr(t("audit.gate.err.email"));
      return;
    }
    setErr("");
    setBusy(true);
    try {
      const res = await fetch("/api/audit", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          email: email.trim(),
          firstName: firstName.trim(),
          lastName: lastName.trim(),
          lang: lang,
          source: "busywork-audit",
          website: honey,
          audit: payload
        })
      });
      if (res.status === 429) {
        setErr(t("audit.gate.err.ratelimited"));
        setBusy(false);
        return;
      }
      if (!res.ok) throw new Error("Request failed");
      onUnlock();
    } catch {
      setErr(t("audit.gate.err.generic"));
      setBusy(false);
    }
  };

  return (
    <div style={{
      position: "absolute", inset: 0,
      background: "rgba(13,13,13,0.72)",
      display: "flex", alignItems: "center", justifyContent: "center",
      padding: 20
    }}>
      <div style={{
        width: "100%", maxWidth: 440,
        background: "var(--graphite)",
        border: "1px solid var(--slate)",
        padding: 32
      }}>
        <Eyebrow>{t("audit.gate.eyebrow")}</Eyebrow>
        <h2 style={{
          fontSize: 22, fontWeight: 600, margin: "14px 0 10px",
          letterSpacing: "-0.01em", lineHeight: 1.25
        }}>{t("audit.gate.h")}</h2>
        <p style={{ margin: "0 0 22px", color: "var(--mist-dim)", fontSize: 14, lineHeight: 1.6 }}>
          {t("audit.gate.p")}
        </p>

        <form onSubmit={submit} noValidate>
          <input
            type="text" name="website" tabIndex={-1} autoComplete="off"
            value={honey} onChange={(e) => setHoney(e.target.value)}
            aria-hidden="true"
            style={{ position: "absolute", left: -9999, width: 1, height: 1, opacity: 0 }}
          />
          <div className="name-grid" style={{ marginBottom: 14 }}>
            <div>
              <label className="lbl" htmlFor="gate-first">{t("audit.gate.firstname.label")}</label>
              <input
                id="gate-first"
                className="fld"
                type="text"
                maxLength={60}
                autoComplete="given-name"
                placeholder={t("audit.gate.firstname.placeholder")}
                value={firstName}
                onChange={(e) => setFirstName(e.target.value)}
              />
            </div>
            <div>
              <label className="lbl" htmlFor="gate-last">{t("audit.gate.lastname.label")}</label>
              <input
                id="gate-last"
                className="fld"
                type="text"
                maxLength={60}
                autoComplete="family-name"
                placeholder={t("audit.gate.lastname.placeholder")}
                value={lastName}
                onChange={(e) => setLastName(e.target.value)}
              />
            </div>
          </div>
          <label className="lbl" htmlFor="gate-email">{t("audit.gate.email.label")}</label>
          <input
            id="gate-email"
            className="fld"
            type="email"
            autoComplete="email"
            placeholder={t("audit.gate.email.placeholder")}
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            style={{ marginBottom: 14 }}
          />
          {err && (
            <p role="alert" style={{ margin: "0 0 14px", color: "var(--periwinkle)", fontSize: 13 }}>{err}</p>
          )}
          <Button size="lg">{busy ? t("audit.gate.submitting") : t("audit.gate.submit")}</Button>
        </form>

        <p style={{ margin: "18px 0 0", color: "var(--mist-faint)", fontSize: 12, lineHeight: 1.5 }}>
          {t("audit.gate.foot")}
        </p>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Results
// ────────────────────────────────────────────────────────────
function Results({ result, unlocked, onUnlock, t, lang }) {
  const { rows, byCost, totalHours, totalCost } = result;
  const months = totalHours / HOURS_PER_FTE_MONTH;

  const payload = {
    hourlyRate: result.rate,
    annualHours: totalHours,
    annualCost: totalCost,
    tasks: rows.map((r) => ({
      name: r.name,
      annualHours: r.annualHours,
      annualCost: r.annualCost,
      errorCost: r.errorCost
    }))
  };

  return (
    <section style={{ marginTop: 64 }}>
      <div style={{
        border: "1px solid var(--slate)",
        background: "var(--graphite)",
        padding: "44px 32px",
        marginBottom: 40
      }}>
        <Eyebrow>{t("audit.result.eyebrow")}</Eyebrow>
        <p style={{
          margin: "18px 0 6px", fontSize: 18, fontWeight: 500, color: "var(--mist-dim)"
        }}>{t("audit.result.losing")}</p>
        <div style={{
          fontSize: "clamp(48px, 11vw, 88px)", fontWeight: 700, lineHeight: 1,
          letterSpacing: "-0.03em", color: "var(--blue)"
        }}>{fmtMoney(totalCost)}</div>
        <p style={{
          margin: "10px 0 0", fontSize: 18, fontWeight: 500, color: "var(--mist-dim)"
        }}>{t("audit.result.peryear")}</p>

        <div style={{ height: 1, background: "var(--slate)", margin: "30px 0 24px" }} />

        <p style={{ margin: 0, fontSize: 16, lineHeight: 1.65, color: "var(--mist)", maxWidth: 620 }}>
          {lang === "es" ? (
            <React.Fragment>
              Son <strong style={{ fontWeight: 600 }}>{fmtNum(totalHours)} horas</strong> al año
              repartidas en {rows.length} {taskCountLabel(t, rows.length)}, unos{" "}
              <strong style={{ fontWeight: 600 }}>{months.toFixed(1)} meses de tiempo completo</strong>{" "}
              de la capacidad de alguien dedicados a trabajo que se repite exactamente igual cada vez.
            </React.Fragment>
          ) : (
            <React.Fragment>
              That's <strong style={{ fontWeight: 600 }}>{fmtNum(totalHours)} hours</strong> a year across{" "}
              {rows.length} {taskCountLabel(t, rows.length)}, or about{" "}
              <strong style={{ fontWeight: 600 }}>{months.toFixed(1)} full-time months</strong> of someone's
              capacity spent on work that repeats the same way every time.
            </React.Fragment>
          )}
        </p>
      </div>

      <div style={{ position: "relative" }}>
        <Breakdown rows={rows} byCost={byCost} locked={!unlocked} t={t} lang={lang} />
        {!unlocked && <EmailGate onUnlock={onUnlock} payload={payload} t={t} lang={lang} />}
      </div>

      {unlocked && (
        <div style={{
          border: "1px solid var(--slate)",
          background: "var(--graphite)",
          padding: 32,
          marginTop: 40
        }}>
          <h3 style={{ fontSize: 22, fontWeight: 600, margin: "0 0 12px", letterSpacing: "-0.01em" }}>
            {t("audit.cta.h")}
          </h3>
          <p style={{ margin: "0 0 24px", color: "var(--mist-dim)", fontSize: 15, lineHeight: 1.6, maxWidth: 620 }}>
            {t("audit.cta.p")}
          </p>
          <Button href="https://cal.com/soptix-khw4jx/30min" size="lg" arrow external>{t("audit.cta.button")}</Button>
        </div>
      )}
    </section>
  );
}

// ────────────────────────────────────────────────────────────
// App
// ────────────────────────────────────────────────────────────
function AuditApp() {
  const { lang, setLang, t } = useLang();
  const [rate, setRate] = useStateA("45");
  // Lazy init: newTask() bumps a module counter, so it must not run on every render.
  const [tasks, setTasks] = useStateA(() => [newTask()]);
  const [result, setResult] = useStateA(null);
  const [unlocked, setUnlocked] = useStateA(false);
  const [warn, setWarn] = useStateA("");
  const resultsRef = useRefA(null);

  const completeCount = useMemoA(() => tasks.filter(isComplete).length, [tasks]);

  const change = (id, key, val) =>
    setTasks((ts) => ts.map((tk) => (tk.id === id ? { ...tk, [key]: val } : tk)));
  const remove = (id) => setTasks((ts) => ts.filter((t) => t.id !== id));
  const add = () => setTasks((ts) => (ts.length < MAX_TASKS ? ts.concat([newTask()]) : ts));

  const compute = () => {
    const r = num(rate);
    if (r <= 0) {
      setWarn(t("audit.warn.rate"));
      return;
    }
    const done = tasks.filter(isComplete);
    if (done.length === 0) {
      setWarn(t("audit.warn.notasks"));
      return;
    }
    setWarn("");
    const rows = done.map((tk) => computeTask(tk, r)).sort((a, b) => b.score - a.score);
    setResult({
      rate: r,
      rows,
      byCost: rows.slice().sort((a, b) => b.annualCost - a.annualCost),
      totalHours: rows.reduce((s, x) => s + x.annualHours, 0),
      totalCost: rows.reduce((s, x) => s + x.annualCost, 0)
    });
    setUnlocked(false);
    requestAnimationFrame(() => {
      if (resultsRef.current) resultsRef.current.scrollIntoView({ behavior: "smooth", block: "start" });
    });
  };

  return (
    <React.Fragment>
      <MiniHeader lang={lang} setLang={setLang} />

      <main style={{ maxWidth: 1000, margin: "0 auto", padding: "64px 28px 0" }}>
        <h1 style={{
          fontSize: "clamp(34px, 6vw, 56px)", fontWeight: 600, lineHeight: 1.12,
          letterSpacing: "-0.03em", margin: "0 0 20px", maxWidth: 800
        }}>
          {t("audit.h1.a")}{" "}
          <span style={{ color: "var(--blue)" }}>{t("audit.h1.b")}</span>
        </h1>
        <p style={{
          fontSize: 18, lineHeight: 1.6, color: "var(--mist-dim)", margin: "0 0 48px", maxWidth: 620
        }}>
          {t("audit.sub")}
        </p>

        <div style={{ border: "1px solid var(--slate)", padding: 28, marginBottom: 36 }}>
          <label className="lbl" htmlFor="rate">{t("audit.rate.label")}</label>
          <div style={{ display: "flex", alignItems: "center", gap: 10, maxWidth: 220 }}>
            <span style={{ fontSize: 20, fontWeight: 600, color: "var(--mist-faint)" }}>$</span>
            <input
              id="rate" className="fld" type="number" min="0" step="any" inputMode="decimal"
              value={rate} onChange={(e) => setRate(e.target.value)}
            />
            <span style={{ fontSize: 14, color: "var(--mist-faint)", whiteSpace: "nowrap" }}>{t("audit.rate.perhr")}</span>
          </div>
          <p style={{ margin: "12px 0 0", fontSize: 13, color: "var(--mist-faint)", lineHeight: 1.5, maxWidth: 520 }}>
            {t("audit.rate.hint")}
          </p>
        </div>

        <h2 style={{ fontSize: 20, fontWeight: 600, margin: "0 0 6px", letterSpacing: "-0.01em" }}>
          {t("audit.tasks.h")}
        </h2>
        <p style={{ margin: "0 0 22px", color: "var(--mist-dim)", fontSize: 14, lineHeight: 1.6, maxWidth: 620 }}>
          {t("audit.tasks.sub")}
        </p>

        {tasks.map((tk, i) => (
          <TaskRow
            key={tk.id} task={tk} index={i}
            onChange={change} onRemove={remove}
            canRemove={tasks.length > 1}
            t={t}
          />
        ))}

        <div style={{ display: "flex", flexWrap: "wrap", gap: 14, alignItems: "center", marginTop: 24 }}>
          {tasks.length < MAX_TASKS && (
            <Button variant="ghost" onClick={add}>{t("audit.add")}</Button>
          )}
          <Button size="lg" onClick={compute} arrow>{t("audit.compute")}</Button>
          {completeCount > 0 && (
            <span style={{ fontSize: 13, color: "var(--mist-faint)" }}>
              {completeCount} {t("audit.of")} {tasks.length} {taskCountLabel(t, tasks.length)} {t("audit.filledin")}
            </span>
          )}
        </div>

        {warn && (
          <p role="alert" style={{ margin: "18px 0 0", color: "var(--periwinkle)", fontSize: 14 }}>{warn}</p>
        )}

        <div ref={resultsRef} style={{ scrollMarginTop: 24 }}>
          {result && (
            <Results result={result} unlocked={unlocked} onUnlock={() => setUnlocked(true)} t={t} lang={lang} />
          )}
        </div>
      </main>

      <MiniFooter t={t} />
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<AuditApp />);
