/* global React, ReactDOM, MEKABOTS_DATA, MEKABOTS_WIP, MEKABOTS_LOG, MekaViewer, MekaEngagement, MEKABOTS_ORGANIZATION_IDENTITY, MEKABOTS_COMBAT_PROFILE */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "heroLayout": "parade"
}/*EDITMODE-END*/;

const { useState, useEffect, useMemo, useRef } = React;

const ASSET_REFRESH_VERSION = "20260622-mk23-release";
const ARCHIVE_ASSET_BASE_URL = "https://sin1.contabostorage.com/48ea6e0cdf344a96ad45b1c7eb1c766a:anomaliexperiment/assets/";
const ARCHIVE_MOBILE_QUERY = "(max-width: 720px)";
const REGISTERED_OPERATORS_ROUTE = "#registered-operators";
const ORGANIZATION_DIRECTORY_COMPACT_QUERY = "(max-width: 1100px)";
const ORGANIZATION_DIRECTORY_PREVIEW_WIDE_LIMIT = 6;
const ORGANIZATION_DIRECTORY_PREVIEW_COMPACT_LIMIT = 3;
const ASSISTANT_AVATAR_FALLBACK_URL = "./assets/virtual-assistant-sample.svg";
const SIGNUP_PROGRESS_STORAGE_KEY = "supermekabots.signupProgress.v1";
const SIGNUP_STARTER_ID_STORAGE_KEY = "supermekabots.signupStarterId";
const SIGNUP_STARTER_INTENT_STORAGE_KEY = "supermekabots.signupStarterIntent";

function getPublicApiBaseUrl() {
  const configured = String(window.PUBLIC_API_BASE_URL || "").trim();
  if (configured) return configured.replace(/\/+$/, "");
  if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
    return (location.protocol + "//" + location.hostname + ":8787/api").replace(/\/+$/, "");
  }
  return "/api";
}

const PUBLIC_API_BASE_URL = getPublicApiBaseUrl();

function normalizePublicApiPath(path) {
  const rawPath = String(path || "");
  if (/^https?:\/\//i.test(rawPath)) return rawPath;
  const normalizedPath = rawPath.startsWith("/api/") && /\/api$/.test(PUBLIC_API_BASE_URL)
    ? rawPath.slice(4)
    : rawPath;
  return PUBLIC_API_BASE_URL + (normalizedPath.startsWith("/") ? normalizedPath : "/" + normalizedPath);
}

async function publicApi(path, options = {}) {
  if (!PUBLIC_API_BASE_URL) return null;
  const response = await fetch(normalizePublicApiPath(path), {
    credentials: "include",
    headers: {
      "Content-Type": "application/json",
      ...(options.headers || {})
    },
    ...options
  });
  if (!response.ok) {
    let body = null;
    try { body = await response.json(); } catch (err) { body = null; }
    const error = new Error((body && body.error) || ("API " + response.status));
    error.status = response.status;
    error.body = body;
    throw error;
  }
  return response.json();
}

function versionAssetUrl(url) {
  if (!url || /^(?:data|blob):/i.test(url) || url.includes("assetv=")) return url;
  const resolved = url.startsWith("assets/")
    ? ARCHIVE_ASSET_BASE_URL + url.slice("assets/".length)
    : url;
  const hashIndex = resolved.indexOf("#");
  const path = hashIndex >= 0 ? resolved.slice(0, hashIndex) : resolved;
  const hash = hashIndex >= 0 ? resolved.slice(hashIndex) : "";
  return path + (path.includes("?") ? "&" : "?") + "assetv=" + ASSET_REFRESH_VERSION + hash;
}

function getArchiveBatchSize() {
  if (typeof window === "undefined" || !window.matchMedia) return 9;
  return window.matchMedia(ARCHIVE_MOBILE_QUERY).matches ? 3 : 9;
}

function getOrganizationDirectoryPreviewLimit() {
  if (typeof window === "undefined" || !window.matchMedia) return ORGANIZATION_DIRECTORY_PREVIEW_WIDE_LIMIT;
  return window.matchMedia(ORGANIZATION_DIRECTORY_COMPACT_QUERY).matches
    ? ORGANIZATION_DIRECTORY_PREVIEW_COMPACT_LIMIT
    : ORGANIZATION_DIRECTORY_PREVIEW_WIDE_LIMIT;
}

const HERO_LAYOUTS = [
  { id: "stage",     label: "STAGE" },
  { id: "parade",    label: "PARADE" },
  { id: "spotlight", label: "SPOTLIGHT" },
  { id: "filmstrip", label: "FILMSTRIP" }
];

const FAMILIES = [
  { id: "all",     label: "ALL" },
  { id: "purple",  label: "VIOLET" },
  { id: "red",     label: "CRIMSON" },
  { id: "yellow",  label: "OCHRE" },
  { id: "dark",    label: "OBSIDIAN" },
  { id: "neutral", label: "GREYSCALE" },
  { id: "multi",   label: "TRI-TONE" }
];

function mechaIdNumber(value) {
  const match = String(value || "").match(/MK-(\d+)/i);
  return match ? Number(match[1]) : 0;
}

function compareMechaId(a, b) {
  const diff = mechaIdNumber(a.id) - mechaIdNumber(b.id);
  if (diff !== 0) return diff;
  return String(a.id).localeCompare(String(b.id), undefined, { numeric: true, sensitivity: "base" });
}

function isArchiveDispatchRarityLocked(mech) {
  if (!mech) return false;
  if (mech.eligibleForWeeklyDispatch === true) return true;
  if (mech.starterExclusionReason === "archive_dispatch_rarity") return true;
  if (mech.everFeaturedInArchiveDispatch === true) return true;
  if (mech.rarityLock === "archive_dispatch") return true;
  if (Array.isArray(mech.archiveDispatchFeaturedCodes) && mech.archiveDispatchFeaturedCodes.length > 0) return true;
  return false;
}

function isStarterUnitEligible(mech) {
  return Boolean(mech) && mech.eligibleForStarterUnit !== false && !isArchiveDispatchRarityLocked(mech);
}

const MEKABOTS_BY_ID = [...MEKABOTS_DATA].sort((a, b) => compareMechaId(b, a));
const FORMATION_VISIBLE_SLOT_COUNT = 5;
const STARTER_PREVIEW_ROSTER = MEKABOTS_BY_ID.filter(isStarterUnitEligible);
const MEKABOTS_LOG_BY_ID = [...MEKABOTS_LOG].sort((a, b) => {
  const diff = mechaIdNumber(a.text) - mechaIdNumber(b.text);
  if (diff !== 0) return diff;
  return String(a.date).localeCompare(String(b.date));
});

const DOSSIER_ITEMS = [
  { id: "fullbody", label: "Full-body concept", test: (mech) => Boolean(mech.fullbody) },
  { id: "head", label: "Head concept", test: (mech) => Boolean(mech.image) },
  { id: "pilot", label: "Pilot file", test: (mech) => Boolean(mech.pilotImage && mech.pilot) },
  { id: "bond", label: "Bond record", test: (mech) => Boolean(mech.epicBondRecord && mech.epicBondRecord.image) },
  { id: "lore", label: "Lore dossier", test: (mech) => Boolean(mech.lore && mech.lore.text) },
  { id: "print", label: "3D / print file", test: (mech) => Boolean(mech.fullbodyDownloadModel || mech.fullbodyModel || mech.stl) }
];

function makeFallbackEngagement() {
  return {
    schemaVersion: 1,
    favorites: {},
    printQueue: {},
    dossierProgress: {},
    organization: {
      name: "",
      callsign: "",
      motto: "",
      assistantName: "",
      operatorLore: null,
      starterMechId: "",
      crestSeed: "",
      crestSignature: "",
      logoStatus: "unclaimed",
      logoUrl: "",
      logoPrompt: "",
      logoDna: null,
      foundedAt: null,
      updatedAt: null
    },
    comms: { inbox: [], context: null },
    meta: { storageStatus: "unavailable", migratedFrom: [], lastResetAt: null }
  };
}

function useEngagementStore() {
  const [snapshot, setSnapshot] = useState(() => (
    typeof MekaEngagement !== "undefined" ? MekaEngagement.getSnapshot() : makeFallbackEngagement()
  ));

  useEffect(() => {
    if (typeof MekaEngagement === "undefined") return undefined;
    setSnapshot(MekaEngagement.getSnapshot());
    return MekaEngagement.subscribe(setSnapshot);
  }, []);

  const dispatch = (action) => {
    if (typeof MekaEngagement === "undefined") return snapshot;
    const next = MekaEngagement.dispatch(action);
    setSnapshot(next);
    return next;
  };

  return { snapshot, dispatch };
}

function normalizeAccountSession(payload) {
  const input = payload && typeof payload === "object" ? payload : {};
  return {
    status: input.user ? "signed-in" : "signed-out",
    user: input.user || null,
    organization: input.organization || null,
    error: ""
  };
}

function clearSignupBrowserDrafts() {
  try {
    if (typeof window !== "undefined" && window.sessionStorage) {
      window.sessionStorage.removeItem(SIGNUP_PROGRESS_STORAGE_KEY);
      window.sessionStorage.removeItem(SIGNUP_STARTER_ID_STORAGE_KEY);
      window.sessionStorage.removeItem(SIGNUP_STARTER_INTENT_STORAGE_KEY);
    }
  } catch (error) {
    // Signup draft cleanup is best-effort for hardened browser storage modes.
  }
}

function clearSignedInLocalData() {
  clearSignupBrowserDrafts();
  if (typeof MekaEngagement !== "undefined" && typeof MekaEngagement.clearLocalData === "function") {
    MekaEngagement.clearLocalData();
    return;
  }
  try {
    if (typeof window !== "undefined" && window.localStorage) {
      window.localStorage.removeItem("supermekabots.engagement.v1");
    }
  } catch (error) {
    // Storage access can fail in hardened browser modes; signed-out state still proceeds.
  }
}

function useAccountSession() {
  const [session, setSession] = useState(() => ({
    status: PUBLIC_API_BASE_URL ? "checking" : "offline",
    user: null,
    organization: null,
    error: ""
  }));

  const applySession = (payload) => {
    const next = normalizeAccountSession(payload);
    setSession(next);
    return next;
  };

  const syncOrganization = (organization) => {
    if (!organization) return null;
    setSession((current) => (
      current.status === "signed-in"
        ? { ...current, organization, error: "" }
        : current
    ));
    return organization;
  };

  const verifySessionCookie = async () => {
    const verified = normalizeAccountSession(await publicApi("/auth/me"));
    setSession(verified);
    if (verified.status !== "signed-in") {
      const error = new Error("SESSION COOKIE NOT AVAILABLE");
      error.status = 401;
      throw error;
    }
    return verified;
  };

  const restore = async () => {
    if (!PUBLIC_API_BASE_URL) {
      setSession({ status: "offline", user: null, organization: null, error: "" });
      return null;
    }
    setSession((current) => ({ ...current, status: "checking", error: "" }));
    try {
      return applySession(await publicApi("/auth/me"));
    } catch (error) {
      if (error.status === 401) {
        setSession({ status: "signed-out", user: null, organization: null, error: "" });
        return null;
      }
      setSession({ status: "error", user: null, organization: null, error: error.message || "SESSION RESTORE FAILED" });
      return null;
    }
  };

  useEffect(() => {
    restore();
  }, []);

  const signup = async (payload) => {
    setSession((current) => ({ ...current, status: "checking", error: "" }));
    try {
      await publicApi("/auth/signup", {
        method: "POST",
        body: JSON.stringify(payload)
      });
      return verifySessionCookie();
    } catch (error) {
      setSession({ status: "signed-out", user: null, organization: null, error: error.message || "SIGNUP FAILED" });
      throw error;
    }
  };

  const login = async (payload) => {
    setSession((current) => ({ ...current, status: "checking", error: "" }));
    try {
      await publicApi("/auth/login", {
        method: "POST",
        body: JSON.stringify(payload)
      });
      return verifySessionCookie();
    } catch (error) {
      setSession({ status: "signed-out", user: null, organization: null, error: error.message || "LOGIN FAILED" });
      throw error;
    }
  };

  const renameOrganization = async (organizationRoot) => {
    const result = await publicApi("/organizations/current", {
      method: "PATCH",
      body: JSON.stringify({ organizationRoot })
    });
    if (result && result.organization) {
      syncOrganization(result.organization);
    }
    return result && result.organization ? result.organization : null;
  };

  const signout = async () => {
    try {
      await publicApi("/auth/signout", { method: "POST", body: "{}" });
    } catch (error) {
      // Local signout state still clears even if the network drops.
    }
    clearSignedInLocalData();
    setSession({ status: "signed-out", user: null, organization: null, error: "" });
  };

  return { ...session, restore, signup, login, signout, syncOrganization, renameOrganization };
}

function normalizeOrganizationRegistry(payload) {
  const organizations = Array.isArray(payload && payload.organizations) ? payload.organizations : [];
  return organizations
    .map((entry) => ({
      organization: entry && entry.organization ? entry.organization : null,
      owner: entry && entry.owner ? entry.owner : null,
      starterMechId: String((entry && entry.starterMechId) || (entry && entry.organization && entry.organization.starterMechId) || "").toUpperCase(),
      status: String((entry && entry.status) || "reserved"),
      createdAt: entry && entry.createdAt ? entry.createdAt : null
    }))
    .filter((entry) => entry.organization && entry.organization.name)
    .sort((a, b) => organizationRegistrySortTime(b) - organizationRegistrySortTime(a));
}

function organizationRegistrySortTime(entry) {
  const organization = entry && entry.organization ? entry.organization : null;
  const time = Date.parse(
    (entry && entry.createdAt) ||
    (organization && organization.foundedAt) ||
    (organization && organization.updatedAt) ||
    ""
  );
  return Number.isFinite(time) ? time : 0;
}

function normalizeOwnershipRegistry(payload) {
  const ownership = Array.isArray(payload && payload.ownership) ? payload.ownership : [];
  return ownership.reduce((map, entry) => {
    const starterMechId = String(entry && entry.starterMechId || "").toUpperCase();
    if (!starterMechId) return map;
    map[starterMechId] = {
      starterMechId,
      status: String((entry && entry.status) || "reserved"),
      organization: entry && entry.organization ? entry.organization : null,
      owner: entry && entry.owner ? entry.owner : null,
      createdAt: entry && entry.createdAt ? entry.createdAt : null
    };
    return map;
  }, {});
}

function useOrganizationRegistry(account) {
  const [registry, setRegistry] = useState(() => ({
    status: PUBLIC_API_BASE_URL ? "loading" : "offline",
    organizations: [],
    ownership: {},
    error: ""
  }));

  const refresh = async () => {
    if (!PUBLIC_API_BASE_URL) {
      setRegistry({ status: "offline", organizations: [], ownership: {}, error: "" });
      return null;
    }
    try {
      const [organizationsPayload, ownershipPayload] = await Promise.all([
        publicApi("/organizations"),
        publicApi("/mekas/ownership")
      ]);
      const next = {
        status: "ready",
        organizations: normalizeOrganizationRegistry(organizationsPayload),
        ownership: normalizeOwnershipRegistry(ownershipPayload),
        error: ""
      };
      setRegistry(next);
      return next;
    } catch (error) {
      const next = {
        status: "error",
        organizations: [],
        ownership: {},
        error: error.message || "REGISTRY OFFLINE"
      };
      setRegistry(next);
      return next;
    }
  };

  useEffect(() => {
    refresh();
  }, [account && account.status, account && account.organization && account.organization.updatedAt]);

  return { ...registry, refresh };
}

function useOnboardingStatus(account) {
  const [state, setState] = useState(() => ({
    status: PUBLIC_API_BASE_URL ? "idle" : "offline",
    data: null,
    error: "",
    actionBusy: ""
  }));

  async function loadOnboardingStatus() {
    if (!PUBLIC_API_BASE_URL || !account || account.status !== "signed-in") {
      setState({ status: PUBLIC_API_BASE_URL ? "idle" : "offline", data: null, error: "", actionBusy: "" });
      return null;
    }
    setState((current) => ({ ...current, status: current.data ? "ready" : "loading", error: "" }));
    try {
      const result = await publicApi("/onboarding/current");
      if (result && result.organization) account.syncOrganization(result.organization);
      setState((current) => ({ ...current, status: "ready", data: result, error: "" }));
      return result;
    } catch (error) {
      setState((current) => ({
        ...current,
        status: "error",
        error: (error.message || "ONBOARDING STATUS CHECK FAILED").toUpperCase()
      }));
      return null;
    }
  }

  async function retryOnboardingGeneration(action) {
    if (!action || !action.href || action.enabled === false) return null;
    setState((current) => ({ ...current, actionBusy: action.id || "generation_action", error: "" }));
    try {
      const result = await publicApi(action.href, {
        method: action.method || "POST",
        body: action.href.includes("/logo-generations")
          ? JSON.stringify({ type: action.targetType, targetType: action.targetType })
          : JSON.stringify({ type: action.targetType, jobId: action.jobId })
      });
      if (result && result.organization) account.syncOrganization(result.organization);
      const next = result && result.phase ? result : await loadOnboardingStatus();
      if (next) setState((current) => ({ ...current, status: "ready", data: next, error: "", actionBusy: "" }));
      return next;
    } catch (error) {
      setState((current) => ({
        ...current,
        status: current.data ? "ready" : "error",
        error: (error.message || "GENERATION ACTION FAILED").toUpperCase(),
        actionBusy: ""
      }));
      return null;
    }
  }

  async function recordAssistantIntro(action, step) {
    if (!PUBLIC_API_BASE_URL || !account || account.status !== "signed-in") return null;
    setState((current) => ({ ...current, actionBusy: "assistant_intro", error: "" }));
    try {
      const result = await publicApi("/onboarding/current/assistant-intro", {
        method: "POST",
        body: JSON.stringify({ action, step })
      });
      if (result && result.organization) account.syncOrganization(result.organization);
      setState((current) => ({ ...current, status: "ready", data: result, error: "", actionBusy: "" }));
      return result;
    } catch (error) {
      setState((current) => ({
        ...current,
        status: current.data ? "ready" : "error",
        error: (error.message || "ASSISTANT INTRO UPDATE FAILED").toUpperCase(),
        actionBusy: ""
      }));
      return null;
    }
  }

  async function recordDirective(directiveId, action) {
    if (!PUBLIC_API_BASE_URL || !account || account.status !== "signed-in" || !directiveId) return null;
    setState((current) => ({ ...current, actionBusy: "directive:" + directiveId, error: "" }));
    try {
      const result = await publicApi("/onboarding/current/directive", {
        method: "POST",
        body: JSON.stringify({ directiveId, action })
      });
      if (result && result.organization) account.syncOrganization(result.organization);
      setState((current) => ({ ...current, status: "ready", data: result, error: "", actionBusy: "" }));
      return result;
    } catch (error) {
      setState((current) => ({
        ...current,
        status: current.data ? "ready" : "error",
        error: (error.message || "DIRECTIVE UPDATE FAILED").toUpperCase(),
        actionBusy: ""
      }));
      return null;
    }
  }

  useEffect(() => {
    loadOnboardingStatus();
  }, [account && account.status, account && account.organization && account.organization.id, account && account.organization && account.organization.updatedAt]);

  useEffect(() => {
    if (!state.data || !state.data.pollAfterMs || account.status !== "signed-in") return undefined;
    const timer = window.setInterval(loadOnboardingStatus, state.data.pollAfterMs);
    return () => window.clearInterval(timer);
  }, [state.data && state.data.pollAfterMs, account && account.status, account && account.organization && account.organization.id]);

  return { ...state, refresh: loadOnboardingStatus, runAction: retryOnboardingGeneration, recordAssistantIntro, recordDirective };
}

function useArchiveDispatchStatus(account) {
  const [state, setState] = useState(() => ({
    status: PUBLIC_API_BASE_URL ? "idle" : "offline",
    data: null,
    ownerships: [],
    error: "",
    actionBusy: ""
  }));

  async function loadArchiveDispatchStatus() {
    if (!PUBLIC_API_BASE_URL) {
      setState({ status: "offline", data: null, ownerships: [], error: "", actionBusy: "" });
      return null;
    }
    setState((current) => ({ ...current, status: current.data ? "ready" : "loading", error: "" }));
    try {
      const result = await publicApi("/archive-dispatches/current");
      let ownerships = state.ownerships || [];
      if (account && account.status === "signed-in") {
        try {
          const ownershipPayload = await publicApi("/ownerships");
          ownerships = Array.isArray(ownershipPayload && ownershipPayload.ownerships) ? ownershipPayload.ownerships : [];
        } catch (ownershipError) {
          ownerships = [];
        }
      }
      setState((current) => ({ ...current, status: "ready", data: result, ownerships, error: "", actionBusy: "" }));
      return result;
    } catch (error) {
      setState((current) => ({
        ...current,
        status: "error",
        error: (error.message || "ARCHIVE DISPATCH SYNC FAILED").toUpperCase(),
        actionBusy: ""
      }));
      return null;
    }
  }

  async function runDispatchMutation(actionId, path, body) {
    if (!PUBLIC_API_BASE_URL || !account || account.status !== "signed-in") return null;
    setState((current) => ({ ...current, actionBusy: actionId, error: "" }));
    try {
      const result = await publicApi(path, {
        method: "POST",
        body: JSON.stringify(body || {})
      });
      const refreshed = await loadArchiveDispatchStatus();
      setState((current) => ({ ...current, status: "ready", data: refreshed || current.data, error: "", actionBusy: "" }));
      return result;
    } catch (error) {
      const progress = error && error.body && error.body.progress ? error.body.progress : null;
      const refreshed = await loadArchiveDispatchStatus();
      if (progress) {
        setState((current) => ({
          ...current,
          data: refreshed ? { ...refreshed, organizationProgress: progress } : current.data ? { ...current.data, organizationProgress: progress } : current.data,
          status: refreshed || current.data ? "ready" : "error",
          error: (error.body && error.body.error ? error.body.error : error.message || "DISPATCH ACTION FAILED").toUpperCase(),
          actionBusy: ""
        }));
      } else {
        setState((current) => ({
          ...current,
          data: refreshed || current.data,
          status: refreshed || current.data ? "ready" : "error",
          error: (error.message || "DISPATCH ACTION FAILED").toUpperCase(),
          actionBusy: ""
        }));
      }
      error.progress = progress;
      throw error;
    }
  }

  function currentDispatchId() {
    return state.data && state.data.dispatch ? state.data.dispatch.id : "";
  }

  async function startDispatch() {
    const dispatchId = currentDispatchId();
    if (!dispatchId) return null;
    return runDispatchMutation("start", "/archive-dispatches/" + dispatchId + "/start", {});
  }

  async function selectClaimTarget(mechId, confirmChange = false) {
    const dispatchId = currentDispatchId();
    if (!dispatchId || !mechId) return null;
    return runDispatchMutation("target:" + mechId, "/archive-dispatches/" + dispatchId + "/claim-target", { mechId, confirmChange });
  }

  async function recordDispatchDirective(directiveId, action = "complete") {
    const dispatchId = currentDispatchId();
    if (!dispatchId || !directiveId) return null;
    return runDispatchMutation("directive:" + directiveId, "/archive-dispatches/" + dispatchId + "/directives/" + directiveId, { action });
  }

  async function claimMeka() {
    const dispatchId = currentDispatchId();
    if (!dispatchId) return null;
    return runDispatchMutation("claim", "/archive-dispatches/" + dispatchId + "/claim-meka", {});
  }

  useEffect(() => {
    loadArchiveDispatchStatus();
  }, [account && account.status, account && account.organization && account.organization.id]);

  return {
    ...state,
    refresh: loadArchiveDispatchStatus,
    startDispatch,
    selectClaimTarget,
    recordDispatchDirective,
    claimMeka
  };
}

function findMechById(id) {
  return MEKABOTS_BY_ID.find((mech) => mech.id === id);
}

function getDossierStatus(mech) {
  const items = DOSSIER_ITEMS.map((item) => ({ ...item, complete: item.test(mech) }));
  return {
    items,
    total: items.length,
    complete: items.filter((item) => item.complete).length
  };
}

function getEngagementCounts(engagement, account) {
  const owned = getOwnedMechs(account).length;
  return {
    owned,
    hangar: owned,
    transmissions: (engagement.comms && engagement.comms.inbox ? engagement.comms.inbox.length : 0)
  };
}

function getHangarLimit() {
  return window.MekaEngagement && window.MekaEngagement.MAX_HANGAR_UNITS
    ? window.MekaEngagement.MAX_HANGAR_UNITS
    : 5;
}

function getOwnedMechs(account) {
  const accountOrganization = getAccountOrganization(account);
  const starter = accountOrganization && accountOrganization.starterMechId
    ? findMechById(accountOrganization.starterMechId)
    : null;
  return starter ? [starter] : [];
}

function getOrganizationRosterMechs(account, archiveDispatchStatus) {
  const starterMechs = getOwnedMechs(account);
  const ownerships = Array.isArray(archiveDispatchStatus && archiveDispatchStatus.ownerships)
    ? archiveDispatchStatus.ownerships
    : [];
  const roster = [...starterMechs];
  ownerships.forEach((ownership) => {
    if (!ownership || ownership.ownershipClass !== "dispatch_claim") return;
    const mech = findMechById(ownership.mechId);
    if (mech && !roster.some((entry) => entry.id === mech.id)) roster.push(mech);
  });
  return roster;
}

function getOrganizationRosterOwnership(account, archiveDispatchStatus, mech) {
  if (!mech) return null;
  const accountOrganization = getAccountOrganization(account);
  if (accountOrganization && accountOrganization.starterMechId === mech.id) {
    return {
      id: "starter:" + accountOrganization.id,
      mechId: mech.id,
      ownershipClass: "starter",
      sourceType: "founding",
      ownershipSerial: "FOUNDING UNIT"
    };
  }
  const ownerships = Array.isArray(archiveDispatchStatus && archiveDispatchStatus.ownerships)
    ? archiveDispatchStatus.ownerships
    : [];
  return ownerships.find((ownership) => ownership && ownership.mechId === mech.id) || null;
}

function getOwnedRosterUnitLabel(ownership, activeIsStarter) {
  if (ownership && ownership.ownershipClass === "dispatch_claim") return "OWNED MEKA";
  if (activeIsStarter) return "OWNED STARTER";
  return "OWNED UNIT";
}

function getOwnedRosterUnitStatus(accountOrganization, ownership, activeIsStarter) {
  if (ownership && ownership.ownershipClass === "dispatch_claim") return "CLAIMED";
  if (activeIsStarter) return getOwnedStarterStatus(accountOrganization, true, false);
  return ownership ? "OWNED" : "UNCLAIMED";
}

function getOwnedRosterUnitCopy(mech, ownership, accountOrganization) {
  if (!mech) return "Select an owned unit to review its current roster record.";
  const organizationName = (accountOrganization && accountOrganization.name) || "your organization";
  if (ownership && ownership.ownershipClass === "dispatch_claim") {
    const serial = ownership.ownershipSerial ? " Ownership serial " + ownership.ownershipSerial + "." : "";
    return mech.id + " / " + mech.codename + " is secured through Archive Dispatch and now belongs to " + organizationName + "'s owned roster." + serial;
  }
  return mech.id + " / " + mech.codename + " anchors " + organizationName + "'s founding record as the starter unit.";
}

const CERTIFICATE_VAULT_FUTURE_SOURCES = [
  { id: "battle_honors", label: "BATTLE HONORS", copy: "Arena victories and combat milestones will file here." },
  { id: "special_events", label: "SPECIAL EVENTS", copy: "Limited ceremonies and seasonal awards will file here." }
];

function formatCertificateDate(value) {
  if (!value) return "DATE PENDING";
  try {
    return new Date(value).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" });
  } catch (error) {
    return "DATE PENDING";
  }
}

function certificateSortTime(value) {
  const time = Date.parse(value || "");
  return Number.isFinite(time) ? time : 0;
}

function getCertificateVaultKind(ownership) {
  if (!ownership) return "Certificate";
  if (ownership.sourceType === "founding" || ownership.ownershipClass === "starter") return "Founding Starter";
  if (ownership.sourceType === "battle") return "Battle Honors";
  if (ownership.sourceType === "event") return "Special Event";
  if (ownership.sourceType === "archive_dispatch" || ownership.ownershipClass === "dispatch_claim") return "Meka Claim";
  return "Certificate";
}

function getOwnershipCertificateSealCopy(dispatchCode) {
  const normalized = String(dispatchCode || "").trim().toUpperCase();
  if (!normalized || normalized === "ARCHIVE SEAL") {
    return { kicker: "Archive Seal", mark: "Filed", detail: "Certificate Ledger" };
  }
  if (normalized === "FOUNDING" || normalized.includes("STARTER")) {
    return { kicker: "Founding Seal", mark: "Starter", detail: "Organization Deed" };
  }
  const weekMatch = normalized.match(/(?:^|-)W(\d{1,2})(?:$|-)/);
  const yearMatch = normalized.match(/\b(20\d{2})\b/);
  if (weekMatch) {
    return {
      kicker: "Dispatch Seal",
      mark: "Week " + Number(weekMatch[1]),
      detail: (yearMatch ? yearMatch[1] + " " : "") + "Dispatch"
    };
  }
  return {
    kicker: "Dispatch Seal",
    mark: "Filed",
    detail: normalized.replace(/^AD-/, "").replace(/-/g, " ") || "Archive Dispatch"
  };
}

function buildStarterOwnershipSerial(mechId, organizationId) {
  return "STARTER-" + String(mechId || "").replace(/[^a-z0-9]/gi, "").toUpperCase() + "-" + String(organizationId || "").slice(0, 4).toUpperCase();
}

function buildStarterCeremonyFallback(session, starterMech) {
  const organization = session && session.organization ? session.organization : null;
  const mech = starterMech || findMechById(organization && organization.starterMechId) || null;
  if (!organization || !mech) return null;
  const claimedAt = organization.foundedAt || organization.createdAt || new Date().toISOString();
  const ownershipSerial = buildStarterOwnershipSerial(mech.id, organization.id);
  return {
    ceremonyMode: "starter",
    organization,
    ownership: {
      id: "starter:" + organization.id,
      organizationId: organization.id,
      mechId: mech.id,
      ownershipClass: "starter",
      sourceType: "founding",
      sourceId: organization.id,
      ownershipSerial,
      claimedAt
    },
    artifacts: {
      ownershipSerial,
      ownershipCertificate: {
        title: "Founding Starter Certificate",
        licenseId: ownershipSerial,
        ownershipSerial,
        organizationName: organization.name || "Your Organization",
        mechId: mech.id,
        codename: mech.codename,
        dispatchCode: "FOUNDING",
        claimedAt
      },
      dispatchSeal: { code: "FOUNDING", label: "Founding Seal", issuedAt: claimedAt },
      archiveChronicleEntry: {
        code: "FOUNDING",
        text: "FOUNDING: " + (organization.name || "Your Organization") + " registered " + mech.id + " / " + mech.codename + " as its starter Meka.",
        earnedAt: claimedAt
      }
    }
  };
}

function buildCertificateVaultItems(account, archiveDispatchStatus) {
  const ownerships = Array.isArray(archiveDispatchStatus && archiveDispatchStatus.ownerships)
    ? archiveDispatchStatus.ownerships
    : [];
  return ownerships.map((ownership) => {
    const mech = findMechById(ownership && ownership.mechId);
    const title = mech
      ? mech.id + " / " + mech.codename
      : String(ownership && ownership.mechId ? ownership.mechId : "Certificate");
    return {
      id: ownership.id,
      title,
      kind: getCertificateVaultKind(ownership),
      serial: ownership.ownershipSerial || "CERTIFICATE PENDING",
      earnedAt: ownership.claimedAt || "",
      earnedLabel: formatCertificateDate(ownership.claimedAt),
      href: ownership.certificateHref || ("#ownership/" + encodeURIComponent(ownership.id)),
      mech
    };
  }).filter((item) => item && item.id)
    .sort((a, b) => certificateSortTime(b.earnedAt) - certificateSortTime(a.earnedAt));
}

function getFormationDisplayMechs(displayMechs, activeId, visibleCount = FORMATION_VISIBLE_SLOT_COUNT) {
  const roster = Array.isArray(displayMechs) ? displayMechs.filter(Boolean) : [];
  const requestedActiveIndex = roster.findIndex((mech) => mech.id === activeId);
  const activeIndex = requestedActiveIndex >= 0 ? requestedActiveIndex : 0;
  const activeMech = roster[activeIndex];
  if (!activeMech) return [];
  const visibleLimit = Math.min(Math.max(1, visibleCount), roster.length);
  const formation = [activeMech];
  for (let radius = 1; formation.length < visibleLimit; radius += 1) {
    const previous = roster[(activeIndex - radius + roster.length) % roster.length];
    const next = roster[(activeIndex + radius) % roster.length];
    if (previous && !formation.some((mech) => mech.id === previous.id)) formation.push(previous);
    if (formation.length >= visibleLimit) break;
    if (next && !formation.some((mech) => mech.id === next.id)) formation.push(next);
  }
  return formation;
}

function getAdjacentPreviewMechId(displayMechs, activeId, direction) {
  if (!displayMechs.length) return "";
  const activeIndex = displayMechs.findIndex((mech) => mech.id === activeId);
  const startIndex = activeIndex >= 0 ? activeIndex : 0;
  const nextIndex = (startIndex + direction + displayMechs.length) % displayMechs.length;
  return displayMechs[nextIndex].id;
}

function getOwnedStarterStatus(accountOrganization, activeIsOwned, previewMode) {
  if (previewMode) return "PREVIEW";
  if (!activeIsOwned) return "UNCLAIMED";
  const logoStatus = String(accountOrganization && accountOrganization.logoStatus || "").toUpperCase();
  if (logoStatus === "GENERATED") return "READY";
  if (logoStatus === "QUEUED" || logoStatus === "PROCESSING") return "CREST " + logoStatus;
  if (logoStatus) return logoStatus;
  return "ACTIVE";
}

function getReadyCount() {
  return MEKABOTS_BY_ID.filter((mech) => mech.fullbodyDownloadModel || mech.fullbodyModel || mech.stl).length;
}

function CombatProfilePanel({ mech, variant = "" }) {
  const combatApi = typeof MEKABOTS_COMBAT_PROFILE !== "undefined" ? MEKABOTS_COMBAT_PROFILE : null;
  const stats = useMemo(() => (
    combatApi && combatApi.getCombatProfile ? combatApi.getCombatProfile(mech) : []
  ), [combatApi, mech]);
  const tags = useMemo(() => (
    combatApi && combatApi.getCombatProfileTags ? combatApi.getCombatProfileTags(mech) : []
  ), [combatApi, mech]);

  if (!mech || !stats.length) return null;

  return (
    <div className={["combat-profile", variant ? "combat-profile-" + variant : ""].filter(Boolean).join(" ")} aria-label={mech.id + " combat profile"}>
      <div className="combat-profile-head">
        <span>COMBAT PROFILE</span>
        <b>FIELD ESTIMATE</b>
      </div>
      <div className="combat-profile-stats">
        {stats.map((stat) => (
          <div className="combat-profile-stat" key={stat.key} title={stat.label + " " + stat.value}>
            <span>{stat.key}</span>
            <b>{String(stat.value).padStart(2, "0")}</b>
            <em className="combat-profile-meter" aria-hidden="true">
              <i style={{ "--combat-value": stat.value + "%" }}></i>
            </em>
          </div>
        ))}
      </div>
      <div className="combat-profile-tags">
        {tags.map((tag) => <span key={tag}>{tag}</span>)}
      </div>
    </div>
  );
}

function HangarSelectionControls({ displayMechs, activeMech, onSelect }) {
  const total = displayMechs.length;
  const activeIndex = Math.max(0, displayMechs.findIndex((mech) => activeMech && mech.id === activeMech.id));
  const current = total ? activeIndex + 1 : 0;

  function selectAdjacent(direction) {
    const nextId = getAdjacentPreviewMechId(displayMechs, activeMech && activeMech.id, direction);
    if (nextId) onSelect(nextId);
  }

  return (
    <div className="hangar-selection-controls" aria-label="Mecha preview selection controls">
      <button type="button" className="hangar-step-button" aria-label="PREVIOUS MEKA" onClick={() => selectAdjacent(-1)}>
        <span>PREV</span>
      </button>
      <div className="hangar-selection-readout" aria-live="polite">
        <span>ROSTER</span>
        <b>{String(current).padStart(2, "0")} / {String(total).padStart(2, "0")}</b>
      </div>
      <button type="button" className="hangar-step-button" aria-label="NEXT MEKA" onClick={() => selectAdjacent(1)}>
        <span>NEXT</span>
      </button>
    </div>
  );
}

function MechaPreviewDossier({ mech, availability, variant = "" }) {
  if (!mech) return null;
  const dossier = getDossierStatus(mech);
  const headerStatus = variant === "claim" ? "COMPACT DOSSIER" : (availability ? availability.label : "PREVIEW READY");
  const classification = mech.lore && mech.lore.classification ? mech.lore.classification : mech.series || "UNCLASSIFIED FRAME";
  const pilotLink = mech.pilot && mech.pilot.callsign ? mech.pilot.callsign : "UNASSIGNED";
  const printProfile = mech.print ? String(mech.print).replace(/\s*\u00c2·\s*/g, " / ").replace(/\s*·\s*/g, " / ") : (mech.stl ? "STL READY" : "PRINT PROFILE PENDING");
  const origin = mech.lore && mech.lore.origin ? mech.lore.origin : "ARCHIVE ORIGIN SEALED";
  const armament = mech.lore && Array.isArray(mech.lore.armaments) && mech.lore.armaments.length ? mech.lore.armaments[0] : (mech.tags && mech.tags[0] ? mech.tags[0].toUpperCase() : "FIELD KIT PENDING");
  const brief = mech.brief || "No field brief has been attached to this meka yet.";

  return (
    <div className={["mecha-preview-dossier", variant ? "mecha-preview-dossier-" + variant : ""].filter(Boolean).join(" ")} aria-live="polite">
      <div className="preview-dossier-head">
        <span>SELECTED PREVIEW DOSSIER</span>
        <b>{headerStatus}</b>
      </div>
      <div className="preview-dossier-grid">
        <div><span>CLASSIFICATION</span><b>{classification}</b></div>
        <div><span>PILOT LINK</span><b>{pilotLink}</b></div>
        <div><span>PRINT PROFILE</span><b>{printProfile}</b></div>
        <div><span>DOSSIER READINESS</span><b>{dossier.complete}/{dossier.total}</b></div>
      </div>
      <p>{brief}</p>
      <a className="preview-dossier-link" href={"#mech/" + mech.id}>READ FULL DOSSIER</a>
      <div className="preview-dossier-foot">
        <div>
          <span>ORIGIN</span>
          <b>{origin}</b>
        </div>
        <div>
          <span>PRIMARY SYSTEM</span>
          <b>{armament}</b>
        </div>
      </div>
      <div className="preview-dossier-palette" aria-label={mech.id + " colorway"}>
        {mech.palette.slice(0, 5).map((color, index) => (
          <i key={index} style={{ background: color }}></i>
        ))}
      </div>
    </div>
  );
}

function getHangarCropStyle(mech) {
  const cropApi = window.MEKABOTS_HANGAR_CROP;
  if (!cropApi || typeof cropApi.normalizeHangarCrop !== "function") return {};
  return cropApi.normalizeHangarCrop(mech && mech.hangarCrop);
}

function getHangarPreviewCandidate(mech) {
  const previewApi = window.MEKABOTS_HANGAR_PREVIEW;
  return previewApi && typeof previewApi.getHangarPreviewUrl === "function"
    ? previewApi.getHangarPreviewUrl(mech)
    : "";
}

function getHangarPreviewSource(mech) {
  const preview = getHangarPreviewCandidate(mech);
  return versionAssetUrl(preview || getHangarFallbackSource(mech));
}

function getOrganizationPreviewSource(organization) {
  if (organization && organization.logoUrl) return versionAssetUrl(organization.logoUrl);
  const api = window.MEKABOTS_ORGANIZATION_IDENTITY;
  return api && typeof api.renderCrestSvgDataUrl === "function"
    ? api.renderCrestSvgDataUrl(organization)
    : "";
}

function getAssistantAvatarSource(organization) {
  return versionAssetUrl((organization && organization.avatarUrl) || ASSISTANT_AVATAR_FALLBACK_URL);
}

function getAccountOrganization(account) {
  return account && account.status === "signed-in" && account.organization ? account.organization : null;
}

function getVisibleOrganization(account) {
  const accountOrganization = getAccountOrganization(account);
  if (accountOrganization) return accountOrganization;
  return makeFallbackEngagement().organization;
}

function getOwnershipEntryForMech(mech, registry, account) {
  if (!mech) return null;
  const accountOrganization = getAccountOrganization(account);
  if (accountOrganization && accountOrganization.starterMechId === mech.id) {
    return {
      state: "owned-by-you",
      label: "OWNED BY YOU",
      organization: accountOrganization,
      owner: account && account.user ? { username: account.user.username } : null
    };
  }
  const entry = registry && registry.ownership ? registry.ownership[mech.id] : null;
  if (!entry || !entry.organization) return null;
  return {
    state: entry.status === "owned" ? "owned" : "reserved",
    label: (entry.status === "owned" ? "OWNED BY " : "RESERVED BY ") + entry.organization.name,
    organization: entry.organization,
    owner: entry.owner
  };
}

function isStarterClaimedByOther(starterMechId, registry, accountOrganization) {
  const entry = registry && registry.ownership ? registry.ownership[String(starterMechId || "").toUpperCase()] : null;
  if (!entry || !entry.organization) return false;
  return !accountOrganization || entry.organization.id !== accountOrganization.id;
}

function isOrganizationRootValid(value) {
  const text = String(value || "").trim();
  return text.length >= 3 && text.length <= 24 && /^[a-z0-9]+$/i.test(text);
}

function getOrganizationRootWord(organization) {
  if (!organization) return "";
  return organization.rootWord || String(organization.name || "").trim().split(/\s+/)[0] || "";
}

function getOrganizationMottoText(organization) {
  if (!organization) return "Register an organization to claim a starter unit.";
  if (organization.motto) return organization.motto;
  if (organization.logoStatus === "generated") return "Founding motto is carried in the crest.";
  return "Doctrine pending until the final crest is generated.";
}

function getHangarFallbackSource(mech) {
  const previewApi = window.MEKABOTS_HANGAR_PREVIEW;
  const fallback = previewApi && typeof previewApi.getHangarFallbackUrl === "function"
    ? previewApi.getHangarFallbackUrl(mech)
    : "";
  return fallback || (mech ? mech.fullbody || mech.image : "");
}

function StatusBar() {
  const total = MEKABOTS_BY_ID.length;
  const latest = MEKABOTS_BY_ID[0];
  return (
    <div className="statusbar">
      <div><span className="dot"></span> ARCHIVE ONLINE · {new Date().getFullYear()}</div>
      <div className="scroll">
        <div className="scroll-track">
          <span>★ SUPER MEKABOTS · AI-GENERATED MECHA HEAD ARCHIVE · TAILORED PROMPT · NON-COMMERCIAL ★</span>
          <span>NEW · {latest.id} {latest.codename} ARCHIVED {latest.date}</span>
          <span>★ CONCEPTS AI-GENERATED · LORE HAND-WRITTEN · STL FILES PER ENTRY ★</span>
          <span>★ SUPER MEKABOTS · AI-GENERATED MECHA HEAD ARCHIVE · TAILORED PROMPT · NON-COMMERCIAL ★</span>
          <span>NEW · {latest.id} {latest.codename} ARCHIVED {latest.date}</span>
          <span>★ CONCEPTS AI-GENERATED · LORE HAND-WRITTEN · STL FILES PER ENTRY ★</span>
        </div>
      </div>
      <div>ENTRIES <b style={{ color: "var(--accent)" }}>{String(total).padStart(3, "0")}</b> · REV 26.05</div>
    </div>
  );
}

function getRegistryCount(registry) {
  return registry && Array.isArray(registry.organizations) ? registry.organizations.length : 0;
}

function Nav({ engagement, account, registry }) {
  const counts = getEngagementCounts(engagement, account);
  const registryCount = getRegistryCount(registry);
  const signedOut = !account || account.status !== "signed-in";
  return (
    <nav className="nav">
      <a className="brand" href="#top">
        <img src="assets/header-logo.png" alt="SUPER MEKABOTS · AI-Generated Mecha Archive" className="brand-logo" />
      </a>
      {signedOut && (
        <div className="nav-auth-actions">
          <a className="nav-signin" href="#signin">SIGN IN</a>
          <ClaimEntryCta label="SIGN UP" className="nav-claim" />
        </div>
      )}
      <div className="nav-links">
        {!signedOut && <a href="#hangar">Hangar{counts.hangar > 0 && <b>{String(counts.hangar).padStart(2, "0")}</b>}</a>}
        <a href="#registry">Registry{registryCount > 0 && <b>{String(registryCount).padStart(2, "0")}</b>}</a>
        <a href="#archive">Index</a>
        <a href="#comms">Comms</a>
        <a href="#about">About</a>
      </div>
    </nav>
  );
}

function HeroCollage({ layout, fullbodyMechs, latest }) {
  // Each layout renders the fullbody renders differently
  if (layout === "parade") {
    // Row count grows with archive size, capped at 5 rows:
    //   1–7 mechs → 1 row, 8–14 → 2 rows, 15–21 → 3, 22–28 → 4, 29+ → 5 rows.
    // Once at 5 rows, additional mechs distribute round-robin
    // (mech 36 → row 1, 37 → row 2, …), so each row stays balanced indefinitely.
    const total = fullbodyMechs.length;
    const numRows = total === 0 ? 1 : Math.min(5, Math.ceil(total / 7));
    const rows = Array.from({ length: numRows }, () => []);
    fullbodyMechs.forEach((m, i) => { rows[i % numRows].push(m); });
    const doubled = (arr) => [...arr, ...arr];
    return (
      <div
        className="hero-collage layout-parade"
        style={{ "--parade-rows": numRows }}
        aria-hidden="true"
      >
        <div className="parade-wall">
          {rows.map((row, rIdx) => (
            <div
              key={"row-" + rIdx}
              className={"parade-track parade-track-" + (rIdx % 2 === 0 ? "l" : "r")}
            >
              {doubled(row).map((m, i) => (
                <div className="parade-cell" key={"r" + rIdx + "-" + m.id + "-" + i}>
                  <img src={versionAssetUrl(m.fullbody)} alt="" />
                </div>
              ))}
            </div>
          ))}
        </div>
        <div className="collage-glow"></div>
        <div className="collage-scan"></div>
        <div className="collage-vignette"></div>
      </div>
    );
  }

  if (layout === "spotlight") {
    // One large featured mech (the latest fullbody) + small thumbs of the others
    const feature = fullbodyMechs[0];
    const rest = fullbodyMechs.filter(m => m !== feature);
    return (
      <div className="hero-collage layout-spotlight" aria-hidden="true">
        {feature && (
          <img className="spotlight-feature" src={versionAssetUrl(feature.fullbody)} alt="" />
        )}
        <div className="spotlight-thumbs">
          {rest.map((m) => (
            <div className="spotlight-thumb" key={m.id}>
              <img src={versionAssetUrl(m.fullbody)} alt="" />
              <span>{m.id}</span>
            </div>
          ))}
        </div>
        <div className="collage-glow"></div>
        <div className="collage-scan"></div>
        <div className="collage-vignette"></div>
      </div>
    );
  }

  if (layout === "filmstrip") {
    // Endless horizontal marquee of all fullbodies
    const doubled = [...fullbodyMechs, ...fullbodyMechs];
    return (
      <div className="hero-collage layout-filmstrip" aria-hidden="true">
        <div className="filmstrip-track">
          {doubled.map((m, i) => (
            <div className="filmstrip-cell" key={m.id + "-" + i}>
              <img src={versionAssetUrl(m.fullbody)} alt="" />
              <span className="filmstrip-id">{m.id} · {m.codename}</span>
            </div>
          ))}
        </div>
        <div className="collage-scan"></div>
        <div className="collage-vignette"></div>
      </div>
    );
  }

  // default: "stage" — original overlapping cinematic layout
  return (
    <div className="hero-collage layout-stage" aria-hidden="true">
      {fullbodyMechs.map((m, i) => (
        <img
          key={"fb-" + m.id}
          className={"collage-feature collage-feature-" + (i + 1)}
          src={versionAssetUrl(m.fullbody)}
          alt=""
        />
      ))}
      <div className="collage-glow"></div>
      <div className="collage-scan"></div>
      <div className="collage-vignette"></div>
    </div>
  );
}

function HeroClaimConsole({ starterMech, availability, onUseStarter, onSelectNext, canSelectNextAvailable }) {
  const starterLabel = starterMech ? starterMech.id + " / " + starterMech.codename : "SELECT STARTER";
  const starterIsClaimed = availability && availability.state === "claimed";
  const starterIsBlocked = Boolean(availability && availability.blocked);
  const availabilityLabel = availability ? availability.label : "CHECKING";
  const stateLine = starterIsClaimed
    ? "This starter is already claimed. Select the next available unit or sign in to continue."
    : starterIsBlocked
      ? "Starter availability is still syncing with the registry."
      : "Sign up opens the starter formation with this unit ready to review.";

  return (
    <div className={"hero-claim-console" + (starterIsClaimed ? " is-claimed" : "")} aria-label="Starter claim console">
      <div className="hero-claim-console-copy">
        <span>READY TO CLAIM</span>
        <b>Claim your starter</b>
        <p>{stateLine}</p>
      </div>
      <div className="hero-claim-console-status">
        <div>
          <span>SUGGESTED STARTER</span>
          <b>{starterLabel}</b>
        </div>
        <div>
          <span>AVAILABILITY</span>
          <b>{availabilityLabel}</b>
        </div>
      </div>
      <div className="hero-claim-console-actions">
        {starterIsClaimed ? (
          <button type="button" className="btn primary" onClick={onSelectNext} disabled={!canSelectNextAvailable}>SELECT NEXT AVAILABLE</button>
        ) : (
          <button type="button" className="btn primary" onClick={onUseStarter} disabled={starterIsBlocked}>CLAIM YOUR STARTER</button>
        )}
        <a className="btn" href="#signin">SIGN IN</a>
        <a className="hero-claim-console-link" href="#archive">BROWSE INDEX</a>
      </div>
    </div>
  );
}

function Hero({ heroLayout, heroClaimConsole }) {
  const total = MEKABOTS_BY_ID.length;
  const stlReady = MEKABOTS_BY_ID.filter(m => m.stl).length;
  const latest = MEKABOTS_BY_ID[0];
  const fullbodyMechs = MEKABOTS_BY_ID.filter(m => m.fullbody);
  return (
    <section className="hero">
      <HeroCollage layout={heroLayout} fullbodyMechs={fullbodyMechs} latest={latest} />
      <div className="hero-inner">
        <div className="hero-meta">
          <div>FILE · <b>MEKABOTS-ARCHIVE.IDX</b></div>
          <div>EST. <b>2024.11</b></div>
          <div>LATEST · <b>{latest.id} / {latest.date}</b></div>
          <div>WORKFLOW · <b>AI · TAILORED PROMPT</b></div>
        </div>
        <h1 className="hero-title">
          <span className="l1">SUPER</span>
          <span className="l2">MEKA<span className="slash">/</span>BOTS</span>
        </h1>
        <div className="hero-sub">
          <p className="lede">
            A growing archive of <em>AI-generated mecha head concepts</em>, each one
            rendered through a tailored prompt, dressed up with a hand-written
            dossier and a named pilot, then exported as a printable STL.
            Browse the index, study the spec sheets, orbit the model in 3D, and
            pull the file if you want to print your own.
          </p>
          <div className="stats">
            <div className="stat"><div className="k">Heads Archived</div><div className="v">{String(total).padStart(2, "0")}<span className="u">units</span></div></div>
            <div className="stat"><div className="k">Pilots Logged</div><div className="v">{String(total).padStart(2, "0")}<span className="u">named</span></div></div>
            <div className="stat"><div className="k">STL Ready</div><div className="v">{String(stlReady).padStart(2, "0")}<span className="u">/{total}</span></div></div>
            <div className="stat"><div className="k">Cadence</div><div className="v">3<span className="u">/wk</span></div></div>
          </div>
          {heroClaimConsole}
        </div>
      </div>
    </section>
  );
}

function LocalOpsStrip({ engagement, account, onReset }) {
  const counts = getEngagementCounts(engagement, account);
  const hangarLimit = getHangarLimit();
  const complete = MEKABOTS_BY_ID.filter((mech) => getDossierStatus(mech).complete === getDossierStatus(mech).total).length;
  const accountOrganization = getAccountOrganization(account);
  return (
    <section className="local-ops" aria-label="Archive engagement summary">
      <div className="local-ops-inner">
        <a className="local-op" href="#hangar">
          <span>MY HANGAR</span>
          <b>{String(counts.hangar).padStart(2, "0")} OWNED UNIT</b>
        </a>
        <a className="local-op" href="#hangar">
          <span>HANGAR LIMIT</span>
          <b>{String(hangarLimit).padStart(2, "0")} SLOTS</b>
        </a>
        <a className="local-op" href="#archive">
          <span>DOSSIERS</span>
          <b>{String(complete).padStart(2, "0")} / {String(MEKABOTS_BY_ID.length).padStart(2, "0")} COMPLETE</b>
        </a>
        <a className="local-op local-op-muted" href={accountOrganization ? "#hangar" : "#signin"}>
          <span>ACCOUNT</span>
          <b>{accountOrganization ? accountOrganization.name : "SIGN IN TO CLAIM"}</b>
        </a>
        {!accountOrganization && (
          <a className="local-op local-op-claim" href="#signup">
            <span>FIRST SORTIE</span>
            <b>CLAIM YOUR STARTER</b>
          </a>
        )}
      </div>
    </section>
  );
}

function MobileUtilityNav({ engagement, account, registry }) {
  const counts = getEngagementCounts(engagement, account);
  const registryCount = getRegistryCount(registry);
  const signedOut = !account || account.status !== "signed-in";
  return (
    <nav className="mobile-utility" aria-label="Archive navigation">
      {signedOut && <a className="mobile-utility-claim" href="#signup"><span>SIGN UP</span><b>CLAIM</b></a>}
      {signedOut && <a className="mobile-utility-signin" href="#signin"><span>EXISTING</span><b>SIGN IN</b></a>}
      {!signedOut && <a href="#hangar"><span>HANGAR</span><b>{String(counts.hangar).padStart(2, "0")}</b></a>}
      <a href="#registry"><span>REGISTRY</span><b>{String(registryCount).padStart(2, "0")}</b></a>
      <a href="#archive"><span>INDEX</span><b>{String(MEKABOTS_BY_ID.length).padStart(2, "0")}</b></a>
      <a href="#comms"><span>COMMS</span><b>{String(counts.transmissions).padStart(2, "0")}</b></a>
    </nav>
  );
}

function getArchiveDispatchBundle(archiveDispatchStatus) {
  const data = archiveDispatchStatus && archiveDispatchStatus.data ? archiveDispatchStatus.data : null;
  return {
    dispatch: data && data.dispatch ? data.dispatch : null,
    entries: Array.isArray(data && data.entries) ? data.entries : [],
    progress: data && data.organizationProgress ? data.organizationProgress : null
  };
}

function getArchiveDispatchEndState(archiveDispatchStatus) {
  const { entries, progress } = getArchiveDispatchBundle(archiveDispatchStatus);
  const activeTargetId = progress && progress.activeTargetMechId ? progress.activeTargetMechId : "";
  const ownedByYouEntry = entries.find((entry) => entry.availability && entry.availability.state === "owned_by_you");
  const activeEntry = entries.find((entry) => entry.mechId === activeTargetId) || ownedByYouEntry || null;
  const availableEntries = entries.filter((entry) => entry.availability && entry.availability.state === "available");
  const allEntriesUnavailable = entries.length > 0 && entries.every((entry) => entry.availability && entry.availability.state !== "available");
  if ((progress && progress.status === "complete") || ownedByYouEntry) {
    return {
      closed: true,
      reason: "owned",
      activeEntry,
      availableCount: availableEntries.length,
      totalCount: entries.length
    };
  }
  if (allEntriesUnavailable) {
    return {
      closed: true,
      reason: "sold_out",
      activeEntry: null,
      availableCount: 0,
      totalCount: entries.length
    };
  }
  return {
    closed: false,
    reason: "open",
    activeEntry,
    availableCount: availableEntries.length,
    totalCount: entries.length
  };
}

function LicenseAuthorityMeter({ progress }) {
  const value = Math.max(0, Math.min(100, Number(progress && progress.licenseAuthority || 0)));
  const target = Number(progress && progress.licenseAuthorityTarget || 100);
  return (
    <div className="license-authority-meter" role="progressbar" aria-valuemin="0" aria-valuemax={target} aria-valuenow={value} aria-label={value + " / " + target + " License Authority"}>
      <div className="license-authority-head">
        <span>License Authority</span>
        <b>{value} / {target}</b>
      </div>
      <div className="license-authority-track" aria-hidden="true"><i style={{ width: Math.min(100, (value / target) * 100) + "%" }}></i></div>
    </div>
  );
}

function ClaimTargetPlate({ mech, progress, availability, dispatchEndState }) {
  if (!mech) {
    const soldOut = dispatchEndState && dispatchEndState.reason === "sold_out";
    return (
      <div className={"claim-target-plate is-empty" + (soldOut ? " is-sold-out" : "")}>
        <span>{soldOut ? "Claim Window" : "Claim Target"}</span>
        <b>{soldOut ? "No Targets Remain" : "Target not logged"}</b>
        <p>{soldOut ? "All weekly dispatch units are already secured. Stand by for next week's drop." : "Choose one featured Meka from this week's Archive Dispatch."}</p>
      </div>
    );
  }
  const count = availability && availability.targetingOrganizationCount ? availability.targetingOrganizationCount : 0;
  return (
    <div className="claim-target-plate">
      <div className="claim-target-image">
        <HangarPreviewImage mech={mech} alt={mech.codename + " Claim Target"} />
      </div>
      <div className="claim-target-copy">
        <span>Claim Target</span>
        <b>{mech.id} / {mech.codename}</b>
        <p>{progress && progress.status === "complete" ? "Ownership claimed. This unit is now secured in your Organization Roster." : progress && progress.status === "reward_ready" ? "Registry claim is ready if the target remains available." : "Target logged. Ownership is secured only after the registry claim succeeds."}</p>
        <em>{count ? count + " organizations targeting" : "No contention reported"}</em>
      </div>
    </div>
  );
}

function DispatchDirectiveList({ progress }) {
  const directives = Array.isArray(progress && progress.directives) ? progress.directives : [];
  return (
    <div className="dispatch-directive-list" aria-label="Dispatch Directives">
      {directives.map((directive) => (
        <div key={directive.id} className={"dispatch-directive-row is-" + directive.status + (directive.invalidatedAt ? " is-invalidated" : "")}>
          <span>{directive.complete && !directive.invalidatedAt ? "OK" : directive.invalidatedAt ? "REVERIFY" : String(directive.authority).padStart(2, "0")}</span>
          <b>{directive.label}</b>
          <em>{directive.licenseAuthorityAwarded || directive.authority} LA</em>
        </div>
      ))}
    </div>
  );
}

function CommandDispatchPanel({ account, archiveDispatchStatus, onOpen, onSelectOwned, onClaimComplete, onDispatchDirectiveCompleted, placement = "primary" }) {
  const { dispatch, entries, progress } = getArchiveDispatchBundle(archiveDispatchStatus);
  const dispatchEndState = getArchiveDispatchEndState(archiveDispatchStatus);
  const signedIn = account && account.status === "signed-in";
  const targetMechId = progress && progress.activeTargetMechId
    ? progress.activeTargetMechId
    : dispatchEndState.activeEntry && dispatchEndState.activeEntry.mechId;
  const targetMech = targetMechId ? findMechById(targetMechId) : null;
  const targetEntry = entries.find((entry) => entry.mechId === (targetMech && targetMech.id));
  const busy = archiveDispatchStatus && archiveDispatchStatus.actionBusy;
  const sidebarBottom = placement === "sidebar-bottom";
  const showClaimTargetPlate = dispatchEndState.reason !== "owned";
  const showDispatchProgress = dispatchEndState.reason !== "owned";
  const title = dispatchEndState.closed
    ? (dispatchEndState.reason === "sold_out" ? "Dispatch Window Closed" : "Weekly Grant Secured")
    : (dispatch ? dispatch.title : "Archive Dispatch");
  const status = progress ? progress.status : (signedIn ? "available" : "preview");
  const closureCopy = dispatchEndState.reason === "sold_out"
    ? "No more weekly claim chances remain in this dispatch. All featured Mekas are already owned by operators."
    : (targetMech ? targetMech.id + " is now an Owned Meka in your Organization Roster. No more weekly claim chances remain in this dispatch." : "No more weekly claim chances remain in this dispatch because your weekly License Grant is already secured.");
  const closureNextCopy = "Next Archive Dispatch opens with next week's drop.";
  const stateCopy = dispatchEndState.closed
    ? closureCopy
    : progress && progress.status === "retarget_required"
      ? "Authority retained. Choose a new target and verify its dossier before claiming again."
      : "This week's Archive Dispatch is open.";
  const primaryLabel = !signedIn
    ? "SIGN UP TO CLAIM"
    : dispatchEndState.reason === "sold_out"
      ? "NEXT DROP STANDBY"
      : dispatchEndState.reason === "owned" || status === "complete"
        ? "VIEW IN ROSTER"
        : status === "reward_ready"
          ? "CLAIM MEKA"
          : status === "available"
            ? "INSPECT DISPATCH"
            : progress && progress.currentDirective ? progress.currentDirective.label.toUpperCase() : "CONTINUE DIRECTIVE";

  async function handlePrimary() {
    if (!archiveDispatchStatus || busy) return;
    if (!signedIn) {
      window.location.hash = "#signup";
      return;
    }
    if (dispatchEndState.reason === "sold_out") return;
    if (!progress || progress.status === "available") {
      activateDirectiveTarget("#archive-dispatch");
      const result = await archiveDispatchStatus.startDispatch();
      if (result && onDispatchDirectiveCompleted) onDispatchDirectiveCompleted("open_archive_dispatch", result);
      return;
    }
    if (progress.status === "reward_ready") {
      const result = await archiveDispatchStatus.claimMeka();
      if (result && onClaimComplete) onClaimComplete(result);
      return;
    }
    if (dispatchEndState.reason === "owned" || progress.status === "complete") {
      if (targetMech && typeof onSelectOwned === "function") {
        onSelectOwned(targetMech.id);
        activateDirectiveTarget("#hangar");
        return;
      }
      if (targetMech && onOpen) onOpen(targetMech.id);
      return;
    }
    if (progress.currentDirective && progress.currentDirective.targetHref) {
      activateDirectiveTarget(getArchiveDispatchRouteTarget(progress.currentDirective));
    }
  }

  return (
    <section className={"command-dispatch-panel is-" + status + (sidebarBottom ? " is-sidebar-bottom" : "") + (dispatchEndState.reason === "sold_out" ? " is-sold-out" : "") + (dispatchEndState.reason === "owned" ? " is-owned-complete" : "") + (!showClaimTargetPlate ? " is-receipt-only" : "")} aria-label="Command Dispatch">
      <div className="command-dispatch-head">
        <span>{sidebarBottom ? "Dispatch Status" : "This Week's Dispatch"}</span>
        <b>{dispatch ? dispatch.code : "SYNCING"}</b>
      </div>
      <div className="command-dispatch-grid">
        {showClaimTargetPlate && <ClaimTargetPlate mech={targetMech} progress={progress} availability={targetEntry && targetEntry.availability} dispatchEndState={dispatchEndState} />}
        <div className="command-dispatch-copy">
          <h3>{title}</h3>
          <p>{stateCopy}</p>
          {dispatchEndState.closed && (
            <div className="dispatch-closure-note">
              <span>{dispatchEndState.reason === "sold_out" ? "Drop Exhausted" : "Claim Cycle Complete"}</span>
              <b>{dispatchEndState.reason === "sold_out" ? "0 / " + dispatchEndState.totalCount + " targets available" : "Owned Meka secured"}</b>
              <p>{closureNextCopy}</p>
            </div>
          )}
          {showDispatchProgress && <LicenseAuthorityMeter progress={progress} />}
          {showDispatchProgress && <DispatchDirectiveList progress={progress} />}
          <div className="command-dispatch-actions">
            <button type="button" className="btn primary" onClick={handlePrimary} disabled={Boolean(busy) || dispatchEndState.reason === "sold_out"}>
              {primaryLabel}
            </button>
            <button type="button" className="btn" onClick={() => { activateDirectiveTarget("#archive-dispatch"); }}>
              VIEW DISPATCH
            </button>
          </div>
        </div>
      </div>
    </section>
  );
}

function ArchiveDispatchTargetCard({ entry, progress, signedIn, busy, dispatchClosed, onSelect, onInspect }) {
  const mech = findMechById(entry.mechId);
  const availability = entry.availability || {};
  const active = progress && progress.activeTargetMechId === entry.mechId;
  const ownedByYou = availability.state === "owned_by_you";
  const ownedByOther = availability.state === "owned_by_other";
  const owned = ownedByYou || ownedByOther;
  const targetSelectionBlocked = !signedIn || owned || dispatchClosed;
  const stateLabel = ownedByYou
    ? "Owned by you"
    : ownedByOther
      ? "Claimed"
      : dispatchClosed
        ? "Closed"
      : active
        ? "Claim target"
        : "Available";
  const actionLabel = ownedByYou
    ? "View owned unit"
    : ownedByOther
      ? "View dossier"
      : dispatchClosed
        ? "View dossier"
      : !signedIn
        ? "View dossier"
        : active
          ? "Target logged"
          : "Select claim target";
  const cardTitle = mech ? mech.id + " / " + mech.codename : entry.mechId;
  return (
    <button
      type="button"
      className={"archive-dispatch-target-card" + (active ? " is-active" : "") + (ownedByYou ? " is-owned-by-you" : "") + (ownedByOther ? " is-owned-by-other" : "") + (dispatchClosed ? " is-closed" : "")}
      onClick={() => targetSelectionBlocked ? onInspect(entry.mechId) : onSelect(entry.mechId)}
      disabled={Boolean(busy)}
      aria-pressed={active ? "true" : "false"}
      aria-label={actionLabel + ": " + cardTitle}
    >
      <span className="archive-dispatch-target-rank">{String(entry.slotRank || 0).padStart(2, "0")}</span>
      <span className="archive-dispatch-target-status">{stateLabel}</span>
      <span className="archive-dispatch-target-image">
        {mech ? <HangarPreviewImage mech={mech} alt={mech.codename + " Archive Dispatch target"} /> : <span>{entry.mechId}</span>}
      </span>
      <span className="archive-dispatch-target-copy">
        <b>{cardTitle}</b>
        <em>{entry.spotlightCopy || (mech && mech.brief) || "Weekly dispatch target staged for the License Grant loop."}</em>
      </span>
      <span className="archive-dispatch-target-action">{actionLabel}</span>
    </button>
  );
}

function ArchiveDispatchDock({ account, archiveDispatchStatus, onOpen, onDispatchDirectiveCompleted }) {
  const { dispatch, entries, progress } = getArchiveDispatchBundle(archiveDispatchStatus);
  const signedIn = account && account.status === "signed-in";
  const dispatchEndState = getArchiveDispatchEndState(archiveDispatchStatus);
  async function handleTargetSelect(mechId) {
    if (!signedIn || !archiveDispatchStatus || archiveDispatchStatus.actionBusy) return;
    if (dispatchEndState.closed) return;
    try {
      if (!progress || progress.status === "available") {
        const startResult = await archiveDispatchStatus.startDispatch();
        if (startResult && onDispatchDirectiveCompleted) onDispatchDirectiveCompleted("open_archive_dispatch", startResult);
      }
      const targetResult = await archiveDispatchStatus.selectClaimTarget(mechId);
      if (targetResult && onDispatchDirectiveCompleted) onDispatchDirectiveCompleted("select_claim_target", targetResult);
    } catch (error) {
      // Dispatch mutation errors are reflected in the dock state; keep clicks from leaking uncaught promise errors.
    }
  }
  if (!dispatch) return null;
  return (
    <section id="archive-dispatch" className="archive-dispatch-dock" aria-label="Archive Dispatch dock">
      <div className="archive-dispatch-dock-copy">
        <span>This Week's Archive Dispatch</span>
        <b>{dispatch.code}</b>
        <p>{signedIn ? "Choose one featured Meka as this week's Claim Target. Dispatch units are permanently locked out of starter selection." : "Preview this week's dispatch. Sign up to claim one weekly Meka through the License Grant loop."}</p>
      </div>
      <div className="archive-dispatch-dock-roster">
        {entries.map((entry) => (
          <ArchiveDispatchTargetCard
            key={entry.mechId}
            entry={entry}
            progress={progress}
            signedIn={signedIn}
            busy={archiveDispatchStatus && archiveDispatchStatus.actionBusy}
            dispatchClosed={dispatchEndState.closed}
            onSelect={handleTargetSelect}
            onInspect={onOpen}
          />
        ))}
      </div>
    </section>
  );
}

function OwnedRosterStrip({ account, archiveDispatchStatus, activeMech, onSelect }) {
  const roster = getOrganizationRosterMechs(account, archiveDispatchStatus);
  return (
    <div className="owned-roster-strip" aria-label="Organization Roster">
      <div className="owned-roster-head">
        <span>Organization Roster</span>
        <b>{roster.length ? roster.length + " Owned Meka" : "No dispatch claims yet"}</b>
      </div>
      <div className="owned-roster-list">
        {roster.map((mech) => {
          const ownership = getOrganizationRosterOwnership(account, archiveDispatchStatus, mech);
          const isDispatchClaim = ownership && ownership.ownershipClass === "dispatch_claim";
          const selected = Boolean(activeMech && activeMech.id === mech.id);
          const className = [
            isDispatchClaim ? "is-dispatch-claim" : "",
            selected ? "is-active" : ""
          ].filter(Boolean).join(" ");
          return (
            <button
              key={mech.id}
              type="button"
              onClick={() => onSelect(mech.id)}
              className={className}
              aria-pressed={Boolean(activeMech && activeMech.id === mech.id)}
              aria-label={"Select owned roster unit " + mech.id + " " + mech.codename}
            >
              <span>{isDispatchClaim ? "Owned Meka" : "Starter Meka"}</span>
              <b>{mech.id} / {mech.codename}</b>
              <em>{ownership && ownership.ownershipSerial ? ownership.ownershipSerial : "FOUNDING UNIT"}</em>
            </button>
          );
        })}
      </div>
    </div>
  );
}

function CertificateVaultPanel({ account, archiveDispatchStatus, onOpenVault }) {
  const certificates = buildCertificateVaultItems(account, archiveDispatchStatus);
  const status = archiveDispatchStatus && archiveDispatchStatus.status;
  const loading = status === "idle" || status === "loading";
  const latestCertificate = certificates[0] || null;
  return (
    <section className="certificate-vault-panel is-compact" aria-label="Certificate Vault">
      <button type="button" className="certificate-vault-launch" onClick={onOpenVault}>
        <span className="certificate-vault-mark" aria-hidden="true">CERT</span>
        <span className="certificate-vault-copy">
          <em>Certificate Vault</em>
          <b>{certificates.length ? certificates.length + " Collected" : loading ? "Syncing" : "No Certificates"}</b>
          <i>{latestCertificate ? latestCertificate.title : "Mission certificates file here"}</i>
        </span>
        <span className="certificate-vault-status">Open</span>
      </button>
    </section>
  );
}

function CertificateVaultOverlay({ account, archiveDispatchStatus, onClose }) {
  const certificates = buildCertificateVaultItems(account, archiveDispatchStatus);
  const status = archiveDispatchStatus && archiveDispatchStatus.status;
  const loading = status === "idle" || status === "loading";
  const [selectedCertificateId, setSelectedCertificateId] = useState("");
  const selectedCertificate = certificates.find((certificate) => certificate.id === selectedCertificateId) || null;
  const certificateIdSignature = certificates.map((certificate) => certificate.id).join("|");
  useEffect(() => {
    if (selectedCertificateId && !certificates.some((certificate) => certificate.id === selectedCertificateId)) {
      setSelectedCertificateId("");
    }
  }, [selectedCertificateId, certificateIdSignature]);
  useEffect(() => {
    if (typeof window === "undefined") return undefined;
    const handleKeyDown = (event) => {
      if (event.key !== "Escape") return;
      event.preventDefault();
      if (selectedCertificateId) {
        setSelectedCertificateId("");
      } else if (onClose) {
        onClose();
      }
    };
    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [onClose, selectedCertificateId]);
  return (
    <div className="certificate-vault-overlay" role="dialog" aria-modal="true" aria-label="Certificate Vault" onClick={onClose}>
      <section className={"certificate-vault-modal" + (selectedCertificateId ? " is-detail" : "")} onClick={(event) => event.stopPropagation()}>
        <div className="certificate-vault-modal-head">
          <div>
            <span>Certificate Vault</span>
            <h3>{selectedCertificate ? selectedCertificate.title : certificates.length ? certificates.length + " Collected" : loading ? "Ledger Syncing" : "No Certificates"}</h3>
            <p>{selectedCertificate ? selectedCertificate.kind + " / " + selectedCertificate.earnedLabel : "Founding deeds, Meka claims, battle honors, and event awards are filed here."}</p>
          </div>
          <div className="certificate-vault-modal-actions">
            {selectedCertificateId && (
              <button type="button" className="certificate-vault-back" onClick={() => setSelectedCertificateId("")}>BACK TO CERTIFICATE LIST</button>
            )}
            <button type="button" className="certificate-vault-close" onClick={onClose}>Close</button>
          </div>
        </div>
        {selectedCertificateId ? (
          <div className="certificate-vault-detail" key={selectedCertificateId}>
            <OwnershipCertificateView
              ownershipId={selectedCertificateId}
              onClose={() => setSelectedCertificateId("")}
              embedded={true}
              backLabel="BACK TO CERTIFICATE LIST"
              fallbackCertificate={selectedCertificate}
            />
          </div>
        ) : (
          <>
            <div className="certificate-vault-list">
              {certificates.length ? certificates.map((certificate) => (
                <button
                  key={certificate.id}
                  type="button"
                  className="certificate-vault-row"
                  onClick={() => {
                    setSelectedCertificateId(certificate.id);
                  }}
                >
                  <span className="certificate-vault-mark" aria-hidden="true">CERT</span>
                  <span className="certificate-vault-copy">
                    <b>{certificate.title}</b>
                    <em>{certificate.kind} / {certificate.earnedLabel}</em>
                  </span>
                  <span className="certificate-vault-serial">{certificate.serial}</span>
                </button>
              )) : (
                <div className="certificate-vault-empty">
                  {loading ? "Certificate ledger syncing." : "Mission certificates will appear after your first award."}
                </div>
              )}
            </div>
            <div className="certificate-vault-future" aria-label="Future certificate sources">
              {CERTIFICATE_VAULT_FUTURE_SOURCES.map((source) => (
                <div key={source.id}>
                  <span>{source.label}</span>
                  <b>{source.copy}</b>
                </div>
              ))}
            </div>
          </>
        )}
      </section>
    </div>
  );
}

function RegistryClaimCeremony({ claim, account, onClose, onOpenCertificate, onViewHangar, onContinueArchive }) {
  const [actionsReady, setActionsReady] = useState(false);
  const titleRef = useRef(null);
  const ownership = claim && claim.ownership ? claim.ownership : null;
  const artifacts = claim && claim.artifacts ? claim.artifacts : {};
  const mech = ownership ? findMechById(ownership.mechId) : null;
  const organization = (claim && claim.organization) || getAccountOrganization(account);
  const certificate = artifacts.ownershipCertificate || {};
  const organizationName = certificate.organizationName || (organization && organization.name) || "Your Organization";
  const claimDate = certificate.claimedAt ? new Date(certificate.claimedAt).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }) : "Registry timestamp pending";
  const ceremonyMode = claim && claim.ceremonyMode ? claim.ceremonyMode : "dispatch";
  const isStarterCeremony = ceremonyMode === "starter" || ownership && ownership.ownershipClass === "starter";
  const ceremonyLabel = isStarterCeremony ? "Certificate Acquired" : "License Grant Ceremony";
  const ceremonyTitle = isStarterCeremony ? "STARTER DEED REGISTERED" : "Claim Accepted";
  const ceremonyStamp = isStarterCeremony ? "FOUNDING STARTER" : "OWNERSHIP CLAIMED";
  const ceremonyCopy = isStarterCeremony
    ? "Command Channel: founding claim confirmed. " + (mech ? mech.id : "This Meka") + " is now registered as the organization's first starter unit."
    : "Command Channel: Registry claim confirmed. " + (mech ? mech.id : "This Meka") + " is now secured in the organization roster.";
  const continueLabel = isStarterCeremony ? "CONTINUE SETUP" : "CONTINUE ARCHIVE";
  useEffect(() => {
    setActionsReady(false);
    const prefersReduced = typeof window !== "undefined" && window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const readyTimer = window.setTimeout(() => setActionsReady(true), prefersReduced ? 0 : 4000);
    const focusTimer = window.setTimeout(() => {
      if (titleRef.current) titleRef.current.focus();
    }, prefersReduced ? 0 : 320);
    return () => {
      window.clearTimeout(readyTimer);
      window.clearTimeout(focusTimer);
    };
  }, [ownership && ownership.id]);
  if (!ownership || !mech) return null;
  return (
    <div className={"registry-claim-ceremony" + (isStarterCeremony ? " is-starter-certificate" : "")} role="status" aria-live="polite" aria-label={isStarterCeremony ? "Certificate Acquired Ceremony" : "Registry Claim Ceremony"}>
      <div className="registry-claim-stage">
        <div className="registry-claim-meka">
          <HangarPreviewImage mech={mech} alt={mech.codename + " claimed Meka"} />
          <div className="registry-claimed-stamp" aria-hidden="true">{ceremonyStamp}</div>
        </div>
        <div className="registry-claim-certificate">
          <span>{ceremonyLabel}</span>
          <h2 ref={titleRef} tabIndex="-1">{ceremonyTitle}</h2>
          <div className="registry-organization-crest" aria-label={organizationName + " crest"}>
            {organization ? <img src={getOrganizationPreviewSource(organization)} alt="" /> : <b>{organizationName.slice(0, 2).toUpperCase()}</b>}
            <em>{organizationName}</em>
          </div>
          <p>{ceremonyCopy}</p>
          <div className="registry-license-id">
            <span>License ID</span>
            <b>{ownership.ownershipSerial}</b>
          </div>
          <div className="registry-artifact-grid">
            <div><span>Certificate</span><b>{certificate.title}</b></div>
            <div><span>Dispatch Seal</span><b>{artifacts.dispatchSeal && artifacts.dispatchSeal.code}</b></div>
            <div><span>Chronicle</span><b>{artifacts.archiveChronicleEntry && artifacts.archiveChronicleEntry.code}</b></div>
            <div><span>Claim Date</span><b>{claimDate}</b></div>
          </div>
          <div className="registry-claim-actions">
            <button type="button" className="btn primary" onClick={onViewHangar} disabled={!actionsReady}>VIEW IN HANGAR</button>
            <button type="button" className="btn" onClick={() => onOpenCertificate(ownership.id)} disabled={!actionsReady}>VIEW CERTIFICATE</button>
            <button type="button" className="btn" onClick={onContinueArchive} disabled={!actionsReady}>{continueLabel}</button>
            <button type="button" className="registry-skip-ceremony" onClick={onClose}>SKIP CEREMONY</button>
          </div>
        </div>
      </div>
    </div>
  );
}

function OwnershipCertificateView({ ownershipId, onClose, embedded = false, backLabel, fallbackCertificate }) {
  const [state, setState] = useState({ status: "loading", data: null, error: "" });
  useEffect(() => {
    let cancelled = false;
    async function loadCertificate() {
      try {
        const result = await publicApi("/ownerships/" + encodeURIComponent(ownershipId));
        if (!cancelled) setState({ status: "ready", data: result, error: "" });
      } catch (error) {
        if (!cancelled) setState({ status: "error", data: null, error: (error.message || "CERTIFICATE UNAVAILABLE").toUpperCase() });
      }
    }
    loadCertificate();
    return () => { cancelled = true; };
  }, [ownershipId]);
  const certificate = state.data && state.data.certificate ? state.data.certificate : null;
  const payload = certificate && certificate.ownershipCertificate ? certificate.ownershipCertificate : null;
  const mech = payload ? findMechById(payload.mechId) : null;
  const dispatchCode = payload && payload.dispatchCode
    ? payload.dispatchCode
    : (certificate && certificate.dispatchSeal && certificate.dispatchSeal.code ? certificate.dispatchSeal.code : "ARCHIVE SEAL");
  const sealCopy = getOwnershipCertificateSealCopy(dispatchCode);
  const claimDate = payload && payload.claimedAt
    ? new Date(payload.claimedAt).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" })
    : "Timestamp pending";
  const fallbackTitle = fallbackCertificate && fallbackCertificate.title ? fallbackCertificate.title : "Certificate";
  const fallbackSerial = fallbackCertificate && fallbackCertificate.serial ? fallbackCertificate.serial : "";
  return (
    <div
      className={"ownership-certificate-view" + (embedded ? " is-embedded" : "")}
      role={embedded ? "region" : "dialog"}
      aria-modal={embedded ? undefined : "true"}
      aria-label="Ownership Certificate"
    >
      <div className="ownership-certificate-panel">
        <div className="ownership-certificate-guilloche" aria-hidden="true"></div>
        {mech && (
          <div className="ownership-certificate-watermark" aria-hidden="true">
            <HangarPreviewImage mech={mech} alt="" />
          </div>
        )}
        {!embedded && (
          <button type="button" className="back" onClick={onClose}>{backLabel || "BACK TO HANGAR"}</button>
        )}
        {payload ? (
          <>
            <div className="ownership-certificate-topline">
              <span>Ownership Certificate</span>
              <b>{dispatchCode}</b>
            </div>
            <div className="ownership-certificate-body">
              <div className="ownership-certificate-copy">
                <span>Registered Meka Deed</span>
                <h2>{payload.mechId} / {payload.codename}</h2>
                <p>{payload.organizationName}</p>
                <div className="ownership-certificate-license">
                  <span>License ID</span>
                  <b>{payload.licenseId}</b>
                </div>
              </div>
              <div className="ownership-certificate-illustration">
                <div className="ownership-certificate-silhouette" aria-hidden="true"></div>
                {mech && <HangarPreviewImage mech={mech} alt={payload.codename + " certificate illustration"} />}
                <div className="ownership-certificate-medallion" aria-label={"Verified dispatch claim seal " + dispatchCode}>
                  <span>{sealCopy.kicker}</span>
                  <b>{sealCopy.mark}</b>
                  <em>{sealCopy.detail}</em>
                </div>
              </div>
            </div>
            <div className="ownership-certificate-artifacts">
              <div><span>Registered To</span><b>{payload.organizationName}</b></div>
              <div><span>Claim Date</span><b>{claimDate}</b></div>
              <div><span>Dispatch Seal</span><b>{dispatchCode}</b></div>
              <div><span>Certificate Class</span><b>{payload.title || "Ownership Certificate"}</b></div>
            </div>
            <div className="ownership-certificate-seal">
              <b>{certificate.dispatchSeal && certificate.dispatchSeal.code}</b>
              <span>{certificate.archiveChronicleEntry && certificate.archiveChronicleEntry.text}</span>
            </div>
          </>
        ) : (
          <div className="ownership-certificate-loading">
            <span>{state.status === "loading" ? "Registry Seal Opening" : "Certificate Unavailable"}</span>
            <h2>{fallbackTitle}</h2>
            <p>{state.status === "loading" ? "Confirming certificate ledger..." : state.error}</p>
            {fallbackSerial && (
              <div className="ownership-certificate-license">
                <span>License ID</span>
                <b>{fallbackSerial}</b>
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  );
}

function archiveDispatchIsUnlockedForIndex(account, onboardingStatus) {
  return Boolean(account && account.status === "signed-in" && phaseOneDirectivesAreClear(onboardingStatus && onboardingStatus.data));
}

function archiveDispatchHasPublicEntries(archiveDispatchStatus) {
  const { dispatch, entries } = getArchiveDispatchBundle(archiveDispatchStatus);
  return Boolean(dispatch && entries.length);
}

function ArchiveSection({ onOpen, engagement, engagementDispatch, account, registry, onboardingStatus, archiveDispatchStatus, onDispatchDirectiveCompleted }) {
  const [filter, setFilter] = useState("all");
  const [view, setView] = useState("grid");
  const [query, setQuery] = useState("");
  const [batchSize, setBatchSize] = useState(() => getArchiveBatchSize());
  const [visibleCount, setVisibleCount] = useState(() => getArchiveBatchSize());
  const loadMoreRef = useRef(null);
  const archiveRoster = STARTER_PREVIEW_ROSTER;

  const filtered = useMemo(() => {
    return archiveRoster.filter((m) => {
      if (filter !== "all" && m.family !== filter) return false;
      if (query) {
        const q = query.toLowerCase();
        if (!(m.codename.toLowerCase().includes(q) || m.id.toLowerCase().includes(q) || (m.tags || []).join(" ").toLowerCase().includes(q))) return false;
      }
      return true;
    });
  }, [archiveRoster, filter, query]);

  const visible = useMemo(() => filtered.slice(0, visibleCount), [filtered, visibleCount]);
  const hasMore = visible.length < filtered.length;

  useEffect(() => {
    if (typeof window === "undefined" || !window.matchMedia) return;
    const queryList = window.matchMedia(ARCHIVE_MOBILE_QUERY);
    const updateBatch = () => setBatchSize(queryList.matches ? 3 : 9);
    updateBatch();
    if (queryList.addEventListener) {
      queryList.addEventListener("change", updateBatch);
      return () => queryList.removeEventListener("change", updateBatch);
    }
    queryList.addListener(updateBatch);
    return () => queryList.removeListener(updateBatch);
  }, []);

  useEffect(() => {
    setVisibleCount(batchSize);
  }, [filter, query, batchSize]);

  useEffect(() => {
    if (!hasMore || typeof window === "undefined" || !window.IntersectionObserver) return;
    const node = loadMoreRef.current;
    if (!node) return;
    const observer = new IntersectionObserver(([entry]) => {
      if (!entry.isIntersecting) return;
      setVisibleCount((count) => Math.min(count + batchSize, filtered.length));
    }, { root: null, rootMargin: "600px 0px", threshold: 0 });
    observer.observe(node);
    return () => observer.disconnect();
  }, [hasMore, batchSize, filtered.length]);

  const counts = useMemo(() => {
    const c = { all: archiveRoster.length };
    FAMILIES.forEach((f) => { if (f.id !== "all") c[f.id] = archiveRoster.filter(m => m.family === f.id).length; });
    return c;
  }, [archiveRoster]);

  const resultCopy = hasMore
    ? "LOADED " + visible.length + " / " + filtered.length + " MATCHES"
    : (filtered.length === archiveRoster.length ? "SHOWING ALL " + filtered.length + " STARTERS" : "SHOWING " + filtered.length + " OF " + archiveRoster.length);
  const showArchiveDispatchDock = archiveDispatchHasPublicEntries(archiveDispatchStatus);

  return (
    <section id="archive" className="section" data-screen-label="Archive">
      <div className="section-inner">
        <div className="section-head">
          <div>
            <div className="label">SECTION · 03 / THE INDEX</div>
            <h2>The Index</h2>
          </div>
          <div className="right">
            {resultCopy}
          </div>
        </div>

        {showArchiveDispatchDock && <ArchiveDispatchDock account={account} archiveDispatchStatus={archiveDispatchStatus} onOpen={onOpen} onDispatchDirectiveCompleted={onDispatchDirectiveCompleted} />}

        <section className="starter-unit-index" aria-label="Starter Unit List">
          <div className="starter-unit-index-head">
            <div>
              <span>Starter Unit List</span>
              <h3>Founding Starter Archive</h3>
              <p>Starter-eligible MK units only. Weekly Archive Dispatch targets stay rare and never return to the founding pool.</p>
            </div>
            <b>{String(filtered.length).padStart(2, "0")} / {String(archiveRoster.length).padStart(2, "0")} MATCHES</b>
          </div>

        <div className="filters">
          <span className="ftitle">FILTER ·</span>
          {FAMILIES.map((f) => (
            <button key={f.id} className={"chip " + (filter === f.id ? "active" : "")} onClick={() => setFilter(f.id)}>
              {f.label}{counts[f.id] != null && <span className="count">[{counts[f.id]}]</span>}
            </button>
          ))}
          <input
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            placeholder="SEARCH ID / CODENAME / TAG"
            className="chip"
            style={{ width: 240, color: "var(--text)" }}
          />
          <div className="view-toggle">
            <button className={"chip " + (view === "grid" ? "active" : "")} onClick={() => setView("grid")}>▦ GRID</button>
            <button className={"chip " + (view === "list" ? "active" : "")} onClick={() => setView("list")}>≡ LIST</button>
          </div>
        </div>

        {filtered.length === 0 ? (
          <div style={{ padding: "48px 0", textAlign: "center", fontFamily: "JetBrains Mono, monospace", color: "var(--muted)", letterSpacing: "0.18em", fontSize: 12 }}>
            NO STARTER UNITS MATCH THIS QUERY · CLEAR FILTERS
          </div>
        ) : (
          <React.Fragment>
            <div className={"archive-grid " + (view === "list" ? "list" : "")}>
              {visible.map((m, i) => (
                <ArchiveCard
                  key={m.id}
                  mech={m}
                  index={i}
                  onOpen={onOpen}
                  engagement={engagement}
                  engagementDispatch={engagementDispatch}
                  account={account}
                  registry={registry}
                />
              ))}
            </div>
            {hasMore && (
              <div className="archive-load-sentinel" ref={loadMoreRef}>
                <button
                  type="button"
                  className="archive-load-trigger"
                  onClick={() => setVisibleCount((count) => Math.min(count + batchSize, filtered.length))}
                >
                  LOAD NEXT BATCH / {visible.length}/{filtered.length}
                </button>
              </div>
            )}
          </React.Fragment>
        )}
        </section>
      </div>
    </section>
  );
}

function ArchiveCard({ mech, index, onOpen, engagement, engagementDispatch, account, registry }) {
  const href = "#mech/" + mech.id;
  const dossier = getDossierStatus(mech);
  const ownership = getOwnershipEntryForMech(mech, registry, account);
  const ownedByYou = ownership && ownership.state === "owned-by-you";
  const handleClick = (event) => {
    if (
      event.defaultPrevented ||
      event.button !== 0 ||
      event.metaKey ||
      event.ctrlKey ||
      event.shiftKey ||
      event.altKey
    ) {
      return;
    }
    event.preventDefault();
    onOpen(mech.id);
  };

  return (
    <article className={"card " + (ownedByYou ? "is-owned" : "")}>
      <a className="card-link" href={href} onClick={handleClick} aria-label={"Open " + mech.id + " " + mech.codename + " entry"}>
      <div className="card-head">
        <span className="designation">{mech.id}</span>
        <span>{mech.date}</span>
      </div>
      <div className="card-img">
        <span className="card-tag-corner">{mech.series}</span>
        <OwnershipBadge mech={mech} registry={registry} account={account} compact />
        <img src={versionAssetUrl(mech.fullbody || mech.image)} alt={mech.codename + " full body"} loading="lazy" />
      </div>
      <div className="card-body">
        <div className="card-name">{mech.codename}</div>
        <div className="card-meta">
          <span>{mech.height} · {mech.series}</span>
          <span>#{String(index + 1).padStart(2, "0")}</span>
        </div>
        <div className="card-palette">
          {mech.palette.slice(0, 5).map((c, i) => <span key={i} style={{ background: c }}></span>)}
        </div>
      </div>
      </a>
      <div className="card-foot">
        <div className="card-foot-status">
          <span className={"card-stl-pill " + (mech.stl ? "ready" : "")}>{mech.stl ? "● STL READY" : "○ STL PENDING"}</span>
          <span className="card-stl-pill ready">DOSSIER {dossier.complete}/{dossier.total}</span>
        </div>
        <span className="card-cta">VIEW SPEC</span>
      </div>
    </article>
  );
}

function Detail({ mechId, onClose, onNavigate, engagement, engagementDispatch, onCommsContext, account, registry, archiveDispatchStatus, onDispatchDirectiveCompleted }) {
  const idx = MEKABOTS_BY_ID.findIndex((m) => m.id === mechId);
  const mech = MEKABOTS_BY_ID[idx];
  const prev = MEKABOTS_BY_ID[(idx - 1 + MEKABOTS_BY_ID.length) % MEKABOTS_BY_ID.length];
  const next = MEKABOTS_BY_ID[(idx + 1) % MEKABOTS_BY_ID.length];
  const [lightboxIndex, setLightboxIndex] = useState(null);
  const [modelMode, setModelMode] = useState("fullbody");

  const lightboxItems = useMemo(() => {
    if (!mech) return [];
    return [
      {
        slot: "fullbody",
        label: "01 / FULL-BODY",
        meta: "FRAME · CHASSIS · " + mech.codename,
        src: versionAssetUrl(mech.fullbody),
        alt: mech.codename + " full body"
      },
      {
        slot: "head",
        label: "02 / HEAD",
        meta: "SCULPT · " + mech.height,
        src: versionAssetUrl(mech.image),
        alt: mech.codename + " head sculpt"
      },
      {
        slot: "pilot",
        label: "03 / PILOT",
        meta: mech.pilot ? "CALLSIGN · " + mech.pilot.callsign : "UNASSIGNED",
        src: versionAssetUrl(mech.pilotImage),
        alt: mech.pilot ? mech.pilot.name : mech.codename + " pilot"
      },
      {
        slot: "bond",
        label: "04 / BOND RECORD",
        meta: mech.epicBondRecord ? mech.epicBondRecord.kicker : "",
        src: mech.epicBondRecord ? versionAssetUrl(mech.epicBondRecord.image) : null,
        alt: mech.epicBondRecord ? mech.id + " " + mech.codename + " bond record scene" : ""
      }
    ].filter((item) => item.src);
  }, [mech]);

  const openLightbox = (slot) => {
    const target = lightboxItems.findIndex((item) => item.slot === slot);
    if (target >= 0) {
      engagementDispatch({ type: "DOSSIER_SECTION_VIEWED", mechId: mech.id, section: slot });
      setLightboxIndex(target);
    }
  };

  const modelOptions = useMemo(() => {
    if (!mech) return [];
    const options = [];
    if (mech.fullbodyModel) {
      const fullbodyDownloadUrl = mech.fullbodyDownloadModel || mech.fullbodyModel;
      const fullbodyDownloadExt = getAssetExtension(fullbodyDownloadUrl, "glb");
      options.push({
        id: "fullbody",
        label: "FULLBODY",
        kind: "glb",
        url: versionAssetUrl(mech.fullbodyModel),
        downloadUrl: versionAssetUrl(fullbodyDownloadUrl),
        downloadName: mech.id + "_" + mech.codename.replace(/\s+/g, "_") + "_FULLBODY." + fullbodyDownloadExt
      });
    }
    if (mech.stl) {
      options.push({
        id: "head",
        label: "HEAD",
        kind: "stl",
        url: versionAssetUrl(mech.stl),
        downloadUrl: versionAssetUrl(mech.stl),
        downloadName: mech.id + "_" + mech.codename.replace(/\s+/g, "_") + "_HEAD.stl"
      });
    }
    return options;
  }, [mech]);

  useEffect(() => {
    if (!mech) return;
    setModelMode(mech.fullbodyModel ? "fullbody" : (mech.stl ? "head" : "placeholder"));
  }, [mechId]);

  useEffect(() => {
    if (!mech) return;
    engagementDispatch({ type: "DOSSIER_OPENED", mechId: mech.id });
  }, [mechId]);

  useEffect(() => {
    if (!mech || !archiveDispatchStatus || typeof archiveDispatchStatus.recordDispatchDirective !== "function") return;
    const data = archiveDispatchStatus.data || null;
    const progress = data && data.organizationProgress ? data.organizationProgress : null;
    if (!progress || progress.activeTargetMechId !== mech.id) return;
    void archiveDispatchStatus.recordDispatchDirective("inspect_target_dossier", "complete")
      .then((result) => {
        if (result && onDispatchDirectiveCompleted) onDispatchDirectiveCompleted("inspect_target_dossier", result);
        return archiveDispatchStatus.recordDispatchDirective("review_combat_profile", "complete");
      })
      .then((result) => {
        if (result && onDispatchDirectiveCompleted) onDispatchDirectiveCompleted("review_combat_profile", result);
      })
      .catch(() => null);
  }, [mechId, archiveDispatchStatus && archiveDispatchStatus.data && archiveDispatchStatus.data.organizationProgress && archiveDispatchStatus.data.organizationProgress.activeTargetMechId]);

  useEffect(() => {
    if (!mech) return undefined;
    document.body.style.overflow = "hidden";
    const root = document.querySelector(".detail-scroll");
    if (root) root.scrollTop = 0;
    const onKey = (e) => {
      if (lightboxIndex !== null) return;
      if (e.key === "Escape") onClose();
      if (e.key === "ArrowLeft") onNavigate(prev.id);
      if (e.key === "ArrowRight") onNavigate(next.id);
    };
    window.addEventListener("keydown", onKey);
    return () => {
      document.body.style.overflow = "";
      window.removeEventListener("keydown", onKey);
    };
  }, [mechId, lightboxIndex]);

  if (!mech) return null;

  const selectedModel = modelOptions.find((option) => option.id === modelMode) || modelOptions[0] || {
    id: "placeholder",
    label: "PROCEDURAL",
    kind: "placeholder",
    url: null,
    downloadUrl: null,
    downloadName: null
  };
  const primaryDownloadRawUrl = mech.fullbodyDownloadModel || mech.stl;
  const primaryDownloadUrl = versionAssetUrl(primaryDownloadRawUrl);
  const primaryDownloadExt = getAssetExtension(primaryDownloadRawUrl, "stl");
  const primaryDownloadReady = Boolean(primaryDownloadRawUrl);
  const primaryDownloadName = primaryDownloadReady
    ? mech.id + "_" + mech.codename.replace(/\s+/g, "_") + (mech.fullbodyDownloadModel ? "_FULLBODY" : "") + "." + primaryDownloadExt
    : undefined;
  const primaryDownloadLabel = (mech.fullbodyDownloadModel ? "PRINT " : "") + primaryDownloadExt.toUpperCase();
  const dossier = mech ? getDossierStatus(mech) : { complete: 0, total: DOSSIER_ITEMS.length, items: [] };
  const ownership = getOwnershipEntryForMech(mech, registry, account);
  const ownedByYou = ownership && ownership.state === "owned-by-you";

  return (
    <div className="detail" data-screen-label={"Detail · " + mech.id}>
      <div className="detail-top">
        <button className="back" onClick={onClose}>← BACK TO ARCHIVE</button>
        <div className="detail-count">
          {String(idx + 1).padStart(2, "0")} / {String(MEKABOTS_BY_ID.length).padStart(2, "0")} · ENTRY DETAIL
        </div>
        <div className="nav-prev-next">
          <button onClick={() => onNavigate(prev.id)}>← {prev.id}</button>
          <button onClick={() => onNavigate(next.id)}>{next.id} →</button>
        </div>
      </div>

      <div className="detail-scroll">

        {/* ── Movie-poster hero ── */}
        <section className="detail-hero">
          {/* Featured full-body — full-width, dominant */}
          <div className="trio-featured">
            <div className="trio-label">
              <span>01 / FULL-BODY</span>
              <span>FRAME · CHASSIS · {mech.codename}</span>
            </div>
            <div className={"concept-frame trio-frame-feature ar-169 " + (mech.fullbody ? "" : "is-empty")}>
              <ConceptCorners />
              <div className="concept-readout tl">
                <div>{mech.id} · UNIT RENDER</div>
                <div style={{ color: "var(--accent)" }}>FRAME &amp; CHASSIS · ORTHO</div>
              </div>
              <div className="concept-readout tr">
                <div>{mech.series}</div>
                <div>{mech.date}</div>
              </div>
              {mech.fullbody ? (
                <button
                  type="button"
                  className="concept-zoom-trigger"
                  onClick={() => openLightbox("fullbody")}
                  aria-label={"Open " + mech.codename + " full body image fullscreen"}
                >
                  <img src={versionAssetUrl(mech.fullbody)} alt={mech.codename + " full body"} loading="eager" decoding="async" />
                  <span>ZOOM</span>
                </button>
              ) : (
                <div className="concept-placeholder">
                  <div className="cp-glyph">▢</div>
                  <div className="cp-line">FULL-BODY CONCEPT</div>
                  <div className="cp-sub">DATA.JS → fullbody</div>
                </div>
              )}
              <div className="concept-readout bl">{mech.codename} · FRAME PROFILE</div>
              <div className="concept-readout br">★ AI-GENERATED · TAILORED PROMPT</div>
            </div>
          </div>

          {/* Head + Pilot row */}
          <div className="trio-row">
            <div className="trio-cell">
              <div className="trio-label">
                <span>02 / HEAD</span>
                <span>SCULPT · {mech.height}</span>
              </div>
              <div className="concept-frame trio-frame ar-32">
                <ConceptCorners />
                <div className="concept-readout tl"><div>{mech.id}</div></div>
                <button
                  type="button"
                  className="concept-zoom-trigger"
                  onClick={() => openLightbox("head")}
                  aria-label={"Open " + mech.codename + " head sculpt image fullscreen"}
                >
                  <img src={versionAssetUrl(mech.image)} alt={mech.codename + " head sculpt"} loading="lazy" decoding="async" />
                  <span>ZOOM</span>
                </button>
                <div className="concept-readout br">SCALE 1:1</div>
              </div>
            </div>

            <div className="trio-cell">
              <div className="trio-label">
                <span>03 / PILOT</span>
                <span>{mech.pilot ? "CALLSIGN · " + mech.pilot.callsign : "UNASSIGNED"}</span>
              </div>
              <div className={"concept-frame trio-frame ar-169 tint-alert " + (mech.pilotImage ? "" : "is-empty")}>
                <ConceptCorners />
                <div className="concept-readout tl"><div>{mech.pilot ? mech.pilot.name : "—"}</div></div>
                {mech.pilotImage ? (
                  <button
                    type="button"
                    className="concept-zoom-trigger"
                    onClick={() => openLightbox("pilot")}
                    aria-label={"Open " + (mech.pilot ? mech.pilot.name : mech.codename + " pilot") + " image fullscreen"}
                  >
                    <img src={versionAssetUrl(mech.pilotImage)} alt={mech.pilot ? mech.pilot.name : mech.codename + " pilot"} loading="lazy" decoding="async" />
                    <span>ZOOM</span>
                  </button>
                ) : (
                  <div className="concept-placeholder">
                    <div className="cp-glyph">▢</div>
                    <div className="cp-line">PILOT</div>
                    <div className="cp-sub">DATA.JS → pilotImage</div>
                  </div>
                )}
                <div className="concept-readout br">CLASSIFIED</div>
              </div>
            </div>
          </div>

          <div className="detail-hero-bar">
            <div>
              <div className="detail-designation">DESIGNATION · {mech.id}</div>
              <h1 className="detail-name">{mech.codename}</h1>
            </div>
            <div className="detail-tag-row">
              <span className="series">{mech.series}</span>
              <span className="date">{mech.date}</span>
              <OwnershipBadge mech={mech} registry={registry} account={account} />
              {mech.tags.map((t) => <span key={t}>#{t}</span>)}
            </div>
            <div className="detail-local-actions">
              {ownedByYou && <span className="detail-owned-note">OWNED STARTER</span>}
              <button
                type="button"
                className="btn compact"
                onClick={() => onCommsContext(mech)}
              >
                COMMS ABOUT UNIT
              </button>
            </div>
          </div>
        </section>

        {/* ── Pilot dossier — paired with pilot concept in the hero ── */}
        {mech.epicBondRecord && mech.epicBondRecord.image && (
          <EpicBondRecord
            mech={mech}
            record={mech.epicBondRecord}
            onOpen={() => openLightbox("bond")}
          />
        )}

        {mech.pilot && (
          <section className="detail-section">
            <div className="pilot-block">
              <div className="pilot-stamp">PILOT<br/>FILE<br/>{mech.id}</div>
              <div className="pilot-grid">
                <div className="pilot-info">
                  <div className="callsign-row">{mech.pilot.callsign}</div>
                  <div className="pilot-name">{mech.pilot.name}</div>
                  <div className="pilot-line">
                    <span>AGE · <b>{mech.pilot.age}</b></span>
                    <span>ORIGIN · <b>{mech.pilot.origin}</b></span>
                  </div>
                  <div className="pilot-line">
                    <span>FACTION · <b>{mech.pilot.faction}</b></span>
                  </div>
                  <div className="pilot-stats">
                    <div>
                      <div className="k">Sync Rating</div>
                      <div className="v">{mech.pilot.sync}%</div>
                      <div className="sync-bar"><i style={{ width: mech.pilot.sync + "%" }}></i></div>
                    </div>
                    <div>
                      <div className="k">Missions Logged</div>
                      <div className="v">{mech.pilot.missions}</div>
                      <div className="vsmall">CONFIRMED SORTIES</div>
                    </div>
                  </div>
                  <div className="pilot-bio">{mech.pilot.bio}</div>
                </div>
              </div>
            </div>
          </section>
        )}

        {/* ── Brief + specs + palette + actions ── */}
        <section className="detail-section detail-info-row">
          <div className="detail-info-left">
            <div className="lore-section-label" style={{ color: "var(--muted)" }}>OVERVIEW</div>
            <p className="detail-brief">{mech.brief}</p>
          </div>

          <div className="detail-info-right">
            <div className="detail-specs">
              <div className="spec"><div className="k">Height</div><div className="v">{mech.height}</div></div>
              <div className="spec"><div className="k">Family</div><div className="v">{(FAMILIES.find(f => f.id === mech.family) || {}).label || mech.family}</div></div>
              <div className="spec"><div className="k">STL Status</div><div className="v" style={{ color: primaryDownloadReady ? "var(--ok)" : "var(--muted)" }}>{primaryDownloadReady ? "READY" : "PENDING"}</div></div>
              <div className="spec"><div className="k">Series</div><div className="v">{mech.series}</div></div>
            </div>

            <div className="detail-combat-profile">
              <CombatProfilePanel mech={mech} />
            </div>

            <div className="dossier-status">
              <div className="dossier-status-head">
                <span>DOSSIER STATUS</span>
                <b>{dossier.complete}/{dossier.total}</b>
              </div>
              <div className="dossier-status-grid">
                {dossier.items.map((item) => (
                  <span key={item.id} className={item.complete ? "complete" : ""}>
                    {item.complete ? "READY" : "PENDING"} / {item.label}
                  </span>
                ))}
              </div>
            </div>

            <div className="detail-palette">
              <div className="ftitle">COLORWAY · {mech.palette.length} CH</div>
              <div className="detail-palette-row">
                {mech.palette.map((c, i) => (
                  <div className="swatch" key={i}>
                    <span className="chip" style={{ background: c }}></span>
                    <div className="lab">{c.toUpperCase()}</div>
                  </div>
                ))}
              </div>
            </div>

            <div className="detail-actions">
              <a className={"btn " + (primaryDownloadReady ? "primary" : "")} href={primaryDownloadUrl || undefined}
                 download={primaryDownloadName}
                 onClick={(e) => { if (!primaryDownloadReady) e.preventDefault(); }}
                 style={!primaryDownloadReady ? { opacity: 0.5, cursor: "not-allowed" } : {}}>
                ↓ DOWNLOAD {primaryDownloadLabel} {!primaryDownloadReady && "(pending)"}
              </a>
              <button type="button" className="btn" onClick={() => onCommsContext(mech)}>COMMS ABOUT UNIT</button>
              <button className="btn">⎘ SHARE</button>
            </div>
          </div>
        </section>

        {/* ── 3D Viewer — 16:9 ── */}
        <section className="detail-section">
          <div className="detail-section-head">
            <div>
              <div className="lore-section-label">3D · MODEL VIEWER</div>
              <h2 className="lore-heading">Orbit The Unit</h2>
            </div>
            <div className="detail-section-side model-switch-panel">
              <div className="model-switch" role="group" aria-label="3D model selector">
                {modelOptions.length ? modelOptions.map((option) => (
                  <button
                    type="button"
                    key={option.id}
                    className={modelMode === option.id ? "active" : ""}
                    onClick={() => {
                      engagementDispatch({ type: "DOSSIER_SECTION_VIEWED", mechId: mech.id, section: "model" });
                      setModelMode(option.id);
                    }}
                  >
                    {option.label}
                  </button>
                )) : (
                  <span>NO MODEL ATTACHED</span>
                )}
              </div>
              <div>DRAG · ORBIT  /  WHEEL · ZOOM</div>
            </div>
          </div>
          <div className="concept-frame viewer-frame">
            <DeferredMekaViewer mech={mech} model={selectedModel} />
          </div>
        </section>

        {/* ── Lore ── */}
        {mech.lore && (
          <section className="detail-section">
            <div className="lore-block">
              <div className="lore-section-label">CHAPTER 01 · UNIT LORE</div>
              <h2 className="lore-heading">{mech.lore.classification}</h2>
              <div className="lore-meta">
                <div>
                  <div className="k">Origin</div>
                  <div className="v">{mech.lore.origin}</div>
                </div>
                <div>
                  <div className="k">First Activation</div>
                  <div className="v">{mech.lore.activated}</div>
                </div>
                <div>
                  <div className="k">Unit ID</div>
                  <div className="v">{mech.id} · {mech.codename}</div>
                </div>
              </div>
              <p className="lore-text">{mech.lore.text}</p>
              {mech.lore.armaments && mech.lore.armaments.length > 0 && (
                <div className="lore-arms">
                  <div className="label">★ NOTABLE FEATURES · {mech.lore.armaments.length} ENTRIES</div>
                  <ul>
                    {mech.lore.armaments.map((a, i) => <li key={i}>{a}</li>)}
                  </ul>
                </div>
              )}
            </div>
          </section>
        )}

        {/* ── Pilot dossier moved up — see top of detail ── */}

        <div className="detail-end-rule">
          <span>★ END OF FILE · {mech.id} · {mech.codename} ★</span>
        </div>
      </div>

      {lightboxIndex !== null && (
        <ImageLightbox
          mech={mech}
          items={lightboxItems}
          index={lightboxIndex}
          onIndexChange={setLightboxIndex}
          onClose={() => setLightboxIndex(null)}
        />
      )}
    </div>
  );
}

function DeferredMekaViewer({ mech, model }) {
  const gateRef = useRef(null);
  const activationTimerRef = useRef(null);
  const [shouldMount, setShouldMount] = useState(false);
  const [activating, setActivating] = useState(false);
  const [mobileManual, setMobileManual] = useState(false);
  const modelKey = [
    mech.id,
    model?.id || "placeholder",
    model?.url || "none"
  ].join("|");

  useEffect(() => {
    setShouldMount(false);
    setActivating(false);
    if (activationTimerRef.current) window.clearTimeout(activationTimerRef.current);
    const isMobileLike = typeof window !== "undefined"
      && window.matchMedia
      && window.matchMedia("(max-width: 720px), (pointer: coarse)").matches;
    setMobileManual(Boolean(isMobileLike));
    return () => {
      if (activationTimerRef.current) window.clearTimeout(activationTimerRef.current);
    };
  }, [modelKey]);

  const queueViewerMount = () => {
    if (shouldMount || activating) return;
    setActivating(true);
    if (typeof window === "undefined") {
      setShouldMount(true);
      return;
    }
    window.requestAnimationFrame(() => {
      activationTimerRef.current = window.setTimeout(() => {
        setShouldMount(true);
      }, 80);
    });
  };

  useEffect(() => {
    if (shouldMount || mobileManual) return;
    const node = gateRef.current;
    if (!node) return;
    if (typeof window === "undefined" || !window.IntersectionObserver) {
      setShouldMount(true);
      return;
    }
    const observer = new IntersectionObserver(([entry]) => {
      if (!entry.isIntersecting) return;
      queueViewerMount();
      observer.disconnect();
    }, { root: null, rootMargin: "180px 0px", threshold: 0.01 });
    observer.observe(node);
    return () => observer.disconnect();
  }, [shouldMount, mobileManual, modelKey]);

  if (shouldMount) {
    return <MekaViewer key={modelKey} mech={mech} model={model} />;
  }

  return (
    <div className="viewer-deferred" ref={gateRef}>
      <div className="viewer-deferred-card">
        <div className="viewer-deferred-mark">3D</div>
        <div><b>MODEL PREVIEW STANDBY</b></div>
        <div className="viewer-deferred-copy">
          {activating
            ? "Preparing the viewport before the large model starts."
            : mobileManual
            ? "Tap to load the 3D viewer when you are ready to orbit."
            : "3D viewer loads when this section enters range."}
        </div>
        <button type="button" onClick={queueViewerMount} disabled={activating}>
          {activating ? "PREPARING..." : "LOAD 3D PREVIEW"}
        </button>
      </div>
    </div>
  );
}

function EpicBondRecord({ mech, record, onOpen }) {
  const metrics = [
    ["SCENE TYPE", record.type || "FIELD RECONSTRUCTION"],
    ["SOURCE", record.source || "UNIT TELEMETRY"],
    ["PILOT LINK", record.link || "CONFIRMED"],
    ["REFERENCED FEATURE", record.feature || mech.series]
  ];

  return (
    <section className="detail-section bond-record-section">
      <div className="detail-section-head bond-record-head">
        <div>
          <div className="lore-section-label">CHAPTER 02 / BOND RECORD</div>
          <h2 className="lore-heading">{record.title || mech.codename + " Sync Event"}</h2>
        </div>
        <div className="detail-section-side">{record.kicker || "FIELD RECONSTRUCTION / PILOT-UNIT LINK"}</div>
      </div>

      <div className="bond-record-grid">
        <div className="concept-frame bond-record-frame ar-169">
          <ConceptCorners />
          <div className="concept-readout tl"><div>{mech.id} / SCENE STILL</div></div>
          <div className="concept-readout tr"><div>{record.source || "FIELD RECONSTRUCTION"}</div></div>
          <button
            type="button"
            className="concept-zoom-trigger bond-record-trigger"
            onClick={onOpen}
            aria-label={"Open " + mech.id + " " + mech.codename + " bond record image fullscreen"}
          >
            <img src={versionAssetUrl(record.image)} alt={mech.id + " " + mech.codename + " bond record scene"} loading="lazy" decoding="async" />
            <span>ZOOM</span>
          </button>
          <div className="concept-readout bl">{mech.codename} / PILOT-UNIT LINK</div>
          <div className="concept-readout br">SYNC EVENT / ARCHIVED</div>
        </div>

        <div className="bond-record-copy">
          <div className="bond-record-kicker">{record.label || mech.id + " / " + mech.codename}</div>
          <p>{record.caption}</p>
          <div className="bond-record-metrics">
            {metrics.map(([label, value]) => (
              <div key={label}>
                <span>{label}</span>
                <b>{value}</b>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function ImageLightbox({ mech, items, index, onIndexChange, onClose }) {
  const stageRef = useRef(null);
  const gestureRef = useRef({
    pointers: new Map(),
    lastX: 0,
    lastY: 0,
    startX: 0,
    startY: 0,
    lastDistance: 0
  });
  const [scale, setScale] = useState(1);
  const [offset, setOffset] = useState({ x: 0, y: 0 });
  const active = items[index] || items[0];
  const canBrowse = items.length > 1;

  const clampScale = (value) => Math.max(1, Math.min(4, value));
  const resetView = () => {
    setScale(1);
    setOffset({ x: 0, y: 0 });
  };
  const goTo = (delta) => {
    if (!canBrowse) return;
    resetView();
    onIndexChange((index + delta + items.length) % items.length);
  };
  const zoomTo = (value) => {
    const nextScale = clampScale(value);
    setScale(nextScale);
    if (nextScale === 1) setOffset({ x: 0, y: 0 });
  };
  const distanceBetweenPointers = (pointers) => {
    const list = Array.from(pointers.values());
    if (list.length < 2) return 0;
    const dx = list[0].x - list[1].x;
    const dy = list[0].y - list[1].y;
    return Math.hypot(dx, dy);
  };

  useEffect(() => {
    resetView();
    if (stageRef.current) stageRef.current.focus();
  }, [index]);

  useEffect(() => {
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      if (e.key === "ArrowLeft") goTo(-1);
      if (e.key === "ArrowRight") goTo(1);
      if (e.key === "+" || e.key === "=") zoomTo(scale + 0.5);
      if (e.key === "-" || e.key === "_") zoomTo(scale - 0.5);
      if (e.key === "0") resetView();
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [index, scale, items.length]);

  if (!active) return null;

  const handleWheel = (e) => {
    e.preventDefault();
    zoomTo(scale + (e.deltaY < 0 ? 0.3 : -0.3));
  };

  const handlePointerDown = (e) => {
    e.currentTarget.setPointerCapture(e.pointerId);
    const pointers = gestureRef.current.pointers;
    pointers.set(e.pointerId, { x: e.clientX, y: e.clientY });
    gestureRef.current.lastX = e.clientX;
    gestureRef.current.lastY = e.clientY;
    gestureRef.current.startX = e.clientX;
    gestureRef.current.startY = e.clientY;
    if (pointers.size === 2) {
      gestureRef.current.lastDistance = distanceBetweenPointers(pointers);
    }
  };

  const handlePointerMove = (e) => {
    const state = gestureRef.current;
    const pointers = state.pointers;
    if (!pointers.has(e.pointerId)) return;
    pointers.set(e.pointerId, { x: e.clientX, y: e.clientY });

    if (pointers.size >= 2) {
      const nextDistance = distanceBetweenPointers(pointers);
      if (state.lastDistance > 0 && nextDistance > 0) {
        zoomTo(scale * (nextDistance / state.lastDistance));
      }
      state.lastDistance = nextDistance;
      return;
    }

    const dx = e.clientX - state.lastX;
    const dy = e.clientY - state.lastY;
    state.lastX = e.clientX;
    state.lastY = e.clientY;

    if (scale > 1) {
      setOffset((current) => ({ x: current.x + dx, y: current.y + dy }));
    }
  };

  const handlePointerEnd = (e) => {
    const state = gestureRef.current;
    const pointers = state.pointers;
    const dx = e.clientX - state.startX;
    const dy = e.clientY - state.startY;

    if (scale === 1 && Math.abs(dx) > 64 && Math.abs(dx) > Math.abs(dy) * 1.35) {
      goTo(dx < 0 ? 1 : -1);
    }

    pointers.delete(e.pointerId);
    state.lastDistance = distanceBetweenPointers(pointers);
    const remaining = Array.from(pointers.values())[0];
    if (remaining) {
      state.lastX = remaining.x;
      state.lastY = remaining.y;
      state.startX = remaining.x;
      state.startY = remaining.y;
    }
  };

  return (
    <div
      className="image-lightbox"
      role="dialog"
      aria-modal="true"
      aria-label={mech.id + " " + mech.codename + " image viewer"}
      tabIndex="-1"
      ref={stageRef}
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
    >
      <div className="image-lightbox-top">
        <div>
          <div className="image-lightbox-kicker">{mech.id} / {mech.codename}</div>
          <div className="image-lightbox-title">{active.label}</div>
        </div>
        <button type="button" className="image-lightbox-close" onClick={onClose} aria-label="Close image viewer">X</button>
      </div>

      <div
        className={"image-lightbox-stage " + (scale > 1 ? "is-zoomed" : "")}
        onWheel={handleWheel}
        onPointerDown={handlePointerDown}
        onPointerMove={handlePointerMove}
        onPointerUp={handlePointerEnd}
        onPointerCancel={handlePointerEnd}
        onDoubleClick={() => { scale > 1 ? resetView() : zoomTo(2.5); }}
      >
        {canBrowse && (
          <button type="button" className="image-lightbox-nav prev" onClick={() => goTo(-1)} aria-label="Previous image">&lt;</button>
        )}
        <img
          src={active.src}
          alt={active.alt}
          decoding="async"
          draggable="false"
          style={{ transform: "translate(" + offset.x + "px, " + offset.y + "px) scale(" + scale + ")" }}
        />
        {canBrowse && (
          <button type="button" className="image-lightbox-nav next" onClick={() => goTo(1)} aria-label="Next image">&gt;</button>
        )}
      </div>

      <div className="image-lightbox-bottom">
        <div className="image-lightbox-meta">
          <span>{active.meta}</span>
          <span>ZOOM {Math.round(scale * 100)}%</span>
        </div>
        <div className="image-lightbox-actions">
          <button type="button" onClick={() => zoomTo(scale - 0.5)} aria-label="Zoom out">-</button>
          <button type="button" onClick={resetView}>RESET</button>
          <button type="button" onClick={() => zoomTo(scale + 0.5)} aria-label="Zoom in">+</button>
        </div>
        <div className="image-lightbox-thumbs" aria-label="Image choices">
          {items.map((item, itemIndex) => (
            <button
              type="button"
              key={item.slot}
              className={itemIndex === index ? "active" : ""}
              onClick={() => onIndexChange(itemIndex)}
              aria-label={"View " + item.label}
            >
              <img src={item.src} alt="" loading="lazy" decoding="async" />
              <span>{item.label.replace(/^\d+\s\/\s/, "")}</span>
            </button>
          ))}
        </div>
      </div>
    </div>
  );
}

function ConceptCorners() {
  return (
    <React.Fragment>
      <i className="cf-c cf-tl"></i>
      <i className="cf-c cf-tr"></i>
      <i className="cf-c cf-bl"></i>
      <i className="cf-c cf-br"></i>
    </React.Fragment>
  );
}

function ConceptSlot({ image, alt, label, placeholder, placeholderSub, tint }) {
  return (
    <div className={"concept-frame " + (image ? "" : "is-empty ") + (tint === "alert" ? "tint-alert" : "")}>
      <ConceptCorners />
      <div className="concept-readout tl"><div>{label}</div></div>
      <div className="concept-readout tr"><div>16 : 9 · AI-GEN</div></div>
      {image ? (
        <img src={image} alt={alt} />
      ) : (
        <div className="concept-placeholder">
          <div className="cp-glyph">▢</div>
          <div className="cp-line">{placeholder}</div>
          <div className="cp-sub">{placeholderSub}</div>
        </div>
      )}
      <div className="concept-readout br">★ AI-GENERATED · TAILORED PROMPT</div>
    </div>
  );
}

function HangarPreviewImage({ mech, alt, className }) {
  const [fallback, setFallback] = useState(false);
  const preview = getHangarPreviewCandidate(mech);
  const useFallback = fallback || !preview;
  const source = useFallback ? versionAssetUrl(getHangarFallbackSource(mech)) : getHangarPreviewSource(mech);
  const modeClass = useFallback ? "is-fallback" : "is-preview";

  return (
    <img
      className={[className, modeClass].filter(Boolean).join(" ")}
      src={source}
      alt={alt || ""}
      loading="lazy"
      onError={() => {
        if (!useFallback && getHangarFallbackSource(mech)) setFallback(true);
      }}
    />
  );
}

function OwnershipBadge({ mech, registry, account, compact }) {
  const ownership = getOwnershipEntryForMech(mech, registry, account);
  if (!ownership) return null;
  return (
    <span className={"ownership-badge " + (compact ? "compact " : "") + ownership.state}>
      {ownership.label}
    </span>
  );
}

function getOrganizationEntryById(registry, organizationId) {
  const target = String(organizationId || "");
  const organizations = registry && registry.organizations ? registry.organizations : [];
  return organizations.find((entry) => {
    const organization = entry && entry.organization ? entry.organization : null;
    if (!organization) return false;
    return String(organization.id || organization.name) === target;
  }) || null;
}

function getOrganizationFoundedLabel(organization) {
  if (!organization || !organization.foundedAt) return "DRAFT";
  return new Date(organization.foundedAt).toLocaleDateString();
}

function getOrganizationLore(entry, starter) {
  const organization = entry && entry.organization ? entry.organization : {};
  const ownerName = entry && entry.owner ? entry.owner.username : "an unnamed operator";
  const starterName = starter ? starter.id + " " + starter.codename : "an unassigned starter frame";
  const motto = getOrganizationMottoText(organization);
  return [
    organization.name + " is registered under " + ownerName + " as a first-wave operator in the Super Mekabots archive.",
    "Its starter unit is " + starterName + ", anchoring the organization doctrine around a single accountable machine before future acquisition systems open.",
    "Public doctrine: " + motto
  ];
}

function getOrganizationStructuredLore(entry, starter) {
  const organization = entry && entry.organization ? entry.organization : {};
  const rawLore = organization.operatorLore && typeof organization.operatorLore === "object" ? organization.operatorLore : {};
  const fallbackLines = getOrganizationLore(entry, starter);
  const assistantName = organization.assistantName || "the assigned assistant";
  const doctrineLines = Array.isArray(rawLore.doctrineLines)
    ? rawLore.doctrineLines.filter(Boolean).slice(0, 3)
    : [];
  while (doctrineLines.length < 3 && fallbackLines[doctrineLines.length]) {
    doctrineLines.push(fallbackLines[doctrineLines.length]);
  }
  return {
    title: rawLore.title || "Public Doctrine",
    summary: rawLore.summary || fallbackLines[0] || "",
    doctrineLines,
    assistantLine: rawLore.assistantLine || (assistantName + " keeps the public command channel aligned with the crest, motto, and starter record.")
  };
}

function OrganizationDossier({ organizationId, registry, account, onClose, onOpenMech }) {
  const entry = getOrganizationEntryById(registry, organizationId);
  const organization = entry && entry.organization ? entry.organization : null;
  const starter = organization ? findMechById(organization.starterMechId) : null;
  const isMine = Boolean(account && account.organization && organization && account.organization.id === organization.id);
  const lore = entry ? getOrganizationStructuredLore(entry, starter) : null;
  const assistantName = organization && organization.assistantName ? organization.assistantName : "MIRA";
  const assistantAvatarStatus = organization && organization.avatarStatus ? organization.avatarStatus : "not-started";

  useEffect(() => {
    document.body.style.overflow = "hidden";
    const onKey = (event) => {
      if (event.key === "Escape") onClose();
    };
    window.addEventListener("keydown", onKey);
    return () => {
      document.body.style.overflow = "";
      window.removeEventListener("keydown", onKey);
    };
  }, [organizationId]);

  if (!organization) {
    return (
      <div className="detail organization-detail" data-screen-label="Operator Dossier">
        <div className="detail-top">
          <button className="back" onClick={onClose}>← BACK TO REGISTRY</button>
          <div className="detail-count">OPERATOR DOSSIER</div>
          <div className="nav-prev-next"><span>{registry.status === "loading" ? "SYNCING" : "NOT FOUND"}</span></div>
        </div>
        <div className="detail-scroll">
          <section className="detail-section organization-detail-empty">
            <div className="lore-section-label">ORGANIZATION REGISTRY</div>
            <h2 className="lore-heading">Operator Not Found</h2>
            <p>The requested organization dossier is not available in the current registry snapshot.</p>
          </section>
        </div>
      </div>
    );
  }

  return (
    <div className="detail organization-detail" data-screen-label={"Operator Dossier · " + organization.name}>
      <div className="detail-top">
        <button className="back" onClick={onClose}>← BACK TO REGISTRY</button>
        <div className="detail-count">OPERATOR DOSSIER</div>
        <div className="nav-prev-next">
          <span>{isMine ? "YOUR ORGANIZATION" : "REGISTERED OPERATOR"}</span>
        </div>
      </div>

      <div className="detail-scroll">
        <section className="detail-section organization-detail-hero">
          <div className="organization-detail-copy">
            <div className="lore-section-label">{isMine ? "YOUR ORGANIZATION" : "REGISTERED OPERATOR"}</div>
            <h1 className="detail-name">{organization.name}</h1>
            <p className="detail-brief">{getOrganizationMottoText(organization)}</p>
            <div className="detail-tag-row">
              <span>CALLSIGN · {organization.callsign || "PENDING"}</span>
              <span>{entry.status || "registered"}</span>
              {starter && <span>{starter.id} · {starter.codename}</span>}
            </div>
          </div>
          <div className="organization-detail-logo organization-logo-stage" aria-label={organization.name + " crest"}>
            <img src={getOrganizationPreviewSource(organization)} alt={organization.name + " crest"} />
          </div>
        </section>

        <section className="detail-section detail-info-row organization-detail-grid">
          <div className="detail-info-left">
            <div className="lore-section-label">OPERATOR LORE</div>
            <h2 className="lore-heading">{lore.title}</h2>
            <p className="detail-brief organization-lore-line">{lore.summary}</p>
            <div className="organization-doctrine-list">
              {lore.doctrineLines.map((line, index) => (
                <p className="detail-brief organization-lore-line" key={line}>
                  <span>{String(index + 1).padStart(2, "0")}</span>
                  {line}
                </p>
              ))}
            </div>
          </div>

          <div className="detail-info-right">
            <div className="detail-specs">
              <div className="spec"><div className="k">Owner</div><div className="v">{entry.owner ? entry.owner.username : "UNKNOWN"}</div></div>
              <div className="spec"><div className="k">Callsign</div><div className="v">{organization.callsign || "PENDING"}</div></div>
              <div className="spec"><div className="k">Founded</div><div className="v">{getOrganizationFoundedLabel(organization)}</div></div>
              <div className="spec"><div className="k">Logo</div><div className="v">{organization.logoStatus || "local-draft"}</div></div>
            </div>

            <div className="organization-logo-lock">
              <div>
                <span>OWNERSHIP</span>
                <b>{isMine ? "OWNED BY YOU" : "PUBLIC OPERATOR"}</b>
              </div>
              <p>
                {isMine
                  ? "This organization is linked to your account. Its owned unit is the starter frame selected at signup."
                  : "This operator is publicly registered. Its roster currently exposes only the starter unit."}
              </p>
            </div>

            <div className="organization-assistant-card">
              <div className="organization-assistant-avatar">
                <img src={getAssistantAvatarSource(organization)} alt={assistantName + " virtual assistant"} loading="lazy" />
              </div>
              <div className="organization-assistant-copy">
                <span>VIRTUAL ASSISTANT</span>
                <h3>{assistantName}</h3>
                <p>{lore.assistantLine}</p>
                <b>{assistantAvatarStatus === "generated" ? "COMMAND CHANNEL ONLINE" : "AVATAR " + assistantAvatarStatus.toUpperCase()}</b>
              </div>
            </div>
          </div>
        </section>

        <section className="detail-section organization-starter-section">
          <div className="detail-section-head">
            <div>
              <div className="lore-section-label">STARTER UNIT</div>
              <h2 className="lore-heading">{starter ? starter.id + " / " + starter.codename : "Pending Assignment"}</h2>
            </div>
            {starter && <div className="detail-section-side">OWNED FRAME · ORGANIZATION STARTER</div>}
          </div>
          {starter ? (
            <div className="organization-starter-card">
              <div className="organization-starter-image">
                <HangarPreviewImage mech={starter} alt={starter.codename + " preview"} />
              </div>
              <div className="organization-starter-copy">
                <div className="detail-designation">DESIGNATION · {starter.id}</div>
                <h3>{starter.codename}</h3>
                <p>{starter.brief}</p>
                <div className="organization-starter-action organization-actions">
                  <button type="button" className="btn primary" onClick={() => onOpenMech(starter.id)}>OPEN STARTER MEKA</button>
                </div>
              </div>
            </div>
          ) : (
            <div className="organization-directory-empty">NO STARTER UNIT ASSIGNED</div>
          )}
        </section>
      </div>
    </div>
  );
}

function useOrganizationDirectoryRows(registry, isPreview) {
  const organizations = registry && registry.organizations ? registry.organizations : [];
  const [previewLimit, setPreviewLimit] = useState(() => getOrganizationDirectoryPreviewLimit());

  useEffect(() => {
    if (!isPreview || typeof window === "undefined" || !window.matchMedia) return;
    const queryList = window.matchMedia(ORGANIZATION_DIRECTORY_COMPACT_QUERY);
    const updatePreviewLimit = () => {
      setPreviewLimit(queryList.matches
        ? ORGANIZATION_DIRECTORY_PREVIEW_COMPACT_LIMIT
        : ORGANIZATION_DIRECTORY_PREVIEW_WIDE_LIMIT);
    };
    updatePreviewLimit();
    if (queryList.addEventListener) {
      queryList.addEventListener("change", updatePreviewLimit);
      return () => queryList.removeEventListener("change", updatePreviewLimit);
    }
    queryList.addListener(updatePreviewLimit);
    return () => queryList.removeListener(updatePreviewLimit);
  }, [isPreview]);

  const visibleOrganizations = isPreview ? organizations.slice(0, previewLimit) : organizations;
  const hiddenOrganizationCount = Math.max(0, organizations.length - visibleOrganizations.length);
  return { organizations, visibleOrganizations, hiddenOrganizationCount };
}

function OrganizationDirectoryContent({ registry, account, onOpenOrganization, visibleOrganizations, hiddenOrganizationCount, isPreview }) {
  const hasOrganizations = visibleOrganizations.length > 0;
  return (
    <div className={"organization-directory" + (isPreview ? " is-preview" : " is-full")}>
      <div className="organization-directory-head">
        <div>
          <span>{isPreview ? "PUBLIC ROSTER PREVIEW" : "PUBLIC ROSTER"}</span>
          <b>STARTER OWNERSHIP LOG</b>
        </div>
        <b>{registry.status === "loading" ? "SYNCING" : isPreview ? "LIVE PREVIEW" : "LIVE DIRECTORY"}</b>
      </div>
      {!hasOrganizations ? (
        <div className="organization-directory-empty">
          {registry.status === "error"
            ? "REGISTRY OFFLINE - ACCOUNT DATA WILL SYNC WHEN AVAILABLE"
            : "NO REGISTERED ORGANIZATIONS YET"}
        </div>
      ) : (
        <>
          <div className="organization-directory-grid">
            {visibleOrganizations.map((entry) => {
              const organization = entry.organization;
              const starter = findMechById(organization.starterMechId);
              const isMine = account && account.organization && account.organization.id === organization.id;
              return (
                <article key={organization.id || organization.name} className={"organization-card " + (isMine ? "is-mine" : "")}>
                  <div className="organization-card-logo">
                    <img src={getOrganizationPreviewSource(organization)} alt={organization.name + " logo"} loading="lazy" />
                  </div>
                  <div className="organization-card-body">
                    <span>{isMine ? "YOUR ORGANIZATION" : "REGISTERED OPERATOR"}</span>
                    <h4>{organization.name}</h4>
                    <p>{getOrganizationMottoText(organization)}</p>
                  </div>
                  <div className="organization-card-meta">
                    <div><span>OWNER</span><b>{entry.owner ? entry.owner.username : "UNKNOWN"}</b></div>
                    <div><span>STARTER</span><b>{starter ? starter.id + " / " + starter.codename : "PENDING"}</b></div>
                    <div><span>FOUNDED</span><b>{organization.foundedAt ? new Date(organization.foundedAt).toLocaleDateString() : "DRAFT"}</b></div>
                  </div>
                  <div className="organization-card-command">
                    <span>{starter ? "STARTER CLAIMED" : "AWAITING STARTER"}</span>
                    <button type="button" className="btn compact" onClick={() => onOpenOrganization(organization.id || organization.name)}>
                      OPEN OPERATOR DOSSIER
                    </button>
                  </div>
                </article>
              );
            })}
          </div>
          {isPreview && hiddenOrganizationCount > 0 && (
            <div className="organization-directory-more">
              <div>
                <span>FULL DIRECTORY AVAILABLE</span>
                <b>{String(hiddenOrganizationCount).padStart(2, "0")} MORE REGISTERED OPERATORS</b>
              </div>
              <a className="btn primary compact" href={REGISTERED_OPERATORS_ROUTE}>VIEW ALL REGISTERED OPERATORS</a>
            </div>
          )}
        </>
      )}
    </div>
  );
}

function OrganizationDirectory({ registry, account, onOpenOrganization }) {
  const isPreview = true;
  const { organizations, visibleOrganizations, hiddenOrganizationCount } = useOrganizationDirectoryRows(registry, isPreview);
  return (
    <section id="registry" className="section organization-registry-section" aria-label="Registered organizations" data-screen-label="Organization Registry">
      <div className="section-inner">
        <div className="section-head">
          <div>
            <div className="label">SECTION · 02 / ORGANIZATION REGISTRY</div>
            <h2>Registered Operators</h2>
          </div>
          <div className="right">
            {registry.status === "loading" ? "SYNCING" : String(organizations.length).padStart(2, "0") + " ACTIVE"}
          </div>
        </div>

        <OrganizationDirectoryContent
          registry={registry}
          account={account}
          onOpenOrganization={onOpenOrganization}
          visibleOrganizations={visibleOrganizations}
          hiddenOrganizationCount={hiddenOrganizationCount}
          isPreview={isPreview}
        />
      </div>
    </section>
  );
}

function RegisteredOperatorsPage({ registry, account, onOpenOrganization }) {
  const isPreview = false;
  const { organizations, visibleOrganizations, hiddenOrganizationCount } = useOrganizationDirectoryRows(registry, isPreview);
  return (
    <section id="registered-operators" className="section organization-registry-section is-full-directory" aria-label="Registered operators directory" data-screen-label="Registered Operators">
      <div className="section-inner">
        <div className="section-head">
          <div>
            <div className="label">REGISTRY DIRECTORY / FULL ROSTER</div>
            <h2>Registered Operators</h2>
          </div>
          <div className="right">
            {registry.status === "loading" ? "SYNCING" : String(organizations.length).padStart(2, "0") + " ACTIVE"}
          </div>
        </div>

        <OrganizationDirectoryContent
          registry={registry}
          account={account}
          onOpenOrganization={onOpenOrganization}
          visibleOrganizations={visibleOrganizations}
          hiddenOrganizationCount={hiddenOrganizationCount}
          isPreview={isPreview}
        />
      </div>
    </section>
  );
}

const FOUNDING_STEPS = [
  { id: "starter", label: "01 CHOOSE STARTER" },
  { id: "root", label: "02 FOUND ORGANIZATION" },
  { id: "account", label: "03 CREATE ACCOUNT" },
  { id: "review", label: "04 REVIEW CLAIM" }
];
const FOUNDING_STEP_IDS = FOUNDING_STEPS.map((step) => step.id);

function readSignupProgressDraft(fallbackStarterId) {
  const fallback = {
    selectedStarterId: fallbackStarterId,
    foundingStep: "starter",
    organizationRootDraft: "",
    signupDraft: { username: "", email: "", password: "" }
  };
  if (typeof window === "undefined" || !window.sessionStorage) return fallback;
  try {
    const raw = window.sessionStorage.getItem(SIGNUP_PROGRESS_STORAGE_KEY);
    if (!raw) return fallback;
    const saved = JSON.parse(raw);
    if (!saved || typeof saved !== "object") return fallback;
    const savedStarterId = String(saved.selectedStarterId || fallbackStarterId || "").toUpperCase();
    const selectedStarterId = STARTER_PREVIEW_ROSTER.some((mech) => mech.id === savedStarterId) ? savedStarterId : fallbackStarterId;
    const savedRoot = String(saved.organizationRootDraft || "");
    const savedUsername = String((saved.signupDraft && saved.signupDraft.username) || "");
    const savedEmail = String((saved.signupDraft && saved.signupDraft.email) || "");
    const savedStepIsKnown = FOUNDING_STEP_IDS.includes(saved.foundingStep);
    const persistedStep = saved.foundingStep === "review" ? "account" : saved.foundingStep;
    const foundingStep = savedStepIsKnown
      ? (["account", "review"].includes(saved.foundingStep) && !isOrganizationRootValid(savedRoot) ? "root" : persistedStep)
      : "starter";
    return {
      selectedStarterId,
      foundingStep,
      organizationRootDraft: savedRoot,
      signupDraft: { username: savedUsername, email: savedEmail, password: "" }
    };
  } catch (error) {
    return fallback;
  }
}

function writeSignupProgressDraft(progress) {
  if (typeof window === "undefined" || !window.sessionStorage) return;
  try {
    window.sessionStorage.setItem(SIGNUP_PROGRESS_STORAGE_KEY, JSON.stringify({
      selectedStarterId: progress.selectedStarterId || "",
      foundingStep: progress.foundingStep || "starter",
      organizationRootDraft: progress.organizationRootDraft || "",
      signupDraft: {
        username: progress.signupDraft && progress.signupDraft.username ? progress.signupDraft.username : "",
        email: progress.signupDraft && progress.signupDraft.email ? progress.signupDraft.email : ""
      },
      updatedAt: new Date().toISOString()
    }));
  } catch (error) {
    // Signup progress is a convenience; the route still works without storage.
  }
}

function ClaimEntryCta({ label = "CLAIM STARTER", className = "" }) {
  return (
    <a className={["claim-entry-cta", className].filter(Boolean).join(" ")} href="#signup">
      {label}
    </a>
  );
}

function getStarterClaimAvailability(starterMechId, registry, accountOrganization) {
  const id = String(starterMechId || "").toUpperCase();
  if (!id) {
    return {
      state: "missing",
      label: "SELECT STARTER",
      detail: "Choose a Meka before starting the founding record.",
      blocked: true
    };
  }
  const starterMeka = findMechById(id);
  if (!isStarterUnitEligible(starterMeka)) {
    return {
      state: "starter-ineligible",
      label: "ARCHIVE DISPATCH RESERVED",
      detail: "This Meka is permanently reserved for License Grant history and cannot be chosen as a founding starter.",
      blocked: true
    };
  }
  if (registry && registry.status === "error") {
    return {
      state: "registry-error",
      label: "REGISTRY UNAVAILABLE",
      detail: "Availability cannot be verified right now. Starter claiming is paused until the registry responds.",
      blocked: true
    };
  }
  if (!registry || registry.status !== "ready") {
    return {
      state: "not-verified",
      label: "AVAILABILITY NOT VERIFIED",
      detail: "The archive is checking current ownership before it opens this starter for founding.",
      blocked: true
    };
  }
  const claimedByOther = isStarterClaimedByOther(id, registry, accountOrganization);
  if (claimedByOther) {
    const entry = registry.ownership[id];
    const organizationName = entry && entry.organization ? entry.organization.name : "ANOTHER ORGANIZATION";
    return {
      state: "claimed",
      label: "CLAIMED BY " + organizationName,
      detail: "This unit already anchors a registered organization. Select the next available starter.",
      blocked: true
    };
  }
  return {
    state: "available",
    label: "AVAILABLE FOR FOUNDING",
    detail: "This starter can be bound to your new organization claim.",
    blocked: false
  };
}

function findNextAvailableStarterId(currentId, registry, accountOrganization, candidateMechs = MEKABOTS_BY_ID) {
  const starterRoster = candidateMechs && candidateMechs.length ? candidateMechs : MEKABOTS_BY_ID;
  const currentIndex = Math.max(0, starterRoster.findIndex((mech) => mech.id === currentId));
  const ordered = [...starterRoster.slice(currentIndex + 1), ...starterRoster.slice(0, currentIndex + 1)];
  const available = ordered.find((mech) => !getStarterClaimAvailability(mech.id, registry, accountOrganization).blocked);
  return available ? available.id : currentId;
}

function findFirstAvailableStarterId(registry, accountOrganization, candidateMechs = MEKABOTS_BY_ID) {
  const starterRoster = candidateMechs && candidateMechs.length ? candidateMechs : MEKABOTS_BY_ID;
  if (!starterRoster.length) return "";
  if (!registry || registry.status !== "ready") return starterRoster[0].id;
  const available = starterRoster.find((mech) => !getStarterClaimAvailability(mech.id, registry, accountOrganization).blocked);
  return available ? available.id : starterRoster[0].id;
}

function getHangarPreviewAvailabilityLabel(mech, previewMode, registry, accountOrganization) {
  if (!previewMode || !mech) return "";
  return " - " + getStarterClaimAvailability(mech.id, registry, accountOrganization).label;
}

function FoundingStepTracker({ activeStep, onStepSelect }) {
  const activeIndex = FOUNDING_STEPS.findIndex((step) => step.id === activeStep);
  const activeLabel = FOUNDING_STEPS[activeIndex] ? FOUNDING_STEPS[activeIndex].label : "";
  return (
    <div className="founding-step-rail" aria-label="Signup progress" data-current={"STEP " + String(activeIndex + 1).padStart(2, "0") + " / " + String(FOUNDING_STEPS.length).padStart(2, "0") + " - " + activeLabel}>
      {FOUNDING_STEPS.map((step, index) => {
        const stepCanBeEdited = index < activeIndex && typeof onStepSelect === "function";
        const stepClassName = "founding-step" + (step.id === activeStep ? " active" : "") + (index < activeIndex ? " complete" : "") + (stepCanBeEdited ? " is-editable" : "");
        if (stepCanBeEdited) {
          return (
            <button
              key={step.id}
              type="button"
              className={stepClassName}
              onClick={() => onStepSelect(step.id)}
              aria-label={"Edit " + step.label}
            >
              {step.label}
            </button>
          );
        }
        return (
          <div
            key={step.id}
            className={stepClassName}
            aria-current={step.id === activeStep ? "step" : undefined}
            aria-disabled={index > activeIndex ? "true" : undefined}
          >
            {step.label}
          </div>
        );
      })}
    </div>
  );
}

function SignupStarterChoiceStage({
  starterMech,
  availability,
  onSelectNext,
  onSelectStarter,
  onBeginClaim,
  onSignIn,
  disabled,
  error
}) {
  const activeMech = starterMech || STARTER_PREVIEW_ROSTER[0] || MEKABOTS_BY_ID[0];
  const formationMechs = getFormationDisplayMechs(STARTER_PREVIEW_ROSTER, activeMech && activeMech.id);
  const formationIsReordered = Boolean(STARTER_PREVIEW_ROSTER[0] && activeMech && STARTER_PREVIEW_ROSTER[0].id !== activeMech.id);
  const starterIsClaimed = availability.state === "claimed";
  const rosterIndex = Math.max(0, STARTER_PREVIEW_ROSTER.findIndex((mech) => activeMech && mech.id === activeMech.id));
  const starterDockCopy = starterIsClaimed
    ? (activeMech ? activeMech.id + " / " + activeMech.codename : "This starter") + " is already anchored to a registered organization. Select the next available unit or sign in if this is yours."
    : availability.detail;

  function selectStarter(nextId) {
    if (!nextId || !onSelectStarter) return;
    onSelectStarter(nextId);
  }

  function handleSelectionKeyDown(event) {
    const isPreviousKey = event.key === "ArrowLeft";
    const isNextKey = event.key === "ArrowRight";
    if (!isPreviousKey && !isNextKey) return;
    event.preventDefault();
    const direction = isPreviousKey ? -1 : 1;
    const nextId = getAdjacentPreviewMechId(STARTER_PREVIEW_ROSTER, activeMech && activeMech.id, direction);
    selectStarter(nextId);
  }

  return (
    <div className={"signup-choice-hangar epic-hangar is-preview starter-state-" + availability.state}>
      <div
        className={"epic-hangar-stage" + (formationIsReordered ? " is-reordered" : "")}
        aria-label={"Starter selection formation: " + FORMATION_VISIBLE_SLOT_COUNT + " visible slots from " + STARTER_PREVIEW_ROSTER.length + " selectable Mekas"}
        tabIndex={0}
        onKeyDownCapture={handleSelectionKeyDown}
      >
        <div className="hangar-ceiling"></div>
        <div className="hangar-backwall"></div>
        <div className="hangar-floor"></div>
        {formationMechs.map((mech, index) => (
          <button
            key={mech.id + "-signup-slot-" + (index + 1)}
            type="button"
            className={"hangar-unit hangar-slot-" + (index + 1) + (activeMech && activeMech.id === mech.id ? " active" : "")}
            onClick={() => selectStarter(mech.id)}
            aria-label={"Select " + mech.id + " " + mech.codename + " for founding"}
            aria-pressed={Boolean(activeMech && activeMech.id === mech.id)}
            style={getHangarCropStyle(mech)}
          >
            <HangarPreviewImage mech={mech} alt="" />
            <span>{mech.id}</span>
          </button>
        ))}
        <HangarSelectionControls displayMechs={STARTER_PREVIEW_ROSTER} activeMech={activeMech} onSelect={selectStarter} />
        <div className="hangar-platform">
          <span>STARTER FORMATION</span>
          <b>{formationMechs.length}-SLOT WINDOW / {STARTER_PREVIEW_ROSTER.length} ROSTER</b>
        </div>
      </div>

      <div className="hangar-stage-dock" aria-label="Selected starter telemetry">
        <div className="hangar-dock-brief">
          <span>STARTER UNIT STATUS</span>
          <b>{availability.label}</b>
          <p>{starterDockCopy}</p>
        </div>
        <CombatProfilePanel mech={activeMech} variant="claim" />
        <div className="hangar-readouts signup-hangar-readouts">
          <div><span>ROSTER</span><b>{String(rosterIndex + 1).padStart(2, "0")}</b></div>
          <div><span>STARTER</span><b>{starterIsClaimed ? "CLAIMED" : "YES"}</b></div>
          <div><span>UNITS</span><b>{String(STARTER_PREVIEW_ROSTER.length).padStart(2, "0")}</b></div>
        </div>
      </div>

      <aside className="epic-hangar-panel signup-choice-panel">
        <div className="hangar-panel-title">
          <div className="panel-kicker">01 CHOOSE STARTER</div>
          <h3>{activeMech ? activeMech.id + " / " + activeMech.codename : "No Starter Selected"}</h3>
          <div className="owned-starter-status" aria-label={"Selected starter status " + availability.label}>
            <span>STATUS</span>
            <b>{availability.label}</b>
          </div>
        </div>
        <p>Choose the founding Meka first. The next steps only ask for the organization root word and account details.</p>
        <div className={"hangar-panel-actions starter-claim-actions" + (starterIsClaimed ? " is-claimed" : "")}>
          {starterIsClaimed ? (
            <>
              <div className="hangar-claim-status">CLAIM UNAVAILABLE: {availability.label}</div>
              <button type="button" className="btn primary" onClick={onSelectNext} disabled={disabled}>
                SELECT NEXT AVAILABLE
              </button>
            </>
          ) : (
            <button type="button" className="btn primary" onClick={onBeginClaim} disabled={disabled || availability.blocked}>BEGIN FOUNDING</button>
          )}
          <button type="button" className="btn starter-restore-action" onClick={onSignIn} disabled={disabled}>SIGN IN</button>
        </div>
        {error && <div className="account-error">{error}</div>}
        {activeMech && <MechaPreviewDossier mech={activeMech} availability={availability} />}
      </aside>
    </div>
  );
}

function FoundingClaimSummary({
  starterMech,
  rootWord,
  username,
  availability,
  onEditStarter,
  onEditOrganization,
  disabled
}) {
  const starterLabel = starterMech ? starterMech.id + " / " + starterMech.codename : "PENDING";
  const rootLabel = rootWord ? rootWord.toUpperCase() : "ROOT WORD PENDING";
  const accountLabel = username ? username.trim().toUpperCase() : "ACCOUNT PENDING";
  const statusLabel = availability && availability.label ? availability.label : "STATUS PENDING";
  return (
    <aside className="founding-selected-summary founding-claim-summary" aria-label="Founding claim summary">
      <div className="founding-summary-head">
        <span>FOUNDING CLAIM</span>
        <b>{starterLabel}</b>
        <em>{statusLabel}</em>
      </div>
      <div className="founding-summary-root">
        <span>ROOT WORD</span>
        <b>{rootLabel}</b>
      </div>
      <div className="founding-claim-summary-grid">
        <div>
          <span>STARTER</span>
          <b>{starterLabel}</b>
        </div>
        <div>
          <span>ACCOUNT</span>
          <b>{accountLabel}</b>
        </div>
      </div>
      <div className="founding-summary-actions">
        {onEditStarter && (
          <button type="button" className="btn" onClick={onEditStarter} disabled={disabled}>
            EDIT STARTER
          </button>
        )}
        {onEditOrganization && (
          <button type="button" className="btn" onClick={onEditOrganization} disabled={disabled}>
            EDIT ORGANIZATION
          </button>
        )}
      </div>
    </aside>
  );
}

function FoundingReview({ starterMech, rootWord, username, isBusy, error, onBack, onSubmit }) {
  return (
    <div className="founding-review">
      <div className="founding-review-head">
        <span>FOUNDING REVIEW</span>
        <h4>Review Claim</h4>
        <p>The archive will register your organization, claim your starter unit, and begin identity generation.</p>
      </div>
      <div className="founding-review-grid">
        <div><span>OPERATOR</span><b>{username}</b></div>
        <div><span>ROOT WORD</span><b>{rootWord}</b></div>
        <div><span>ASSIGNED SUFFIX</span><b>ARCHIVE GENERATED</b></div>
        <div><span>STARTER UNIT</span><b>{starterMech ? starterMech.id + " / " + starterMech.codename : "PENDING"}</b></div>
      </div>
      {error && <div className="account-error">{error}</div>}
      <div className="founding-actions">
        <button type="button" className="btn" onClick={onBack} disabled={isBusy}>BACK</button>
        <button type="button" className="btn primary account-submit" onClick={onSubmit} disabled={isBusy}>
          {isBusy ? "SYNCING..." : "CONFIRM & FOUND"}
        </button>
      </div>
    </div>
  );
}

function AccountSignInForm({ account, onSuccess, compact = false }) {
  const [signinDraft, setSigninDraft] = useState({ email: "", password: "" });
  const [signinError, setSigninError] = useState("");
  const isBusy = account.status === "checking";

  useEffect(() => {
    setSigninError("");
  }, [signinDraft.email, signinDraft.password]);

  function updateSigninDraft(key, value) {
    setSigninDraft((current) => ({ ...current, [key]: value }));
  }

  async function submitLogin(event) {
    event.preventDefault();
    setSigninError("");
    try {
      await account.login({ email: signinDraft.email.trim(), password: signinDraft.password });
      setSigninDraft((current) => ({ ...current, password: "" }));
      if (onSuccess) onSuccess();
    } catch (err) {
      setSigninError((err.message || "SIGN IN FAILED").toUpperCase());
    }
  }

  if (account.status === "offline") {
    return (
      <div className="organization-auth compact account-signin-unavailable">
        <div>
          <span>ACCOUNT</span>
          <b>SIGN IN UNAVAILABLE</b>
        </div>
        <p>Account services are not connected in this build. You can still browse the archive.</p>
      </div>
    );
  }

  return (
    <form className={"organization-auth-form account-signin-form" + (compact ? " compact" : "")} onSubmit={submitLogin}>
      <label>
        <span>EMAIL</span>
        <input value={signinDraft.email} onChange={(event) => updateSigninDraft("email", event.target.value)} placeholder="operator@example.com" autoComplete="email" required />
      </label>
      <label>
        <span>PASSWORD</span>
        <input value={signinDraft.password} onChange={(event) => updateSigninDraft("password", event.target.value)} type="password" placeholder="password" autoComplete="current-password" required />
      </label>
      {(signinError || account.error) && <div className="account-error">{signinError || account.error}</div>}
      <button type="submit" className="btn primary account-submit" disabled={isBusy}>
        {isBusy ? "SIGNING IN..." : "SIGN IN"}
      </button>
    </form>
  );
}

function SignupFoundingFlow({ starterMech, account, registry, onSelectStarter, onStepChange, onStarterClaimed }) {
  const accountOrganization = getAccountOrganization(account);
  const routeStarterId = (starterMech && starterMech.id) || (MEKABOTS_BY_ID[0] && MEKABOTS_BY_ID[0].id) || "";
  const fallbackStarterId = routeStarterId;
  const [restoredSignupProgress] = useState(() => readSignupProgressDraft(fallbackStarterId));
  const [selectedStarterId, setSelectedStarterId] = useState(restoredSignupProgress.selectedStarterId || fallbackStarterId);
  const [foundingStep, setFoundingStep] = useState(restoredSignupProgress.foundingStep || "starter");
  const [organizationRootDraft, setOrganizationRootDraft] = useState(restoredSignupProgress.organizationRootDraft || "");
  const [signupDraft, setSignupDraft] = useState(restoredSignupProgress.signupDraft || { username: "", email: "", password: "" });
  const [accountFormError, setAccountFormError] = useState("");
  const isBusy = account.status === "checking";
  const visibleSelectedStarterId = foundingStep === "starter" && routeStarterId
    ? routeStarterId
    : selectedStarterId;
  const selectedStarter = findMechById(visibleSelectedStarterId) || starterMech || MEKABOTS_BY_ID[0];
  const availability = getStarterClaimAvailability(selectedStarter ? selectedStarter.id : visibleSelectedStarterId, registry, accountOrganization);
  const effectiveSignupRoot = organizationRootDraft.trim();
  const organizationRootIsValid = isOrganizationRootValid(effectiveSignupRoot);
  const usernameIsValid = /^[a-z0-9][a-z0-9_-]{2,23}$/i.test(signupDraft.username.trim());
  const emailIsValid = /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(signupDraft.email.trim());
  const passwordIsValid = signupDraft.password.length >= 8;
  const signupReady = usernameIsValid && emailIsValid && passwordIsValid && organizationRootIsValid && !availability.blocked;
  const accountVisibleError = accountFormError || account.error;

  useEffect(() => {
    if (starterMech && starterMech.id && foundingStep === "starter") {
      setSelectedStarterId(starterMech.id);
    }
  }, [starterMech && starterMech.id, foundingStep]);

  useEffect(() => {
    setAccountFormError("");
  }, [selectedStarterId, organizationRootDraft, signupDraft.username, signupDraft.email, signupDraft.password]);

  useEffect(() => {
    if (onStepChange) onStepChange(foundingStep);
  }, [foundingStep, onStepChange]);

  useEffect(() => {
    writeSignupProgressDraft({
      selectedStarterId: selectedStarter ? selectedStarter.id : selectedStarterId,
      foundingStep,
      organizationRootDraft,
      signupDraft
    });
  }, [selectedStarter && selectedStarter.id, selectedStarterId, foundingStep, organizationRootDraft, signupDraft.username, signupDraft.email]);

  useEffect(() => {
    if (foundingStep !== "root" && foundingStep !== "account") return;
    const frame = window.requestAnimationFrame(() => {
      const scrollTarget = foundingStep === "account"
        ? document.querySelector(".founding-account-step")
        : document.querySelector(".founding-root-step");
      if (scrollTarget) scrollTarget.scrollIntoView({ behavior: "auto", block: "start" });
      const input = document.querySelector(foundingStep === "root" ? ".founding-root-step input" : ".founding-account-form input");
      if (input) input.focus({ preventScroll: true });
    });
    return () => window.cancelAnimationFrame(frame);
  }, [foundingStep]);

  if (account.status === "offline") {
    return (
      <div id="founding" className="organization-auth compact founding-sequence">
        <div>
          <span>ACCOUNT</span>
          <b>OFFLINE MODE</b>
        </div>
        <p>Account services are not connected in this build. Dossiers remain available for browsing.</p>
      </div>
    );
  }

  function updateSignupDraft(key, value) {
    setSignupDraft((current) => ({ ...current, [key]: value }));
  }

  function goToFoundingStep(nextStep) {
    if (!FOUNDING_STEP_IDS.includes(nextStep)) return;
    setAccountFormError("");
    setFoundingStep(nextStep);
  }

  function selectNextAvailableStarter() {
    const currentId = selectedStarter ? selectedStarter.id : visibleSelectedStarterId;
    const nextId = findNextAvailableStarterId(currentId, registry, accountOrganization, STARTER_PREVIEW_ROSTER);
    if (!nextId || nextId === currentId) return;
    setSelectedStarterId(nextId);
    if (onSelectStarter) onSelectStarter(nextId);
  }

  function selectStarterFromCarousel(nextId) {
    if (!nextId) return;
    setSelectedStarterId(nextId);
    if (onSelectStarter) onSelectStarter(nextId);
  }

  function beginStarterClaim() {
    if (availability.blocked) {
      setAccountFormError(availability.label);
      return;
    }
    setSelectedStarterId(visibleSelectedStarterId);
    goToFoundingStep("root");
  }

  function continueToAccount() {
    if (!organizationRootIsValid) {
      setAccountFormError("ROOT WORD MUST BE 3-24 LETTERS OR NUMBERS. NO SPACES.");
      return;
    }
    goToFoundingStep("account");
  }

  function continueToReview() {
    if (!usernameIsValid) {
      setAccountFormError("USERNAME MUST BE 3-24 LETTERS, NUMBERS, _ OR -");
      return;
    }
    if (!emailIsValid) {
      setAccountFormError("ENTER A VALID EMAIL");
      return;
    }
    if (!passwordIsValid) {
      setAccountFormError("PASSWORD MUST BE AT LEAST 8 CHARACTERS");
      return;
    }
    if (!organizationRootIsValid) {
      setAccountFormError("ROOT WORD MUST BE 3-24 LETTERS OR NUMBERS. NO SPACES.");
      return;
    }
    if (availability.blocked) {
      setAccountFormError(availability.label);
      return;
    }
    goToFoundingStep("review");
  }

  async function submitSignup(event) {
    if (event) event.preventDefault();
    setAccountFormError("");
    if (!signupReady) {
      continueToReview();
      return;
    }
    try {
      const nextSession = await account.signup({
        username: signupDraft.username.trim(),
        email: signupDraft.email.trim(),
        password: signupDraft.password,
        organizationRoot: effectiveSignupRoot,
        starterMechId: selectedStarter ? selectedStarter.id : selectedStarterId
      });
      clearSignupBrowserDrafts();
      setSignupDraft((current) => ({ ...current, password: "" }));
      if (onStarterClaimed) onStarterClaimed(nextSession, selectedStarter);
      window.location.hash = "#generation";
    } catch (err) {
      setAccountFormError((err.message || "SIGNUP FAILED").toUpperCase());
    }
  }

  return (
    <div id="founding" className="founding-sequence">
        <div className="founding-sequence-head">
        <span>CLAIM STARTER</span>
        <h4>Found an organization around one starter unit</h4>
        <p>Choose a Meka, register one root word, then create your account.</p>
      </div>
      <FoundingStepTracker activeStep={foundingStep} onStepSelect={goToFoundingStep} />
      {foundingStep === "starter" && (
        <SignupStarterChoiceStage
          starterMech={selectedStarter}
          availability={availability}
          onSelectNext={selectNextAvailableStarter}
          onSelectStarter={selectStarterFromCarousel}
          onBeginClaim={beginStarterClaim}
          onSignIn={() => { window.location.hash = "#signin"; }}
          disabled={isBusy}
          error={accountVisibleError}
        />
      )}

      {foundingStep === "root" && (
        <div className="founding-input-layout">
          <FoundingClaimSummary
            starterMech={selectedStarter}
            rootWord={organizationRootDraft}
            username={signupDraft.username}
            availability={availability}
            onEditStarter={() => goToFoundingStep("starter")}
            disabled={isBusy}
          />
          <div className="founding-step-panel founding-root-step">
          <label>
            <span>ROOT WORD</span>
            <input
              name="organizationRoot"
              value={organizationRootDraft}
              onChange={(event) => setOrganizationRootDraft(event.target.value)}
              placeholder="Sedino"
              maxLength="24"
              required
              aria-invalid={organizationRootDraft ? !organizationRootIsValid : undefined}
            />
          </label>
          <p className="field-helper">Enter one root word. The archive assigns the second word and callsign.</p>
          <p className="field-helper">3-24 letters or numbers. No spaces.</p>
          {accountVisibleError && <div className="account-error">{accountVisibleError}</div>}
          <div className="founding-actions">
            <button type="button" className="btn" onClick={() => goToFoundingStep("starter")} disabled={isBusy}>BACK TO STARTER</button>
            <button type="button" className="btn primary" onClick={continueToAccount} disabled={isBusy}>CONTINUE TO ACCOUNT</button>
          </div>
          </div>
        </div>
      )}

      {foundingStep === "account" && (
        <div className="founding-input-layout">
          <FoundingClaimSummary
            starterMech={selectedStarter}
            rootWord={effectiveSignupRoot}
            username={signupDraft.username}
            availability={availability}
            onEditStarter={() => goToFoundingStep("starter")}
            onEditOrganization={() => goToFoundingStep("root")}
            disabled={isBusy}
          />
          <div className="founding-step-panel founding-account-step">
          <div className="founding-account-intro">
            <span>ACCOUNT</span>
            <b>Create your account</b>
            <p>Already registered? <a href="#signin">Sign in to your account</a>.</p>
          </div>
          <form className="organization-auth-form founding-account-form" onSubmit={(event) => { event.preventDefault(); continueToReview(); }}>
            <label>
              <span>USERNAME</span>
              <input name="username" value={signupDraft.username} onChange={(event) => updateSignupDraft("username", event.target.value)} placeholder="operator-one" autoComplete="username" required pattern="[a-zA-Z0-9][a-zA-Z0-9_-]{2,23}" maxLength="24" />
            </label>
            <label>
              <span>EMAIL</span>
              <input name="email" value={signupDraft.email} onChange={(event) => updateSignupDraft("email", event.target.value)} type="email" placeholder="operator@example.com" autoComplete="email" required />
            </label>
            <label>
              <span>PASSWORD</span>
              <input name="password" value={signupDraft.password} onChange={(event) => updateSignupDraft("password", event.target.value)} type="password" placeholder="8+ characters" autoComplete="new-password" required minLength={8} />
            </label>
            <div className={"account-hint " + (signupReady ? "is-ok" : "")}>
              {signupReady ? "FOUNDING CLAIM READY FOR REVIEW" : "COMPLETE ACCOUNT DETAILS TO REVIEW THE CLAIM"}
            </div>
            {accountVisibleError && <div className="account-error">{accountVisibleError}</div>}
            <div className="founding-actions founding-account-actions">
              <button type="button" className="btn" onClick={() => goToFoundingStep("root")} disabled={isBusy}>BACK TO ORGANIZATION</button>
              <button type="submit" className="btn primary account-submit" disabled={isBusy}>REVIEW CLAIM</button>
            </div>
          </form>
          </div>
        </div>
      )}

      {foundingStep === "review" && (
        <FoundingReview
          starterMech={selectedStarter}
          rootWord={effectiveSignupRoot}
          username={signupDraft.username.trim()}
          isBusy={isBusy}
          error={accountVisibleError}
          onBack={() => goToFoundingStep("account")}
          onSubmit={submitSignup}
        />
      )}
    </div>
  );
}

function SignupPage({ account, registry, starterMech, onSelectStarter, onStarterClaimed }) {
  return (
    <section id="signup" className="section auth-route-section signup-route" data-screen-label="Sign Up">
      <div className="section-inner auth-route-inner">
        <SignupFoundingFlow starterMech={starterMech} account={account} registry={registry} onSelectStarter={onSelectStarter} onStarterClaimed={onStarterClaimed} />
      </div>
    </section>
  );
}

function SignInPage({ account }) {
  return (
    <section id="signin" className="section auth-route-section signin-route" data-screen-label="Sign In">
      <div className="section-inner auth-route-inner auth-route-signin">
        <div className="auth-route-head">
          <div>
            <div className="label">ACCOUNT ACCESS</div>
            <h2>Sign In</h2>
          </div>
          <div className="auth-route-actions">
            <a className="btn" href="#signup">SIGN UP</a>
          </div>
        </div>
        <div className="signin-panel">
          <div className="signin-copy">
            <span>SIGN IN TO YOUR ACCOUNT</span>
            <h3>Open your organization and hangar</h3>
            <p>Existing operators can sign in here directly. No starter selection is required.</p>
          </div>
          <AccountSignInForm account={account} onSuccess={() => { window.location.hash = "#top"; }} />
        </div>
      </div>
    </section>
  );
}

const GENERATION_FOUNDING_LABELS = {
  account_linked: "ACCOUNT LINKED",
  organization_registered: "ORGANIZATION REGISTERED",
  starter_claimed: "STARTER CLAIMED",
  public_doctrine_ready: "PUBLIC DOCTRINE READY"
};

function getGenerationCheckpointState(status, id) {
  const checkpoints = Array.isArray(status && status.checkpoints) ? status.checkpoints : [];
  const checkpoint = checkpoints.find((entry) => entry.id === id);
  return checkpoint ? checkpoint.state : "waiting";
}

function getCrestGenerationLabel(status) {
  const state = String(status && status.assets && status.assets.crest && status.assets.crest.status || "not_started");
  if (state === "ready") return "CREST VERIFIED";
  if (state === "queued") return "CREST QUEUED";
  if (state === "processing") return "CREST PROCESSING";
  if (state === "failed") return "CREST FAILED";
  if (state === "not_configured") return "CREST GENERATION UNAVAILABLE";
  if (state === "local_draft") return "CREST READY TO QUEUE";
  return "CREST STANDBY";
}

function getAssistantGenerationLabel(status) {
  const state = String(status && status.assets && status.assets.assistantAvatar && status.assets.assistantAvatar.status || "not_started");
  if (state === "ready") return "ASSISTANT AVATAR VERIFIED";
  if (state === "queued") return "ASSISTANT AVATAR QUEUED";
  if (state === "processing") return "ASSISTANT AVATAR PROCESSING";
  if (state === "failed") return "ASSISTANT AVATAR FAILED";
  if (state === "not_configured") return "ASSISTANT AVATAR UNAVAILABLE";
  return "ASSISTANT AVATAR QUEUED";
}

function getCommandChannelLabel(status) {
  return status && status.assistantIntro && status.assistantIntro.ready
    ? "COMMAND CHANNEL ONLINE"
    : "COMMAND CHANNEL WAITING";
}

function getGenerationStatusRows(status) {
  const foundingRows = Object.keys(GENERATION_FOUNDING_LABELS).map((id) => ({
    id,
    label: GENERATION_FOUNDING_LABELS[id],
    state: getGenerationCheckpointState(status, id)
  }));
  return [
    ...foundingRows,
    {
      id: "crest",
      label: getCrestGenerationLabel(status),
      state: getGenerationCheckpointState(status, "crest")
    },
    {
      id: "assistant_avatar",
      label: getAssistantGenerationLabel(status),
      state: getGenerationCheckpointState(status, "assistant_avatar")
    },
    {
      id: "command_channel",
      label: getCommandChannelLabel(status),
      state: getGenerationCheckpointState(status, "command_channel")
    }
  ];
}

function getGenerationPhaseTitle(onboarding) {
  const phase = String(onboarding && onboarding.phase || "");
  if (phase === "assistant_intro_ready") return "Command Channel Online";
  if (phase === "waiting_for_avatar") return "Assistant Avatar Sync";
  if (phase === "waiting_for_crest") return "Crest Verification";
  if (phase === "action_required") return "Generation Needs Attention";
  if (phase === "complete") return "Command Channel Stable";
  return "Founding Record Secured";
}

function getGenerationPhaseCopy(onboarding) {
  const phase = String(onboarding && onboarding.phase || "");
  if (phase === "assistant_intro_ready") return "The crest and assistant avatar are ready. Open the command channel when you want the first transmission.";
  if (phase === "waiting_for_avatar") return "Crest verification is complete. Assistant avatar sync is running against the finalized identity.";
  if (phase === "waiting_for_crest") return "Crest generation can take up to 2 minutes. You can keep browsing while it completes.";
  if (phase === "action_required") return "Starter assignment is safe. A generation job needs review or a retry before the command channel can open.";
  return "Your organization, starter unit, public doctrine, and account link are saved while the archive prepares final identity assets.";
}

function getActionDetail(onboarding, id) {
  const actions = Array.isArray(onboarding && onboarding.actionDetails) ? onboarding.actionDetails : [];
  return actions.find((action) => action.id === id) || null;
}

function getGenerationPrimaryAction(onboarding) {
  if (!onboarding) return { id: "view_starter_bay", label: "VIEW STARTER BAY", method: "GET", href: "#hangar", enabled: true };
  const openChannel = getActionDetail(onboarding, "open_command_channel");
  if (openChannel && openChannel.enabled !== false) return { ...openChannel, label: "OPEN COMMAND CHANNEL" };
  const retry = (onboarding.actionDetails || []).find((action) => action.id === "retry_generation" && action.enabled);
  if (retry) return { ...retry, label: "RETRY GENERATION" };
  const start = getActionDetail(onboarding, "start_generation");
  if (start && start.enabled) return { ...start, label: start.targetType === "assistant_avatar" ? "GENERATE ASSISTANT AVATAR" : "GENERATE FOUNDING CREST" };
  return { id: "view_starter_bay", label: "VIEW STARTER BAY", method: "GET", href: "#hangar", enabled: true };
}

function shouldShowGenerationWaitingBay(account, onboardingStatus) {
  if (!account || account.status !== "signed-in") return false;
  if (onboardingStatus && (onboardingStatus.status === "idle" || onboardingStatus.status === "loading" || onboardingStatus.status === "error")) return true;
  const onboarding = onboardingStatus && onboardingStatus.data;
  if (!onboarding) return false;
  if (onboarding.assistantIntro && onboarding.assistantIntro.ready && !onboarding.assistantIntro.finished) return true;
  return onboarding.phase !== "complete";
}

function AssistantIntroSequence({ onboarding, organization, starterMech, onboardingStatus }) {
  const assistantIntro = onboarding && onboarding.assistantIntro ? onboarding.assistantIntro : {};
  const introLines = Array.isArray(assistantIntro.lines) ? [...assistantIntro.lines] : [];
  const starterLine = starterMech
    ? starterMech.id + " / " + starterMech.codename + " is secured in your starter bay."
    : (introLines[1] || "Starter assignment is secured in your starter bay.");
  const lines = [
    introLines[0] || ("Crest verified. " + (organization.name || "Command") + " command channel is online."),
    starterLine,
    introLines[2] || ("Public doctrine logged: " + (organization.motto || "Doctrine pending.")),
    introLines[3] || "Your organization enters the archive to inspect, license, and deploy Mekas.",
    introLines[4] || "First directive: inspect your starter dossier. Weekly drops, battle reports, and Hall of Fame records come next."
  ];
  const [introStep, setIntroStep] = useState(() => Math.min(Number(assistantIntro.step || 0), Math.max(0, lines.length - 1)));
  const assistantName = organization && organization.assistantName ? organization.assistantName : "MIRA";
  const avatarSource = getAssistantAvatarSource(organization);
  const isBusy = onboardingStatus && onboardingStatus.actionBusy === "assistant_intro";
  const activeLine = lines[introStep] || lines[0];
  const progressLabel = String(introStep + 1).padStart(2, "0") + " / " + String(lines.length).padStart(2, "0");
  const assistantIntroPrimaryLabel = introStep >= lines.length - 1 ? "ENTER HANGAR" : "CONTINUE";

  useEffect(() => {
    setIntroStep(Math.min(Number(assistantIntro.step || 0), Math.max(0, lines.length - 1)));
  }, [organization && organization.id, assistantIntro.step, assistantIntro.status]);

  useEffect(() => {
    if (!assistantIntro.ready || assistantIntro.finished || assistantIntro.seen) return;
    onboardingStatus.recordAssistantIntro("seen", introStep);
  }, [assistantIntro.ready, assistantIntro.finished, assistantIntro.seen, organization && organization.id]);

  function routeAfterAssistantIntro(action, result) {
    if (!result || !result.assistantIntro || !result.assistantIntro.finished) return;
    const postIntroHash = "#hangar";
    if (action === "complete" || action === "skip") window.location.hash = postIntroHash;
  }

  async function syncAssistantIntro(action, nextStep) {
    const result = await onboardingStatus.recordAssistantIntro(action, nextStep);
    routeAfterAssistantIntro(action, result);
  }

  function advanceAssistantDialogue() {
    if (isBusy) return;
    const nextStep = Math.min(introStep + 1, lines.length - 1);
    if (introStep >= lines.length - 1) {
      syncAssistantIntro("complete", lines.length);
      return;
    }
    setIntroStep(nextStep);
    syncAssistantIntro("advance", nextStep);
  }

  function handleAssistantIntroPrimary(event) {
    event.stopPropagation();
    if (isBusy) return;
    advanceAssistantDialogue();
  }

  function skipAssistantIntro(event) {
    event.stopPropagation();
    if (isBusy) return;
    syncAssistantIntro("skip", introStep);
  }

  function handleIntroKeyDown(event) {
    if (event.key === "Enter" || event.key === " ") {
      event.preventDefault();
      advanceAssistantDialogue();
    }
  }

  return (
    <section
      id="assistant-intro"
      className="assistant-intro-sequence"
      aria-label="Virtual assistant introduction"
      tabIndex={0}
      onClick={advanceAssistantDialogue}
      onKeyDown={handleIntroKeyDown}
    >
      <div className="assistant-intro-portrait">
        <span>VIRTUAL ASSISTANT</span>
        {avatarSource ? <img src={avatarSource} alt={assistantName + " virtual assistant portrait"} loading="lazy" /> : <div className="assistant-avatar-loading"><i></i><i></i><i></i><b>AVATAR READY</b></div>}
      </div>
      <div className="assistant-intro-dialogue">
        <div className="assistant-speaker">{assistantName}</div>
        <p>{activeLine}</p>
        <div className="assistant-dialogue-foot">
          <span>{progressLabel}</span>
          <b>CLICK OR TAP TO ADVANCE</b>
        </div>
        <div className="assistant-intro-actions">
          <button type="button" className="assistant-intro-skip-link" onClick={skipAssistantIntro} disabled={Boolean(isBusy)}>SKIP INTRO</button>
          <button type="button" className="btn primary assistant-intro-primary" onClick={handleAssistantIntroPrimary} disabled={Boolean(isBusy)}>
            {isBusy ? "SYNCING..." : assistantIntroPrimaryLabel}
          </button>
        </div>
      </div>
    </section>
  );
}

function GenerationWaitingBay({ account, onboardingStatus }) {
  const onboarding = onboardingStatus && onboardingStatus.data;
  const organization = (onboarding && onboarding.organization) || getAccountOrganization(account) || {};
  const starterId = (onboarding && onboarding.starter && onboarding.starter.id) || organization.starterMechId || "";
  const starterMech = findMechById(starterId);
  const assistantIntro = onboarding && onboarding.assistantIntro ? onboarding.assistantIntro : null;
  const showAssistantIntro = Boolean(assistantIntro && assistantIntro.ready && !assistantIntro.finished);
  const rows = onboarding ? getGenerationStatusRows(onboarding) : getGenerationStatusRows(null);
  const completedRows = rows.filter((row) => row.state === "complete").length;
  const primaryAction = getGenerationPrimaryAction(onboarding);
  const browseAction = getActionDetail(onboarding, "browse_index") || { id: "browse_index", label: "BROWSE INDEX", method: "GET", href: "#archive", enabled: true };
  const retryUnavailable = onboarding && (onboarding.actionDetails || []).find((action) => action.id === "retry_generation" && !action.enabled);
  const startUnavailable = onboarding && getActionDetail(onboarding, "start_generation") && getActionDetail(onboarding, "start_generation").enabled === false
    ? getActionDetail(onboarding, "start_generation")
    : null;
  const activeJob = onboarding && Array.isArray(onboarding.jobs)
    ? onboarding.jobs.find((job) => ["queued", "processing", "failed"].includes(job.publicStatus)) || onboarding.jobs[0]
    : null;
  const isBusy = onboardingStatus && onboardingStatus.actionBusy;
  const isLoading = onboardingStatus && onboardingStatus.status === "loading";

  function handleAction(action) {
    if (!action || action.enabled === false) return;
    if (String(action.method || "GET").toUpperCase() === "GET") {
      window.location.hash = action.href === "#index" ? "#archive" : (action.href || "#hangar");
      return;
    }
    onboardingStatus.runAction(action);
  }

  if (showAssistantIntro) {
    return (
      <section id="generation" className="section generation-waiting-bay is-assistant-intro" data-screen-label="Virtual Assistant Introduction">
        <div className="section-inner generation-waiting-inner">
          <AssistantIntroSequence
            onboarding={onboarding}
            organization={organization}
            starterMech={starterMech}
            onboardingStatus={onboardingStatus}
          />
        </div>
      </section>
    );
  }

  return (
    <section id="generation" className="section generation-waiting-bay" data-screen-label="Generation Waiting Bay">
      <div className="section-inner generation-waiting-inner">
        <div className="generation-waiting-head">
          <div>
            <div className="label">GENERATION WAITING BAY</div>
            <h2>{isLoading ? "Linking Generation Status" : getGenerationPhaseTitle(onboarding)}</h2>
          </div>
          <div className="generation-progress" aria-label={"Generation progress " + completedRows + " of " + rows.length}>
            <span>{String(completedRows).padStart(2, "0")}</span>
            <b>/ {String(rows.length).padStart(2, "0")}</b>
          </div>
        </div>

        <div className="generation-waiting-grid">
          <div className="generation-waiting-copy">
            <div className="generation-org-tag">
              <span>ORGANIZATION</span>
              <b>{organization.name || "FOUNDING RECORD"}</b>
            </div>
            <p>{isLoading ? "The archive is restoring your resumable generation state." : getGenerationPhaseCopy(onboarding)}</p>
            <div className="generation-starter-link">
              <span>STARTER ASSIGNMENT SECURE</span>
              <b>{starterMech ? starterMech.id + " / " + starterMech.codename : starterId || "PENDING"}</b>
            </div>
            {organization.motto && (
              <div className="generation-doctrine">
                <span>PUBLIC DOCTRINE</span>
                <b>{organization.motto}</b>
              </div>
            )}
            {(onboardingStatus && onboardingStatus.error) && (
              <div className="generation-warning" role="status">{onboardingStatus.error}</div>
            )}
            {(retryUnavailable || startUnavailable) && (
              <div className="generation-warning">
                {(retryUnavailable || startUnavailable).disabledReason ? String((retryUnavailable || startUnavailable).disabledReason).replace(/_/g, " ").toUpperCase() : "GENERATION ACTION NOT AVAILABLE"}
              </div>
            )}
            <div className="generation-waiting-actions">
              <button type="button" className="btn primary" onClick={() => handleAction(primaryAction)} disabled={primaryAction.enabled === false || Boolean(isBusy)}>
                {isBusy ? "SYNCING..." : primaryAction.label}
              </button>
              <button type="button" className="btn" onClick={() => handleAction(browseAction)} disabled={Boolean(isBusy)}>
                BROWSE INDEX
              </button>
              <button type="button" className="btn" onClick={onboardingStatus.refresh} disabled={Boolean(isBusy)}>
                REFRESH STATUS
              </button>
            </div>
          </div>

          <div className="generation-checklist" aria-label="Generation status checklist">
            {rows.map((row, index) => (
              <div className={"generation-checkpoint is-" + row.state} key={row.id}>
                <span>{String(index + 1).padStart(2, "0")}</span>
                <b>{row.label}</b>
                <i>{row.state.toUpperCase()}</i>
              </div>
            ))}
          </div>

          <div className="generation-job-strip" aria-label="Durable generation job state">
            <div>
              <span>ACTIVE JOB</span>
              <b>{activeJob ? activeJob.type.replace(/_/g, " ") : "QUEUE STANDBY"}</b>
            </div>
            <div>
              <span>STATUS</span>
              <b>{activeJob ? activeJob.publicStatus : (onboarding ? onboarding.phase.replace(/_/g, " ") : "LOADING")}</b>
            </div>
            <div>
              <span>NEXT POLL</span>
              <b>{onboarding && onboarding.pollAfterMs ? Math.round(onboarding.pollAfterMs / 1000) + "S" : "MANUAL"}</b>
            </div>
          </div>

        </div>
      </div>
    </section>
  );
}

function OrganizationConsole({ starterMech, account, registry, compact = false, onSelectStarter }) {
  const organization = getVisibleOrganization(account);
  const hasOrganization = Boolean(organization && organization.name);
  const accountOrganization = getAccountOrganization(account);
  const [error, setError] = useState("");
  const [editingOrganizationName, setEditingOrganizationName] = useState(false);
  const [organizationRootEdit, setOrganizationRootEdit] = useState("");
  const [nameEditBusy, setNameEditBusy] = useState(false);
  const [logoConsent, setLogoConsent] = useState(false);
  const [logoJob, setLogoJob] = useState(null);
  const [logoBusy, setLogoBusy] = useState(false);
  const [activeFoundingStep, setActiveFoundingStep] = useState("starter");
  const previewSource = getOrganizationPreviewSource(organization);
  const accountIsSignedIn = account && account.status === "signed-in";
  const logoIsFinal = Boolean(organization.logoStatus === "generated" && organization.logoUrl);
  const logoIsPending = ["queued", "processing"].includes(organization.logoStatus) || (logoJob && ["queued", "processing"].includes(logoJob.status));
  const avatarIsPending = ["queued", "processing"].includes(organization.avatarStatus);
  const asyncOrganizationPending = logoIsPending || avatarIsPending;
  const logoNameLocked = Boolean(logoIsFinal || logoIsPending);
  const canEditOrganizationName = Boolean(accountIsSignedIn && hasOrganization && !logoNameLocked);
  const AUTH_RECOVERY_ERRORS = [
    "NOT SIGNED IN",
    "SIGN IN BEFORE FINAL LOGO GENERATION",
    "SESSION EXPIRED - SIGN IN AGAIN"
  ];

  useEffect(() => {
    if (hasOrganization && organization.name && !editingOrganizationName) {
      const rootWord = getOrganizationRootWord(organization);
      setOrganizationRootEdit(rootWord);
    }
  }, [hasOrganization, organization.name, editingOrganizationName]);

  useEffect(() => {
    if (account.status !== "signed-out") return;
    setOrganizationRootEdit("");
    setEditingOrganizationName(false);
    setLogoConsent(false);
    setLogoJob(null);
  }, [account.status]);

  useEffect(() => {
    if (accountIsSignedIn && AUTH_RECOVERY_ERRORS.includes(error)) {
      setError("");
    }
  }, [accountIsSignedIn, error]);

  useEffect(() => {
    if (!accountIsSignedIn || !hasOrganization || !asyncOrganizationPending) return undefined;
    let cancelled = false;
    async function pollLogoStatus() {
      try {
        const result = await publicApi("/organizations/current/logo-generations/latest");
        if (cancelled || !result) return;
        if (result.organization) {
          account.syncOrganization(result.organization);
        }
        if (result.generation) setLogoJob(result.generation);
        setError((current) => current === "LOGO STATUS CHECK RETRYING" ? "" : current);
      } catch (err) {
        if (!cancelled) setError("LOGO STATUS CHECK RETRYING");
      }
    }
    pollLogoStatus();
    const timer = window.setInterval(pollLogoStatus, 10000);
    return () => {
      cancelled = true;
      window.clearInterval(timer);
    };
  }, [accountIsSignedIn, asyncOrganizationPending, hasOrganization, logoIsPending, organization.avatarStatus, organization.logoStatus]);

  async function generateFinalLogo() {
    if (!accountIsSignedIn) {
      setError("SIGN IN BEFORE FINAL LOGO GENERATION");
      return;
    }
    if (logoIsFinal) {
      setError("FINAL LOGO ALREADY GENERATED");
      return;
    }
    if (logoIsPending) return;
    if (!logoConsent) {
      setError("CONFIRM THE ORGANIZATION NAME FIRST");
      return;
    }
    setLogoBusy(true);
    setError("");
    try {
      const restoredSession = await account.restore();
      if (!restoredSession || restoredSession.status !== "signed-in") {
        setError("SESSION EXPIRED - SIGN IN AGAIN");
        return;
      }
      const result = await publicApi("/organizations/current/logo-generations", {
        method: "POST",
        body: "{}"
      });
      if (result && result.organization) {
        account.syncOrganization(result.organization);
      }
      if (result && result.generation) {
        setLogoJob(result.generation);
      }
      if (result && result.logo && result.logo.generationEnabled === false) {
        setError("FINAL GENERATOR NOT ENABLED YET");
      }
    } catch (err) {
      if (err.status === 401) {
        await account.restore();
        setError("SESSION EXPIRED - SIGN IN AGAIN");
        return;
      }
      setError((err.message || "LOGO GENERATION FAILED").toUpperCase());
    } finally {
      setLogoBusy(false);
    }
  }

  function getFinalLogoButtonLabel() {
    if (logoBusy) return "QUEUEING...";
    if (logoIsFinal) return "FINAL LOGO";
    if (logoIsPending) return "GENERATION QUEUED";
    if (!accountIsSignedIn) return "SIGN IN REQUIRED";
    if (!logoConsent) return "CONFIRM NAME FIRST";
    return "GENERATE FINAL LOGO";
  }

  const logoActionBlockedReason = logoIsFinal
    ? ""
    : logoIsPending
      ? "Generation is already queued."
      : !accountIsSignedIn
        ? "Create an account or sign in to attach the final logo to an owner."
        : !logoConsent
          ? "Confirm the organization name before generating the final logo."
          : "";
  const finalLogoDisabled = Boolean(logoBusy || logoIsFinal || logoIsPending || !accountIsSignedIn || !logoConsent);
  const showLogoWorkflow = Boolean(hasOrganization && !logoIsFinal && !compact);
  const starterAvailability = getStarterClaimAvailability(starterMech ? starterMech.id : "", registry, accountOrganization);
  const starterSummaryLabel = starterMech ? starterMech.id + " / " + starterMech.codename : "PENDING";
  const userClaimLabel = hasOrganization ? "CLAIMED" : "UNCLAIMED";
  const activeFoundingStepIndex = Math.max(0, FOUNDING_STEPS.findIndex((step) => step.id === activeFoundingStep));
  const activeFoundingStepDefinition = FOUNDING_STEPS[activeFoundingStepIndex] || FOUNDING_STEPS[0];
  const activeFoundingStepName = activeFoundingStepDefinition.label.replace(/^\d+\s+/, "");
  const activeFoundingStepLabel = hasOrganization
    ? "FOUNDED"
    : String(activeFoundingStepIndex + 1).padStart(2, "0") + " / " + String(FOUNDING_STEPS.length).padStart(2, "0") + " - " + activeFoundingStepName;
  const nextClaimAction = hasOrganization
    ? logoIsPending
      ? "WAIT FOR CREST"
      : logoIsFinal
        ? "OPEN HANGAR"
        : "GENERATE CREST"
    : starterAvailability.state === "available"
      ? "BEGIN FOUNDING"
      : starterAvailability.state === "claimed"
        ? "SELECT AVAILABLE STARTER"
        : "WAIT FOR REGISTRY";

  async function saveOrganizationName(event) {
    event.preventDefault();
    const nextRoot = organizationRootEdit.trim();
    if (!isOrganizationRootValid(nextRoot)) {
      setError("ENTER ONE ORGANIZATION ROOT WORD");
      return;
    }
    if (logoNameLocked) {
      setError("ORGANIZATION NAME IS LOCKED");
      return;
    }
    setNameEditBusy(true);
    setError("");
    try {
      await account.renameOrganization(nextRoot);
      setEditingOrganizationName(false);
      setLogoConsent(false);
    } catch (err) {
      setError((err.message || "ORGANIZATION NAME UPDATE FAILED").toUpperCase());
    } finally {
      setNameEditBusy(false);
    }
  }

  function renderAccountAccess() {
    if (account.status === "signed-in" && account.user) {
      const handleSignout = () => {
        setOrganizationRootEdit("");
        setEditingOrganizationName(false);
        setLogoConsent(false);
        setLogoJob(null);
        account.signout();
      };
      return (
        <div className="organization-auth signed">
          <div>
            <span>ACCOUNT LINKED</span>
            <b>{account.user.username}</b>
            <p>{account.user.email}</p>
          </div>
          <button type="button" className="btn" onClick={handleSignout}>SIGN OUT</button>
        </div>
      );
    }
    return null;
  }

  return (
    <div className={"organization-console " + (hasOrganization ? "is-claimed" : "is-unclaimed") + (compact ? " is-compact" : "")}>
      <div className="organization-identity">
        {hasOrganization ? (
          <>
            <div className="organization-state">FOUNDING CREST</div>
            <h3>{organization.name}</h3>
            <p>{getOrganizationMottoText(organization)}</p>
          </>
        ) : (
          <>
            <div className="organization-state">READY TO CLAIM</div>
            <h3>Starter Claim</h3>
            <p>Use a dedicated sign-up page to choose the starter, create the account, and review the founding record.</p>
          </>
        )}
        {!compact && (
          <div className="founding-side-status" aria-label="Claim progress summary">
            <div>
              <span>CURRENT STEP</span>
              <b>{activeFoundingStepLabel}</b>
            </div>
            <div>
              <span>SELECTED STARTER</span>
              <b>{starterSummaryLabel}</b>
            </div>
            <div>
              <span>{hasOrganization ? "STARTER STATE" : "AVAILABILITY"}</span>
              <b>{hasOrganization ? "OWNED STARTER" : starterAvailability.label}</b>
            </div>
            <div>
              <span>CLAIM STATE</span>
              <b>{userClaimLabel}</b>
            </div>
            <div>
              <span>NEXT ACTION</span>
              <b>{nextClaimAction}</b>
            </div>
          </div>
        )}
      </div>

      <div
        className={"organization-logo-stage" + (logoIsPending ? " is-loading" : "")}
        aria-label={logoIsPending ? "Organization logo generation in progress" : "Organization crest preview"}
        aria-busy={logoIsPending ? "true" : undefined}
      >
        {logoIsPending ? (
          <div className="organization-logo-loading" role="status" aria-live="polite">
            <div className="logo-loader-mark" aria-hidden="true">
              <i></i>
              <i></i>
              <i></i>
            </div>
            <div className="async-status-bar" aria-hidden="true">
              <i></i><i></i><i></i>
            </div>
            <b>GENERATING CREST</b>
            <small>FINAL IMAGE IN PROGRESS</small>
          </div>
        ) : previewSource ? (
          <img src={previewSource} alt={hasOrganization ? organization.name + " crest" : ""} />
        ) : (
          <span>SMB</span>
        )}
      </div>

      <div className="organization-action-tray">
        <div className="organization-readouts">
          <div><span>YOUR CALLSIGN</span><b>{hasOrganization ? organization.callsign : "PENDING"}</b></div>
          <div><span>YOUR CLAIM</span><b>{userClaimLabel}</b></div>
          <div><span>ACCOUNT</span><b>{accountIsSignedIn ? "LINKED" : "SIGN IN"}</b></div>
        </div>

        {showLogoWorkflow && (
          <div className={"organization-logo-lock" + (compact ? " compact" : "")}>
            <div>
              <span>ONE FINAL LOGO</span>
              <b>{logoIsPending ? "GENERATING" : accountIsSignedIn ? "READY" : "SIGN IN REQUIRED"}</b>
            </div>
            {!compact && (
              <p>
                {logoIsPending
                  ? "Generation is queued. You can leave this page; the status will refresh while this session is open."
                  : accountIsSignedIn
                    ? "Final logo generation can take up to 2 minutes. Confirm the organization name before starting."
                    : "Create an account or sign in first, then this final logo can be generated and saved to that organization."}
              </p>
            )}
            {compact && logoIsPending && (
              <p>Final crest and assistant avatar are synchronizing in the background.</p>
            )}
            {!compact && logoActionBlockedReason && !logoIsPending && (
              <div className="organization-action-hint">{logoActionBlockedReason}</div>
            )}
            {canEditOrganizationName && (
              editingOrganizationName ? (
                <form className="organization-name-edit" onSubmit={saveOrganizationName}>
                  <label>
                    <span>ROOT WORD</span>
                    <input
                      value={organizationRootEdit}
                      onChange={(event) => setOrganizationRootEdit(event.target.value)}
                      maxLength="24"
                      aria-invalid={organizationRootEdit ? !isOrganizationRootValid(organizationRootEdit) : undefined}
                    />
                  </label>
                  <button type="submit" className="btn primary" disabled={nameEditBusy || !isOrganizationRootValid(organizationRootEdit)}>
                    {nameEditBusy ? "SAVING..." : "SAVE ROOT"}
                  </button>
                  <button type="button" className="btn" onClick={() => { setEditingOrganizationName(false); setOrganizationRootEdit(getOrganizationRootWord(organization)); }}>CANCEL</button>
                </form>
              ) : (
                <button type="button" className="btn compact" onClick={() => { setOrganizationRootEdit(getOrganizationRootWord(organization)); setEditingOrganizationName(true); }}>
                  EDIT ROOT WORD
                </button>
              )
            )}
            {!logoIsPending && (
              <label className="final-logo-confirm">
                <input type="checkbox" checked={logoConsent} onChange={(event) => setLogoConsent(event.target.checked)} />
                <span>I CONFIRM THIS ORGANIZATION NAME IS FINAL</span>
              </label>
            )}
            {logoIsPending && (
              <div className="async-status-bar" aria-label="Logo generation queued">
                <i></i><i></i><i></i>
              </div>
            )}
            <div className="organization-actions">
              <button type="button" className="btn primary" onClick={generateFinalLogo} disabled={finalLogoDisabled} title={logoActionBlockedReason || undefined}>
                {getFinalLogoButtonLabel()}
              </button>
            </div>
          </div>
        )}

        {account.status === "checking" ? (
          <div className="organization-auth compact">
            <div>
              <span>ACCOUNT</span>
              <b>RESTORING SESSION</b>
            </div>
            <p>Checking operator access before opening the founding controls.</p>
          </div>
        ) : accountIsSignedIn ? renderAccountAccess() : (
          <SignupFoundingFlow starterMech={starterMech} account={account} registry={registry} onSelectStarter={onSelectStarter} onStepChange={setActiveFoundingStep} />
        )}
        {error && <div className="organization-error">{error}</div>}
      </div>
    </div>
  );
}

function getCurrentDirective(onboarding, starterMech, archiveDispatchStatus) {
  const current = onboarding && onboarding.directives && onboarding.directives.current
    ? onboarding.directives.current
    : null;
  if (current) return current;
  const licenseDirective = getLicenseMoreMekasDirective(onboarding, archiveDispatchStatus);
  if (licenseDirective) return licenseDirective;
  const nextArchiveDirective = getPostLicenseArchiveDirective(onboarding, archiveDispatchStatus);
  if (nextArchiveDirective) return nextArchiveDirective;
  if (onboarding && onboarding.directives && !current) {
    return {
      id: "archive_stable",
      status: "idle",
      label: "Archive stable",
      title: "Archive stable",
      copy: "Archive directives are clear for now. Keep your roster ready for the next command cycle.",
      requiredAction: "",
      targetHref: "#archive"
    };
  }
  const starterLabel = starterMech ? starterMech.id + " / " + starterMech.codename : "your starter";
  const starterHref = starterMech ? "#mech/" + starterMech.id : "#hangar";
  return {
    id: "inspect_starter_dossier",
    status: "available",
    label: "Inspect starter dossier",
    title: "Inspect starter dossier",
    copy: "Directive sync unavailable. Open the first field record for " + starterLabel + ".",
    requiredAction: "open_starter_dossier",
    targetHref: starterHref
  };
}

const DIRECTIVE_ROUTE_COMPLETION_IDS = [
  "inspect_starter_dossier",
  "browse_weekly_drop",
  "visit_registry"
];

function normalizeDirectiveTargetHref(href) {
  const target = String(href || "#archive").trim();
  return target === "#index" ? "#archive" : target;
}

function getArchiveDispatchRouteTarget(directive) {
  const target = normalizeDirectiveTargetHref(directive && directive.targetHref ? directive.targetHref : "#archive-dispatch");
  return target === "#archive" ? "#archive-dispatch" : target;
}

function directiveCompletesOnRoute(directive) {
  return Boolean(directive && DIRECTIVE_ROUTE_COMPLETION_IDS.includes(directive.id));
}

function routeMatchesDirectiveTarget(routeHash, directive) {
  if (!directiveCompletesOnRoute(directive)) return false;
  return String(routeHash || "#top") === normalizeDirectiveTargetHref(directive.targetHref);
}

function getDirectivePanelState(onboarding, directive) {
  const guidanceState = String(onboarding && onboarding.assistantGuidance && onboarding.assistantGuidance.state || "");
  if (directive && directive.id === "license_more_mekas") return "available";
  if (guidanceState === "idle" || !directive) return "idle";
  if (guidanceState === "error" || directive.id === "repair_command_channel") return "error";
  if (guidanceState === "locked" || directive.status === "locked") return "locked";
  return "available";
}

function getDirectiveActionLabel(directive, panelState) {
  if (directive && directive.actionLabel) return directive.actionLabel;
  if (panelState === "error") return "REVIEW GENERATION";
  if (panelState === "locked") return "VIEW STATUS";
  if (!directive || panelState === "idle") return "VIEW ARCHIVE";
  if (directive.id === "inspect_starter_dossier" || directive.id === "review_combat_profile") return "OPEN DOSSIER";
  if (directive.id === "browse_weekly_drop") return "BROWSE INDEX";
  if (directive.id === "visit_registry") return "OPEN REGISTRY";
  return "OPEN";
}

function getDirectiveLockedActionCopy(onboarding, directive) {
  const reason = String(onboarding && onboarding.assistantGuidance && onboarding.assistantGuidance.reason || "");
  if (reason === "waiting_for_crest") {
    return {
      label: "CREST GENERATING",
      hint: "Command Channel unlocks after the founding crest and assistant avatar finish generating."
    };
  }
  if (reason === "waiting_for_assistant_avatar") {
    return {
      label: "AVATAR GENERATING",
      hint: "Command Channel unlocks after the assistant avatar finishes generating."
    };
  }
  if (directive && directive.id === "open_command_channel") {
    return {
      label: "GENERATION LOCKED",
      hint: "Command Channel unlocks after generation finishes."
    };
  }
  return {
    label: "WAITING",
    hint: "This directive unlocks automatically when the required system work is ready."
  };
}

function getDirectiveMutationAction(directive) {
  if (directive && directive.id === "license_more_mekas") return "";
  if (!directive || directive.id === "archive_stable" || directive.status === "idle" || directive.status === "upcoming" || directive.id === "repair_command_channel" || directive.status === "locked") return "";
  if (directive.id === "open_command_channel") return "seen";
  return "complete";
}

const DIRECTIVE_COMPLETION_RECEIPT_DELAY_MS = 7000;
const DIRECTIVE_COMPLETION_RECEIPT_DISMISS_MS = 14000;
let directiveReceiptAudioContext = null;

function getDirectiveReceiptAudioContext() {
  if (typeof window === "undefined") return null;
  const AudioContextConstructor = window.AudioContext || window.webkitAudioContext;
  if (!AudioContextConstructor) return null;
  if (!directiveReceiptAudioContext) {
    directiveReceiptAudioContext = new AudioContextConstructor();
  }
  return directiveReceiptAudioContext;
}

function primeDirectiveReceiptSound() {
  const context = getDirectiveReceiptAudioContext();
  if (!context || context.state !== "suspended") return;
  context.resume().catch(() => {});
}

function playDirectiveRelayTick(context, destination, startTime, frequency, duration, peakGain) {
  const tick = context.createOscillator();
  const tickFilter = context.createBiquadFilter();
  const tickGain = context.createGain();

  tick.type = "square";
  tick.frequency.setValueAtTime(frequency, startTime);
  tick.frequency.exponentialRampToValueAtTime(frequency * 0.72, startTime + duration);

  tickFilter.type = "bandpass";
  tickFilter.frequency.setValueAtTime(frequency, startTime);
  tickFilter.Q.setValueAtTime(7.5, startTime);

  tickGain.gain.setValueAtTime(0.0001, startTime);
  tickGain.gain.exponentialRampToValueAtTime(peakGain, startTime + 0.004);
  tickGain.gain.exponentialRampToValueAtTime(0.0001, startTime + duration);

  tick.connect(tickFilter);
  tickFilter.connect(tickGain);
  tickGain.connect(destination);
  tick.start(startTime);
  tick.stop(startTime + duration + 0.012);
  tick.onended = () => {
    tick.disconnect();
    tickFilter.disconnect();
    tickGain.disconnect();
  };
}

function playDirectiveServoSweep(context, destination, startTime) {
  const servo = context.createOscillator();
  const servoFilter = context.createBiquadFilter();
  const servoGain = context.createGain();

  servo.type = "sawtooth";
  servo.frequency.setValueAtTime(190, startTime);
  servo.frequency.exponentialRampToValueAtTime(92, startTime + 0.2);

  servoFilter.type = "lowpass";
  servoFilter.frequency.setValueAtTime(520, startTime);
  servoFilter.frequency.exponentialRampToValueAtTime(240, startTime + 0.2);
  servoFilter.Q.setValueAtTime(2.2, startTime);

  servoGain.gain.setValueAtTime(0.0001, startTime);
  servoGain.gain.exponentialRampToValueAtTime(0.022, startTime + 0.018);
  servoGain.gain.exponentialRampToValueAtTime(0.0001, startTime + 0.22);

  servo.connect(servoFilter);
  servoFilter.connect(servoGain);
  servoGain.connect(destination);
  servo.start(startTime);
  servo.stop(startTime + 0.24);
  servo.onended = () => {
    servo.disconnect();
    servoFilter.disconnect();
    servoGain.disconnect();
  };
}

function playDirectiveReceiptSound() {
  const context = getDirectiveReceiptAudioContext();
  if (!context) return;
  const play = () => {
    const now = context.currentTime;
    const bus = context.createGain();
    const limiter = context.createDynamicsCompressor();

    limiter.threshold.setValueAtTime(-24, now);
    limiter.knee.setValueAtTime(8, now);
    limiter.ratio.setValueAtTime(8, now);
    limiter.attack.setValueAtTime(0.003, now);
    limiter.release.setValueAtTime(0.12, now);

    bus.gain.setValueAtTime(0.72, now);
    bus.connect(limiter);
    limiter.connect(context.destination);

    playDirectiveRelayTick(context, bus, now + 0.000, 1280, 0.034, 0.035);
    playDirectiveRelayTick(context, bus, now + 0.048, 760, 0.038, 0.026);
    playDirectiveServoSweep(context, bus, now + 0.075);
    playDirectiveRelayTick(context, bus, now + 0.235, 1560, 0.026, 0.018);

    window.setTimeout(() => {
      bus.disconnect();
      limiter.disconnect();
    }, 360);
  };

  if (context.state === "suspended") {
    context.resume().then(play).catch(() => {});
    return;
  }
  play();
}

function getDirectiveItemById(onboarding, directiveId) {
  const items = onboarding && onboarding.directives && Array.isArray(onboarding.directives.items)
    ? onboarding.directives.items
    : [];
  return items.find((item) => item && item.id === directiveId) || null;
}

function getDirectiveCompletionLine(directive, nextDirective) {
  const title = directive && (directive.title || directive.label) ? (directive.title || directive.label) : "Directive";
  if (nextDirective && nextDirective.id && nextDirective.id !== directive.id) {
    return title + " logged. I have queued the next archive step when you are ready.";
  }
  return title + " logged. Archive directive queue is clear for now.";
}

function getDispatchDirectiveItemById(progress, directiveId) {
  const directives = Array.isArray(progress && progress.directives) ? progress.directives : [];
  return directives.find((item) => item && item.id === directiveId) || null;
}

function getDispatchDirectiveCompletionLine(directive, nextDirective, progress) {
  const title = directive && directive.label ? directive.label : "Dispatch directive";
  const authority = Number(progress && progress.licenseAuthority || 0);
  const target = Number(progress && progress.licenseAuthorityTarget || 100);
  if (nextDirective && nextDirective.id && nextDirective.id !== directive.id) {
    return title + " logged. License Authority now " + authority + " / " + target + ". Next dispatch step is queued.";
  }
  if (progress && progress.status === "reward_ready") {
    return title + " logged. License Authority is full; registry claim is ready.";
  }
  return title + " logged. License Authority now " + authority + " / " + target + ".";
}

function phaseOneDirectivesAreClear(onboarding) {
  const directives = onboarding && onboarding.directives ? onboarding.directives : null;
  const items = directives && Array.isArray(directives.items) ? directives.items : [];
  if (onboarding && onboarding.assistantGuidance && onboarding.assistantGuidance.reason === "all_directives_complete") return true;
  if (!items.length) return false;
  return items.every((item) => item && (
    item.status === "complete" ||
    item.status === "skipped" ||
    item.completedAt ||
    item.skippedAt
  ));
}

function getDispatchClaimOwnerships(archiveDispatchStatus) {
  const ownerships = Array.isArray(archiveDispatchStatus && archiveDispatchStatus.ownerships)
    ? archiveDispatchStatus.ownerships
    : [];
  return ownerships.filter((ownership) => ownership && ownership.ownershipClass === "dispatch_claim");
}

function getLicenseMoreMekasObjectiveState(onboardingStatus, archiveDispatchStatus) {
  const onboarding = onboardingStatus && onboardingStatus.data ? onboardingStatus.data : onboardingStatus;
  const { entries, progress } = getArchiveDispatchBundle(archiveDispatchStatus);
  if (getDispatchClaimOwnerships(archiveDispatchStatus).length > 0) return "complete";
  if (progress && (progress.status === "complete" || progress.claimedOwnership)) return "complete";
  if (!phaseOneDirectivesAreClear(onboarding)) return "future";
  const dispatchEndState = getArchiveDispatchEndState(archiveDispatchStatus);
  if (dispatchEndState.reason === "sold_out") return "future";
  if (progress && ["available", "target_needed", "in_progress", "reward_ready", "retarget_required"].includes(progress.status)) return "active";
  if (entries.some((entry) => entry.availability && entry.availability.state === "available")) return "active";
  return "future";
}

function getLicenseMoreMekasDirective(onboarding, archiveDispatchStatus) {
  if (getLicenseMoreMekasObjectiveState(onboarding, archiveDispatchStatus) !== "active") return null;
  const { dispatch, progress } = getArchiveDispatchBundle(archiveDispatchStatus);
  const currentDispatchDirective = progress && progress.currentDirective ? progress.currentDirective : null;
  const dispatchTitle = dispatch && dispatch.title ? dispatch.title : "this week's Archive Dispatch";
  let targetHref = currentDispatchDirective ? getArchiveDispatchRouteTarget(currentDispatchDirective) : "#archive-dispatch";
  let actionLabel = "OPEN DISPATCH";
  let copy = "Phase 1 directives are clear. Open " + dispatchTitle + ", select a claim target, and build License Authority to license another Meka.";

  if (progress && progress.status === "reward_ready") {
    targetHref = "#hangar";
    actionLabel = "CLAIM MEKA";
    copy = "License Authority is full. Claim your selected dispatch Meka before the weekly roster closes.";
  } else if (progress && progress.status === "retarget_required") {
    copy = "Your previous target was secured by another operator. Retarget the weekly dispatch and reverify target-specific proof.";
  } else if (currentDispatchDirective && currentDispatchDirective.label) {
    copy = "Next dispatch step: " + currentDispatchDirective.label + ". Keep going to claim a weekly Meka for your organization roster.";
  }

  return {
    id: "license_more_mekas",
    status: "available",
    label: "License more Mekas",
    title: "License more Mekas",
    copy,
    requiredAction: "license_more_mekas",
    targetHref,
    actionLabel
  };
}

async function openLicenseMoreMekasDirective(directive, archiveDispatchStatus, onDispatchDirectiveCompleted) {
  if (!directive || directive.id !== "license_more_mekas") return false;
  const { progress } = getArchiveDispatchBundle(archiveDispatchStatus);
  const shouldStartDispatch = !progress || progress.status === "available";
  if (shouldStartDispatch && archiveDispatchStatus && typeof archiveDispatchStatus.startDispatch === "function") {
    try {
      const result = await archiveDispatchStatus.startDispatch();
      if (result && typeof onDispatchDirectiveCompleted === "function") {
        onDispatchDirectiveCompleted("open_archive_dispatch", result);
      }
    } catch (error) {
      // Dispatch state owns mutation errors; the directive button should not leak a rejected click.
    }
  }
  return true;
}

function getPostLicenseArchiveDirective(onboarding, archiveDispatchStatus) {
  if (!phaseOneDirectivesAreClear(onboarding)) return null;
  if (getLicenseMoreMekasObjectiveState(onboarding, archiveDispatchStatus) !== "complete") return null;
  return {
    id: "enter_official_battles",
    status: "upcoming",
    label: "Enter official battles",
    title: "Battle Arena standby",
    copy: "Next objective: enter official battles. Arena systems are not live yet, so keep the roster ready, review your licensed units, and watch for the Battle Arena command cycle.",
    requiredAction: "future_battle_arena",
    targetHref: "#hangar",
    actionLabel: "VIEW ROSTER"
  };
}

function DirectiveCompletionTransmission({ receipt, onDismiss }) {
  if (!receipt) return null;
  return (
    <aside className="directive-completion-transmission" aria-live="polite" aria-atomic="true">
      <div className="directive-completion-card" role="status">
        <div className="directive-completion-avatar" aria-hidden="true">
          {receipt.avatarSource ? (
            <img src={receipt.avatarSource} alt="" loading="lazy" />
          ) : (
            <span>AI</span>
          )}
        </div>
        <div className="directive-completion-copy">
          <div className="directive-completion-kicker">{receipt.assistantName} / DIRECTIVE RECEIPT</div>
          <h3>{receipt.title}</h3>
          <p>{receipt.line}</p>
          {receipt.nextTitle && <b>NEXT: {receipt.nextTitle}</b>}
        </div>
        <button type="button" className="directive-completion-dismiss" onClick={onDismiss} aria-label="Dismiss directive confirmation">
          CLOSE
        </button>
      </div>
    </aside>
  );
}

function getDirectivePresentation(onboardingStatus, starterMech, archiveDispatchStatus) {
  const onboarding = onboardingStatus && onboardingStatus.data ? onboardingStatus.data : null;
  const directive = getCurrentDirective(onboarding, starterMech, archiveDispatchStatus);
  const panelState = getDirectivePanelState(onboarding, directive);
  const title = directive && (directive.title || directive.label) ? (directive.title || directive.label) : "Archive stable";
  const copy = directive && directive.copy
    ? directive.copy
    : "Archive stable. Weekly drops will update the next directive.";
  const targetHref = directive && directive.targetHref ? directive.targetHref : "#archive";
  const dispatchIsBusy = Boolean(directive && directive.id === "license_more_mekas" && archiveDispatchStatus && archiveDispatchStatus.actionBusy);
  const isBusy = Boolean(onboardingStatus && onboardingStatus.actionBusy === "directive:" + directive.id) || dispatchIsBusy;
  const statusLabel = directive && directive.status === "idle" ? "stable" : (directive && directive.status ? directive.status : panelState);
  const lockedActionCopy = panelState === "locked" ? getDirectiveLockedActionCopy(onboarding, directive) : null;
  const actionDisabled = Boolean(lockedActionCopy);
  const actionLabel = actionDisabled ? lockedActionCopy.label : getDirectiveActionLabel(directive, panelState);
  const actionHint = lockedActionCopy ? lockedActionCopy.hint : "";
  return { directive, panelState, title, copy, targetHref, isBusy, statusLabel, actionDisabled, actionLabel, actionHint };
}

function activateDirectiveTarget(targetHref) {
  if (typeof window === "undefined") return normalizeDirectiveTargetHref(targetHref);
  const normalizedTargetHref = normalizeDirectiveTargetHref(targetHref);
  if (window.location.hash !== normalizedTargetHref) {
    history.pushState(null, "", window.location.pathname + window.location.search + normalizedTargetHref);
    window.dispatchEvent(new Event("hashchange"));
  }
  window.setTimeout(() => {
    scrollToRouteHashSection(normalizedTargetHref, "smooth");
  }, 40);
  return normalizedTargetHref;
}

function OperatorDirectivePanel({ onboardingStatus, starterMech, archiveDispatchStatus, onDirectiveCompleted, onDispatchDirectiveCompleted }) {
  const { directive, panelState, title, copy, targetHref, isBusy, statusLabel, actionDisabled, actionLabel, actionHint } = getDirectivePresentation(onboardingStatus, starterMech, archiveDispatchStatus);

  async function activateDirective() {
    if (actionDisabled) return;
    if (!directive) return;
    const mutationAction = getDirectiveMutationAction(directive);
    if (mutationAction === "complete") primeDirectiveReceiptSound();
    activateDirectiveTarget(targetHref);
    if (await openLicenseMoreMekasDirective(directive, archiveDispatchStatus, onDispatchDirectiveCompleted)) return;
    if (mutationAction && onboardingStatus && typeof onboardingStatus.recordDirective === "function") {
      const result = await onboardingStatus.recordDirective(directive.id, mutationAction);
      if (mutationAction === "complete" && result && typeof onDirectiveCompleted === "function") {
        onDirectiveCompleted(directive, result);
      }
    }
  }

  return (
    <section className={"operator-directive-panel is-" + panelState} aria-label="Next Directive">
      <div className="operator-directive-head">
        <span>NEXT DIRECTIVE</span>
        <b>{String(statusLabel).replace(/_/g, " ")}</b>
      </div>
      <div className="operator-directive-copy">
        <h3>{title}</h3>
        <p>{copy}</p>
      </div>
      <div className="operator-directive-actions">
        <button type="button" className="btn primary" onClick={activateDirective} disabled={isBusy || actionDisabled}>
          {isBusy ? "SYNCING..." : actionLabel}
        </button>
        {actionHint && <p className="directive-action-hint">{actionHint}</p>}
      </div>
    </section>
  );
}

function AssistantDirectiveBrief({
  onboardingStatus,
  starterMech,
  archiveDispatchStatus,
  avatarSource,
  assistantLoading = false,
  avatarLoadingTitle = "AVATAR STANDBY",
  avatarLoadingLine = "WAITING FOR FINAL AVATAR",
  onDirectiveCompleted,
  onDispatchDirectiveCompleted
}) {
  const { directive, panelState, title, copy, targetHref, isBusy, statusLabel, actionDisabled, actionLabel, actionHint } = getDirectivePresentation(onboardingStatus, starterMech, archiveDispatchStatus);
  const directiveLabel = "NEXT DIRECTIVE";
  const avatarIsLoading = Boolean(assistantLoading && !avatarSource);

  async function activateDirective(event) {
    event.stopPropagation();
    if (actionDisabled) return;
    if (!directive) return;
    const mutationAction = getDirectiveMutationAction(directive);
    if (mutationAction === "complete") primeDirectiveReceiptSound();
    activateDirectiveTarget(targetHref);
    if (await openLicenseMoreMekasDirective(directive, archiveDispatchStatus, onDispatchDirectiveCompleted)) return;
    if (mutationAction && onboardingStatus && typeof onboardingStatus.recordDirective === "function") {
      const result = await onboardingStatus.recordDirective(directive.id, mutationAction);
      if (mutationAction === "complete" && result && typeof onDirectiveCompleted === "function") {
        onDirectiveCompleted(directive, result);
      }
    }
  }

  return (
    <div className={"assistant-directive-brief is-" + panelState} onClick={(event) => event.stopPropagation()}>
      <div className="assistant-directive-lead">
        <div className={"assistant-directive-avatar" + (avatarIsLoading ? " is-loading" : "")} aria-hidden="true">
          {avatarSource ? (
            <img src={avatarSource} alt="" loading="lazy" />
          ) : avatarIsLoading ? (
            <div className="assistant-directive-avatar-loading">
              <i></i>
              <i></i>
              <i></i>
              <b>{avatarLoadingTitle}</b>
              <span>{avatarLoadingLine}</span>
            </div>
          ) : (
            <span>AI</span>
          )}
        </div>
        <div className="assistant-directive-title">
          <div className="assistant-directive-head">
            <span>{directiveLabel}</span>
            <b>{String(statusLabel).replace(/_/g, " ")}</b>
          </div>
          <h3>{title}</h3>
        </div>
      </div>
      <p>{copy}</p>
      <div className="assistant-directive-actions">
        <button type="button" className="btn primary" onClick={activateDirective} disabled={isBusy || actionDisabled}>
          {isBusy ? "SYNCING..." : actionLabel}
        </button>
        {actionHint && <p className="directive-action-hint">{actionHint}</p>}
      </div>
    </div>
  );
}

function getArchiveObjectiveState(objective, onboardingStatus, organization, archiveDispatchStatus) {
  const onboarding = onboardingStatus && onboardingStatus.data ? onboardingStatus.data : null;
  if (objective.id === "build_organization") {
    if (organization || (onboarding && onboarding.organization)) return "complete";
    if (getGenerationCheckpointState(onboarding, "organization_registered") === "complete") return "complete";
    return "active";
  }
  if (objective.id === "complete_dossiers") {
    return phaseOneDirectivesAreClear(onboarding) ? "complete" : "active";
  }
  if (objective.id === "license_more_mekas") {
    return getLicenseMoreMekasObjectiveState(onboardingStatus, archiveDispatchStatus);
  }
  return objective.state;
}

function UniverseObjectivesPanel({ onboardingStatus, organization, archiveDispatchStatus }) {
  const objectives = [
    { id: "build_organization", label: "Build an organization", state: "active" },
    { id: "complete_dossiers", label: "Complete dossiers", state: "active" },
    { id: "license_more_mekas", label: "License more Mekas", state: "future" },
    { id: "enter_official_battles", label: "Enter official battles", state: "future" },
    { id: "publish_battle_reports", label: "Publish battle reports", state: "future" },
    { id: "earn_hall_of_fame", label: "Earn Hall of Fame recognition", state: "future" }
  ];
  return (
    <section className="universe-objectives-panel" aria-label="Archive Objective">
      <div className="universe-objectives-head">
        <span>ARCHIVE OBJECTIVE</span>
      </div>
      <p>Build an organization around your starter, expand your licensed roster, and turn battle reports into public recognition.</p>
      <div className="universe-objectives-list">
        {objectives.map((objective, index) => {
          const state = getArchiveObjectiveState(objective, onboardingStatus, organization, archiveDispatchStatus);
          const stateClass = state === "future" ? " is-future" : (state === "complete" ? " is-complete" : "");
          const statusLabel = state === "future" ? "PENDING" : (state === "complete" ? "COMPLETE" : "ACTIVE");
          return (
            <div className={"universe-objective-row" + stateClass} key={objective.label}>
              <span>{String(index + 1).padStart(2, "0")}</span>
              <b>{objective.label}</b>
              <em>{statusLabel}</em>
            </div>
          );
        })}
      </div>
    </section>
  );
}

function VirtualAssistantAvatarDialogue({ account, organization, starterMech, onboardingStatus, onboarding, archiveDispatchStatus, onDirectiveCompleted, onDispatchDirectiveCompleted }) {
  const [dialogueIndex, setDialogueIndex] = useState(0);
  const resolvedOnboarding = onboardingStatus && onboardingStatus.data ? onboardingStatus.data : onboarding;
  const guidance = resolvedOnboarding && resolvedOnboarding.assistantGuidance ? resolvedOnboarding.assistantGuidance : null;
  const directive = getCurrentDirective(resolvedOnboarding, starterMech, archiveDispatchStatus);
  const organizationLogoIsPending = Boolean(organization && ["queued", "processing"].includes(organization.logoStatus));
  const assistantIsPending = Boolean(organization && ["queued", "processing"].includes(organization.avatarStatus));
  const assistantReady = Boolean(organization && organization.logoStatus === "generated" && organization.avatarStatus === "generated" && organization.avatarUrl);
  const guidanceState = String(guidance && guidance.state || "");
  const directiveIsAvailable = Boolean(directive && directive.status === "available" && directive.id !== "archive_stable");
  const effectiveGuidanceState = directiveIsAvailable && guidanceState === "idle" ? "directive_available" : guidanceState;
  const showAssistantLoading = assistantIsPending || organizationLogoIsPending || !assistantReady || effectiveGuidanceState === "locked" || effectiveGuidanceState === "error";
  const assistantName = organization && organization.assistantName ? organization.assistantName : "MIRA";
  const operatorName = account && account.user ? account.user.username : "Operator";
  const organizationName = organization && organization.name ? organization.name : "your organization";
  const starterLabel = starterMech ? starterMech.id + " / " + starterMech.codename : "starter unit";
  const directiveTitle = directive && (directive.title || directive.label) ? (directive.title || directive.label) : "Archive stable";
  const avatarSource = assistantReady ? getAssistantAvatarSource(organization) : "";
  const avatarLoadingTitle = organizationLogoIsPending ? "CREST GENERATING" : (assistantIsPending ? "AVATAR GENERATION" : "AVATAR STANDBY");
  const avatarLoadingLine = organizationLogoIsPending ? "FINAL LOGO REQUIRED FIRST" : (assistantIsPending ? "SYNCING CREST REFERENCE" : "WAITING FOR FINAL AVATAR");
  const pendingDialogueLines = effectiveGuidanceState === "error" ? [
    "GENERATION ACTION REQUIRED BEFORE THE COMMAND CHANNEL CAN OPEN",
    "STARTER ASSIGNMENT SECURE",
    "REVIEW GENERATION STATUS TO REPAIR THE CHANNEL"
  ] : organizationLogoIsPending ? [
    "COMMAND CHANNEL WAITING ON CREST VERIFICATION",
    "AVATAR SYNC WILL BEGIN AFTER CREST VERIFICATION",
    "STARTER ASSIGNMENT SECURE"
  ] : assistantIsPending ? [
    "ASSISTANT AVATAR GENERATION IN PROGRESS",
    "SYNCING CREST REFERENCE",
    "STARTER ASSIGNMENT SECURE"
  ] : [
    "ASSISTANT AVATAR IS NOT READY YET",
    "STARTER ASSIGNMENT SECURE",
    "OPEN GENERATION STATUS TO RESUME THE CHANNEL"
  ];
  const readyDialogueLines = [
    effectiveGuidanceState === "idle"
      ? "Archive stable, " + operatorName + ". Weekly drops will update the next directive."
      : "Next directive from " + assistantName + ": " + directiveTitle + ".",
    effectiveGuidanceState === "directive_available"
      ? "Next directive logged: " + ((directive && (directive.title || directive.label)) || "review archive status") + "."
      : starterLabel + " is standing by in the owned starter bay.",
    "Welcome back, " + operatorName + ". " + organizationName + " command channel is online.",
    "Your archive loop is inspect, collect, complete directives, and prepare reports.",
    "Battle reports and Hall of Fame records come next."
  ];
  const dialogueLines = showAssistantLoading ? pendingDialogueLines : readyDialogueLines;
  const activeLine = dialogueLines[dialogueIndex % dialogueLines.length];
  const speakerLabel = showAssistantLoading ? "SYSTEM STATUS" : assistantName;

  useEffect(() => {
    setDialogueIndex(0);
  }, [organization && organization.id, starterMech && starterMech.id, assistantIsPending, organizationLogoIsPending]);

  function advanceAssistantDialogue() {
    setDialogueIndex((current) => (current + 1) % dialogueLines.length);
  }

  function handleAssistantKey(event) {
    if (event.key === "Enter" || event.key === " ") {
      event.preventDefault();
      advanceAssistantDialogue();
    }
  }

  return (
    <section
      className={"assistant-dialogue-panel" + (showAssistantLoading ? " is-loading" : "") + (assistantReady ? " is-generated" : "")}
      aria-label="Virtual assistant dialogue"
      tabIndex={0}
      onClick={advanceAssistantDialogue}
      onKeyDown={handleAssistantKey}
    >
      <div className="assistant-panel-tag">{assistantName}</div>
      <div className="assistant-avatar-stage">
        {showAssistantLoading ? (
          <div className="assistant-avatar-loading" role="status" aria-live="polite">
            <i></i>
            <i></i>
            <i></i>
            <b>{avatarLoadingTitle}</b>
            <span>{avatarLoadingLine}</span>
          </div>
        ) : (
          <img src={avatarSource} alt={assistantName + " virtual assistant avatar"} loading="lazy" />
        )}
      </div>
      <div className="assistant-dialogue-box">
        <AssistantDirectiveBrief
          onboardingStatus={onboardingStatus}
          starterMech={starterMech}
          archiveDispatchStatus={archiveDispatchStatus}
          avatarSource={avatarSource}
          assistantLoading={showAssistantLoading}
          avatarLoadingTitle={avatarLoadingTitle}
          avatarLoadingLine={avatarLoadingLine}
          onDirectiveCompleted={onDirectiveCompleted}
          onDispatchDirectiveCompleted={onDispatchDirectiveCompleted}
        />
        <div className="assistant-speaker">{speakerLabel}</div>
        <p>{activeLine}</p>
        <div className="assistant-dialogue-foot">
          <span>{dialogueIndex + 1} / {dialogueLines.length}</span>
          <b>CLICK OR TAP TO ADVANCE</b>
        </div>
      </div>
    </section>
  );
}

function HangarBay({ engagement, onOpen, onOpenOrganization, onOpenCertificate, onOpenCertificateVault, account, registry, onboardingStatus, archiveDispatchStatus, onSignupStarterIntent, onDirectiveCompleted, onDispatchDirectiveCompleted, onRegistryClaim }) {
  const ownedMechs = getOrganizationRosterMechs(account, archiveDispatchStatus);
  const hangarLimit = getHangarLimit();
  const openSlots = Math.max(0, hangarLimit - ownedMechs.length);
  const displayMechs = ownedMechs.length ? ownedMechs : STARTER_PREVIEW_ROSTER;
  const previewMode = ownedMechs.length === 0;
  const accountOrganization = getAccountOrganization(account);
  const organizationStarterMech = accountOrganization && accountOrganization.starterMechId
    ? findMechById(accountOrganization.starterMechId)
    : null;
  const isSignedInDashboard = Boolean(account && account.status === "signed-in" && accountOrganization);
  const archiveDispatchUnlocked = Boolean(isSignedInDashboard && phaseOneDirectivesAreClear(onboardingStatus && onboardingStatus.data));
  const dispatchEndState = getArchiveDispatchEndState(archiveDispatchStatus);
  const dispatchPanelResting = archiveDispatchUnlocked && dispatchEndState.closed;
  const [activeId, setActiveId] = useState(displayMechs[0] ? displayMechs[0].id : null);
  const [manualStarterSelection, setManualStarterSelection] = useState(false);
  const defaultableStarterId = previewMode && !manualStarterSelection
    ? findFirstAvailableStarterId(registry, accountOrganization, displayMechs)
    : "";
  const visibleActiveId = defaultableStarterId || activeId;
  const activeMech = findMechById(visibleActiveId) || displayMechs[0];
  const activeOwnership = getOrganizationRosterOwnership(account, archiveDispatchStatus, activeMech);
  const activeIsOwned = Boolean(activeOwnership) || Boolean(activeMech && ownedMechs.some((mech) => mech.id === activeMech.id));
  const activeIsStarter = Boolean(accountOrganization && activeMech && accountOrganization.starterMechId === activeMech.id);
  const activeOwnedLabel = previewMode ? "PREVIEW FORMATION" : getOwnedRosterUnitLabel(activeOwnership, activeIsStarter);
  const formationMechs = getFormationDisplayMechs(displayMechs, activeMech && activeMech.id);
  const formationIsReordered = Boolean(displayMechs[0] && activeMech && displayMechs[0].id !== activeMech.id);
  const activeStarterAvailability = getStarterClaimAvailability(activeMech ? activeMech.id : "", registry, accountOrganization);
  const activeOwnedStatus = previewMode ? activeStarterAvailability.label : getOwnedRosterUnitStatus(accountOrganization, activeOwnership, activeIsStarter);
  const hangarClaimIsClaimed = previewMode && activeStarterAvailability.state === "claimed";
  const hangarClaimIsBlocked = previewMode && activeStarterAvailability.blocked;
  const nextAvailableStarterId = activeMech
    ? findNextAvailableStarterId(activeMech.id, registry, accountOrganization, displayMechs)
    : "";
  const canSelectNextAvailableStarter = activeStarterAvailability.state === "claimed" && nextAvailableStarterId && nextAvailableStarterId !== activeMech.id;
  const hangarDockStatus = previewMode ? activeStarterAvailability.label : activeOwnedStatus;
  const hangarDockCopy = previewMode && activeStarterAvailability.state === "claimed"
    ? (activeMech ? activeMech.id + " / " + activeMech.codename : "This starter") + " is already anchored to a registered organization. Select the next available starter, or sign in if this is your organization."
    : previewMode
      ? activeStarterAvailability.detail
      : getOwnedRosterUnitCopy(activeMech, activeOwnership, accountOrganization);

  function selectActiveStarter(nextId, manual = true) {
    setActiveId(nextId);
    if (manual) setManualStarterSelection(true);
  }

  function claimActiveStarter(activeStarterId) {
    if (!activeStarterId) return;
    if (onSignupStarterIntent) onSignupStarterIntent(activeStarterId);
    window.location.hash = "#signup";
  }

  function selectNextAvailableStarterInHangar(activeStarterId) {
    if (!activeStarterId) return;
    const nextId = findNextAvailableStarterId(activeStarterId, registry, accountOrganization, displayMechs);
    if (nextId && nextId !== activeStarterId) selectActiveStarter(nextId);
  }

  function handleHangarSelectionKeyDown(event) {
    const isPreviousKey = event.key === "ArrowLeft";
    const isNextKey = event.key === "ArrowRight";
    if (!isPreviousKey && !isNextKey) return;
    event.preventDefault();
    const direction = isPreviousKey ? -1 : 1;
    const nextId = getAdjacentPreviewMechId(displayMechs, activeMech && activeMech.id, direction);
    if (nextId) selectActiveStarter(nextId);
  }

  useEffect(() => {
    if (!displayMechs.length) return;
    if (!activeId || !displayMechs.some((mech) => mech.id === activeId)) {
      const defaultStarterId = previewMode
        ? findFirstAvailableStarterId(registry, accountOrganization, displayMechs)
        : displayMechs[0].id;
      setActiveId(defaultStarterId);
      setManualStarterSelection(false);
    }
  }, [
    displayMechs.map((mech) => mech.id).join("|"),
    previewMode,
    registry && registry.status,
    Object.keys((registry && registry.ownership) || {}).join("|"),
    accountOrganization && accountOrganization.id
  ]);

  useEffect(() => {
    if (!previewMode || manualStarterSelection || !activeMech || !registry || registry.status !== "ready") return;
    const firstAvailableId = findFirstAvailableStarterId(registry, accountOrganization, displayMechs);
    if (firstAvailableId && firstAvailableId !== activeMech.id) {
      selectActiveStarter(firstAvailableId, false);
    }
  }, [
    previewMode,
    manualStarterSelection,
    activeMech && activeMech.id,
    registry && registry.status,
    Object.keys((registry && registry.ownership) || {}).join("|"),
    accountOrganization && accountOrganization.id
  ]);

  const hangarTelemetry = (
    <>
      <CombatProfilePanel mech={activeMech} />
      <div className="hangar-readouts">
        <div><span>OWNED</span><b>{String(ownedMechs.length).padStart(2, "0")}</b></div>
        <div><span>TYPE</span><b>{previewMode ? (activeIsOwned ? "OWNED" : "STARTER") : (activeIsStarter ? "STARTER" : "CLAIM")}</b></div>
        <div><span>FREE</span><b>{String(openSlots).padStart(2, "0")}</b></div>
      </div>
    </>
  );

  const hangarFormation = (
    <div className={"epic-hangar" + (previewMode ? " is-preview" : "")}>
      <div
        className={"epic-hangar-stage" + (formationIsReordered ? " is-reordered" : "")}
        aria-label={previewMode
          ? "Preview Formation carousel: " + FORMATION_VISIBLE_SLOT_COUNT + " visible slots from " + displayMechs.length + " selectable Mekas"
          : "Owned Meka hangar formation"}
        tabIndex={0}
        onKeyDownCapture={handleHangarSelectionKeyDown}
      >
        <div className="hangar-ceiling"></div>
        <div className="hangar-backwall"></div>
        <div className="hangar-floor"></div>
        {formationMechs.map((mech, index) => (
          <button
            key={mech.id + "-slot-" + (index + 1)}
            type="button"
            className={"hangar-unit hangar-slot-" + (index + 1) + (activeMech && activeMech.id === mech.id ? " active" : "")}
            onClick={() => selectActiveStarter(mech.id)}
            aria-label={"Select " + mech.id + " " + mech.codename + " in hangar" + getHangarPreviewAvailabilityLabel(mech, previewMode, registry, accountOrganization)}
            aria-pressed={Boolean(activeMech && activeMech.id === mech.id)}
            style={getHangarCropStyle(mech)}
          >
            <HangarPreviewImage mech={mech} alt="" />
            <span>{mech.id}</span>
          </button>
        ))}
        {previewMode && (
          <HangarSelectionControls displayMechs={displayMechs} activeMech={activeMech} onSelect={selectActiveStarter} />
        )}
        <div className="hangar-platform">
          <span>DOCKING LINE</span>
          <b>{formationMechs.length}-SLOT WINDOW / {displayMechs.length} ROSTER</b>
        </div>
      </div>

      {previewMode && (
        <div className="hangar-stage-dock" aria-label="Selected Meka telemetry">
          <div className="hangar-dock-brief">
            <span>STARTER UNIT STATUS</span>
            <b>{hangarDockStatus}</b>
            <p>{hangarDockCopy}</p>
          </div>
          {hangarTelemetry}
        </div>
      )}

      <aside className="epic-hangar-panel">
        <div className="hangar-panel-title">
          <div className="panel-kicker">{previewMode ? "PREVIEW FORMATION" : activeOwnedLabel}</div>
          <h3>{activeMech ? activeMech.id + " / " + activeMech.codename : "No Owned Unit"}</h3>
          <div className="owned-starter-status" aria-label={"Selected roster unit status " + (previewMode ? activeStarterAvailability.label : activeOwnedStatus)}>
            <span>STATUS</span>
            <b>{previewMode ? activeStarterAvailability.label : activeOwnedStatus}</b>
          </div>
        </div>
        <p>
          {previewMode
            ? "Create an account to claim one starter unit. Future acquisition systems will unlock more owned mekas."
            : getOwnedRosterUnitCopy(activeMech, activeOwnership, accountOrganization)}
        </p>
        {previewMode && (
          <div className={"hangar-panel-actions" + (hangarClaimIsClaimed ? " is-claimed" : "")}>
            {hangarClaimIsClaimed ? (
              <>
                <div className="hangar-claim-status">CLAIM UNAVAILABLE: {activeStarterAvailability.label}</div>
                <button type="button" className="btn primary" onClick={() => selectNextAvailableStarterInHangar(activeMech ? activeMech.id : "")} disabled={!canSelectNextAvailableStarter}>
                SELECT NEXT AVAILABLE
                </button>
              </>
            ) : hangarClaimIsBlocked ? (
              <div className="hangar-claim-status">{activeStarterAvailability.label}</div>
            ) : (
              <button type="button" className="btn primary" onClick={() => claimActiveStarter(activeMech ? activeMech.id : "")}>USE THIS STARTER</button>
            )}
            <a className="btn" href="#archive">BROWSE INDEX</a>
          </div>
        )}
        {previewMode && <MechaPreviewDossier mech={activeMech} availability={activeStarterAvailability} />}
        {!previewMode && activeMech && (
          <div className="hangar-panel-actions">
            <button type="button" className="btn primary" onClick={() => onOpen(activeMech.id)}>OPEN DOSSIER</button>
          </div>
        )}
        {!previewMode && hangarTelemetry}
      </aside>
    </div>
  );

  return (
    <>
      <section id="hangar" className={"section hangar-section" + (isSignedInDashboard ? " is-dashboard" : "")} data-screen-label="Hangar Bay">
      <div className="section-inner">
        <div className="section-head">
          <div>
            <div className="label">SECTION · 01 / OPERATOR BAY</div>
            <h2>My Hangar</h2>
          </div>
          <div className="right">ACCOUNT OWNERSHIP · STARTER UNIT</div>
        </div>

        {isSignedInDashboard ? (
          <div className="operator-dashboard">
            <div className="dashboard-owned-starter">
              {hangarFormation}
              <OwnedRosterStrip account={account} archiveDispatchStatus={archiveDispatchStatus} activeMech={activeMech} onSelect={selectActiveStarter} />
            </div>
            <div className="operator-dashboard-side">
              {archiveDispatchUnlocked && !dispatchPanelResting && <CommandDispatchPanel account={account} archiveDispatchStatus={archiveDispatchStatus} onOpen={onOpen} onSelectOwned={selectActiveStarter} onClaimComplete={onRegistryClaim} onDispatchDirectiveCompleted={onDispatchDirectiveCompleted} />}
              <CertificateVaultPanel account={account} archiveDispatchStatus={archiveDispatchStatus} onOpenVault={onOpenCertificateVault} />
              <VirtualAssistantAvatarDialogue account={account} organization={accountOrganization} starterMech={organizationStarterMech} onboardingStatus={onboardingStatus} archiveDispatchStatus={archiveDispatchStatus} onDirectiveCompleted={onDirectiveCompleted} onDispatchDirectiveCompleted={onDispatchDirectiveCompleted} />
              <UniverseObjectivesPanel onboardingStatus={onboardingStatus} organization={accountOrganization} archiveDispatchStatus={archiveDispatchStatus} />
              <OrganizationConsole starterMech={organizationStarterMech} account={account} registry={registry} compact onSelectStarter={selectActiveStarter} />
              {archiveDispatchUnlocked && dispatchPanelResting && <CommandDispatchPanel account={account} archiveDispatchStatus={archiveDispatchStatus} onOpen={onOpen} onSelectOwned={selectActiveStarter} onClaimComplete={onRegistryClaim} onDispatchDirectiveCompleted={onDispatchDirectiveCompleted} placement="sidebar-bottom" />}
            </div>
          </div>
        ) : (
          <div className="unclaimed-hangar-claim">
            {hangarFormation}
            <HeroClaimConsole
              starterMech={activeMech}
              availability={activeStarterAvailability}
              onUseStarter={() => claimActiveStarter(activeMech ? activeMech.id : "")}
              onSelectNext={() => selectNextAvailableStarterInHangar(activeMech ? activeMech.id : "")}
              canSelectNextAvailable={canSelectNextAvailableStarter}
            />
          </div>
        )}

      </div>
      </section>
      <OrganizationDirectory registry={registry} account={account} onOpenOrganization={onOpenOrganization} />
    </>
  );
}

function CommsSection({ engagement, engagementDispatch }) {
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [type, setType] = useState("INQUIRY");
  const [message, setMessage] = useState("");
  const [errors, setErrors] = useState({});
  const [sent, setSent] = useState(null); // { seq, ts }
  const inboxCount = engagement.comms && engagement.comms.inbox ? engagement.comms.inbox.length : 0;
  const commsContext = engagement.comms ? engagement.comms.context : null;

  function validate() {
    const e = {};
    if (!name.trim()) e.name = "REQUIRED";
    if (!email.trim()) e.email = "REQUIRED";
    else if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email.trim())) e.email = "INVALID FORMAT";
    if (!message.trim()) e.message = "REQUIRED";
    else if (message.trim().length < 8) e.message = "TOO SHORT";
    setErrors(e);
    return Object.keys(e).length === 0;
  }

  async function submit(ev) {
    ev.preventDefault();
    if (!validate()) return;

    const next = engagementDispatch({
      type: "COMMS_SUBMITTED",
      transmission: {
        name: name.trim(),
        email: email.trim(),
        type,
        message: message.trim(),
        context: commsContext
      }
    });
    const inbox = next.comms && next.comms.inbox ? next.comms.inbox : [];
    const entry = inbox[inbox.length - 1];
    setSent(entry);
  }

  function reset() {
    setName(""); setEmail(""); setType("INQUIRY"); setMessage(""); setErrors({}); setSent(null);
  }

  return (
    <section id="comms" className="section" data-screen-label="Comms">
      <div className="section-inner">
        <div className="section-head">
          <div>
            <div className="label">SECTION · 04 / OPEN COMMS</div>
            <h2>Send A Transmission</h2>
          </div>
          <div className="right">REPLIES ON THE NEXT CYCLE · NOT REAL-TIME</div>
        </div>

        <div className="comms-grid">
          <div className="comms-form-wrap">
            {sent ? (
              <div className="comms-success">
                <div className="cs-stamp">RECEIVED</div>
                <div className="cs-seq">TRANSMISSION · {sent.id}</div>
                <h3 className="cs-line">SIGNAL LOCKED.</h3>
                <p className="cs-msg">
                  Your message has been logged under sequence
                  <b> {sent.id}</b>. Use the email channel if you need a guaranteed
                  reply from the maker.
                </p>
                <div className="cs-readout">
                  <div><span>FROM</span><b>{sent.name}</b></div>
                  <div><span>REPLY-TO</span><b>{sent.email}</b></div>
                  <div><span>TYPE</span><b>{sent.type}</b></div>
                  {sent.context && <div><span>RELATED</span><b>{sent.context.mechId} / {sent.context.codename}</b></div>}
                  <div><span>TIMESTAMP</span><b>{new Date(sent.ts).toUTCString()}</b></div>
                </div>
                <button className="btn primary" onClick={reset}>↺ SEND ANOTHER</button>
              </div>
            ) : (
              <form className="comms-form" onSubmit={submit} noValidate>
                <div className="comms-form-head">
                  <span>TRANSMISSION FORM</span>
                  <span>SEQ #{String(inboxCount + 1).padStart(4, "0")} PENDING</span>
                </div>

                {commsContext && (
                  <div className="comms-context-card">
                    <div>
                      <span>RELATED UNIT</span>
                      <b>{commsContext.mechId} / {commsContext.codename}</b>
                    </div>
                    <button type="button" onClick={() => engagementDispatch({ type: "COMMS_CONTEXT_CLEARED" })}>CLEAR</button>
                  </div>
                )}

                <div className="comms-row">
                  <div className="field">
                    <label>01 / Callsign <span className="req">*</span> {errors.name && <em>· {errors.name}</em>}</label>
                    <input
                      type="text"
                      value={name}
                      onChange={(e) => setName(e.target.value)}
                      placeholder="What should I call you?"
                      className={errors.name ? "has-error" : ""}
                      maxLength={60}
                    />
                  </div>
                  <div className="field">
                    <label>02 / Comms Channel <span className="req">*</span> {errors.email && <em>· {errors.email}</em>}</label>
                    <input
                      type="email"
                      value={email}
                      onChange={(e) => setEmail(e.target.value)}
                      placeholder="reply@somewhere.net"
                      className={errors.email ? "has-error" : ""}
                      maxLength={120}
                    />
                  </div>
                </div>

                <div className="field">
                  <label>03 / Transmission Type</label>
                  <div className="comms-type-row">
                    {["INQUIRY", "FEEDBACK", "FAN-MAIL", "PRINT HELP"].map(t => (
                      <button
                        type="button"
                        key={t}
                        className={"type-chip " + (type === t ? "active" : "")}
                        onClick={() => setType(t)}
                      >
                        {t}
                      </button>
                    ))}
                  </div>
                </div>

                <div className="field">
                  <label>04 / Message <span className="req">*</span> {errors.message && <em>· {errors.message}</em>}</label>
                  <textarea
                    value={message}
                    onChange={(e) => setMessage(e.target.value)}
                    placeholder="Type your transmission. The archive listens."
                    rows={6}
                    className={errors.message ? "has-error" : ""}
                    maxLength={2000}
                  />
                  <div className="field-hint">{message.length} / 2000 CHARS</div>
                </div>

                <div className="comms-actions">
                  <button type="submit" className="btn primary">▶ SEND TRANSMISSION</button>
                  <button type="button" className="btn" onClick={() => { setName(""); setEmail(""); setMessage(""); setErrors({}); }}>⨯ CLEAR</button>
                </div>
              </form>
            )}
          </div>

          <aside className="comms-side">
            <div className="comms-side-card">
              <div className="csc-head">★ ARCHIVE INBOX</div>
              <div className="csc-stat">
                <div className="csc-num">{String(inboxCount).padStart(3, "0")}</div>
                <div className="csc-label">TRANSMISSIONS RECEIVED</div>
              </div>
              <div className="csc-list">
                <div className="csc-row"><span>LATENCY</span><b>~ 3 DAYS</b></div>
                <div className="csc-row"><span>REPLY RATE</span><b>87%</b></div>
                <div className="csc-row"><span>BACKLOG</span><b>2 OPEN</b></div>
                <div className="csc-row"><span>STATUS</span><b style={{ color: "var(--ok)" }}>● ONLINE</b></div>
              </div>
            </div>

            <div className="comms-side-card">
              <div className="csc-head">OTHER CHANNELS</div>
              <div className="csc-list">
                <div className="csc-row"><span>EMAIL</span><b>SUPERMEKABOTS@GMAIL.COM</b></div>
                <div className="csc-row"><span>INSTAGRAM</span><b>@SUPERMEKABOTS</b></div>
              </div>
            </div>

            <div className="comms-disclaimer">
              <b>// NOTE</b>
              For direct contact and guaranteed reply routing, email
              supermekabots@gmail.com.
            </div>
          </aside>
        </div>
      </div>
    </section>
  );
}

function AboutLog() {
  return (
    <section id="about" className="section" data-screen-label="About">
      <div className="section-inner">
        <div className="section-head">
          <div>
            <div className="label">SECTION · 05 / ABOUT &amp; LOG</div>
            <h2>The Workshop</h2>
          </div>
          <div className="right">SOLO MAKER · NOT FOR SALE</div>
        </div>
        <div className="about-grid">
          <div className="about-text">
            <p>
              <em>Super Mekabots</em> is a personal mecha-head archive. Each entry
              starts as an <em>AI-generated concept</em> rendered through a tailored
              prompt I've been refining since 2024 — then it gets a hand-written
              dossier, a pilot, a colorway, and (eventually) a printable STL.
            </p>
            <p>
              The line has its own internal rules: every head is a bust silhouette
              between 160–250&nbsp;mm tall, every colorway uses no more than five hues,
              every entry has a named pilot, and every entry has to read as its own
              character at thumbnail size.
            </p>
            <p id="log">
              This site is the canonical index. There is no shop, no patreon, no
              waitlist — if you want to print one, the STL link on its spec page is
              the whole transaction.
            </p>
            <div className="tools-list">
              <div className="tool"><span>Concept</span><b>AI · TAILORED PROMPT</b></div>
              <div className="tool"><span>Sculpt</span><b>BLENDER / NOMAD</b></div>
              <div className="tool"><span>Slice</span><b>LYCHEE · CHITUBOX</b></div>
              <div className="tool"><span>Print</span><b>SATURN 3 / X1C</b></div>
              <div className="tool"><span>Paint</span><b>ACRYLIC · ENAMEL</b></div>
              <div className="tool"><span>Contact</span><b>SUPERMEKABOTS@GMAIL.COM</b></div>
            </div>
          </div>
          <div className="log-block">
            <div className="head">★ CHANGE LOG · MK ID ORDER</div>
            {MEKABOTS_LOG_BY_ID.map((l, i) => (
              <div className="log-row" key={i}>
                <div className="d">{l.date}</div>
                <div className="t">{l.text}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function Footer() {
  return (
    <footer className="foot">
      <div className="foot-mark">
        <div className="b">M</div>
        <div>SUPER MEKABOTS · ARCHIVE V.26.05</div>
      </div>
      <div>© {new Date().getFullYear()} · AI-GENERATED CONCEPTS · NON-COMMERCIAL ARCHIVE</div>
    </footer>
  );
}

const ROUTE_SCROLL_TARGETS = new Set(["#hangar", "#generation", "#assistant-intro", "#registry", "#archive", "#archive-dispatch", "#comms", "#about"]);
const ROUTE_BOOT_MIN_MS = 540;

function scrollToRouteHashSection(routeHash, behavior = "auto") {
  if (!ROUTE_SCROLL_TARGETS.has(routeHash)) return false;
  const targetId = routeHash.slice(1);
  const node = document.getElementById(targetId);
  if (!node) return false;
  node.scrollIntoView({ behavior, block: "start" });
  return true;
}

function redirectSignedInHomeToHangar(accountStatus, onboardingStatus) {
  if (accountStatus !== "signed-in") return "";
  const generationRouteActive = shouldShowGenerationWaitingBay({ status: accountStatus }, onboardingStatus);
  const targetHash = generationRouteActive ? "#generation" : "#hangar";
  const targetId = generationRouteActive ? "generation" : "hangar";
  const currentHash = window.location.hash || "";
  if (currentHash === "#generation" && generationRouteActive) return "";
  if (currentHash && !["#top", "#signin", "#signup", "#founding", "#generation"].includes(currentHash)) return "";
  if (currentHash !== targetHash) {
    history.replaceState(null, "", window.location.pathname + window.location.search + targetHash);
  }
  window.setTimeout(() => {
    const routeTarget = generationRouteActive ? "" : targetHash;
    if (routeTarget && scrollToRouteHashSection(routeTarget)) return;
    const node = document.getElementById(targetId);
    if (node) node.scrollIntoView({ behavior: "smooth", block: "start" });
  }, 40);
  return targetHash;
}

function getInitialRouteBootHash() {
  if (typeof window === "undefined") return "";
  const hash = window.location.hash || "";
  return ROUTE_SCROLL_TARGETS.has(hash) ? hash : "";
}

function routeWasDedicatedAuth(routeHash) {
  return routeHash === "#signin" || routeHash === "#signup" || routeHash === "#founding";
}

function shouldHoldRouteBoot(routeHash, account, onboardingStatus) {
  if (!routeHash) return false;
  if (account && account.status === "checking") return true;
  if (account && account.status === "signed-in") {
    const status = onboardingStatus && onboardingStatus.status;
    return status === "idle" || status === "loading";
  }
  return false;
}

function getRouteBootCopy(routeHash) {
  if (routeHash === "#hangar") {
    return {
      label: "ROUTE SYNC",
      title: "Aligning Hangar Bay",
      copy: "Restoring account link, directive state, and docking line."
    };
  }
  if (routeHash === "#generation" || routeHash === "#assistant-intro") {
    return {
      label: "COMMAND SYNC",
      title: "Opening Command Channel",
      copy: "Restoring assistant intro and founding transmission state."
    };
  }
  if (routeHash === "#archive") {
    return {
      label: "ARCHIVE SYNC",
      title: "Indexing Archive",
      copy: "Preparing the visible roster and registry state."
    };
  }
  if (routeHash === "#registry") {
    return {
      label: "REGISTRY SYNC",
      title: "Opening Registry",
      copy: "Checking operator records before the route resolves."
    };
  }
  return {
    label: "ROUTE SYNC",
    title: "Tuning Navigation",
    copy: "Preparing the requested command surface."
  };
}

function RouteBootTransmission({ routeHash }) {
  const copy = getRouteBootCopy(routeHash);
  return (
    <div className="route-boot-transmission" role="status" aria-live="polite" aria-label={copy.title}>
      <div className="route-boot-panel">
        <div className="route-boot-kicker">
          <span>{copy.label}</span>
          <b>STANDBY</b>
        </div>
        <div className="route-boot-grid">
          <i></i><i></i><i></i>
        </div>
        <div className="route-boot-copy">
          <h2>{copy.title}</h2>
          <p>{copy.copy}</p>
        </div>
        <div className="route-boot-progress" aria-hidden="true"><i></i></div>
      </div>
    </div>
  );
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [openId, setOpenId] = useState(null);
  const [openOrgId, setOpenOrgId] = useState(null);
  const [openOwnershipId, setOpenOwnershipId] = useState(null);
  const [certificateVaultOpen, setCertificateVaultOpen] = useState(false);
  const [registryClaimCeremony, setRegistryClaimCeremony] = useState(null);
  const [ceremonySkipRequested, setCeremonySkipRequested] = useState(false);
  const lastDedicatedSignupRouteRef = useRef(false);
  const [routeHash, setRouteHash] = useState(() => (typeof window !== "undefined" ? window.location.hash || "" : ""));
  const previousRouteHashRef = useRef(routeHash);
  const routeBootStartedAtRef = useRef(typeof performance !== "undefined" ? performance.now() : Date.now());
  const [routeBootHash, setRouteBootHash] = useState(getInitialRouteBootHash);
  const [signupStarterId, setSignupStarterId] = useState(() => {
    const fallbackId = (STARTER_PREVIEW_ROSTER[0] && STARTER_PREVIEW_ROSTER[0].id) || "";
    if (typeof window === "undefined") return fallbackId;
    try {
      return window.sessionStorage.getItem(SIGNUP_STARTER_ID_STORAGE_KEY) || fallbackId;
    } catch (error) {
      return fallbackId;
    }
  });
  const [signupStarterIntentLocked, setSignupStarterIntentLocked] = useState(() => {
    if (typeof window === "undefined") return false;
    try {
      return window.sessionStorage.getItem(SIGNUP_STARTER_INTENT_STORAGE_KEY) === "explicit";
    } catch (error) {
      return false;
    }
  });
  const engagementApi = useEngagementStore();
  const engagement = engagementApi.snapshot;
  const account = useAccountSession();
  const previousAccountStatusRef = useRef(account.status);
  const registry = useOrganizationRegistry(account);
  const onboardingStatus = useOnboardingStatus(account);
  const archiveDispatchStatus = useArchiveDispatchStatus(account);
  const routeDirectiveCompletionRef = useRef("");
  const directiveReceiptTimerRef = useRef(null);
  const directiveReceiptQueueRef = useRef([]);
  const directiveReceiptSeenKeysRef = useRef(new Set());
  const [directiveReceipt, setDirectiveReceipt] = useState(null);
  const routeIsSignup = routeHash === "#signup" || routeHash === "#founding";
  const routeIsSignin = routeHash === "#signin";
  const routeIsGeneration = routeHash === "#generation";
  const routeIsRegisteredOperators = routeHash === REGISTERED_OPERATORS_ROUTE;
  const showGenerationWaitingBay = shouldShowGenerationWaitingBay(account, onboardingStatus);
  const showPublicEntry = account.status === "signed-out" || account.status === "offline" || account.status === "error";
  const accountJustSignedOut = previousAccountStatusRef.current === "signed-in" && account.status === "signed-out";
  const accountOrganization = getAccountOrganization(account);
  const routeIsSignedOutHangar = routeHash === "#hangar" && showPublicEntry && (typeof window === "undefined" || window.location.hash === "#hangar");
  const routeIsDedicatedSignup = routeIsSignup || routeIsSignedOutHangar;
  const routeIsDedicatedAuth = routeIsDedicatedSignup || routeIsSignin;
  const routeIsDedicatedPage = routeIsDedicatedAuth || routeIsRegisteredOperators;
  const routeBootPending = Boolean(routeBootHash);
  const showHero = showPublicEntry && !routeIsDedicatedPage;
  const defaultableSignupStarterId = (routeIsDedicatedSignup || showPublicEntry) && !signupStarterIntentLocked
    ? findFirstAvailableStarterId(registry, accountOrganization, STARTER_PREVIEW_ROSTER)
    : "";
  const storedSignupStarterEligible = isStarterUnitEligible(findMechById(signupStarterId));
  const safeSignupStarterId = storedSignupStarterEligible ? signupStarterId : ((STARTER_PREVIEW_ROSTER[0] && STARTER_PREVIEW_ROSTER[0].id) || "");
  const visibleSignupStarterId = defaultableSignupStarterId || safeSignupStarterId;
  const signupStarter = findMechById(visibleSignupStarterId) || STARTER_PREVIEW_ROSTER[0] || MEKABOTS_BY_ID[0];
  const publicStarterAvailability = getStarterClaimAvailability(signupStarter ? signupStarter.id : "", registry, accountOrganization);
  const publicNextAvailableStarterId = signupStarter
    ? findNextAvailableStarterId(signupStarter.id, registry, accountOrganization, STARTER_PREVIEW_ROSTER)
    : "";
  const canSelectNextPublicStarter = Boolean(publicNextAvailableStarterId && signupStarter && publicNextAvailableStarterId !== signupStarter.id);

  function beginRouteBoot(nextRouteHash) {
    if (!ROUTE_SCROLL_TARGETS.has(nextRouteHash)) return;
    routeBootStartedAtRef.current = typeof performance !== "undefined" ? performance.now() : Date.now();
    setRouteBootHash(nextRouteHash);
  }

  function armDirectiveReceiptQueue(delayMs = DIRECTIVE_COMPLETION_RECEIPT_DELAY_MS) {
    if (typeof window === "undefined" || directiveReceipt || directiveReceiptTimerRef.current) return;
    const receipt = directiveReceiptQueueRef.current.shift();
    if (!receipt) return;
    directiveReceiptTimerRef.current = window.setTimeout(() => {
      directiveReceiptTimerRef.current = null;
      playDirectiveReceiptSound();
      setDirectiveReceipt(receipt);
    }, delayMs);
  }

  function enqueueDirectiveReceipt(receipt, delayMs = DIRECTIVE_COMPLETION_RECEIPT_DELAY_MS) {
    if (!receipt || !receipt.key) return;
    if (directiveReceiptSeenKeysRef.current.has(receipt.key)) return;
    directiveReceiptSeenKeysRef.current.add(receipt.key);
    directiveReceiptQueueRef.current.push(receipt);
    armDirectiveReceiptQueue(delayMs);
  }

  function buildReceiptShell(keyParts) {
    const assistantName = accountOrganization && accountOrganization.assistantName ? accountOrganization.assistantName : "MIRA";
    const assistantReady = Boolean(accountOrganization && accountOrganization.logoStatus === "generated" && accountOrganization.avatarStatus === "generated" && accountOrganization.avatarUrl);
    return {
      key: keyParts.join(":"),
      assistantName,
      avatarSource: assistantReady ? getAssistantAvatarSource(accountOrganization) : ""
    };
  }

  function queueDirectiveCompletionReceipt(directive, nextOnboarding) {
    if (typeof window === "undefined" || !directive || !nextOnboarding) return;
    const completedDirective = getDirectiveItemById(nextOnboarding, directive.id) || directive;
    if (completedDirective.status !== "complete" && !completedDirective.completedAt) return;
    const completedAt = completedDirective.completedAt || "complete";
    const nextDirective = nextOnboarding.directives && nextOnboarding.directives.current && nextOnboarding.directives.current.status === "available"
      ? nextOnboarding.directives.current
      : null;
    const title = completedDirective.title || completedDirective.label || directive.title || "Directive complete";
    enqueueDirectiveReceipt({
      ...buildReceiptShell([
        accountOrganization && accountOrganization.id ? accountOrganization.id : "organization",
        completedDirective.id,
        completedAt
      ]),
      id: completedDirective.id,
      title: "Directive achieved: " + title,
      line: getDirectiveCompletionLine(completedDirective, nextDirective),
      nextTitle: nextDirective && nextDirective.id !== completedDirective.id ? (nextDirective.title || nextDirective.label || "") : ""
    });
  }

  function queueDispatchDirectiveCompletionReceipt(directiveId, result) {
    if (typeof window === "undefined" || !directiveId || !result) return;
    const progress = result.organizationProgress || (result.data && result.data.organizationProgress) || null;
    const completedDirective = getDispatchDirectiveItemById(progress, directiveId);
    if (!progress || !completedDirective || (completedDirective.status !== "complete" && !completedDirective.completedAt)) return;
    const nextDirective = progress.currentDirective && progress.currentDirective.status === "available"
      ? progress.currentDirective
      : null;
    const completedAt = completedDirective.completedAt || "complete";
    enqueueDirectiveReceipt({
      ...buildReceiptShell([
        accountOrganization && accountOrganization.id ? accountOrganization.id : "organization",
        "archive-dispatch",
        completedDirective.id,
        completedAt
      ]),
      id: completedDirective.id,
      title: "Dispatch achieved: " + (completedDirective.label || "Dispatch directive"),
      line: getDispatchDirectiveCompletionLine(completedDirective, nextDirective, progress),
      nextTitle: nextDirective && nextDirective.id !== completedDirective.id ? (nextDirective.label || "") : ""
    });
  }

  // open detail when hash matches
  useEffect(() => {
    const checkHash = () => {
      const h = window.location.hash;
      setRouteHash(h || "");
      const m = h.match(/^#mech\/([\w-]+)/i);
      const org = h.match(/^#org\/(.+)/i);
      const ownership = h.match(/^#ownership\/(.+)/i);
      if (m) {
        setOpenId(m[1].toUpperCase());
        setOpenOrgId(null);
        setOpenOwnershipId(null);
      } else if (org) {
        setOpenId(null);
        setOpenOrgId(decodeURIComponent(org[1]));
        setOpenOwnershipId(null);
      } else if (ownership) {
        setOpenId(null);
        setOpenOrgId(null);
        setOpenOwnershipId(decodeURIComponent(ownership[1]));
      } else {
        setOpenId(null);
        setOpenOrgId(null);
        setOpenOwnershipId(null);
      }
    };
    checkHash();
    window.addEventListener("hashchange", checkHash);
    return () => window.removeEventListener("hashchange", checkHash);
  }, []);

  useEffect(() => {
    return () => {
      if (directiveReceiptTimerRef.current) window.clearTimeout(directiveReceiptTimerRef.current);
    };
  }, []);

  useEffect(() => {
    if (!directiveReceipt) {
      armDirectiveReceiptQueue(900);
      return undefined;
    }
    const dismissTimer = window.setTimeout(() => {
      setDirectiveReceipt(null);
    }, DIRECTIVE_COMPLETION_RECEIPT_DISMISS_MS);
    return () => window.clearTimeout(dismissTimer);
  }, [directiveReceipt && directiveReceipt.key]);

  useEffect(() => {
    const redirectedHash = redirectSignedInHomeToHangar(account.status, onboardingStatus);
    if (redirectedHash) {
      setRouteHash(redirectedHash);
      beginRouteBoot(redirectedHash);
    }
  }, [account.status, onboardingStatus.status, onboardingStatus.data && onboardingStatus.data.phase, routeHash]);

  useEffect(() => {
    if (!routeBootHash) return undefined;
    if (routeHash !== routeBootHash) {
      setRouteBootHash("");
      return undefined;
    }
    if (shouldHoldRouteBoot(routeBootHash, account, onboardingStatus)) return undefined;

    const now = typeof performance !== "undefined" ? performance.now() : Date.now();
    const remaining = Math.max(0, ROUTE_BOOT_MIN_MS - (now - routeBootStartedAtRef.current));
    const finishTimer = window.setTimeout(() => {
      scrollToRouteHashSection(routeBootHash);
      setRouteBootHash("");
    }, remaining);
    return () => window.clearTimeout(finishTimer);
  }, [
    routeBootHash,
    routeHash,
    account.status,
    onboardingStatus.status,
    onboardingStatus.data && onboardingStatus.data.phase
  ]);

  useEffect(() => {
    const previousRouteHash = previousRouteHashRef.current;
    previousRouteHashRef.current = routeHash;
    if (account.status !== "signed-in") return;
    const authRouteExitedIntoLongPage = routeWasDedicatedAuth(previousRouteHash) && ROUTE_SCROLL_TARGETS.has(routeHash);
    if (authRouteExitedIntoLongPage) beginRouteBoot(routeHash);
  }, [account.status, routeHash]);

  useEffect(() => {
    if (account.status !== "signed-in") return;
    if (!onboardingStatus || typeof onboardingStatus.recordDirective !== "function") return;
    if (onboardingStatus.actionBusy) return;
    const data = onboardingStatus.data || null;
    const directive = data && data.directives && data.directives.current ? data.directives.current : null;
    if (!directive || directive.status !== "available" || !routeMatchesDirectiveTarget(routeHash, directive)) return;
    const completionKey = [
      accountOrganization && accountOrganization.id ? accountOrganization.id : "organization",
      directive.id,
      routeHash
    ].join(":");
    if (routeDirectiveCompletionRef.current === completionKey) return;
    routeDirectiveCompletionRef.current = completionKey;
    void (async () => {
      const result = await onboardingStatus.recordDirective(directive.id, "complete");
      if (result) queueDirectiveCompletionReceipt(directive, result);
    })();
  }, [
    account.status,
    accountOrganization && accountOrganization.id,
    routeHash,
    onboardingStatus.actionBusy,
    onboardingStatus.data && onboardingStatus.data.directives && onboardingStatus.data.directives.current && onboardingStatus.data.directives.current.id,
    onboardingStatus.data && onboardingStatus.data.directives && onboardingStatus.data.directives.current && onboardingStatus.data.directives.current.status
  ]);

  useEffect(() => {
    const previousStatus = previousAccountStatusRef.current;
    previousAccountStatusRef.current = account.status;
    if (previousStatus !== "signed-in" || account.status !== "signed-out") return;
    if (typeof window === "undefined") return;
    history.replaceState(null, "", window.location.pathname + window.location.search + "#top");
    setRouteHash("#top");
    setOpenId(null);
    setOpenOrgId(null);
    setOpenOwnershipId(null);
    if (directiveReceiptTimerRef.current) {
      window.clearTimeout(directiveReceiptTimerRef.current);
      directiveReceiptTimerRef.current = null;
    }
    directiveReceiptQueueRef.current = [];
    directiveReceiptSeenKeysRef.current.clear();
    setDirectiveReceipt(null);
    window.scrollTo({ top: 0, left: 0, behavior: "auto" });
    const root = document.getElementById("root");
    if (root) root.scrollTop = 0;
  }, [account.status]);

  useEffect(() => {
    if (routeIsSignedOutHangar && !accountJustSignedOut) {
      history.replaceState(null, "", window.location.pathname + window.location.search + "#signup");
      setRouteHash("#signup");
    }
  }, [routeIsSignedOutHangar, accountJustSignedOut]);

  useEffect(() => {
    if (routeIsDedicatedSignup && !lastDedicatedSignupRouteRef.current) {
      window.scrollTo({ top: 0, left: 0, behavior: "auto" });
      const root = document.getElementById("root");
      if (root) root.scrollTop = 0;
    }
    lastDedicatedSignupRouteRef.current = routeIsDedicatedSignup;
  }, [routeIsDedicatedSignup]);

  useEffect(() => {
    if (routeIsRegisteredOperators) {
      window.scrollTo({ top: 0, left: 0, behavior: "auto" });
      const root = document.getElementById("root");
      if (root) root.scrollTop = 0;
    }
  }, [routeIsRegisteredOperators]);

  useEffect(() => {
    if (routeIsDedicatedPage) return;
    const scrollTimer = window.setTimeout(() => {
      scrollToRouteHashSection(routeHash, "smooth");
    }, 0);
    return () => window.clearTimeout(scrollTimer);
  }, [routeHash, routeIsDedicatedPage]);

  const openDetail = (id) => {
    window.location.hash = "#mech/" + id;
  };
  const openOrganizationDossier = (id) => {
    window.location.hash = "#org/" + encodeURIComponent(id);
  };
  const openOwnershipCertificate = (id) => {
    if (id) window.location.hash = "#ownership/" + encodeURIComponent(id);
  };
  const closeOwnershipCertificate = () => {
    history.replaceState(null, "", window.location.pathname + window.location.search + "#hangar");
    setOpenOwnershipId(null);
    setCertificateVaultOpen(true);
    setRouteHash("#hangar");
  };
  const openCertificateVault = () => {
    setCertificateVaultOpen(true);
  };
  const closeCertificateVault = () => {
    setCertificateVaultOpen(false);
  };
  const openStarterCertificateCeremony = async (nextSession, starterMech) => {
    const fallbackClaim = buildStarterCeremonyFallback(nextSession, starterMech);
    if (!fallbackClaim) return;
    setCeremonySkipRequested(false);
    setRegistryClaimCeremony(fallbackClaim);
    archiveDispatchStatus.refresh();
    registry.refresh();
    try {
      const result = await publicApi("/ownerships/" + encodeURIComponent(fallbackClaim.ownership.id));
      if (result && result.ownership && result.certificate) {
        const ledgerClaim = {
          ceremonyMode: "starter",
          organization: result.organization || fallbackClaim.organization,
          ownership: result.ownership,
          artifacts: result.certificate
        };
        setRegistryClaimCeremony((current) => (
          current && current.ownership && current.ownership.id === fallbackClaim.ownership.id
            ? ledgerClaim
            : current
        ));
      }
    } catch (error) {
      // The starter certificate is still shown from signup state if the ledger is momentarily behind.
    }
  };
  const openRegistryClaimCeremony = (claimResult) => {
    setCeremonySkipRequested(false);
    setRegistryClaimCeremony(claimResult);
    if (claimResult && claimResult.ownership && claimResult.ownership.id) {
      history.replaceState(null, "", window.location.pathname + window.location.search + "#registry-claim/" + encodeURIComponent(claimResult.ownership.id));
      setRouteHash("#registry-claim/" + claimResult.ownership.id);
    }
    archiveDispatchStatus.refresh();
    registry.refresh();
  };
  const skipCeremony = () => {
    setCeremonySkipRequested(true);
    setRegistryClaimCeremony(null);
    if (typeof window !== "undefined" && /^#registry-claim\//i.test(window.location.hash || "")) {
      history.replaceState(null, "", window.location.pathname + window.location.search + "#hangar");
      setRouteHash("#hangar");
    }
  };
  const closeDetail = () => {
    history.replaceState(null, "", window.location.pathname + window.location.search);
    setOpenId(null);
    setOpenOrgId(null);
    setOpenOwnershipId(null);
  };
  const resetLocalOps = () => {
    if (window.confirm("Reset print queue, dossier progress, and transmissions in this browser?")) {
      engagementApi.dispatch({ type: "ENGAGEMENT_RESET" });
    }
  };
  const routeCommsContext = (mech) => {
    engagementApi.dispatch({ type: "COMMS_CONTEXT_SET", mechId: mech.id, source: "detail" });
    closeDetail();
    window.setTimeout(() => {
      if (!scrollToRouteHashSection("#comms")) window.location.hash = "#comms";
    }, 80);
  };
  const rememberSignupStarter = (starterId) => {
    const normalizedId = String(starterId || "").toUpperCase();
    if (!normalizedId) return;
    const candidate = findMechById(normalizedId);
    if (!isStarterUnitEligible(candidate)) return;
    setSignupStarterId(normalizedId);
    setSignupStarterIntentLocked(true);
    try {
      window.sessionStorage.setItem(SIGNUP_STARTER_ID_STORAGE_KEY, normalizedId);
      window.sessionStorage.setItem(SIGNUP_STARTER_INTENT_STORAGE_KEY, "explicit");
    } catch (error) {
      // Session storage is only a convenience for carrying the selected starter into signup.
    }
  };
  const openSignupWithStarter = (starterId) => {
    if (starterId) rememberSignupStarter(starterId);
    window.location.hash = "#signup";
  };
  const selectNextAvailablePublicStarter = (starterId) => {
    const nextId = findNextAvailableStarterId(starterId, registry, accountOrganization, STARTER_PREVIEW_ROSTER);
    if (nextId && nextId !== starterId) rememberSignupStarter(nextId);
  };

  useEffect(() => {
    if (!routeIsDedicatedSignup || signupStarterIntentLocked || registry.status !== "ready") return;
    const firstAvailableId = findFirstAvailableStarterId(registry, accountOrganization, STARTER_PREVIEW_ROSTER);
    if (firstAvailableId && firstAvailableId !== signupStarterId) {
      setSignupStarterId(firstAvailableId);
      try {
        window.sessionStorage.setItem(SIGNUP_STARTER_ID_STORAGE_KEY, firstAvailableId);
      } catch (error) {
        // Session storage is only a convenience for carrying the selected starter into signup.
      }
    }
  }, [
    routeIsDedicatedSignup,
    signupStarterIntentLocked,
    signupStarterId,
    registry.status,
    Object.keys((registry && registry.ownership) || {}).join("|"),
    account.organization && account.organization.id
  ]);

  return (
      <React.Fragment>
      <div className={"app-shell" + (routeBootPending ? " is-route-booting" : "")} aria-hidden={routeBootPending ? "true" : undefined}>
        <StatusBar />
        <Nav engagement={engagement} account={account} registry={registry} />
        {showHero && (
          <Hero
            heroLayout={t.heroLayout}
            heroClaimConsole={
              <HeroClaimConsole
                starterMech={signupStarter}
                availability={publicStarterAvailability}
                onUseStarter={() => openSignupWithStarter(signupStarter ? signupStarter.id : "")}
                onSelectNext={() => selectNextAvailablePublicStarter(signupStarter ? signupStarter.id : "")}
                canSelectNextAvailable={canSelectNextPublicStarter}
              />
            }
          />
        )}
        {routeIsDedicatedSignup && <SignupPage account={account} registry={registry} starterMech={signupStarter} onSelectStarter={rememberSignupStarter} onStarterClaimed={openStarterCertificateCeremony} />}
        {routeIsSignin && <SignInPage account={account} />}
        {routeIsRegisteredOperators && <RegisteredOperatorsPage registry={registry} account={account} onOpenOrganization={openOrganizationDossier} />}
        {!routeIsDedicatedPage && (
          <>
            {showGenerationWaitingBay && <GenerationWaitingBay account={account} onboardingStatus={onboardingStatus} />}
            {!showPublicEntry && <HangarBay onOpen={openDetail} onOpenOrganization={openOrganizationDossier} onOpenCertificate={openOwnershipCertificate} onOpenCertificateVault={openCertificateVault} engagement={engagement} account={account} registry={registry} onboardingStatus={onboardingStatus} archiveDispatchStatus={archiveDispatchStatus} onSignupStarterIntent={rememberSignupStarter} onDirectiveCompleted={queueDirectiveCompletionReceipt} onDispatchDirectiveCompleted={queueDispatchDirectiveCompletionReceipt} onRegistryClaim={openRegistryClaimCeremony} />}
            {showPublicEntry && <OrganizationDirectory registry={registry} account={account} onOpenOrganization={openOrganizationDossier} />}
            <ArchiveSection onOpen={openDetail} engagement={engagement} engagementDispatch={engagementApi.dispatch} account={account} registry={registry} onboardingStatus={onboardingStatus} archiveDispatchStatus={archiveDispatchStatus} onDispatchDirectiveCompleted={queueDispatchDirectiveCompletionReceipt} />
            <CommsSection engagement={engagement} engagementDispatch={engagementApi.dispatch} />
            <AboutLog />
            <Footer />
            <MobileUtilityNav engagement={engagement} account={account} registry={registry} />
          </>
        )}
        {openId && (
          <Detail
            mechId={openId}
            onClose={closeDetail}
            onNavigate={openDetail}
            engagement={engagement}
            engagementDispatch={engagementApi.dispatch}
            onCommsContext={routeCommsContext}
            account={account}
            registry={registry}
            archiveDispatchStatus={archiveDispatchStatus}
            onDispatchDirectiveCompleted={queueDispatchDirectiveCompletionReceipt}
          />
        )}
        {openOrgId && (
          <OrganizationDossier
            organizationId={openOrgId}
            registry={registry}
            account={account}
            onClose={closeDetail}
            onOpenMech={openDetail}
          />
        )}
        {openOwnershipId && (
          <OwnershipCertificateView
            ownershipId={openOwnershipId}
            onClose={closeOwnershipCertificate}
            backLabel="BACK TO CERTIFICATE LIST"
          />
        )}
        {certificateVaultOpen && (
          <CertificateVaultOverlay
            account={account}
            archiveDispatchStatus={archiveDispatchStatus}
            onClose={closeCertificateVault}
          />
        )}
        <TweaksPanel>
          <TweakSection label="Hero collage" />
          <TweakRadio
            label="Layout"
            value={t.heroLayout}
            options={HERO_LAYOUTS.map(l => ({ value: l.id, label: l.label }))}
            onChange={(v) => setTweak('heroLayout', v)}
          />
        </TweaksPanel>
      </div>
      <DirectiveCompletionTransmission receipt={directiveReceipt} onDismiss={() => setDirectiveReceipt(null)} />
      {registryClaimCeremony && !ceremonySkipRequested && (
        <RegistryClaimCeremony
          claim={registryClaimCeremony}
          account={account}
          onClose={skipCeremony}
          onOpenCertificate={(id) => {
            skipCeremony();
            openOwnershipCertificate(id);
          }}
          onViewHangar={() => {
            skipCeremony();
            history.replaceState(null, "", window.location.pathname + window.location.search + "#hangar");
            setRouteHash("#hangar");
          }}
          onContinueArchive={() => {
            const continueTarget = registryClaimCeremony && registryClaimCeremony.ceremonyMode === "starter" ? "#generation" : "#archive";
            skipCeremony();
            history.replaceState(null, "", window.location.pathname + window.location.search + continueTarget);
            setRouteHash(continueTarget);
          }}
        />
      )}
      {routeBootPending && <RouteBootTransmission routeHash={routeBootHash || routeHash} />}
    </React.Fragment>
  );
}

function getAssetExtension(url, fallback) {
  const cleanUrl = (url || "").split("?")[0].split("#")[0];
  const match = cleanUrl.match(/\.([a-z0-9]+)$/i);
  return match ? match[1].toLowerCase() : fallback;
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
