/* 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 = "20260813-battle-invitation-visuals";
const ARCHIVE_ASSET_BASE_URL = "https://sin1.contabostorage.com/48ea6e0cdf344a96ad45b1c7eb1c766a:anomaliexperiment/assets/";
const ARCHIVE_MOBILE_QUERY = "(max-width: 720px)";
const DISPATCH_ARCHIVE_LEDGER_COLLAPSE_QUERY = "(max-width: 720px)";
const REGISTERED_OPERATORS_ROUTE = "#registered-operators";
const DISPATCH_ARCHIVE_ROUTE = "#dispatches";
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 = ARCHIVE_ASSET_BASE_URL + "virtual-assistant-sample.svg";
const HEADER_LOGO_URL = ARCHIVE_ASSET_BASE_URL + "header-logo.png";
const SIGNUP_PROGRESS_STORAGE_KEY = "supermekabots.signupProgress.v1";
const SIGNUP_STARTER_ID_STORAGE_KEY = "supermekabots.signupStarterId";
const SIGNUP_STARTER_INTENT_STORAGE_KEY = "supermekabots.signupStarterIntent";
const CREATOR_BATTLE_QUEUE_TOKEN_STORAGE_KEY = "supermekabots.creatorBattleQueueToken";
const BATTLE_ARENA_RETURN_HASH_STORAGE_KEY = "supermekabots.battleArenaReturnHash.v1";

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;
}

function useMediaQueryMatch(query) {
  const [matches, setMatches] = useState(() => (
    typeof window !== "undefined"
    && window.matchMedia
    && window.matchMedia(query).matches
  ));

  useEffect(() => {
    if (typeof window === "undefined" || !window.matchMedia) return undefined;
    const queryList = window.matchMedia(query);
    const sync = () => setMatches(queryList.matches);
    sync();
    queryList.addEventListener("change", sync);
    return () => queryList.removeEventListener("change", sync);
  }, [query]);

  return matches;
}

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 isMekaPublished(mech) {
  return Boolean(mech) && mech.published !== false;
}

function isStarterUnitEligible(mech) {
  return Boolean(mech) && mech.published !== false && mech.eligibleForStarterUnit !== false && !isArchiveDispatchRarityLocked(mech);
}

const MEKABOTS_BY_ID = MEKABOTS_DATA.filter(isMekaPublished).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(),
      ownedMechIds: Array.isArray(entry && entry.ownedMechIds)
        ? entry.ownedMechIds.map((id) => String(id || "").trim().toUpperCase()).filter(Boolean)
        : [],
      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 getSettledAccountRefreshKey(account, includeOrganizationVersion = false) {
  if (!account || account.status === "checking") return "";
  if (account.status !== "signed-in") return "public";
  const organization = account.organization || {};
  return [
    "signed-in",
    organization.id || "organization",
    includeOrganizationVersion ? organization.updatedAt || "current" : ""
  ].join(":");
}

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;
    }
  };

  const refreshKey = getSettledAccountRefreshKey(account, true);

  useEffect(() => {
    if (!refreshKey) return;
    refresh();
  }, [refreshKey]);

  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", {});
  }

  const refreshKey = getSettledAccountRefreshKey(account);

  useEffect(() => {
    if (!refreshKey) return;
    loadArchiveDispatchStatus();
  }, [refreshKey]);

  return {
    ...state,
    refresh: loadArchiveDispatchStatus,
    startDispatch,
    selectClaimTarget,
    recordDispatchDirective,
    claimMeka
  };
}

function mergeArchiveDispatchHistoryItems(currentItems, nextItems) {
  const merged = [];
  const seenIds = new Set();
  [...(currentItems || []), ...(nextItems || [])].forEach((item) => {
    const itemId = String(item && item.id || "");
    if (!itemId || seenIds.has(itemId)) return;
    seenIds.add(itemId);
    merged.push(item);
  });
  return merged;
}

function useArchiveDispatchHistory() {
  const [state, setState] = useState(() => ({
    status: PUBLIC_API_BASE_URL ? "loading" : "offline",
    items: [],
    nextCursor: null,
    error: "",
    loadingMore: false
  }));
  const requestTokenRef = useRef(0);
  const controllersRef = useRef(new Set());

  async function requestHistoryPage(cursor = null, append = false) {
    if (!PUBLIC_API_BASE_URL) {
      setState({ status: "offline", items: [], nextCursor: null, error: "", loadingMore: false });
      return null;
    }

    const requestToken = ++requestTokenRef.current;
    const controller = new AbortController();
    controllersRef.current.add(controller);

    setState((current) => append
      ? { ...current, loadingMore: true, error: "" }
      : { ...current, status: current.items.length ? "ready" : "loading", error: "", loadingMore: false }
    );

    try {
      const path = cursor
        ? "/archive-dispatches/history?limit=6&cursor=" + encodeURIComponent(cursor)
        : "/archive-dispatches/history?limit=6";
      const result = await publicApi(path, { signal: controller.signal });
      if (controller.signal.aborted || requestToken !== requestTokenRef.current) return null;
      const nextItems = Array.isArray(result && result.items) ? result.items : [];
      const nextCursor = result && result.page ? result.page.nextCursor || null : null;
      setState((current) => ({
        status: "ready",
        items: append ? mergeArchiveDispatchHistoryItems(current.items, nextItems) : nextItems,
        nextCursor,
        error: "",
        loadingMore: false
      }));
      return result;
    } catch (error) {
      if (controller.signal.aborted || error.name === "AbortError" || requestToken !== requestTokenRef.current) return null;
      setState((current) => append
        ? { ...current, error: (error.message || "DISPATCH HISTORY UNAVAILABLE").toUpperCase(), loadingMore: false }
        : {
          ...current,
          status: "error",
          error: (error.message || "DISPATCH HISTORY UNAVAILABLE").toUpperCase(),
          loadingMore: false
        }
      );
      return null;
    } finally {
      controllersRef.current.delete(controller);
    }
  }

  useEffect(() => {
    void requestHistoryPage();
    return () => {
      controllersRef.current.forEach((controller) => controller.abort());
      controllersRef.current.clear();
    };
  }, []);

  const retry = () => requestHistoryPage();
  const loadMore = () => {
    if (!state.nextCursor || state.loadingMore) return null;
    return requestHistoryPage(state.nextCursor, true);
  };

  return { ...state, retry, loadMore };
}

function useBattleArenaStatus(account, battleArenaUnlocked) {
  const [state, setState] = useState(() => ({
    status: PUBLIC_API_BASE_URL ? "idle" : "offline",
    arenas: [],
    battles: [],
    error: "",
    actionBusy: ""
  }));

  async function loadBattleArenaStatus() {
    if (!PUBLIC_API_BASE_URL) {
      setState({ status: "offline", arenas: [], battles: [], error: "", actionBusy: "" });
      return null;
    }
    if (!account || account.status !== "signed-in") {
      setState({ status: "idle", arenas: [], battles: [], error: "", actionBusy: "" });
      return null;
    }
    if (!battleArenaUnlocked) {
      const next = { status: "locked", arenas: [], battles: [], error: "", actionBusy: "" };
      setState(next);
      return next;
    }
    if (!PUBLIC_API_BASE_URL || !account || account.status !== "signed-in") {
      setState({ status: PUBLIC_API_BASE_URL ? "idle" : "offline", arenas: [], battles: [], error: "", actionBusy: "" });
      return null;
    }
    setState((current) => ({ ...current, status: current.arenas.length || current.battles.length ? "ready" : "loading", error: "" }));
    try {
      const [arenaPayload, battlePayload] = await Promise.all([
        publicApi("/battle-arena/arenas"),
        publicApi("/battle-arena/battles/mine")
      ]);
      const next = {
        status: "ready",
        arenas: Array.isArray(arenaPayload && arenaPayload.arenas) ? arenaPayload.arenas : [],
        battles: Array.isArray(battlePayload && battlePayload.battles) ? battlePayload.battles : [],
        error: "",
        actionBusy: ""
      };
      setState(next);
      return next;
    } catch (error) {
      setState((current) => ({
        ...current,
        status: "error",
        error: (error.message || "BATTLE ARENA SYNC FAILED").toUpperCase(),
        actionBusy: ""
      }));
      return null;
    }
  }

  async function runBattleArenaMutation(actionId, path, body) {
    if (!PUBLIC_API_BASE_URL || !account || account.status !== "signed-in" || !battleArenaUnlocked) return null;
    setState((current) => ({ ...current, actionBusy: actionId, error: "" }));
    try {
      const result = await publicApi(path, {
        method: "POST",
        body: JSON.stringify(body || {})
      });
      const refreshed = await loadBattleArenaStatus();
      setState((current) => ({
        ...current,
        status: "ready",
        arenas: refreshed ? refreshed.arenas : current.arenas,
        battles: refreshed ? refreshed.battles : current.battles,
        error: "",
        actionBusy: ""
      }));
      return result;
    } catch (error) {
      const refreshed = await loadBattleArenaStatus();
      setState((current) => ({
        ...current,
        status: refreshed ? "ready" : "error",
        arenas: refreshed ? refreshed.arenas : current.arenas,
        battles: refreshed ? refreshed.battles : current.battles,
        error: (error.message || "BATTLE ARENA ACTION FAILED").toUpperCase(),
        actionBusy: ""
      }));
      throw error;
    }
  }

  async function createChallenge(defenderOrganizationId, arenaId, ownershipId) {
    return runBattleArenaMutation("challenge", "/battle-arena/challenges", {
      defenderOrganizationId,
      arenaId,
      ownershipId,
      visibilityPreference: "participants"
    });
  }

  async function acceptBattle(battleId) {
    if (!battleId) return null;
    return runBattleArenaMutation("accept:" + battleId, "/battle-arena/battles/" + encodeURIComponent(battleId) + "/accept", {});
  }

  async function declineBattle(battleId) {
    if (!battleId) return null;
    return runBattleArenaMutation("decline:" + battleId, "/battle-arena/battles/" + encodeURIComponent(battleId) + "/decline", {});
  }

  async function selectMeka(battleId, ownershipId) {
    if (!battleId || !ownershipId) return null;
    return runBattleArenaMutation("select:" + battleId, "/battle-arena/battles/" + encodeURIComponent(battleId) + "/select-meka", { ownershipId });
  }

  async function recordSceneViewed(battleId) {
    if (!battleId) return null;
    return runBattleArenaMutation("scene-viewed:" + battleId, "/battle-arena/battles/" + encodeURIComponent(battleId) + "/scene-viewed", {});
  }

  useEffect(() => {
    loadBattleArenaStatus();
  }, [account && account.status, account && account.organization && account.organization.id, battleArenaUnlocked]);

  return {
    ...state,
    refresh: loadBattleArenaStatus,
    createChallenge,
    acceptBattle,
    declineBattle,
    selectMeka,
    recordSceneViewed
  };
}

function useBattleTheaterStatus(account) {
  const [state, setState] = useState(() => ({
    status: PUBLIC_API_BASE_URL ? "idle" : "offline",
    battles: [],
    error: "",
    actionBusy: ""
  }));

  async function loadBattleTheaterStatus() {
    if (!PUBLIC_API_BASE_URL) {
      setState({ status: "offline", battles: [], error: "", actionBusy: "" });
      return null;
    }
    setState((current) => ({ ...current, status: current.battles.length ? "ready" : "loading", error: "" }));
    try {
      const payload = await publicApi("/battle-arena/theater");
      const next = {
        status: "ready",
        battles: Array.isArray(payload && payload.battles) ? payload.battles : [],
        error: "",
        actionBusy: ""
      };
      setState(next);
      return next;
    } catch (error) {
      setState((current) => ({
        ...current,
        status: "error",
        error: (error.message || "BATTLE THEATER SYNC FAILED").toUpperCase(),
        actionBusy: ""
      }));
      return null;
    }
  }

  async function runBattleTheaterMutation(actionId, battleId, path, body) {
    if (!PUBLIC_API_BASE_URL || !battleId) return null;
    setState((current) => ({ ...current, actionBusy: actionId + ":" + battleId, error: "" }));
    try {
      const result = await publicApi(path, {
        method: "POST",
        body: JSON.stringify(body || {})
      });
      await loadBattleTheaterStatus();
      return result;
    } catch (error) {
      const refreshed = await loadBattleTheaterStatus();
      setState((current) => ({
        ...current,
        status: refreshed ? "ready" : "error",
        error: (error.message || "BATTLE THEATER ACTION FAILED").toUpperCase(),
        actionBusy: ""
      }));
      throw error;
    }
  }

  async function saluteBattle(battleId) {
    return runBattleTheaterMutation(
      "salute",
      battleId,
      "/battle-arena/theater/" + encodeURIComponent(battleId) + "/salute",
      {}
    );
  }

  async function favoriteBattle(battleId, favorite) {
    return runBattleTheaterMutation(
      "favorite",
      battleId,
      "/battle-arena/theater/" + encodeURIComponent(battleId) + "/favorite",
      { favorite }
    );
  }

  async function recordTheaterView(battleId) {
    return runBattleTheaterMutation(
      "view",
      battleId,
      "/battle-arena/theater/" + encodeURIComponent(battleId) + "/view",
      {}
    );
  }

  const refreshKey = getSettledAccountRefreshKey(account);

  useEffect(() => {
    if (!refreshKey) return;
    loadBattleTheaterStatus();
  }, [refreshKey]);

  return {
    ...state,
    refresh: loadBattleTheaterStatus,
    saluteBattle,
    favoriteBattle,
    recordTheaterView
  };
}

function readCreatorBattleQueueToken() {
  if (typeof window === "undefined" || !window.sessionStorage) return "";
  try {
    return String(window.sessionStorage.getItem(CREATOR_BATTLE_QUEUE_TOKEN_STORAGE_KEY) || "").trim();
  } catch (error) {
    return "";
  }
}

function writeCreatorBattleQueueToken(token) {
  if (typeof window === "undefined" || !window.sessionStorage) return;
  try {
    const normalized = String(token || "").trim();
    if (normalized) window.sessionStorage.setItem(CREATOR_BATTLE_QUEUE_TOKEN_STORAGE_KEY, normalized);
    else window.sessionStorage.removeItem(CREATOR_BATTLE_QUEUE_TOKEN_STORAGE_KEY);
  } catch (error) {
    // Session storage can be unavailable in private or embedded contexts; the in-memory token still works.
  }
}

function creatorBattleQueuePanelRequested() {
  if (typeof window === "undefined") return false;
  try {
    const params = new URLSearchParams(window.location.search || "");
    return params.get("creatorQueue") === "1" ||
      params.get("internalTools") === "battle-queue" ||
      params.get("qa") === "creator-queue" ||
      Boolean(readCreatorBattleQueueToken());
  } catch (error) {
    return Boolean(readCreatorBattleQueueToken());
  }
}

function useCreatorBattleQueueStatus(account) {
  const [state, setState] = useState(() => {
    const token = readCreatorBattleQueueToken();
    return {
      status: PUBLIC_API_BASE_URL ? (token ? "idle" : "locked") : "offline",
      token,
      battles: [],
      scenePackages: [],
      error: "",
      actionBusy: ""
    };
  });

  function internalHeaders(token) {
    return { "X-Internal-Token": String(token || state.token || "").trim() };
  }

  async function loadCreatorBattleQueueStatus(tokenOverride) {
    const token = String(tokenOverride !== undefined ? tokenOverride : state.token || "").trim();
    if (!PUBLIC_API_BASE_URL) {
      setState((current) => ({ ...current, status: "offline", battles: [], scenePackages: [], error: "", actionBusy: "" }));
      return null;
    }
    if (!account || account.status !== "signed-in") {
      setState((current) => ({ ...current, status: token ? "idle" : "locked", token, battles: [], scenePackages: [], error: "", actionBusy: "" }));
      return null;
    }
    if (!token) {
      setState((current) => ({ ...current, status: "locked", token: "", battles: [], scenePackages: [], error: "", actionBusy: "" }));
      return null;
    }
    setState((current) => ({ ...current, token, status: current.battles.length ? "ready" : "loading", error: "" }));
    try {
      const [payload, scenePackagePayload] = await Promise.all([
        publicApi("/internal/battle-arena/queue", {
          headers: internalHeaders(token)
        }),
        publicApi("/internal/battle-arena/scene-packages", {
          headers: internalHeaders(token)
        })
      ]);
      const next = {
        status: "ready",
        token,
        battles: Array.isArray(payload && payload.battles) ? payload.battles : [],
        scenePackages: Array.isArray(scenePackagePayload && scenePackagePayload.scenePackages)
          ? scenePackagePayload.scenePackages
          : [],
        error: "",
        actionBusy: ""
      };
      setState(next);
      return next;
    } catch (error) {
      setState((current) => ({
        ...current,
        token,
        status: error.status === 403 ? "locked" : "error",
        error: (error.message || "CREATOR BATTLE QUEUE SYNC FAILED").toUpperCase(),
        actionBusy: ""
      }));
      return null;
    }
  }

  async function saveToken(token) {
    const normalized = String(token || "").trim();
    writeCreatorBattleQueueToken(normalized);
    if (!normalized) {
      setState({ status: PUBLIC_API_BASE_URL ? "locked" : "offline", token: "", battles: [], scenePackages: [], error: "", actionBusy: "" });
      return null;
    }
    return loadCreatorBattleQueueStatus(normalized);
  }

  function clearToken() {
    writeCreatorBattleQueueToken("");
    setState({ status: PUBLIC_API_BASE_URL ? "locked" : "offline", token: "", battles: [], scenePackages: [], error: "", actionBusy: "" });
  }

  async function runCreatorBattleQueueMutation(actionId, method, path, body) {
    const token = String(state.token || "").trim();
    if (!PUBLIC_API_BASE_URL || !token) return null;
    setState((current) => ({ ...current, actionBusy: actionId, error: "" }));
    try {
      const result = await publicApi(path, {
        method,
        headers: internalHeaders(token),
        body: JSON.stringify(body || {})
      });
      await loadCreatorBattleQueueStatus(token);
      return result;
    } catch (error) {
      setState((current) => ({
        ...current,
        status: error.status === 403 ? "locked" : current.status,
        error: (error.message || "CREATOR BATTLE QUEUE ACTION FAILED").toUpperCase(),
        actionBusy: ""
      }));
      throw error;
    }
  }

  async function updateProduction(battleId, patch) {
    if (!battleId) return null;
    return runCreatorBattleQueueMutation(
      "production:" + battleId,
      "PATCH",
      "/internal/battle-arena/battles/" + encodeURIComponent(battleId) + "/production",
      patch
    );
  }

  async function releaseBattle(battleId) {
    if (!battleId) return null;
    return runCreatorBattleQueueMutation(
      "release:" + battleId,
      "POST",
      "/internal/battle-arena/battles/" + encodeURIComponent(battleId) + "/release",
      {}
    );
  }

  async function assignScenePackage(battleId, scenePackageId) {
    if (!battleId || !scenePackageId) return null;
    return runCreatorBattleQueueMutation(
      "scene-package:" + battleId,
      "POST",
      "/internal/battle-arena/battles/" + encodeURIComponent(battleId) + "/scene-package",
      { scenePackageId }
    );
  }

  async function recordResult(battleId, patch) {
    if (!battleId) return null;
    return runCreatorBattleQueueMutation(
      "result:" + battleId,
      "POST",
      "/internal/battle-arena/battles/" + encodeURIComponent(battleId) + "/result",
      patch
    );
  }

  async function updateTheaterPublishing(battleId, patch) {
    if (!battleId) return null;
    return runCreatorBattleQueueMutation(
      "theater:" + battleId,
      "POST",
      "/internal/battle-arena/battles/" + encodeURIComponent(battleId) + "/theater",
      patch
    );
  }

  useEffect(() => {
    loadCreatorBattleQueueStatus();
  }, [account && account.status, account && account.organization && account.organization.id]);

  return {
    ...state,
    refresh: loadCreatorBattleQueueStatus,
    saveToken,
    clearToken,
    updateProduction,
    assignScenePackage,
    releaseBattle,
    recordResult,
    updateTheaterPublishing
  };
}

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" };
  }
  if (normalized.startsWith("BATTLE")) {
    return {
      kicker: "Battle Honor",
      mark: normalized.includes("VICTORY") ? "Victory" : normalized.includes("DRAW") ? "Draw" : "Combat",
      detail: "Arena Record"
    };
  }
  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.filter(Boolean).map((ownership) => {
    const mech = findMechById(ownership && ownership.mechId);
    const title = ownership.title || (mech
      ? mech.id + " / " + mech.codename
      : String(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 getBattleAftermathRecordsForMeka(mech, archiveDispatchStatus) {
  if (!mech) return [];
  const ownerships = Array.isArray(archiveDispatchStatus && archiveDispatchStatus.ownerships)
    ? archiveDispatchStatus.ownerships
    : [];
  return ownerships
    .filter((ownership) => ownership && ownership.sourceType === "battle" && ownership.mechId === mech.id)
    .sort((a, b) => certificateSortTime(b.claimedAt) - certificateSortTime(a.claimedAt));
}

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 MEKA CONCEPT ARCHIVE · TAILORED PROMPT · NON-COMMERCIAL ★</span>
          <span>NEW · {latest.id} {latest.codename} ARCHIVED {latest.date}</span>
          <span>★ FULL-BODY CONCEPTS · PILOTS · HAND-WRITTEN LORE · 3D MODELS · BATTLE SCENES ★</span>
          <span>★ SUPER MEKABOTS · AI-GENERATED MEKA CONCEPT ARCHIVE · TAILORED PROMPT · NON-COMMERCIAL ★</span>
          <span>NEW · {latest.id} {latest.codename} ARCHIVED {latest.date}</span>
          <span>★ FULL-BODY CONCEPTS · PILOTS · HAND-WRITTEN LORE · 3D MODELS · BATTLE SCENES ★</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 getPublishedDispatchCount(archiveDispatchStatus) {
  if (!archiveDispatchStatus || archiveDispatchStatus.status !== "ready") return null;
  const value = archiveDispatchStatus.data && archiveDispatchStatus.data.publishedDispatchCount;
  return Number.isSafeInteger(value) && value >= 0 ? value : null;
}

function Nav({ engagement, account, registry, archiveDispatchStatus }) {
  const counts = getEngagementCounts(engagement, account);
  const registryCount = getRegistryCount(registry);
  const publishedDispatchCount = getPublishedDispatchCount(archiveDispatchStatus);
  const publishedDispatchLabel = publishedDispatchCount === 1
    ? "1 published dispatch"
    : `${publishedDispatchCount} published dispatches`;
  const signedOut = !account || account.status !== "signed-in";
  return (
    <nav className="nav">
      <a className="brand" href="#top">
        <img src={versionAssetUrl(HEADER_LOGO_URL)} 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>}
        {!signedOut && <a href="#battle-arena">Battle</a>}
        <a href="#registry">Registry{registryCount > 0 && <b>{String(registryCount).padStart(2, "0")}</b>}</a>
        {signedOut && <a href="#battle-theater">Theater</a>}
        <a href="#archive">Index</a>
        <a
          href={DISPATCH_ARCHIVE_ROUTE}
          aria-label={publishedDispatchCount > 0 ? `Dispatches, ${publishedDispatchLabel}` : "Dispatches"}
        >
          Dispatches
          {publishedDispatchCount > 0 && <b aria-hidden="true">{String(publishedDispatchCount).padStart(2, "0")}</b>}
        </a>
        <a href="#comms">Comms</a>
        <a href="#about">About</a>
      </div>
    </nav>
  );
}

function ViewportImage({ src, alt = "", rootMargin = "160px 0px", loading = "lazy", decoding = "async", ...imageProps }) {
  const imageRef = useRef(null);
  const [shouldLoad, setShouldLoad] = useState(() => (
    typeof window === "undefined" || !window.IntersectionObserver
  ));

  useEffect(() => {
    if (shouldLoad || !src) return undefined;
    const image = imageRef.current;
    if (!image) return undefined;
    const observer = new IntersectionObserver(([entry]) => {
      if (!entry.isIntersecting) return;
      setShouldLoad(true);
      observer.disconnect();
    }, { root: null, rootMargin, threshold: 0 });
    observer.observe(image);
    return () => observer.disconnect();
  }, [rootMargin, shouldLoad, src]);

  return (
    <img
      {...imageProps}
      ref={imageRef}
      src={shouldLoad ? src : undefined}
      data-viewport-src={src || undefined}
      alt={alt}
      loading={loading}
      decoding={decoding}
    />
  );
}

function HeroCollage({ layout, fullbodyMechs, latest }) {
  // Each layout renders the fullbody renders differently
  if (layout === "parade") {
    // Keep the cinematic tracks large enough that offscreen units remain truly
    // offscreen and can be loaded progressively as the parade advances.
    const total = fullbodyMechs.length;
    const numRows = total === 0 ? 1 : Math.min(2, 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}>
                  <ViewportImage
                    className="parade-meka-image"
                    src={versionAssetUrl(m.fullbody)}
                    alt=""
                    rootMargin="120px 10%"
                  />
                </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 && (
          <ViewportImage className="spotlight-feature" src={versionAssetUrl(feature.fullbody)} alt="" rootMargin="120px 10%" />
        )}
        <div className="spotlight-thumbs">
          {rest.map((m) => (
            <div className="spotlight-thumb" key={m.id}>
              <ViewportImage src={versionAssetUrl(m.fullbody)} alt="" rootMargin="120px 10%" />
              <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}>
              <ViewportImage src={versionAssetUrl(m.fullbody)} alt="" rootMargin="120px 10%" />
              <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.slice(0, FORMATION_VISIBLE_SLOT_COUNT).map((m, i) => (
        <ViewportImage
          key={"fb-" + m.id}
          className={"collage-feature collage-feature-" + (i + 1)}
          src={versionAssetUrl(m.fullbody)}
          alt=""
          rootMargin="120px 10%"
        />
      ))}
      <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 Meka concepts</em>, expanding into full-body designs, pilot dossiers, hand-written lore, printable 3D models, and cinematic battle scenes.
            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">Mekas 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>}
      {!signedOut && <a href="#battle-arena"><span>BATTLE</span><b>ARENA</b></a>}
      <a href="#registry"><span>REGISTRY</span><b>{String(registryCount).padStart(2, "0")}</b></a>
      {signedOut && <a href="#battle-theater"><span>THEATER</span><b>LIVE</b></a>}
      <a href="#archive"><span>INDEX</span><b>{String(MEKABOTS_BY_ID.length).padStart(2, "0")}</b></a>
      <a href={DISPATCH_ARCHIVE_ROUTE}><span>DISPATCHES</span><b>LOG</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>
        <span className="archive-dispatch-featured-count">{entries.length} FEATURED {entries.length === 1 ? "UNIT" : "UNITS"}</span>
        <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>
        <a className="btn compact archive-dispatch-dock-archive-link" href={DISPATCH_ARCHIVE_ROUTE}>VIEW DISPATCH ARCHIVE</a>
      </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 formatBattleArenaDate(value) {
  if (!value) return "DATE PENDING";
  const timestamp = value.length === 10 ? value + "T00:00:00" : value;
  try {
    return new Date(timestamp).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" });
  } catch (error) {
    return String(value).toUpperCase();
  }
}

function formatBattleArenaDateTime(value) {
  if (!value) return "TIME PENDING";
  try {
    return new Date(value).toLocaleString(undefined, {
      month: "short",
      day: "numeric",
      year: "numeric",
      hour: "2-digit",
      minute: "2-digit"
    });
  } catch (error) {
    return String(value).toUpperCase();
  }
}

function getBattleInvitationExpiryState(expiresAt) {
  const expiresAtMs = Date.parse(expiresAt || "");
  const nowMs = Date.now();
  if (!Number.isFinite(expiresAtMs)) {
    return {
      value: "Waiting for expiry sync",
      detail: "Invitation expires after 1 day.",
      expired: false
    };
  }
  const remainingMs = expiresAtMs - nowMs;
  if (remainingMs <= 0) {
    return {
      value: "Expired",
      detail: "Invitation expired. Refresh status to reopen challenge options.",
      expired: true
    };
  }
  const remainingMinutes = Math.max(1, Math.ceil(remainingMs / 60000));
  const hours = Math.floor(remainingMinutes / 60);
  const minutes = remainingMinutes % 60;
  return {
    value: (hours ? hours + "h " : "") + String(minutes).padStart(2, "0") + "m",
    detail: "Invitation expires " + formatBattleArenaDateTime(expiresAt) + ".",
    expired: false
  };
}

function getBattleArenaParticipant(battle) {
  if (!battle) return null;
  return battle.viewerSide === "challenger" ? battle.challenger : battle.viewerSide === "defender" ? battle.defender : null;
}

function getBattleArenaOpponent(battle) {
  if (!battle) return null;
  return battle.viewerSide === "challenger" ? battle.defender : battle.viewerSide === "defender" ? battle.challenger : null;
}

function getBattleArenaParticipantLabel(participant, fallback) {
  const organization = participant && participant.organization ? participant.organization : null;
  return organization
    ? organization.name || organization.callsign || organization.id || fallback
    : fallback;
}

function getBattleArenaStageMech(participant, fallbackMech) {
  if (participant && participant.selectedMechId) {
    return findMechById(participant.selectedMechId) || fallbackMech || null;
  }
  return fallbackMech || null;
}

function getBattleArenaMekaNumber(mech) {
  const match = String(mech && mech.id ? mech.id : "").match(/^MK-(\d+)$/i);
  return match ? String(Number(match[1])).padStart(2, "0") : "";
}

function getBattleArenaCinematicAvatarPath(mech) {
  const id = String(mech && mech.id ? mech.id : "").toUpperCase();
  const normalizedNumber = getBattleArenaMekaNumber(mech);
  if (normalizedNumber) return "mecha-" + normalizedNumber + "-cinematic-avatar.png";

  const dispatchMatch = id.match(/^AD-W(\d+)-(\d+)$/i);
  if (!dispatchMatch) return "";
  const normalizedWeek = String(Number(dispatchMatch[1])).padStart(2, "0");
  const normalizedSlot = String(Number(dispatchMatch[2])).padStart(2, "0");
  return "ad-w" + normalizedWeek + "-" + normalizedSlot + "-cinematic-avatar.png";
}

const BATTLE_ARENA_CINEMATIC_FACING = Object.freeze({
  "MK-01": "right",
  "MK-02": "right",
  "MK-03": "left",
  "MK-04": "right",
  "MK-05": "left",
  "MK-06": "right",
  "MK-07": "right",
  "MK-08": "right",
  "MK-09": "left",
  "MK-10": "left",
  "MK-11": "right",
  "MK-12": "left",
  "MK-13": "left",
  "MK-14": "left",
  "MK-16": "left",
  "MK-17": "left",
  "MK-18": "left",
  "MK-19": "left",
  "MK-20": "left",
  "MK-21": "left",
  "AD-W23-01": "left",
  "AD-W23-02": "left",
  "AD-W23-03": "left"
});

const BATTLE_ARENA_CINEMATIC_AVATAR_IDS = new Set([
  "MK-01",
  "MK-02",
  "MK-03",
  "MK-04",
  "MK-05",
  "MK-06",
  "MK-07",
  "MK-08",
  "MK-09",
  "MK-10",
  "MK-11",
  "MK-12",
  "MK-13",
  "MK-14",
  "MK-16",
  "MK-17",
  "MK-18",
  "MK-19",
  "MK-20",
  "MK-21",
  "AD-W23-01",
  "AD-W23-02",
  "AD-W23-03"
]);

function normalizeBattleArenaFacing(value) {
  const normalized = String(value || "").toLowerCase();
  return normalized === "left" || normalized === "right" ? normalized : "";
}

function getBattleArenaCinematicFacing(mech) {
  const catalogFacing = normalizeBattleArenaFacing(mech && mech.cinematicAvatarFacing);
  if (catalogFacing) return catalogFacing;
  const id = mech && mech.id ? String(mech.id).toUpperCase() : "";
  return BATTLE_ARENA_CINEMATIC_FACING[id] || "";
}

function shouldFlipBattleArenaMeka(mech, desiredFacing) {
  const facing = getBattleArenaCinematicFacing(mech);
  const desired = normalizeBattleArenaFacing(desiredFacing);
  return Boolean(facing && desired && facing !== desired);
}

function getBattleArenaFacingClass(mech, desiredFacing) {
  return shouldFlipBattleArenaMeka(mech, desiredFacing) ? " is-flipped" : "";
}

function getBattleArenaCinematicAvatarSource(mech) {
  const id = mech && mech.id ? String(mech.id).toUpperCase() : "";
  if (!id || !BATTLE_ARENA_CINEMATIC_AVATAR_IDS.has(id)) return "";
  const assetPath = getBattleArenaCinematicAvatarPath(mech);
  return assetPath ? versionAssetUrl("assets/battle-theater/" + assetPath) : "";
}

function BattleArenaCinematicMekaImage({ mech, alt, side, requireCinematic = false, imageLoading = "lazy" }) {
  const [cinematicFailed, setCinematicFailed] = useState(false);
  const cinematicSource = getBattleArenaCinematicAvatarSource(mech);
  const useCinematic = Boolean(cinematicSource && !cinematicFailed);
  const missingRequired = Boolean(requireCinematic && !useCinematic);
  const loadingMode = imageLoading === "eager" ? "eager" : "lazy";
  const facing = getBattleArenaCinematicFacing(mech);
  const className = [
    "battle-arena-cinematic-avatar",
    useCinematic ? "is-cinematic" : missingRequired ? "is-missing" : "is-fallback",
    side ? "is-" + side : "",
    facing ? "is-source-facing-" + facing : ""
  ].filter(Boolean).join(" ");

  useEffect(() => {
    setCinematicFailed(false);
  }, [cinematicSource]);

  return (
    <div className={className}>
      <div className="battle-arena-cinematic-avatar-frame">
        {useCinematic ? (
          <img
            className="battle-arena-cinematic-avatar-image"
            src={cinematicSource}
            alt={alt || ""}
            loading={loadingMode}
            decoding="async"
            onError={() => setCinematicFailed(true)}
          />
        ) : missingRequired ? (
          <div className="battle-arena-cinematic-missing" role="img" aria-label={(mech && mech.id ? mech.id : "Meka") + " cinematic avatar missing"}>
            <span>Cinematic avatar missing</span>
            <b>{mech && mech.id ? mech.id : "MEKA"}</b>
            <em>Upload required cinematic-avatar asset.</em>
          </div>
        ) : (
          <HangarPreviewImage mech={mech} alt={alt || ""} className="battle-arena-cinematic-avatar-image" />
        )}
      </div>
    </div>
  );
}

const BATTLE_ARENA_HOME_CUTOUTS = Object.freeze({
  "MK-01": "./assets/battle-theater/mecha-01-home-cutout.png",
  "MK-02": "./assets/battle-theater/mecha-02-home-cutout.png",
  "MK-04": "./assets/battle-theater/mecha-04-home-cutout.png",
  "MK-05": "./assets/battle-theater/mecha-05-home-cutout.png",
  "MK-06": "./assets/battle-theater/mecha-06-home-cutout.png",
  "MK-07": "./assets/battle-theater/mecha-07-home-cutout.png",
  "MK-08": "./assets/battle-theater/mecha-08-home-cutout.png",
  "MK-09": "./assets/battle-theater/mecha-09-home-cutout.png",
  "MK-10": "./assets/battle-theater/mecha-10-home-cutout.png",
  "MK-11": "./assets/battle-theater/mecha-11-home-cutout.png",
  "MK-12": "./assets/battle-theater/mecha-12-home-cutout.png",
  "MK-13": "./assets/battle-theater/mecha-13-home-cutout.png",
  "MK-16": "./assets/battle-theater/mecha-16-home-cutout.png",
  "MK-18": "./assets/battle-theater/mecha-18-home-cutout.png",
  "AD-W22-01": "./assets/battle-theater/ad-w22-01-home-cutout.png",
  "AD-W22-02": "./assets/battle-theater/ad-w22-02-home-cutout.png",
  "AD-W22-03": "./assets/battle-theater/ad-w22-03-home-cutout.png"
});

function getBattleArenaHomeCutoutSource(mech) {
  const source = mech && mech.id ? BATTLE_ARENA_HOME_CUTOUTS[String(mech.id).toUpperCase()] : "";
  return source ? versionAssetUrl(source.replace(/^\.\//, "")) : "";
}

function BattleArenaLauncherMekaImage({ mech, alt, desiredFacing }) {
  const [cutoutFailed, setCutoutFailed] = useState(false);
  const cutoutSource = getBattleArenaHomeCutoutSource(mech);
  const flipped = shouldFlipBattleArenaMeka(mech, desiredFacing);
  useEffect(() => {
    setCutoutFailed(false);
  }, [cutoutSource]);

  if (!cutoutSource || cutoutFailed) {
    return (
      <div className={"battle-arena-launcher-cinematic-fallback" + (flipped ? " is-flipped" : "")}>
        <BattleArenaCinematicMekaImage
          mech={mech}
          alt={alt || ""}
          side={desiredFacing}
          requireCinematic
          imageLoading="eager"
        />
      </div>
    );
  }

  return (
    <img
      className={"battle-arena-launcher-cutout-image" + (flipped ? " is-flipped" : "")}
      src={cutoutSource}
      alt={alt || ""}
      loading="eager"
      decoding="async"
      onError={() => setCutoutFailed(true)}
    />
  );
}

function getBattleArenaTone(arena) {
  const environment = String(arena && arena.environmentType ? arena.environmentType : "offline");
  return environment.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "offline";
}

function normalizeBattleArenaChallengeSlug(value) {
  const text = String(value || "").trim();
  if (!text) return "";
  try {
    return decodeURIComponent(text);
  } catch (error) {
    return text;
  }
}

function findPrimaryBattleArenaRecord(battles, targetChallengeSlug = "") {
  const list = Array.isArray(battles) ? battles : [];
  const normalizedTargetSlug = normalizeBattleArenaChallengeSlug(targetChallengeSlug);
  if (normalizedTargetSlug) {
    const matchingBattle = list.find((battle) => normalizeBattleArenaChallengeSlug(battle && battle.challengeSlug) === normalizedTargetSlug);
    if (matchingBattle) return matchingBattle;
    return null;
  }
  return list.find((battle) => battle.status === "invited" && battle.viewerSide === "defender") ||
    list.find((battle) => battle.status === "invited" && battle.viewerSide === "challenger") ||
    list.find((battle) => ["selection_pending", "scheduled"].includes(battle.status) && !((getBattleArenaParticipant(battle) || {}).selectedMechId)) ||
    list.find((battle) => ["selection_pending", "scheduled"].includes(battle.status)) ||
    list.find((battle) => battle.status === "released") ||
    null;
}

function battleArenaBattleHref(battle) {
  const slug = normalizeBattleArenaChallengeSlug(battle && battle.challengeSlug);
  return slug ? "#battle-arena/active/" + encodeURIComponent(slug) : "#battle-arena/active";
}

function battleTheaterParticipantName(participant, fallback) {
  const organization = participant && participant.organization ? participant.organization : null;
  return organization ? organization.name || organization.callsign || fallback : fallback;
}

function battleTheaterMeka(participant) {
  return participant && participant.selectedMechId ? findMechById(participant.selectedMechId) : null;
}

const BATTLE_THEATER_MEKA_CUTOUTS = Object.freeze({
  "MK-11": "./assets/battle-theater/mk-11-preview-cutout.png",
  "MK-13": "./assets/battle-theater/mk-13-preview-cutout.png"
});

function battleTheaterBackdropUrl(battle) {
  const imageUrl = battle && battle.arena && typeof battle.arena.imageUrl === "string"
    ? battle.arena.imageUrl.trim()
    : "";
  if (imageUrl) return imageUrl;
  return "";
}

function battleTheaterBackdropStyle(backdropUrl) {
  if (!backdropUrl) return undefined;
  const safeBackdropUrl = String(backdropUrl).replace(/["\\\r\n]/g, "");
  return { "--battle-theater-backdrop": "url(\"" + safeBackdropUrl + "\")" };
}

function getBattleTheaterMekaCutout(mech) {
  return mech && BATTLE_THEATER_MEKA_CUTOUTS[mech.id] ? BATTLE_THEATER_MEKA_CUTOUTS[mech.id] : "";
}

function BattleTheaterMekaImage({ mech, alt }) {
  const [cutoutFailed, setCutoutFailed] = useState(false);
  const cutout = getBattleTheaterMekaCutout(mech);

  if (cutout && !cutoutFailed) {
    return (
      <img
        className="is-theater-cutout"
        src={versionAssetUrl(cutout)}
        alt={alt || ""}
        loading="lazy"
        decoding="async"
        onError={() => setCutoutFailed(true)}
      />
    );
  }

  return <HangarPreviewImage mech={mech} alt={alt} className="is-theater-fallback" />;
}

function battleTheaterSpectatorLockCopy(account, battle) {
  if (!account || account.status !== "signed-in") return "SIGN IN REQUIRED";
  const viewer = battle && battle.theater && battle.theater.viewer ? battle.theater.viewer : {};
  if (viewer.canEngage) return "";
  if (viewer.lockedReason === "tutorial_incomplete") return "COMPLETE TUTORIAL";
  return "SPECTATOR LOCKED";
}

function BattleTheaterPanel({ account, onboardingStatus, battleTheaterStatus }) {
  const battles = Array.isArray(battleTheaterStatus && battleTheaterStatus.battles)
    ? battleTheaterStatus.battles
    : [];
  const tutorialComplete = Boolean(phaseOneDirectivesAreClear(onboardingStatus && onboardingStatus.data));
  const busy = Boolean(battleTheaterStatus && battleTheaterStatus.actionBusy);
  const [localError, setLocalError] = useState("");

  async function handleSalute(battle) {
    if (!battleTheaterStatus || !battle || typeof battleTheaterStatus.saluteBattle !== "function") return;
    setLocalError("");
    try {
      await battleTheaterStatus.saluteBattle(battle.id);
    } catch (error) {
      setLocalError((error.message || "SPECTATOR SALUTE FAILED").toUpperCase());
    }
  }

  async function handleFavorite(battle) {
    if (!battleTheaterStatus || !battle || typeof battleTheaterStatus.favoriteBattle !== "function") return;
    const viewer = battle.theater && battle.theater.viewer ? battle.theater.viewer : {};
    setLocalError("");
    try {
      await battleTheaterStatus.favoriteBattle(battle.id, !viewer.favorited);
    } catch (error) {
      setLocalError((error.message || "SPECTATOR FAVORITE FAILED").toUpperCase());
    }
  }

  function handleWatchBattle(battle) {
    if (!battleTheaterStatus || !battle || typeof battleTheaterStatus.recordTheaterView !== "function") return;
    const viewer = battle.theater && battle.theater.viewer ? battle.theater.viewer : {};
    if (!viewer.canEngage) return;
    battleTheaterStatus.recordTheaterView(battle.id).catch((error) => {
      setLocalError((error.message || "BATTLE WATCH RECORD FAILED").toUpperCase());
    });
  }

  return (
    <section id="battle-theater" className="section battle-theater-section" aria-label="Battle Theater" data-screen-label="Battle Theater">
      <div className="section-inner">
        <div className="battle-theater-panel">
          <div className="battle-theater-head">
            <div>
              <span>Battle Theater</span>
              <b>{battles.length ? battles.length + " Public Battle" + (battles.length === 1 ? "" : "s") : "Showcase Warming"}</b>
            </div>
            <p>Completed arena scenes become public only after creator review. Spectator actions unlock after all tutorial directives are complete.</p>
          </div>
          {battles.length ? (
            <div className="battle-theater-grid">
              {battles.map((battle) => {
                const challengerMeka = battleTheaterMeka(battle.challenger);
                const defenderMeka = battleTheaterMeka(battle.defender);
                const theater = battle.theater || {};
                const stats = theater.stats || {};
                const viewer = theater.viewer || {};
                const canEngage = Boolean(viewer.canEngage && tutorialComplete);
                const lockCopy = battleTheaterSpectatorLockCopy(account, battle);
                const winner = battle.chronicle && battle.chronicle.winnerMeka
                  ? battle.chronicle.winnerMeka.id
                  : (battle.chronicle && battle.chronicle.winnerSide === "draw" ? "DRAW" : "RESULT FILED");
                const backdropUrl = battleTheaterBackdropUrl(battle);
                return (
                  <article className={"battle-theater-card tone-" + getBattleArenaTone(battle.arena) + (backdropUrl ? " has-backdrop" : "")} key={battle.id} style={battleTheaterBackdropStyle(backdropUrl)}>
                    <div className="battle-theater-arena-signal">
                      <span>{battle.arena && battle.arena.environmentType ? battle.arena.environmentType : "Arena Record"}</span>
                      <b>{battle.arena ? battle.arena.name : "Arena Record"}</b>
                    </div>
                    <div className="battle-theater-stage">
                      <div className="battle-theater-unit">
                        {challengerMeka ? <BattleTheaterMekaImage mech={challengerMeka} alt={challengerMeka.codename + " Battle Theater challenger"} /> : <span>CHALLENGER LOCK</span>}
                        <b>{battle.challenger && battle.challenger.selectedMechId ? battle.challenger.selectedMechId : "PENDING"}</b>
                        <em>{battleTheaterParticipantName(battle.challenger, "Challenger")}</em>
                      </div>
                      <div className="battle-theater-vs">
                        <strong>VS</strong>
                        <span>{battle.arena ? battle.arena.name : "Arena Record"}</span>
                        <b>{winner}</b>
                      </div>
                      <div className="battle-theater-unit">
                        {defenderMeka ? <BattleTheaterMekaImage mech={defenderMeka} alt={defenderMeka.codename + " Battle Theater defender"} /> : <span>DEFENDER LOCK</span>}
                        <b>{battle.defender && battle.defender.selectedMechId ? battle.defender.selectedMechId : "PENDING"}</b>
                        <em>{battleTheaterParticipantName(battle.defender, "Defender")}</em>
                      </div>
                    </div>
                    <div className="battle-theater-body">
                      <div className="battle-theater-meta">
                        <span>{theater.featured ? "FEATURED RECORD" : "PUBLIC RECORD"}</span>
                        <b>{battle.chronicle && battle.chronicle.title ? battle.chronicle.title : (battle.arena ? battle.arena.name : "Battle Chronicle")}</b>
                        <em>{battle.completedAt ? formatBattleArenaDate(battle.completedAt) : formatBattleArenaDate(battle.scheduledBattleDate)}</em>
                      </div>
                      <p>{theater.curatorNote || (battle.chronicle && (battle.chronicle.battleLogLine || battle.chronicle.summary)) || "Battle record cleared for public Theater viewing."}</p>
                      <div className="battle-theater-stats" aria-label="Spectator engagement">
                        <span><b>{stats.saluteCount || 0}</b> Salutes</span>
                        <span><b>{stats.favoriteCount || 0}</b> Favorites</span>
                        <span><b>{stats.watchCount || 0}</b> Watches</span>
                      </div>
                      <div className="battle-theater-actions">
                        <button type="button" className="btn" onClick={() => handleSalute(battle)} disabled={!canEngage || viewer.saluted || busy}>
                          {viewer.saluted ? "SALUTED" : "SALUTE"}
                        </button>
                        <button type="button" className="btn" onClick={() => handleFavorite(battle)} disabled={!canEngage || busy}>
                          {viewer.favorited ? "FAVORITED" : "FAVORITE"}
                        </button>
                        {battle.scenePublicUrl && canEngage ? (
                          <a className="btn primary" href={battle.scenePublicUrl} target="_blank" rel="noreferrer" onClick={() => handleWatchBattle(battle)}>
                            WATCH BATTLE
                          </a>
                        ) : (
                          <button type="button" className="btn primary" disabled>{battle.scenePublicUrl ? "WATCH LOCKED" : "SCENE SEALED"}</button>
                        )}
                      </div>
                      {!canEngage && <div className="battle-theater-lock">{lockCopy}</div>}
                    </div>
                  </article>
                );
              })}
            </div>
          ) : (
            <div className="battle-theater-empty">
              <span>Public Theater Empty</span>
              <b>Completed battles appear after creator approval.</b>
            </div>
          )}
          {(localError || (battleTheaterStatus && battleTheaterStatus.error)) && (
            <div className="battle-arena-error">{localError || battleTheaterStatus.error}</div>
          )}
        </div>
      </div>
    </section>
  );
}

function BattleArenaPanel({ account, registry, archiveDispatchStatus, battleArenaStatus, creatorBattleQueueStatus, activeMech, targetChallengeSlug = "", view = "board" }) {
  const accountOrganization = getAccountOrganization(account);
  const arenas = Array.isArray(battleArenaStatus && battleArenaStatus.arenas) ? battleArenaStatus.arenas : [];
  const battles = Array.isArray(battleArenaStatus && battleArenaStatus.battles) ? battleArenaStatus.battles : [];
  const ownedMechs = getOrganizationRosterMechs(account, archiveDispatchStatus);
  const opponents = Array.isArray(registry && registry.organizations)
    ? registry.organizations.filter((entry) => entry && entry.organization && accountOrganization && entry.organization.id !== accountOrganization.id)
    : [];
  const ownedOptions = ownedMechs.map((mech) => ({
    mech,
    ownership: getOrganizationRosterOwnership(account, archiveDispatchStatus, mech)
  })).filter((entry) => entry.ownership);
  const normalizedTargetChallengeSlug = normalizeBattleArenaChallengeSlug(targetChallengeSlug);
  const primaryBattle = findPrimaryBattleArenaRecord(battles, normalizedTargetChallengeSlug);
  const targetedBattleWithoutMatch = Boolean(normalizedTargetChallengeSlug && !primaryBattle);
  const targetChallengeMissing = Boolean(targetedBattleWithoutMatch && battleArenaStatus && battleArenaStatus.status === "ready");
  const primaryParticipant = getBattleArenaParticipant(primaryBattle);
  const primaryOpponent = getBattleArenaOpponent(primaryBattle);
  const activeBattleRecords = battles.filter((battle) => battle && ["invited", "selection_pending", "scheduled", "released"].includes(battle.status));
  const chronicleBattles = battles
    .filter((battle) => battle && battle !== primaryBattle && (battle.status === "completed" || battle.chronicle))
    .slice(0, 5);
  const incomingInvite = Boolean(primaryBattle && primaryBattle.status === "invited" && primaryBattle.viewerSide === "defender");
  const outgoingInvite = Boolean(primaryBattle && primaryBattle.status === "invited" && primaryBattle.viewerSide === "challenger");
  const closedBattle = Boolean(primaryBattle && ["declined", "expired", "cancelled"].includes(primaryBattle.status));
  const lockReady = Boolean(primaryBattle && ["selection_pending", "scheduled"].includes(primaryBattle.status) && primaryParticipant && !primaryParticipant.selectedMechId);
  const sceneLive = Boolean(primaryBattle && primaryBattle.sceneAvailable && primaryBattle.scenePublicUrl);
  const [selectedOpponentId, setSelectedOpponentId] = useState("");
  const [selectedArenaId, setSelectedArenaId] = useState("");
  const [selectedOwnershipId, setSelectedOwnershipId] = useState("");
  const [localError, setLocalError] = useState("");
  const [issuedChallengeReceipt, setIssuedChallengeReceipt] = useState(null);
  const [challengeTransmissionReceipt, setChallengeTransmissionReceipt] = useState(null);
  const activeOwnership = getOrganizationRosterOwnership(account, archiveDispatchStatus, activeMech);
  const arena = arenas.find((entry) => entry.id === selectedArenaId) || null;
  const selectedOpponentEntry = opponents.find((entry) => entry && entry.organization && entry.organization.id === selectedOpponentId) || opponents[0] || null;
  const selectedOpponentMeka = getBattleOpponentRosterMekas(selectedOpponentEntry)[0] || null;
  const selectedOwnedOption = ownedOptions.find((entry) => entry.ownership && entry.ownership.id === selectedOwnershipId) || ownedOptions[0] || null;
  const selectedChallengeMech = selectedOwnedOption && selectedOwnedOption.mech ? selectedOwnedOption.mech : activeMech || (ownedOptions[0] && ownedOptions[0].mech) || null;
  const busy = Boolean(battleArenaStatus && battleArenaStatus.actionBusy);
  const statusLabel = battleArenaStatus && battleArenaStatus.status === "loading"
    ? "SYNCING"
    : targetChallengeMissing
      ? "INVITE UNAVAILABLE"
      : primaryBattle
      ? String(primaryBattle.status || "READY").replace(/_/g, " ").toUpperCase()
      : "READY";
  const sceneStateLabel = sceneLive
    ? "Scene live"
    : closedBattle
      ? "Challenge closed"
    : incomingInvite
      ? "Invite received"
      : lockReady
        ? "Meka lock required"
        : primaryBattle
          ? statusLabel
          : "Ready to challenge";
  const scheduleLabel = closedBattle
    ? "No production slot"
    : primaryBattle && primaryBattle.scheduledBattleDate
    ? formatBattleArenaDate(primaryBattle.scheduledBattleDate)
    : "3-day production window";
  const publishLabel = closedBattle
    ? "No creator queue"
    : primaryBattle && (primaryBattle.publishAt || primaryBattle.scheduledBattleDate)
    ? formatBattleArenaDate(primaryBattle.publishAt || primaryBattle.scheduledBattleDate)
    : "Creator publish queue";
  const primaryBattleProgressCopy = closedBattle
    ? "Challenge " + String(primaryBattle.status || "closed").replace(/_/g, " ") + ". This invitation is closed; no production slot was created."
    : primaryBattle && primaryBattle.scheduledBattleDate
    ? "Scheduled " + formatBattleArenaDate(primaryBattle.scheduledBattleDate) + " / publish " + formatBattleArenaDate(primaryBattle.publishAt || primaryBattle.scheduledBattleDate)
    : primaryBattle && primaryBattle.status === "invited" && primaryBattle.viewerSide === "challenger"
      ? "Challenge sent. Waiting for " + getBattleArenaParticipantLabel(primaryOpponent, "the opponent") + " to accept."
      : primaryBattle && primaryBattle.status === "invited" && primaryBattle.viewerSide === "defender"
        ? "Incoming challenge. Accept or decline to enter the production queue."
        : "Awaiting invitation response.";
  useEffect(() => {
    if (!selectedOpponentId || !opponents.some((entry) => entry.organization && entry.organization.id === selectedOpponentId)) {
      setSelectedOpponentId(opponents[0] && opponents[0].organization ? opponents[0].organization.id : "");
    }
  }, [opponents.map((entry) => entry.organization && entry.organization.id).join("|")]);

  useEffect(() => {
    if (selectedArenaId && !arenas.some((entry) => entry.id === selectedArenaId)) {
      setSelectedArenaId("");
    }
  }, [selectedArenaId, arenas.map((entry) => entry.id).join("|")]);

  useEffect(() => {
    const preferredOwnershipId = activeOwnership && activeOwnership.id
      ? activeOwnership.id
      : ownedOptions[0] && ownedOptions[0].ownership ? ownedOptions[0].ownership.id : "";
    if (!selectedOwnershipId || !ownedOptions.some((entry) => entry.ownership && entry.ownership.id === selectedOwnershipId)) {
      setSelectedOwnershipId(preferredOwnershipId);
    }
  }, [activeOwnership && activeOwnership.id, ownedOptions.map((entry) => entry.ownership && entry.ownership.id).join("|")]);

  function clearChallengeReceipts() {
    setIssuedChallengeReceipt(null);
    setChallengeTransmissionReceipt(null);
  }

  function handleOpponentChange(nextOpponentId) {
    clearChallengeReceipts();
    setSelectedOpponentId(nextOpponentId);
  }

  function handleArenaChange(nextArenaId) {
    clearChallengeReceipts();
    setSelectedArenaId(nextArenaId);
  }

  async function handleChallengeSubmit(event) {
    event.preventDefault();
    if (!battleArenaStatus || !selectedOpponentId || !selectedArenaId || !selectedOwnershipId) return;
    setLocalError("");
    try {
      const challengeResult = await battleArenaStatus.createChallenge(selectedOpponentId, selectedArenaId, selectedOwnershipId);
      const battle = challengeResult && challengeResult.battle ? challengeResult.battle : null;
      const receiptOpponentOrganization = selectedOpponentEntry && selectedOpponentEntry.organization ? selectedOpponentEntry.organization : null;
      const receipt = {
        kind: "challenge",
        opponentOrganizationId: selectedOpponentId,
        ownershipId: selectedOwnershipId,
        mechName: selectedChallengeMech ? selectedChallengeMech.id + " / " + selectedChallengeMech.codename : "Locked Meka",
        arenaId: selectedArenaId,
        opponentName: receiptOpponentOrganization
          ? receiptOpponentOrganization.name || receiptOpponentOrganization.callsign || receiptOpponentOrganization.id
          : "Opponent",
        arenaName: arena ? arena.name : "Selected arena",
        battleId: battle && battle.id ? battle.id : "",
        scheduledBattleDate: battle && battle.scheduledBattleDate ? battle.scheduledBattleDate : "",
        expiresAt: battle && battle.expiresAt ? battle.expiresAt : "",
        emailHandoff: challengeResult && challengeResult.invitationEmail ? challengeResult.invitationEmail : null,
        issuedAt: new Date().toISOString()
      };
      setIssuedChallengeReceipt(receipt);
      setChallengeTransmissionReceipt(receipt);
      const activeBattleHref = battleArenaBattleHref(battle);
      if (typeof window !== "undefined" && window.location.hash !== activeBattleHref) {
        window.location.hash = activeBattleHref;
      }
    } catch (error) {
      setLocalError((error.message || "BATTLE CHALLENGE FAILED").toUpperCase());
    }
  }

  async function handleBattleArenaRefresh() {
    if (!battleArenaStatus || typeof battleArenaStatus.refresh !== "function") return;
    setLocalError("");
    try {
      await battleArenaStatus.refresh();
    } catch (error) {
      setLocalError((error.message || "BATTLE STATUS REFRESH FAILED").toUpperCase());
    }
  }

  async function handleAcceptBattle() {
    if (!battleArenaStatus || !primaryBattle) return;
    setLocalError("");
    try {
      const result = await battleArenaStatus.acceptBattle(primaryBattle.id);
      openBattleOutcomeTransmission("accepted", result);
    } catch (error) {
      setLocalError((error.message || "BATTLE ACCEPT FAILED").toUpperCase());
    }
  }

  async function handleDeclineBattle() {
    if (!battleArenaStatus || !primaryBattle) return;
    setLocalError("");
    try {
      const result = await battleArenaStatus.declineBattle(primaryBattle.id);
      openBattleOutcomeTransmission("declined", result);
    } catch (error) {
      setLocalError((error.message || "BATTLE DECLINE FAILED").toUpperCase());
    }
  }

  function openBattleOutcomeTransmission(kind, result) {
    const battle = result && result.battle ? result.battle : primaryBattle;
    setChallengeTransmissionReceipt({
      kind,
      battleId: battle && battle.id ? battle.id : primaryBattle.id,
      actorName: accountOrganization.name || accountOrganization.callsign || "Defender organization",
      opponentName: getBattleArenaParticipantLabel(primaryOpponent, "Opponent"),
      arenaName: battle && battle.arena && battle.arena.name ? battle.arena.name : "Selected arena",
      scheduledBattleDate: battle && battle.scheduledBattleDate ? battle.scheduledBattleDate : "",
      emailHandoff: result && result.confirmationEmails ? result.confirmationEmails : null
    });
  }

  async function handleLockMeka() {
    if (!battleArenaStatus || !primaryBattle || !selectedOwnershipId) return;
    setLocalError("");
    try {
      await battleArenaStatus.selectMeka(primaryBattle.id, selectedOwnershipId);
    } catch (error) {
      setLocalError((error.message || "MEKA LOCK FAILED").toUpperCase());
    }
  }

  function handleWatchBattleScene(event) {
    if (!battleArenaStatus || !primaryBattle || !primaryBattle.scenePublicUrl || busy) {
      if (event) event.preventDefault();
      return;
    }
    setLocalError("");
    battleArenaStatus.recordSceneViewed(primaryBattle.id).catch((error) => {
      setLocalError((error.message || "BATTLE SCENE VIEW FAILED").toUpperCase());
    });
  }

  if (!accountOrganization) return null;
  const activeView = view === "active";
  const showInvitationWaitingRoom = Boolean(!targetedBattleWithoutMatch && (outgoingInvite || (!primaryBattle && issuedChallengeReceipt)));
  const showCurrentChallengeStatus = Boolean(primaryBattle && !showInvitationWaitingRoom);

  return (
    <section className="battle-arena-panel" aria-label="Battle Arena">
      <div className="battle-arena-head">
        <div>
          <span>Battle Arena</span>
          <b>{activeView ? "Active Battle" : "Challenge Board"}</b>
        </div>
        <em>{statusLabel}</em>
      </div>
      <BattleChallengeTransmission
        receipt={challengeTransmissionReceipt}
        onDismiss={() => setChallengeTransmissionReceipt(null)}
      />
      {activeView && activeBattleRecords.length > 1 && (
        <nav className="battle-active-records" aria-label="Active battle records">
          <div className="battle-active-records-head">
            <span>Active Records</span>
            <b>{String(activeBattleRecords.length).padStart(2, "0")}</b>
          </div>
          <div className="battle-active-record-list">
            {activeBattleRecords.map((battle) => {
              const opponent = getBattleArenaOpponent(battle);
              const opponentLabel = getBattleArenaParticipantLabel(opponent, "Opponent pending");
              const isCurrent = Boolean(primaryBattle && battle.id === primaryBattle.id);
              return (
                <a className={isCurrent ? "is-active" : ""} href={battleArenaBattleHref(battle)} aria-current={isCurrent ? "page" : undefined} key={battle.id}>
                  <span>{opponentLabel}</span>
                  <b>{String(battle.status || "active").replace(/_/g, " ")}</b>
                </a>
              );
            })}
          </div>
        </nav>
      )}
      <div className={"battle-arena-flow-shell" + (!showCurrentChallengeStatus && !showInvitationWaitingRoom ? " is-pre-submit" : "") + (showInvitationWaitingRoom ? " is-waiting-room" : "") + (targetedBattleWithoutMatch ? " is-target-missing" : "")}>
        {activeView && targetedBattleWithoutMatch ? (
          <div id="battle-challenge-command" className="battle-arena-command-rail">
            <BattleArenaInvitationUnavailable
              challengeSlug={normalizedTargetChallengeSlug}
              accountOrganization={accountOrganization}
              status={battleArenaStatus && battleArenaStatus.status}
              busy={busy}
              onRefresh={handleBattleArenaRefresh}
            />
          </div>
        ) : activeView && showInvitationWaitingRoom ? (
          <BattlePendingWaitingRoom
            battle={primaryBattle}
            participant={primaryParticipant}
            opponent={primaryOpponent}
            accountOrganization={accountOrganization}
            fallbackMeka={selectedChallengeMech}
            fallbackOpponentEntry={selectedOpponentEntry}
            fallbackArena={arena}
            receipt={issuedChallengeReceipt}
            onRefresh={handleBattleArenaRefresh}
            busy={busy}
          />
        ) : !activeView ? (
          <div id="battle-challenge-command" className="battle-arena-command-rail">
            <BattleChallengeJourney
              opponents={opponents}
              selectedOpponentId={selectedOpponentId}
              selectedOpponentEntry={selectedOpponentEntry}
              selectedOpponentMeka={selectedOpponentMeka}
              onOpponentChange={handleOpponentChange}
              arenas={arenas}
              selectedArenaId={selectedArenaId}
              selectedArena={arena}
              onArenaChange={handleArenaChange}
              ownedOptions={ownedOptions}
              selectedOwnershipId={selectedOwnershipId}
              onOwnershipChange={setSelectedOwnershipId}
              activeMech={selectedChallengeMech}
              accountOrganization={accountOrganization}
              busy={busy}
              onSubmit={handleChallengeSubmit}
              issuedChallengeReceipt={issuedChallengeReceipt}
            />
          </div>
        ) : null}
        {activeView && showCurrentChallengeStatus && (
          <BattleArenaCurrentStatus
            battles={battles}
            primaryBattle={primaryBattle}
            primaryParticipant={primaryParticipant}
            primaryOpponent={primaryOpponent}
            primaryBattleProgressCopy={primaryBattleProgressCopy}
            incomingInvite={incomingInvite}
            lockReady={lockReady}
            sceneLive={sceneLive}
            ownedOptions={ownedOptions}
            selectedOwnershipId={selectedOwnershipId}
            onOwnershipChange={setSelectedOwnershipId}
            onAcceptBattle={handleAcceptBattle}
            onDeclineBattle={handleDeclineBattle}
            onLockMeka={handleLockMeka}
            onWatchBattleScene={handleWatchBattleScene}
            onRefresh={handleBattleArenaRefresh}
            scheduleLabel={scheduleLabel}
            publishLabel={publishLabel}
            sceneStateLabel={sceneStateLabel}
            chronicleBattles={chronicleBattles}
            busy={busy}
          />
        )}
        {activeView && !primaryBattle && !targetedBattleWithoutMatch && (
          <BattleArenaCurrentStatus
            battles={battles}
            primaryBattle={null}
            primaryParticipant={null}
            primaryOpponent={null}
            primaryBattleProgressCopy=""
            incomingInvite={false}
            lockReady={false}
            sceneLive={false}
            ownedOptions={ownedOptions}
            selectedOwnershipId={selectedOwnershipId}
            onOwnershipChange={setSelectedOwnershipId}
            onAcceptBattle={handleAcceptBattle}
            onDeclineBattle={handleDeclineBattle}
            onLockMeka={handleLockMeka}
            onWatchBattleScene={handleWatchBattleScene}
            onRefresh={handleBattleArenaRefresh}
            scheduleLabel={scheduleLabel}
            publishLabel={publishLabel}
            sceneStateLabel={sceneStateLabel}
            chronicleBattles={chronicleBattles}
            busy={busy}
          />
        )}
      </div>
      {(localError || (battleArenaStatus && battleArenaStatus.error)) && (
        <div className="battle-arena-error">{localError || battleArenaStatus.error}</div>
      )}
      {activeView && (
        <CreatorBattleQueuePanel
          creatorBattleQueueStatus={creatorBattleQueueStatus}
          onQueueMutationComplete={battleArenaStatus && typeof battleArenaStatus.refresh === "function" ? battleArenaStatus.refresh : null}
        />
      )}
    </section>
  );
}

function BattleArenaInvitationUnavailable({ challengeSlug, accountOrganization, status, busy, onRefresh }) {
  const checking = status === "loading" || status === "idle";
  const organizationName = accountOrganization && (accountOrganization.name || accountOrganization.callsign)
    ? accountOrganization.name || accountOrganization.callsign
    : "this account";

  return (
    <div className={"battle-invite-unavailable" + (checking ? " is-checking" : "")} role="status" aria-live="polite">
      <div>
        <span>{checking ? "CHECKING BATTLE INVITATION" : "BATTLE INVITATION UNAVAILABLE"}</span>
        <b>{checking ? "Verifying challenge route" : "This challenge is not available for this account"}</b>
        <p>
          {checking
            ? "Battle Arena is checking whether this signed-in organization can access the challenge route."
            : "The invitation slug did not match any active battle visible to " + organizationName + ". Sign in with the challenged organization account or request a fresh battle invitation."}
        </p>
      </div>
      <div className="battle-invite-unavailable-route">
        <span>Challenge route</span>
        <b>{challengeSlug || "Unknown challenge"}</b>
      </div>
      <div className="battle-invite-unavailable-actions">
        <button type="button" className="btn primary" onClick={onRefresh} disabled={busy}>{checking ? "CHECK AGAIN" : "REFRESH INVITATION"}</button>
        <a className="btn" href="#battle-arena">OPEN BATTLE ARENA</a>
      </div>
    </div>
  );
}

function BattlePendingWaitingRoom({
  battle,
  participant,
  opponent,
  accountOrganization,
  fallbackMeka,
  fallbackOpponentEntry,
  fallbackArena,
  receipt,
  onRefresh,
  busy
}) {
  const challengerName = accountOrganization
    ? accountOrganization.name || accountOrganization.callsign || "Your organization"
    : "Your organization";
  const fallbackOpponentOrganization = fallbackOpponentEntry && fallbackOpponentEntry.organization ? fallbackOpponentEntry.organization : null;
  const opponentName = getBattleArenaParticipantLabel(
    opponent,
    fallbackOpponentOrganization ? fallbackOpponentOrganization.name || fallbackOpponentOrganization.callsign || fallbackOpponentOrganization.id : (receipt && receipt.opponentName) || "Opponent"
  );
  const lockedMeka = getBattleArenaStageMech(participant, fallbackMeka);
  const lockedMekaLabel = lockedMeka ? lockedMeka.id + " / " + lockedMeka.codename : (receipt && receipt.mechName) || "Locked Meka";
  const arena = battle && battle.arena ? battle.arena : fallbackArena;
  const arenaName = arena ? arena.name : (receipt && receipt.arenaName) || "Selected arena";
  const arenaRegion = arena && arena.region ? arena.region : "Arena command";
  const expiresAt = battle && battle.expiresAt ? battle.expiresAt : receipt && receipt.expiresAt ? receipt.expiresAt : "";
  const expiry = getBattleInvitationExpiryState(expiresAt);
  const waitingArenaStyle = arena && arena.imageUrl
    ? { "--battle-review-arena-image": "url(\"" + String(arena.imageUrl).replace(/["\\\r\n]/g, "") + "\")" }
    : undefined;
  const opponentRosterMekas = getBattleOpponentRosterMekas(fallbackOpponentEntry);

  return (
    <section id="battle-pending-waiting-room" className={"battle-pending-waiting-room tone-" + getBattleArenaTone(arena)} aria-label="Battle invitation waiting room">
      <div className="battle-pending-waiting-head">
        <span>Acceptance Waiting Room</span>
        <b>{challengerName} vs {opponentName}</b>
        <p>{lockedMekaLabel} is locked for {arenaName}. The defender chooses their Meka only after accepting. If no response arrives within 1 day, the invitation expires and challenge options reopen.</p>
      </div>
      <div className="battle-pending-waiting-stage battle-challenge-vs-stage" style={waitingArenaStyle}>
        <div className={"battle-challenge-vs-fighter is-operator" + getBattleArenaFacingClass(lockedMeka, "right")}>
          <span>Locked Challenger Unit</span>
          <div className="battle-challenge-vs-art">
            {lockedMeka ? (
              <BattleArenaCinematicMekaImage mech={lockedMeka} alt={lockedMekaLabel + " locked battle unit"} side="operator" requireCinematic={true} />
            ) : (
              <div className="battle-arena-cinematic-missing"><span>Cinematic avatar missing</span><b>MEKA</b><em>Locked unit sync required.</em></div>
            )}
          </div>
          <b>{lockedMekaLabel}</b>
          <em>{challengerName}</em>
        </div>
        <div className="battle-challenge-vs-center battle-pending-countdown">
          <span>Invitation expires</span>
          <strong>{expiry.value}</strong>
          <b>{arenaName}</b>
          <em>{expiry.detail}</em>
        </div>
        <div className="battle-challenge-vs-fighter is-opponent">
          <span>Defender Meka Pending</span>
          <div className="battle-challenge-vs-art">
            <div className="battle-arena-launcher-scan-slot is-meka-pending">
              <span>Defender bay sealed</span>
              <b>Locks after accept</b>
            </div>
          </div>
          <b>{opponentName}</b>
          <em>{opponentRosterMekas.length ? opponentRosterMekas.length + " public Meka available" : "Defender roster pending"}</em>
        </div>
      </div>
      <div className="battle-pending-waiting-status" aria-label="Pending challenge status">
        <span><b>Challenge Sent</b>Waiting for acceptance</span>
        <span><b>Selected Stage</b>{arenaRegion} / {arenaName}</span>
        <span><b>Next Unlock</b>Defender acceptance opens Meka lock. Production begins when both units are locked.</span>
      </div>
      <div className="battle-pending-waiting-actions">
        <button type="button" className="btn primary" onClick={onRefresh} disabled={busy}>Refresh Status</button>
        <p>New challenges are unavailable while this invitation is active. They reopen if the defender declines or the 1-day invitation window expires.</p>
      </div>
    </section>
  );
}

function BattleArenaCurrentStatus({
  battles,
  primaryBattle,
  primaryParticipant,
  primaryOpponent,
  primaryBattleProgressCopy,
  incomingInvite,
  lockReady,
  sceneLive,
  ownedOptions,
  selectedOwnershipId,
  onOwnershipChange,
  onAcceptBattle,
  onDeclineBattle,
  onLockMeka,
  onWatchBattleScene,
  onRefresh,
  scheduleLabel,
  chronicleBattles,
  busy
}) {
  const ownershipRows = Array.isArray(ownedOptions) ? ownedOptions : [];
  const opponentName = primaryOpponent && primaryOpponent.organization
    ? primaryOpponent.organization.name || primaryOpponent.organization.callsign || "Opponent pending"
    : "Opponent pending";
  const arenaName = primaryBattle && primaryBattle.arena ? primaryBattle.arena.name : "Arena pending";
  const arenaRegion = primaryBattle && primaryBattle.arena && primaryBattle.arena.region ? primaryBattle.arena.region : "Battle Arena";
  const currentArenaImageStyle = primaryBattle && primaryBattle.arena && primaryBattle.arena.imageUrl
    ? { "--battle-current-arena-image": "url(\"" + String(primaryBattle.arena.imageUrl).replace(/["\\\r\n]/g, "") + "\")" }
    : undefined;
  const outgoingInvite = Boolean(primaryBattle && primaryBattle.status === "invited" && primaryBattle.viewerSide === "challenger");
  const battleClosed = Boolean(primaryBattle && ["declined", "expired", "cancelled"].includes(primaryBattle.status));
  const battleOpen = Boolean(primaryBattle && ["selection_pending", "scheduled"].includes(primaryBattle.status));
  const participantLocked = Boolean(primaryParticipant && primaryParticipant.selectedMechId);
  const opponentLocked = Boolean(primaryOpponent && primaryOpponent.selectedMechId);
  const productionLocked = Boolean(primaryBattle && (primaryBattle.status === "scheduled" || (participantLocked && opponentLocked)));
  const currentStatusLabel = !primaryBattle
    ? "No active battle"
    : battleClosed
      ? "Challenge " + String(primaryBattle.status || "closed").replace(/_/g, " ")
    : incomingInvite
      ? "Accept challenge"
      : outgoingInvite
        ? "Challenge sent"
        : sceneLive
          ? "Watch battle"
          : lockReady
            ? "Lock your Meka"
            : productionLocked
              ? "Production locked"
              : battleOpen && participantLocked
                ? "Waiting for opponent Meka"
                : "Battle scheduled";
  const taskActionLabel = !primaryBattle
    ? ownershipRows.length ? "Pick opponent" : "Claim a Meka"
    : battleClosed
      ? "Challenge closed"
    : outgoingInvite
      ? "Waiting for acceptance"
      : incomingInvite
        ? "Accept challenge"
        : lockReady
          ? "Lock your Meka"
          : sceneLive
            ? "Watch battle"
            : productionLocked
              ? "Wait for battle scene"
              : battleOpen && participantLocked
                ? "Wait for opponent lock"
                : "Refresh status";
  const taskHint = !primaryBattle
    ? ownershipRows.length ? "Choose an opponent, lock your Meka, pick an arena, then issue a challenge." : "Claim or unlock a Meka before issuing an arena challenge."
    : battleClosed
      ? "No production slot was created"
    : outgoingInvite
      ? "Waiting for acceptance. This invitation expires after 1 day if the defender does not respond."
      : incomingInvite
        ? "Accept to enter the production queue, or decline to clear this invitation."
        : lockReady
          ? "Choose one owned Meka. Locking it completes your part of the battle setup."
          : sceneLive
            ? "The creator release is live. Open the battle scene from this task."
            : productionLocked
              ? "No further action is required. Production is locked; return here when the battle scene and result are ready."
              : battleOpen && participantLocked
                ? "Your Meka is locked. Waiting for the opponent to lock theirs before production begins."
                : "Watch this task for battle production updates.";
  return (
    <aside id="battle-current-challenge" className="battle-arena-current-status" aria-label="Active Battle Arena task">
      <div className="battle-arena-record-head">
        <span>Active Battle Task</span>
        <b>{currentStatusLabel}</b>
      </div>
      {primaryBattle ? (
        <>
          <div className={"battle-current-card tone-" + getBattleArenaTone(primaryBattle.arena) + (currentArenaImageStyle ? " has-arena-image" : "")} style={currentArenaImageStyle}>
            <div className="battle-current-card-main">
              <span>{arenaRegion}</span>
              <b>{arenaName}</b>
              <p>{primaryBattleProgressCopy}</p>
            </div>
            <div className="battle-current-mini-grid" aria-label="Active battle task details">
              <span><b>Opponent</b>{opponentName}</span>
              <span><b>{battleClosed ? "Production Status" : "Production Window"}</b>{scheduleLabel}</span>
              <span><b>{battleClosed ? "Meka Status" : "Locked Meka"}</b>{battleClosed ? "Not locked before closure" : participantLocked ? primaryParticipant.selectedMechId : "Meka required"}</span>
            </div>
            <div className="battle-current-next-action">
              <span>Primary Task</span>
              <b>{taskActionLabel}</b>
              <em>{taskHint}</em>
            </div>
            {incomingInvite && (
              <div className="battle-arena-actions">
                <button type="button" className="btn primary" onClick={onAcceptBattle} disabled={busy}>ACCEPT</button>
                <button type="button" className="btn" onClick={onDeclineBattle} disabled={busy}>DECLINE</button>
              </div>
            )}
            {lockReady && (
              <div className="battle-arena-owned-lock">
                <span>Lock Owned Meka</span>
                <select value={selectedOwnershipId} onChange={(event) => onOwnershipChange(event.target.value)} disabled={!ownershipRows.length || busy}>
                  {ownershipRows.map((entry) => (
                    <option key={entry.ownership.id} value={entry.ownership.id}>{entry.mech.id} / {entry.mech.codename}</option>
                  ))}
                </select>
                <button type="button" className="btn primary" onClick={onLockMeka} disabled={!selectedOwnershipId || busy}>LOCK MEKA</button>
              </div>
            )}
            {!incomingInvite && !lockReady && primaryParticipant && primaryParticipant.selectedMechId && (
              <div className="battle-arena-locked-unit">
                <span>Locked Unit</span>
                <b>{primaryParticipant.selectedMechId}</b>
              </div>
            )}
            {sceneLive && (
              <div className="battle-arena-live-cta">
                <div>
                  <span>BATTLE SCENE LIVE</span>
                  <b>{primaryBattle.viewerSceneViewedAt ? "Replay available" : "Premiere unlocked"}</b>
                </div>
                <a className="btn primary" href={primaryBattle.scenePublicUrl} target="_blank" rel="noreferrer" onClick={onWatchBattleScene} aria-disabled={busy ? "true" : undefined}>WATCH BATTLE</a>
              </div>
            )}
            {!battleClosed && !incomingInvite && !lockReady && !sceneLive && (
              <div className="battle-arena-status-actions">
                <button type="button" className="btn primary" onClick={onRefresh} disabled={busy}>REFRESH STATUS</button>
              </div>
            )}
          </div>
        </>
      ) : (
        <div className="battle-arena-empty">
          <div>
            <span>Active Battle Task</span>
            <b>{ownershipRows.length ? ownershipRows.length + " owned unit" + (ownershipRows.length === 1 ? "" : "s") + " ready" : "No owned units ready"}</b>
          </div>
          <p>{ownershipRows.length ? "There is no active battle. Open the Challenge Board to issue an invitation." : "Claim or unlock a Meka before issuing an arena challenge."}</p>
          {ownershipRows.length > 0 && <a className="btn primary" href="#battle-arena">OPEN CHALLENGE BOARD</a>}
        </div>
      )}
      {Array.isArray(chronicleBattles) && chronicleBattles.length > 0 && <BattleChroniclePanel battles={chronicleBattles} />}
    </aside>
  );
}

function BattleChallengeJourney({
  opponents,
  selectedOpponentId,
  selectedOpponentEntry,
  selectedOpponentMeka,
  onOpponentChange,
  arenas,
  selectedArenaId,
  selectedArena,
  onArenaChange,
  ownedOptions,
  selectedOwnershipId,
  onOwnershipChange,
  activeMech,
  accountOrganization,
  busy,
  onSubmit,
  issuedChallengeReceipt
}) {
  const operatorName = accountOrganization && (accountOrganization.name || accountOrganization.callsign)
    ? (accountOrganization.name || accountOrganization.callsign)
    : "Your organization";
  const opponentOrganization = selectedOpponentEntry && selectedOpponentEntry.organization ? selectedOpponentEntry.organization : null;
  const opponentName = opponentOrganization ? opponentOrganization.name || opponentOrganization.callsign || opponentOrganization.id : "No operator selected";
  const ownedRows = Array.isArray(ownedOptions) ? ownedOptions : [];
  const selectedOwnedEntry = ownedRows.find((entry) => entry.ownership && entry.ownership.id === selectedOwnershipId) || ownedRows[0] || null;
  const selectedOwnedMeka = selectedOwnedEntry && selectedOwnedEntry.mech ? selectedOwnedEntry.mech : activeMech || null;
  const challengerUnit = selectedOwnedMeka ? selectedOwnedMeka.id + " / " + selectedOwnedMeka.codename : "Owned Meka pending";
  const opponentRosterMekas = getBattleOpponentRosterMekas(selectedOpponentEntry);
  const opponentRosterLabel = opponentRosterMekas.length
    ? opponentRosterMekas.length + " public Meka" + (opponentRosterMekas.length === 1 ? "" : "s")
    : "Roster pending";
  const selectedArenaName = selectedArena ? selectedArena.name : "Arena pending";
  const [currentChallengeStep, setCurrentChallengeStep] = useState("opponent");
  const [confirmedOpponentId, setConfirmedOpponentId] = useState("");
  const [confirmedOwnershipId, setConfirmedOwnershipId] = useState("");
  const [confirmedArenaId, setConfirmedArenaId] = useState("");
  const lockedMekaEntry = ownedRows.find((entry) => entry.ownership && entry.ownership.id === confirmedOwnershipId) || null;
  const lockedMeka = lockedMekaEntry && lockedMekaEntry.mech ? lockedMekaEntry.mech : null;
  const lockedMekaLabel = lockedMeka ? lockedMeka.id + " / " + lockedMeka.codename : "Meka lock pending";
  const canReviewChallenge = Boolean(selectedOpponentEntry && selectedArena && lockedMeka && confirmedOpponentId && confirmedOwnershipId && confirmedArenaId);
  const activeIssuedChallengeReceipt = issuedChallengeReceipt &&
    issuedChallengeReceipt.opponentOrganizationId === selectedOpponentId &&
    issuedChallengeReceipt.ownershipId === selectedOwnershipId &&
    issuedChallengeReceipt.arenaId === selectedArenaId
    ? issuedChallengeReceipt
    : null;
  const issuedReceiptOpponentName = activeIssuedChallengeReceipt && activeIssuedChallengeReceipt.opponentName
    ? activeIssuedChallengeReceipt.opponentName
    : opponentName;
  const issuedReceiptArenaName = activeIssuedChallengeReceipt && activeIssuedChallengeReceipt.arenaName
    ? activeIssuedChallengeReceipt.arenaName
    : selectedArenaName;
  const issuedReceiptMekaName = activeIssuedChallengeReceipt && activeIssuedChallengeReceipt.mechName
    ? activeIssuedChallengeReceipt.mechName
    : lockedMekaLabel;
  const reviewCopy = operatorName + " will send " + lockedMekaLabel + " into an arena challenge against " + opponentName + " at " + selectedArenaName + ". The rival chooses and locks their defender Meka after accepting, then the creator production window opens.";
  const reviewArenaStyle = selectedArena && selectedArena.imageUrl
    ? { "--battle-review-arena-image": "url(\"" + String(selectedArena.imageUrl).replace(/["\\\r\n]/g, "") + "\")" }
    : undefined;
  const challengeSteps = [
    {
      id: "opponent",
      number: "01",
      label: "Pick Opponent",
      detail: confirmedOpponentId ? opponentName : "Choose operator",
      complete: Boolean(confirmedOpponentId),
      enabled: true
    },
    {
      id: "meka",
      number: "02",
      label: "Lock Your Meka",
      detail: !confirmedOpponentId ? "Pick opponent first" : confirmedOwnershipId ? lockedMekaLabel : "Choose owned unit",
      complete: Boolean(confirmedOwnershipId),
      enabled: Boolean(confirmedOpponentId)
    },
    {
      id: "arena",
      number: "03",
      label: "Pick Arena",
      detail: !confirmedOwnershipId ? "Lock your Meka first" : confirmedArenaId ? selectedArenaName : "Choose stage",
      complete: Boolean(confirmedArenaId),
      enabled: Boolean(confirmedOpponentId && confirmedOwnershipId)
    },
    {
      id: "review",
      number: "04",
      label: "Issue Challenge",
      detail: activeIssuedChallengeReceipt ? "Transmitted" : canReviewChallenge ? "Ready to issue" : confirmedOwnershipId ? "Pick arena first" : confirmedOpponentId ? "Lock your Meka first" : "Pick opponent first",
      complete: Boolean(activeIssuedChallengeReceipt),
      enabled: canReviewChallenge
    }
  ];

  useEffect(() => {
    if (confirmedOpponentId && confirmedOpponentId !== selectedOpponentId) {
      setConfirmedOpponentId("");
      setConfirmedOwnershipId("");
      setConfirmedArenaId("");
      setCurrentChallengeStep("opponent");
    }
  }, [selectedOpponentId, confirmedOpponentId]);

  useEffect(() => {
    if (confirmedOwnershipId && confirmedOwnershipId !== selectedOwnershipId) {
      setConfirmedOwnershipId("");
      setConfirmedArenaId("");
      setCurrentChallengeStep("meka");
    }
  }, [selectedOwnershipId, confirmedOwnershipId]);

  useEffect(() => {
    if (confirmedArenaId && confirmedArenaId !== selectedArenaId) {
      setConfirmedArenaId("");
      setCurrentChallengeStep("arena");
    }
  }, [selectedArenaId, confirmedArenaId]);

  function handleOpponentSelect(nextOpponentId) {
    onOpponentChange(nextOpponentId);
  }

  function handleArenaSelect(nextArenaId) {
    onArenaChange(nextArenaId);
  }

  function confirmOpponentStep() {
    if (!selectedOpponentId || busy) return;
    setConfirmedOpponentId(selectedOpponentId);
    setConfirmedOwnershipId("");
    setConfirmedArenaId("");
    setCurrentChallengeStep("meka");
  }

  function confirmMekaStep() {
    if (!selectedOwnershipId || busy) return;
    setConfirmedOwnershipId(selectedOwnershipId);
    setConfirmedArenaId("");
    setCurrentChallengeStep("arena");
  }

  function confirmArenaStep() {
    if (!selectedArenaId || busy) return;
    setConfirmedArenaId(selectedArenaId);
    setCurrentChallengeStep("review");
  }

  function goToChallengeStep(stepId) {
    const step = challengeSteps.find((entry) => entry.id === stepId);
    if (!step || !step.enabled || busy) return;
    setCurrentChallengeStep(stepId);
  }

  return (
    <form className="battle-challenge-journey" onSubmit={onSubmit}>
      <div className="battle-challenge-stepper" aria-label="Battle challenge steps">
        {challengeSteps.map((step) => {
          const active = currentChallengeStep === step.id;
          const StepTag = step.enabled ? "button" : "span";
          return (
            <StepTag
              key={step.id}
              type={step.enabled ? "button" : undefined}
              className={"battle-step-card" + (active ? " is-current" : "") + (step.complete ? " is-complete" : "") + (!step.enabled ? " is-locked" : "")}
              onClick={step.enabled ? () => goToChallengeStep(step.id) : undefined}
              disabled={step.enabled ? busy : undefined}
              aria-current={active ? "step" : undefined}
            >
              <b>{step.number}</b>
              {step.label}
              <em>{step.detail}</em>
            </StepTag>
          );
        })}
      </div>

      <div className="battle-challenge-current-step">
        {currentChallengeStep === "opponent" && (
          <>
            <div className="battle-challenge-step-actions">
              <div>
                <span>Selected Operator</span>
                <b>{opponentName}</b>
                <p>{opponentRosterLabel} ready for defender lock after accept.</p>
              </div>
              <button type="button" className="btn primary" onClick={confirmOpponentStep} disabled={!selectedOpponentId || busy}>CONTINUE TO MEKA</button>
            </div>
            <BattleOpponentPicker
              opponents={opponents}
              selectedOpponentId={selectedOpponentId}
              selectedOpponentEntry={selectedOpponentEntry}
              selectedOpponentMeka={selectedOpponentMeka}
              onOpponentChange={handleOpponentSelect}
              busy={busy}
            />
          </>
        )}

        {currentChallengeStep === "meka" && (
          <>
            <div className="battle-challenge-step-actions">
              <button type="button" className="btn" onClick={() => setCurrentChallengeStep("opponent")} disabled={busy}>BACK TO OPPONENT</button>
              <div>
                <span>Your Battle Unit</span>
                <b>{challengerUnit}</b>
                <p>This Meka is locked into the invitation. The defender chooses their Meka after accepting.</p>
              </div>
              <button type="button" className="btn primary" onClick={confirmMekaStep} disabled={!selectedOwnershipId || busy}>LOCK YOUR MEKA</button>
            </div>
            <BattleMekaLockPicker
              ownedOptions={ownedRows}
              selectedOwnershipId={selectedOwnershipId}
              onOwnershipChange={onOwnershipChange}
              busy={busy}
            />
          </>
        )}

        {currentChallengeStep === "arena" && (
          <>
            <div className="battle-challenge-step-actions">
              <button type="button" className="btn" onClick={() => setCurrentChallengeStep("meka")} disabled={busy}>BACK TO MEKA</button>
              <div>
                <span>Chosen Stage</span>
                <b>{selectedArenaName}</b>
                <p>{selectedArena ? selectedArena.region : "Arena network syncing"}</p>
              </div>
              <button type="button" className="btn primary" onClick={confirmArenaStep} disabled={!selectedArenaId || busy}>CONTINUE TO ISSUE</button>
            </div>
            <BattleArenaPicker
              arenas={arenas}
              selectedArenaId={selectedArenaId}
              selectedArena={selectedArena}
              onArenaChange={handleArenaSelect}
              busy={busy}
            />
          </>
        )}

        {currentChallengeStep === "review" && (
          <div className="battle-challenge-review battle-challenge-finale">
            <div className="battle-challenge-finale-banner">
              <span>Final Authorization</span>
              <b>{operatorName} vs {opponentName}</b>
              <p>{reviewCopy}</p>
            </div>
            <div className={"battle-challenge-vs-stage battle-challenge-finale-stage tone-" + getBattleArenaTone(selectedArena)} style={reviewArenaStyle}>
              <div className={"battle-challenge-vs-fighter is-operator" + getBattleArenaFacingClass(lockedMeka, "right")}>
                <span>Locked Challenger Unit</span>
                <div className="battle-challenge-vs-art">
                  {lockedMeka ? (
                    <BattleArenaCinematicMekaImage mech={lockedMeka} alt={lockedMekaLabel + " battle preview"} side="operator" requireCinematic={true} />
                  ) : (
                    <div className="battle-arena-launcher-scan-slot is-meka-pending"><b>Owned Meka pending</b></div>
                  )}
                </div>
                <b>{lockedMekaLabel}</b>
                <em>{operatorName}</em>
              </div>
              <div className="battle-challenge-vs-center">
                <span>{selectedArena ? selectedArena.region : "Arena pending"}</span>
                <strong>VS</strong>
                <b>{selectedArenaName}</b>
                <em>{activeIssuedChallengeReceipt ? "Challenge sent" : "Ready to transmit"}</em>
              </div>
              <div className="battle-challenge-vs-fighter is-opponent">
                <span>Defender Meka Pending</span>
                <div className="battle-challenge-vs-art">
                  <div className="battle-arena-launcher-scan-slot is-meka-pending"><b>Defender locks after accept</b></div>
                </div>
                <b>{opponentName}</b>
                <em>{opponentName}</em>
              </div>
            </div>
            <div className={"battle-challenge-launch-rail" + (activeIssuedChallengeReceipt ? " is-issued" : "")}>
              <div className="battle-challenge-finale-chips" aria-label="Challenge summary">
                <span><b>Locked Challenger Unit</b>{lockedMekaLabel}</span>
                <span><b>Opponent Command</b>{opponentName}<em>{opponentRosterLabel}</em></span>
                <span><b>Selected Stage</b>{selectedArenaName}</span>
              </div>
            {activeIssuedChallengeReceipt ? (
              <div className="battle-challenge-issued-receipt" role="status" aria-live="polite">
                <div>
                  <span>Challenge transmitted</span>
                  <b>{issuedReceiptOpponentName}</b>
                  <p>{issuedReceiptMekaName} is committed for {issuedReceiptArenaName}. Watch Active Battle for defender acceptance, defender Meka lock, and creator production.</p>
                </div>
                <div className="battle-challenge-issued-actions">
                  <a className="btn primary" href="#battle-current-challenge">VIEW ACTIVE TASK</a>
                </div>
              </div>
            ) : (
              <div className="battle-challenge-finale-actions">
                <button type="button" className="btn" onClick={() => setCurrentChallengeStep("arena")} disabled={busy}>EDIT STAGE</button>
                <button type="submit" className="btn primary" disabled={busy || !canReviewChallenge || Boolean(activeIssuedChallengeReceipt)}>{busy ? "TRANSMITTING..." : "CHALLENGE OPERATOR"}</button>
              </div>
            )}
            </div>
          </div>
        )}
      </div>
    </form>
  );
}

function BattleChallengeTransmission({ receipt, onDismiss }) {
  if (!receipt) return null;
  const kind = receipt.kind || "challenge";
  const scheduledBattleDate = receipt.scheduledBattleDate || "";
  const emailHandoff = receipt.emailHandoff || {};
  const emailStatus = emailHandoff.status || "";
  const statusLabel = kind === "accepted"
    ? "Challenge accepted"
    : kind === "declined"
      ? "Challenge declined"
      : scheduledBattleDate
        ? "Battle scheduled"
        : "Acceptance pending";
  const scheduleCopy = kind === "accepted" && scheduledBattleDate
    ? "Battle date locks to " + formatBattleArenaDate(scheduledBattleDate) + ". Creator production queue is active."
    : kind === "declined"
      ? "The invitation is closed and no battle has been scheduled."
      : "Battle schedule locks after opponent acceptance.";
  const emailHandoffCopy = kind === "challenge"
    ? emailStatus === "sent"
      ? "Invitation email handoff accepted."
      : "Invitation email handoff was not accepted. The challenge remains active."
    : emailStatus === "sent"
      ? "Email handoff accepted for both organizations."
      : emailStatus === "partial"
        ? "Email handoff accepted for one organization; the other notification needs attention."
        : emailStatus === "failed"
          ? "Email handoff was not accepted; battle status is saved."
          : "No email handoff was attempted; battle status is saved.";
  const opponentName = receipt.opponentName || "Opponent";
  const actorName = receipt.actorName || "Defender organization";
  const arenaName = receipt.arenaName || "selected arena";
  const contextCopy = kind === "challenge"
    ? opponentName + " received the challenge for " + arenaName + "."
    : kind === "accepted"
      ? actorName + " accepted the challenge for " + arenaName + "."
      : actorName + " declined the challenge for " + arenaName + ".";

  return ReactDOM.createPortal(
    <div className="battle-challenge-transmission" role="status" aria-live="polite" aria-atomic="true">
      <div className="battle-challenge-transmission-card">
        <div className="battle-challenge-transmission-beam" aria-hidden="true">
          <span></span>
          <span></span>
          <span></span>
        </div>
        <div>
          <span>{kind === "challenge" ? "Battle command transmitted" : "Battle email handoff"}</span>
          <b>{statusLabel}</b>
          <p>{contextCopy} {scheduleCopy} {emailHandoffCopy}</p>
        </div>
        <button type="button" className="battle-challenge-transmission-close" onClick={onDismiss} aria-label="Dismiss battle transmission">CLOSE</button>
      </div>
    </div>,
    document.body
  );
}

function BattleMekaLockPicker({ ownedOptions, selectedOwnershipId, onOwnershipChange, busy }) {
  const rows = Array.isArray(ownedOptions) ? ownedOptions : [];
  return (
    <section className="battle-meka-lock-picker" aria-label="Lock your battle Meka">
      <div className="battle-challenge-section-head">
        <span>Step 02</span>
        <b>Lock Your Meka</b>
      </div>
      <div className="battle-meka-lock-grid">
        {rows.length ? rows.map((entry) => {
          const mech = entry.mech;
          const ownership = entry.ownership;
          const active = ownership && ownership.id === selectedOwnershipId;
          return (
            <button
              key={ownership.id}
              type="button"
              className={"battle-meka-lock-card" + (active ? " is-selected" : "") + getBattleArenaFacingClass(mech, "right")}
              onClick={() => onOwnershipChange(ownership.id)}
              disabled={busy}
              aria-pressed={active}
            >
              <span className="battle-meka-lock-visual">
                <BattleArenaCinematicMekaImage mech={mech} alt={mech.id + " " + mech.codename + " owned Meka lock preview"} side="operator" requireCinematic={true} imageLoading="eager" />
              </span>
              <span className="battle-meka-lock-copy">
                <span>{ownership.ownershipClass === "starter" ? "Starter Meka" : "Owned Meka"}</span>
                <b>{mech.id} / {mech.codename}</b>
                <em>{active ? "Locked for challenge" : "Available to lock"}</em>
              </span>
            </button>
          );
        }) : (
          <div className="battle-meka-lock-empty">
            <span>No owned Meka ready</span>
            <b>Claim a unit before issuing a battle challenge.</b>
          </div>
        )}
      </div>
    </section>
  );
}

function getBattleOpponentRosterMekas(entry) {
  const organization = entry && entry.organization ? entry.organization : null;
  const ids = Array.isArray(entry && entry.ownedMechIds) && entry.ownedMechIds.length
    ? entry.ownedMechIds
    : [entry && entry.starterMechId, organization && organization.starterMechId];
  return ids
    .map((id) => findMechById(id))
    .filter((mech, index, list) => mech && list.findIndex((candidate) => candidate.id === mech.id) === index);
}

function BattleOpponentPicker({ opponents, selectedOpponentId, selectedOpponentEntry, selectedOpponentMeka, onOpponentChange, busy }) {
  const rows = Array.isArray(opponents) ? opponents : [];
  const selectedOrganization = selectedOpponentEntry && selectedOpponentEntry.organization ? selectedOpponentEntry.organization : null;
  const selectedRosterMekas = getBattleOpponentRosterMekas(selectedOpponentEntry);
  const selectedName = selectedOrganization
    ? selectedOrganization.name || selectedOrganization.callsign || selectedOrganization.id
    : "No opponent selected";
  const selectedCallsign = selectedOrganization ? selectedOrganization.callsign || selectedOrganization.id || "OPERATOR" : "REGISTRY";
  const selectedLeadLabel = selectedOpponentMeka ? selectedOpponentMeka.id + " / " + selectedOpponentMeka.codename : "Lead Meka pending";
  return (
    <section className="battle-opponent-picker" aria-label="Pick battle opponent">
      <div className="battle-challenge-section-head">
        <span>Step 01</span>
        <b>Pick Opponent</b>
      </div>
      <div className="battle-opponent-scout">
        <div className={"battle-opponent-grid" + (rows.length === 1 ? " is-single" : "")}>
          {rows.length ? rows.map((entry) => {
            const organization = entry.organization || {};
            const rosterMekas = getBattleOpponentRosterMekas(entry);
            const featuredMeka = rosterMekas[0] || null;
            const supportMekas = featuredMeka
              ? rosterMekas.filter((mech) => mech.id !== featuredMeka.id)
              : rosterMekas;
            const extraSupportMekaCount = Math.max(0, supportMekas.length - 3);
            const active = organization.id === selectedOpponentId;
            return (
              <button
                key={organization.id}
                type="button"
                className="battle-opponent-card"
                onClick={() => onOpponentChange(organization.id)}
                disabled={busy}
                aria-pressed={active}
              >
                <span className={"battle-opponent-featured-meka" + getBattleArenaFacingClass(featuredMeka, "left")}>
                  {featuredMeka ? (
                    <BattleArenaCinematicMekaImage mech={featuredMeka} alt={(organization.name || "Opponent") + " lead Meka"} side="opponent" requireCinematic={true} imageLoading="eager" />
                  ) : (
                    <i>MEKA UNKNOWN</i>
                  )}
                </span>
                <span className="battle-opponent-copy">
                  <span>{organization.callsign || "OPERATOR"}</span>
                  <b>{organization.name || organization.id}</b>
                  <em>{rosterMekas.length ? rosterMekas.length + " public Meka" + (rosterMekas.length === 1 ? "" : "s") : "Roster unknown"}</em>
                  {supportMekas.length > 0 ? (
                    <span className="battle-opponent-roster-strip" aria-label={(organization.name || "Opponent") + " support Meka roster"}>
                      {supportMekas.slice(0, 3).map((mech) => (
                        <span className="battle-opponent-roster-unit" key={mech.id}>
                          <HangarPreviewImage mech={mech} alt={mech.codename + " support roster preview"} />
                          <em>{mech.id}</em>
                        </span>
                      ))}
                      {extraSupportMekaCount > 0 && <span className="battle-opponent-roster-more">+{extraSupportMekaCount}</span>}
                    </span>
                  ) : (
                    <span className="battle-opponent-roster-note">Lead unit only</span>
                  )}
                  {active && <span className="battle-opponent-selected-mark">Selected opponent</span>}
                </span>
              </button>
            );
          }) : (
            <div className="battle-opponent-empty">
              <span>No opponents online</span>
              <b>Registry sync required</b>
            </div>
          )}
        </div>
        <aside className="battle-opponent-scout-bay" aria-live="polite" aria-atomic="true">
          <div className="battle-opponent-scout-top">
            <span>Selected Opponent</span>
            <b>{selectedCallsign}</b>
          </div>
          <div className={"battle-opponent-scout-visual" + getBattleArenaFacingClass(selectedOpponentMeka, "left")}>
            {selectedOpponentMeka ? (
              <BattleArenaCinematicMekaImage mech={selectedOpponentMeka} alt={selectedLeadLabel + " opponent roster preview"} side="opponent" requireCinematic={true} imageLoading="eager" />
            ) : (
              <div className="battle-opponent-scout-empty">Opponent Meka preview pending</div>
            )}
          </div>
          <div className="battle-opponent-scout-copy">
            <span>Opponent Command</span>
            <b>{selectedName}</b>
            <p>{selectedLeadLabel} is a public roster preview. The defender locks their exact battle Meka after accepting.</p>
          </div>
          <div className="battle-opponent-scout-stats">
            <span><b>{selectedRosterMekas.length || 0}</b>Public Meka</span>
            <span><b>{selectedOpponentMeka ? selectedOpponentMeka.id : "--"}</b>Lead Preview</span>
          </div>
          {selectedRosterMekas.length > 0 && (
            <div className="battle-opponent-scout-roster" aria-label={selectedName + " public Meka roster"}>
              {selectedRosterMekas.slice(0, 6).map((mech) => (
                <span key={mech.id}>{mech.id}<em>{mech.codename}</em></span>
              ))}
            </div>
          )}
        </aside>
      </div>
    </section>
  );
}

function BattleArenaPicker({ arenas, selectedArenaId, selectedArena, onArenaChange, busy }) {
  const rows = Array.isArray(arenas) ? arenas : [];
  return (
    <section className="battle-arena-picker-shell" aria-label="Pick battle arena">
      <div className="battle-challenge-section-head">
        <span>Step 03</span>
        <b>Pick Arena</b>
      </div>
      <div className="battle-arena-picker-layout">
        <div className="battle-arena-arena-list" aria-label="Choose Stage">
          {rows.map((entry) => {
            const active = entry.id === selectedArenaId;
            return (
              <button
                key={entry.id}
                type="button"
                className={"battle-arena-arena-option" + (active ? " is-selected" : "")}
                onClick={() => onArenaChange(entry.id)}
                disabled={busy}
                aria-pressed={active}
              >
                <span className={"battle-arena-arena-media" + (entry.imageUrl ? "" : " is-empty")}>
                  {entry.imageUrl ? (
                    <img src={entry.imageUrl} alt={entry.imageAlt || entry.name + " arena preview"} loading={active ? "eager" : "lazy"} />
                  ) : (
                    <i>{entry.environmentType.replace(/_/g, " ")}</i>
                  )}
                </span>
                <span className="battle-arena-arena-copy">
                  <span>{active ? "Active Stage" : entry.region}</span>
                  <b>{entry.name}</b>
                </span>
              </button>
            );
          })}
        </div>
        <div className="battle-arena-preview-card">
          <div className="battle-arena-selected-stage" aria-live="polite" aria-atomic="true">
            <div className="battle-challenge-section-head">
              <span>Selected Stage</span>
              <b>{selectedArena ? selectedArena.name : "Stage pending"}</b>
            </div>
            {selectedArena && selectedArena.imageUrl ? (
              <div className="battle-arena-selected-arena-media">
                <img src={selectedArena.imageUrl} alt={selectedArena.imageAlt || selectedArena.name + " selected arena preview"} loading="eager" />
              </div>
            ) : (
              <div className="battle-arena-selected-arena-media is-empty">
                <span>ARENA PREVIEW SYNCING</span>
              </div>
            )}
            <div className="battle-arena-arena-readout">
              <span>{selectedArena ? selectedArena.environmentType.replace(/_/g, " ").toUpperCase() : "ARENA OFFLINE"}</span>
              <b>{selectedArena ? selectedArena.name : "No arena selected"}</b>
              <p>{selectedArena ? selectedArena.palette : "Arena catalog is syncing."}</p>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

function BattleChroniclePanel({ battles }) {
  const rows = Array.isArray(battles) ? battles.filter((battle) => battle && battle.chronicle) : [];
  return (
    <section id="battle-chronicle" className="battle-chronicle" aria-label="Battle Chronicle">
      <div className="battle-chronicle-head">
        <span>Battle Chronicle</span>
        <b>{rows.length} Filed</b>
      </div>
      {rows.length ? (
        <div className="battle-chronicle-list">
          {rows.map((battle) => {
            const chronicle = battle.chronicle || {};
            const winner = chronicle.winnerMeka && chronicle.winnerMeka.id
              ? chronicle.winnerMeka.id
              : (chronicle.winnerSide === "draw" ? "DRAW" : "RESULT FILED");
            const aftermathRecords = Array.isArray(chronicle.aftermathRecords) ? chronicle.aftermathRecords : [];
            return (
              <article className="battle-chronicle-row" key={battle.id}>
                <div className="battle-chronicle-result">
                  <span>{battle.scheduledBattleDate ? formatBattleArenaDate(battle.scheduledBattleDate) : "DATE FILED"}</span>
                  <b>{chronicle.title || (battle.arena ? battle.arena.name : "Battle Chronicle")}</b>
                  <em>{winner}</em>
                </div>
                <span className="battle-after-action-report">AFTER ACTION REPORT</span>
                <p>{chronicle.battleLogLine || chronicle.summary || "Battle record filed."}</p>
                {aftermathRecords.length > 0 && (
                  <div className="battle-aftermath-strip" aria-label="Battle aftermath rewards">
                    {aftermathRecords.map((record) => (
                      <a
                        key={record.id}
                        className={"battle-aftermath-chip is-" + String(record.result || "filed").replace(/_/g, "-")}
                        href={record.certificateHref || ("#ownership/" + encodeURIComponent(record.id))}
                      >
                        <span>{record.resultLabel || "Battle Record"}</span>
                        <b>{record.mechId}</b>
                      </a>
                    ))}
                  </div>
                )}
                {chronicle.scenePublicUrl && (
                  <div className="battle-chronicle-actions">
                    <a className="btn" href={chronicle.scenePublicUrl} target="_blank" rel="noreferrer">WATCH ARCHIVE</a>
                  </div>
                )}
              </article>
            );
          })}
        </div>
      ) : (
        <div className="battle-chronicle-empty">
          <div>
            <span>Chronicle Pending</span>
            <b>No filed battle records yet</b>
          </div>
          <p>Completed Battle Arena records will file here after creator release.</p>
        </div>
      )}
    </section>
  );
}

function BattleAftermathDossierPanel({ mech, archiveDispatchStatus }) {
  const records = getBattleAftermathRecordsForMeka(mech, archiveDispatchStatus).slice(0, 3);
  if (!mech || !records.length) return null;
  return (
    <section className="battle-dossier-records" aria-label={mech.id + " Battle Record"}>
      <div className="battle-dossier-records-head">
        <span>Battle Record</span>
        <b>{records.length} Chapter{records.length === 1 ? "" : "s"}</b>
      </div>
      <div className="battle-dossier-record-list">
        {records.map((record) => {
          const arenaName = record.arena && record.arena.name ? record.arena.name : "Battle Arena";
          return (
            <article className={"battle-dossier-record is-" + String(record.result || "filed").replace(/_/g, "-")} key={record.id}>
              <div>
                <span>{record.chapterTitle || "Battle Chapter"}</span>
                <b>{record.title || record.resultLabel || "Battle Record"}</b>
                <p>{arenaName}{record.opponentMech && record.opponentMech.id ? " / versus " + record.opponentMech.id : ""}</p>
              </div>
              <div className="battle-dossier-record-actions">
                <a href={record.certificateHref || ("#ownership/" + encodeURIComponent(record.id))}>VIEW HONOR</a>
                {record.scenePublicUrl && <a href={record.scenePublicUrl} target="_blank" rel="noreferrer">WATCH BATTLE</a>}
                {record.specialAttackMedia && record.specialAttackMedia.url && (
                  <a className="battle-special-attack-link" href={record.specialAttackMedia.url} target="_blank" rel="noreferrer">
                    {record.specialAttackMedia.label || "SPECIAL ATTACK"}
                  </a>
                )}
              </div>
            </article>
          );
        })}
      </div>
    </section>
  );
}

function BattleArenaLauncherCard({ battleArenaStatus, onboardingStatus, activeMech, archiveDispatchStatus, ownedMechs = [] }) {
  const unlocked = battleArenaTutorialUnlocked(onboardingStatus);
  const lockState = unlocked ? null : getBattleArenaTutorialLockState(onboardingStatus, activeMech, archiveDispatchStatus);
  const battles = unlocked && Array.isArray(battleArenaStatus && battleArenaStatus.battles) ? battleArenaStatus.battles : [];
  const primaryBattle = findPrimaryBattleArenaRecord(battles);
  const primaryParticipant = getBattleArenaParticipant(primaryBattle);
  const primaryOpponent = getBattleArenaOpponent(primaryBattle);
  const loading = Boolean(unlocked && battleArenaStatus && battleArenaStatus.status === "loading");
  const sceneLive = Boolean(primaryBattle && primaryBattle.sceneAvailable && primaryBattle.scenePublicUrl);
  const invitePending = Boolean(primaryBattle && primaryBattle.status === "invited" && primaryBattle.viewerSide === "defender");
  const lockReady = Boolean(primaryBattle && ["selection_pending", "scheduled"].includes(primaryBattle.status) && primaryParticipant && !primaryParticipant.selectedMechId);
  const opponentLabel = primaryOpponent
    ? getBattleArenaParticipantLabel(primaryOpponent, "Opponent pending")
    : "No active opponent";
  const arenaLabel = primaryBattle && primaryBattle.arena ? primaryBattle.arena.name : "Challenge board ready";
  const opponentMech = primaryOpponent && primaryOpponent.selectedMechId ? findMechById(primaryOpponent.selectedMechId) : null;
  const secondaryMech = opponentMech;
  const battleArena = primaryBattle && primaryBattle.arena ? primaryBattle.arena : null;
  const featuredArena = battleArena && battleArena.imageUrl ? battleArena : null;
  const arenaFeedLabel = battleArena && battleArena.region
    ? battleArena.region
    : primaryBattle ? "Arena feed pending" : "Arena feed standby";
  const arenaNameLabel = battleArena && battleArena.name
    ? battleArena.name
    : primaryBattle ? "Arena preview pending" : "Stage selection pending";
  const emptyArenaLabel = primaryBattle ? "Arena feed pending" : "Arena scan pending";
  const statusLabel = !unlocked
    ? "TUTORIAL LOCKED"
    : loading
      ? "SYNCING"
      : sceneLive
        ? "SCENE LIVE"
        : invitePending
          ? "INVITE RECEIVED"
          : lockReady
            ? "MEKA LOCK REQUIRED"
            : primaryBattle
              ? String(primaryBattle.status || "ACTIVE").replace(/_/g, " ").toUpperCase()
              : "READY";
  const actionLabel = !unlocked
    ? "FINISH TUTORIAL"
    : sceneLive
      ? "WATCH BATTLE"
      : invitePending
        ? "RESPOND"
        : lockReady
          ? "LOCK MEKA"
          : primaryBattle
            ? "VIEW BATTLE"
            : "ENTER ARENA";
  const scheduleLabel = primaryBattle && primaryBattle.scheduledBattleDate
    ? formatBattleArenaDate(primaryBattle.scheduledBattleDate)
    : unlocked ? "3-day production window" : "Tutorial clearance";
  const href = unlocked
    ? primaryBattle ? battleArenaBattleHref(primaryBattle) : "#battle-arena"
    : (lockState && lockState.targetHref ? lockState.targetHref : "#hangar");
  const headline = !unlocked
    ? statusLabel
    : sceneLive
      ? "Battle Scene Live"
      : primaryBattle
        ? "Battle Command " + statusLabel
        : "Battle Arena Ready";
  const secondaryMechLabel = opponentMech ? "Opponent locked" : "Opponent scan";
  const primaryUnitLabel = activeMech ? activeMech.id + " / " + activeMech.codename : "Owned unit scan";
  const secondaryUnitLabel = secondaryMech ? secondaryMech.id + " / " + secondaryMech.codename : secondaryMechLabel;

  function handleLauncherClick(event) {
    if (unlocked) return;
    event.preventDefault();
    activateDirectiveTarget(href);
  }

  return (
    <aside className={"battle-arena-launcher-card" + (sceneLive ? " is-live" : "") + (!unlocked ? " is-locked" : "")} aria-label="Battle Arena launcher">
      <div className="battle-arena-launcher-media" aria-hidden="true">
        {featuredArena && featuredArena.imageUrl ? (
          <img className="battle-arena-launcher-arena" src={featuredArena.imageUrl} alt="" loading="eager" decoding="async" fetchpriority="high" />
        ) : (
          <div className="battle-arena-launcher-arena is-empty"><span>{emptyArenaLabel}</span></div>
        )}
        <div className="battle-arena-launcher-matchup">
          <div className="battle-arena-launcher-unit is-primary">
            <span>Operator Unit</span>
            <div className="battle-arena-launcher-meka is-primary">
              {activeMech ? (
                <BattleArenaLauncherMekaImage mech={activeMech} desiredFacing="right" alt={activeMech.id + " battle ready launcher cutout"} />
              ) : (
                <div className="battle-arena-launcher-scan-slot"><span>Owned unit scan</span></div>
              )}
            </div>
            <b>{primaryUnitLabel}</b>
          </div>
          <div className="battle-arena-launcher-versus"><span>VS</span></div>
          <div className="battle-arena-launcher-unit is-secondary">
            <span>Challenge Target</span>
            <div className="battle-arena-launcher-meka is-secondary">
              {secondaryMech ? (
                <BattleArenaLauncherMekaImage mech={secondaryMech} desiredFacing="left" alt={secondaryMech.id + " battle ready launcher cutout"} />
              ) : (
                <div className="battle-arena-launcher-scan-slot"><span>{secondaryMechLabel}</span></div>
              )}
            </div>
            <b>{secondaryUnitLabel}</b>
          </div>
        </div>
        <div className="battle-arena-launcher-media-label">
          <span>{arenaFeedLabel}</span>
          <b>{arenaNameLabel}</b>
        </div>
      </div>
      <div className="battle-arena-launcher-command">
        <div className="battle-arena-launcher-copy">
          <span>Battle Arena</span>
          <b>{headline}</b>
          <p>{!unlocked && lockState ? lockState.actionHint : primaryBattle ? opponentLabel + " / " + arenaLabel : "Issue a challenge, choose the arena, and track your scheduled battle from the dedicated command page."}</p>
        </div>
        <div className="battle-arena-launcher-readout">
          <div><span>Eligible Roster</span><b>{String(ownedMechs.length).padStart(2, "0")} owned units</b></div>
          <div><span>Battle Day</span><b>{scheduleLabel}</b></div>
          <div><span>Records</span><b>{String(battles.length).padStart(2, "0")}</b></div>
        </div>
        <div className="battle-arena-launcher-cycle" aria-label="Battle Arena cycle">
          <span>Challenge issued</span>
          <i aria-hidden="true"></i>
          <span>3-day scene build</span>
          <i aria-hidden="true"></i>
          <span>Battle report archived</span>
        </div>
        {lockState && lockState.actionDisabled ? (
          <button type="button" className="btn primary" disabled>{lockState.actionLabel}</button>
        ) : (
          <a className="btn primary" href={href} onClick={handleLauncherClick}>{actionLabel}</a>
        )}
      </div>
    </aside>
  );
}

function formatDispatchArchiveDate(value) {
  const time = Date.parse(value || "");
  if (!Number.isFinite(time)) return "DATE PENDING";
  return new Date(time).toLocaleDateString(undefined, {
    year: "numeric",
    month: "short",
    day: "numeric"
  }).toUpperCase();
}

function formatDispatchArchiveRange(startsAt, endsAt) {
  const startLabel = formatDispatchArchiveDate(startsAt);
  const endLabel = formatDispatchArchiveDate(endsAt);
  return startLabel === endLabel ? endLabel : startLabel + " TO " + endLabel;
}

function getDispatchArchiveHeaderStats(currentDispatch, historyItems) {
  const filingDates = [];
  if (currentDispatch && currentDispatch.publishedAt) filingDates.push(currentDispatch.publishedAt);
  (historyItems || []).forEach((item) => {
    if (item && item.publishedAt) filingDates.push(item.publishedAt);
  });
  const latestTime = filingDates.reduce((best, value) => {
    const time = Date.parse(value || "");
    return Number.isFinite(time) && time > best ? time : best;
  }, 0);
  return {
    loadedWeekCount: filingDates.length,
    latestFilingLabel: latestTime ? formatDispatchArchiveDate(new Date(latestTime).toISOString()) : "DATE PENDING"
  };
}

function getDispatchArchiveEntryStateLabel(entry) {
  return entry && entry.availability && entry.availability.state === "claimed" ? "CLAIMED" : "UNCLAIMED";
}

function DispatchArchiveEntryCard({ entry, onOpenMeka }) {
  const mech = findMechById(entry && entry.mechId);
  const cardTitle = mech ? mech.id + " / " + mech.codename : String(entry && entry.mechId || "MEKA DOSSIER");
  const statusLabel = getDispatchArchiveEntryStateLabel(entry);
  const buttonLabel = mech ? "OPEN DOSSIER" : "DOSSIER PENDING";
  const spotlightCopy = entry && entry.spotlightCopy
    ? entry.spotlightCopy
    : mech && mech.brief
      ? mech.brief
      : "Filed archive dispatch entry.";

  function handleArchiveEntryClick(event) {
    if (!mech) {
      event.preventDefault();
      return;
    }
    if (event.defaultPrevented || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.button !== 0) return;
    event.preventDefault();
    onOpenMeka(mech.id);
  }

  return (
    <article className="dispatch-ledger-entry-card">
      <div className="dispatch-ledger-entry-visual">
        {mech ? <HangarPreviewImage mech={mech} alt={cardTitle + " dossier preview"} /> : <span>{String(entry && entry.mechId || "MEKA")}</span>}
      </div>
      <div className="dispatch-ledger-entry-copy">
        <div className="dispatch-ledger-entry-head">
          <span className="dispatch-ledger-entry-status">{statusLabel}</span>
          <span className="dispatch-ledger-entry-rank">SLOT {String(entry && entry.slotRank || 0).padStart(2, "0")}</span>
        </div>
        <h4 className="dispatch-ledger-entry-title">{cardTitle}</h4>
        <p>{spotlightCopy}</p>
      </div>
      {mech ? (
        <a
          className="btn compact"
          href={"#mech/" + mech.id}
          onClick={handleArchiveEntryClick}
        >
          {buttonLabel}
        </a>
      ) : (
        <span className="btn compact" aria-disabled="true">{buttonLabel}</span>
      )}
    </article>
  );
}

function DispatchArchiveCurrentCell({ entry }) {
  const mech = findMechById(entry && entry.mechId);
  const title = mech ? mech.id + " / " + mech.codename : String(entry && entry.mechId || "MEKA DOSSIER");
  return (
    <div className="dispatch-archive-current-cell">
      <div className="dispatch-archive-current-visual">
        {mech ? <HangarPreviewImage mech={mech} alt={title + " live dispatch preview"} /> : <span>{String(entry && entry.mechId || "MEKA")}</span>}
      </div>
      <div className="dispatch-archive-current-copy">
        <span>{getDispatchArchiveEntryStateLabel(entry)}</span>
        <b>{title}</b>
      </div>
    </div>
  );
}

function DispatchArchiveSkeletonRows({ count = 3 }) {
  return (
    <div className="dispatch-ledger-skeleton" aria-hidden="true">
      {Array.from({ length: count }).map((_, index) => (
        <div key={index} className="dispatch-ledger-skeleton-row">
          <span></span>
          <span></span>
          <span></span>
        </div>
      ))}
    </div>
  );
}

function DispatchArchiveLedgerGroup({ dispatch, onOpenMeka }) {
  const entries = Array.isArray(dispatch && dispatch.entries) ? dispatch.entries : [];
  const groupTitle = dispatch && dispatch.title ? dispatch.title : "Archive Dispatch File";
  const statusLabel = String(dispatch && dispatch.status || "closed").toUpperCase();
  const summaryCopy = dispatch && dispatch.summary ? dispatch.summary : "Filed archive dispatch entry.";
  const rangeLabel = formatDispatchArchiveRange(dispatch && dispatch.startsAt, dispatch && dispatch.endsAt);
  const collapseLedgerByBreakpoint = useMediaQueryMatch(DISPATCH_ARCHIVE_LEDGER_COLLAPSE_QUERY);
  const [detailsOpen, setDetailsOpen] = useState(() => !collapseLedgerByBreakpoint);

  useEffect(() => {
    setDetailsOpen(!collapseLedgerByBreakpoint);
  }, [collapseLedgerByBreakpoint, dispatch && dispatch.id]);

  function handleDetailsToggle(event) {
    setDetailsOpen(Boolean(event.currentTarget && event.currentTarget.open));
  }

  return (
    <details className="dispatch-ledger-group" open={detailsOpen} onToggle={handleDetailsToggle}>
      <summary className="dispatch-ledger-summary">
        <div className="dispatch-ledger-summary-copy">
          <span>{dispatch && dispatch.code ? dispatch.code : "ARCHIVE DISPATCH"}</span>
          <h4>{groupTitle}</h4>
        </div>
        <div className="dispatch-ledger-group-meta">
          <b>{statusLabel}</b>
          <span>{rangeLabel}</span>
        </div>
      </summary>
      <div className="dispatch-ledger-group-body">
        <p className="dispatch-ledger-group-summary">{summaryCopy}</p>
        <div className="dispatch-ledger-entry-grid">
          {entries.map((entry) => <DispatchArchiveEntryCard key={(dispatch && dispatch.id) + ":" + entry.mechId} entry={entry} onOpenMeka={onOpenMeka} />)}
        </div>
      </div>
    </details>
  );
}

function DispatchArchivePage({ archiveDispatchStatus, onOpenMeka }) {
  const dispatchHistory = useArchiveDispatchHistory();
  const { dispatch: currentDispatch, entries: currentDispatchEntries } = getArchiveDispatchBundle(archiveDispatchStatus);
  const currentDispatchStatus = archiveDispatchStatus && archiveDispatchStatus.status ? archiveDispatchStatus.status : "idle";
  const showCurrentLoading = currentDispatchStatus === "idle" || currentDispatchStatus === "loading";
  const showCurrentError = currentDispatchStatus === "error";
  const showCurrentReadyEmpty = currentDispatchStatus === "ready" && !currentDispatch;
  const showCurrentReadyWithDispatch = currentDispatchStatus === "ready" && Boolean(currentDispatch);
  const currentDispatchErrorDetail = archiveDispatchStatus && archiveDispatchStatus.error && archiveDispatchStatus.error !== "CURRENT DISPATCH UNAVAILABLE"
    ? archiveDispatchStatus.error
    : "ARCHIVE DISPATCH SYNC FAILED";
  const currentDispatchHeading = showCurrentLoading
    ? "SYNC IN PROGRESS"
    : showCurrentError
      ? "SYNC UNAVAILABLE"
      : showCurrentReadyWithDispatch
        ? (currentDispatch.code || "ARCHIVE DISPATCH")
        : showCurrentReadyEmpty
          ? "NO ACTIVE DISPATCH"
          : "CURRENT DISPATCH";
  const historyItems = Array.isArray(dispatchHistory.items) ? dispatchHistory.items : [];
  const headerStats = getDispatchArchiveHeaderStats(currentDispatch, historyItems);
  const currentCells = Array.isArray(currentDispatchEntries)
    ? currentDispatchEntries.slice(0, Math.min(3, currentDispatchEntries.length))
    : [];
  const showInitialHistoryError = dispatchHistory.status === "error";
  const showHistorySkeleton = dispatchHistory.status === "loading" && !historyItems.length;
  const showHistoryEmpty = dispatchHistory.status === "ready" && !historyItems.length;
  const showLoadMoreError = dispatchHistory.status === "ready" && Boolean(dispatchHistory.error);
  const openArchiveMeka = (mechId) => onOpenMeka(mechId, DISPATCH_ARCHIVE_ROUTE);

  return (
    <section
      id="dispatches"
      className="section dispatch-archive-page"
      aria-label="Dispatch archive"
      data-screen-label="Dispatch Archive"
      data-history-status={dispatchHistory.status}
      data-current-dispatch-status={String(currentDispatchStatus).toUpperCase()}
    >
      <div className="section-inner">
        <div className="section-head">
          <div>
            <div className="label">ARCHIVE DISPATCH / FILED LEDGER</div>
            <h2>DISPATCH ARCHIVE</h2>
          </div>
          <div className="right dispatch-archive-header-right">
            <a className="btn compact" href="#archive">BACK TO ARCHIVE INDEX</a>
            <div className="dispatch-archive-header-readouts">
              <div>
                <span>WEEKS LOADED</span>
                <b>{String(headerStats.loadedWeekCount).padStart(2, "0")}</b>
              </div>
              <div>
                <span>LATEST FILING</span>
                <b>{headerStats.latestFilingLabel}</b>
              </div>
            </div>
          </div>
        </div>
        <div className="dispatch-archive-shell">
          <section className="dispatch-archive-current-band" aria-label="Current archive dispatch">
            <div className="dispatch-archive-band-head">
              <div>
                <span className="dispatch-archive-current-label">CURRENT DISPATCH</span>
                <h3>{currentDispatchHeading}</h3>
              </div>
            </div>

            {showCurrentLoading && (
              <div className="dispatch-archive-empty">
                <b>CURRENT DISPATCH LOADING</b>
                <p>Current dispatch data is being synchronized.</p>
              </div>
            )}

            {showCurrentError && (
              <div className="dispatch-archive-error">
                <b>CURRENT DISPATCH UNAVAILABLE</b>
                <p>{currentDispatchErrorDetail}</p>
              </div>
            )}

            {showCurrentReadyWithDispatch && (
              <React.Fragment>
                <div className="dispatch-archive-band-meta">
                  <span>{formatDispatchArchiveRange(currentDispatch.startsAt, currentDispatch.endsAt)}</span>
                  <b>{String(currentDispatch.status || "active").toUpperCase()}</b>
                </div>
                {currentDispatch.summary && <p className="dispatch-archive-band-summary">{currentDispatch.summary}</p>}
                <div className="dispatch-archive-current-grid">
                  {currentCells.map((entry) => <DispatchArchiveCurrentCell key={entry.mechId} entry={entry} />)}
                </div>
              </React.Fragment>
            )}

            {showCurrentReadyEmpty && (
              <div className="dispatch-archive-empty">
                <b>NO ACTIVE DISPATCH</b>
                <p>Current dispatch data is not filed for this route.</p>
              </div>
            )}
          </section>

          <section className="dispatch-archive-ledger" aria-label="Previous dispatches ledger">
            <div className="dispatch-archive-ledger-head">
              <div>
                <span>PREVIOUS DISPATCHES</span>
                <h3>FILED WEEK LEDGER</h3>
              </div>
              <b>{historyItems.length ? String(historyItems.length).padStart(2, "0") + " LOADED" : "ROUTE-LOCAL HISTORY"}</b>
            </div>

            {showHistorySkeleton && <DispatchArchiveSkeletonRows />}

            {showInitialHistoryError && (
              <div className="dispatch-archive-error">
                <b>DISPATCH HISTORY UNAVAILABLE</b>
                <p>{dispatchHistory.error || "DISPATCH HISTORY UNAVAILABLE"}</p>
                <button type="button" className="btn" onClick={dispatchHistory.retry}>RETRY HISTORY</button>
              </div>
            )}

            {showHistoryEmpty && (
              <div className="dispatch-archive-empty" role="status">
                <b>NO FILED DISPATCHES YET</b>
                <p>Closed published dispatch weeks will file here once the ledger is populated.</p>
              </div>
            )}

            {historyItems.length > 0 && (
              <div className="dispatch-ledger-groups">
                {historyItems.map((dispatch) => <DispatchArchiveLedgerGroup key={dispatch.id} dispatch={dispatch} onOpenMeka={openArchiveMeka} />)}
              </div>
            )}

            {(dispatchHistory.nextCursor || showLoadMoreError) && (
              <div className="dispatch-archive-pagination">
                {showLoadMoreError && <p className="dispatch-archive-error-copy">{dispatchHistory.error}</p>}
                {dispatchHistory.nextCursor && (
                  <button type="button" className="btn" onClick={dispatchHistory.loadMore} disabled={dispatchHistory.loadingMore}>
                    {dispatchHistory.loadingMore ? "LOADING FILED WEEKS" : "LOAD EARLIER DISPATCHES"}
                  </button>
                )}
              </div>
            )}
          </section>
        </div>
      </div>
    </section>
  );
}

function getBattlePageActiveMech(account, archiveDispatchStatus) {
  const ownedMechs = getOrganizationRosterMechs(account, archiveDispatchStatus);
  const accountOrganization = getAccountOrganization(account);
  if (accountOrganization && accountOrganization.starterMechId) {
    const starter = ownedMechs.find((mech) => mech.id === accountOrganization.starterMechId) || findMechById(accountOrganization.starterMechId);
    if (starter) return starter;
  }
  return ownedMechs[0] || null;
}

function BattleArenaLockedPanel({ onboardingStatus, activeMech, archiveDispatchStatus }) {
  const lockState = getBattleArenaTutorialLockState(onboardingStatus, activeMech, archiveDispatchStatus);
  const directive = lockState.directive;

  function handleLockCta(event) {
    if (lockState.actionDisabled) return;
    event.preventDefault();
    activateDirectiveTarget(lockState.targetHref);
  }

  return (
    <section className="battle-arena-locked-panel" aria-label="Battle Arena tutorial lock">
      <div className="battle-arena-locked-copy">
        <span>Battle Arena Clearance</span>
        <b>Finish Phase One before official battles</b>
        <p>Official challenges stay sealed until your operator tutorial directives are complete. Finish the current directive, then return here to choose an opponent, pick an arena, and issue the challenge.</p>
        <div className="battle-arena-locked-directive">
          <span>Next Directive</span>
          <b>{lockState.title}</b>
          <p>{lockState.copy}</p>
        </div>
        {lockState.actionDisabled ? (
          <button type="button" className="btn primary" disabled>{lockState.actionLabel}</button>
        ) : (
          <a className="btn primary" href={lockState.targetHref} onClick={handleLockCta}>{lockState.actionLabel || "CONTINUE TUTORIAL"}</a>
        )}
      </div>
      <div className="battle-arena-locked-preview">
        <span>{directive && directive.id ? String(directive.id).replace(/_/g, " ").toUpperCase() : "PHASE ONE LOCK"}</span>
        {activeMech ? (
          <HangarPreviewImage mech={activeMech} alt={activeMech.codename + " locked Battle Arena standby"} />
        ) : (
          <div className="battle-arena-stage-placeholder">MEKA STANDBY</div>
        )}
        <b>{activeMech ? activeMech.id + " / " + activeMech.codename : "Starter unit pending"}</b>
        <em>{lockState.actionHint}</em>
      </div>
    </section>
  );
}

function BattleArenaPage({ account, registry, archiveDispatchStatus, battleArenaStatus, creatorBattleQueueStatus, battleTheaterStatus, onboardingStatus, battleArenaChallengeSlug = "", view = "board" }) {
  const accountOrganization = getAccountOrganization(account);
  const activeMech = getBattlePageActiveMech(account, archiveDispatchStatus);
  const battleArenaUnlocked = battleArenaTutorialUnlocked(onboardingStatus);
  const organizationName = accountOrganization && (accountOrganization.name || accountOrganization.callsign)
    ? (accountOrganization.name || accountOrganization.callsign)
    : "Operator Command";
  const activeBattleCount = battleArenaUnlocked && Array.isArray(battleArenaStatus && battleArenaStatus.battles)
    ? battleArenaStatus.battles.filter((battle) => battle && ["invited", "selection_pending", "scheduled", "released"].includes(battle.status)).length
    : 0;
  const activeView = view === "active";

  return (
    <main id="battle-arena" className={"battle-page " + (activeView ? "battle-active-page" : "battle-challenge-board-page")} data-screen-label={activeView ? "Active Battle" : "Challenge Board"}>
      <header className="battle-page-head">
        <div>
          <span>Battle Command</span>
          <h1>{activeView ? "Active Battle" : "Challenge Board"}</h1>
          <p>{activeView ? "Respond to an invitation, lock your Meka, or track creator production and battle results." : organizationName + " can choose an opponent, lock an owned Meka, select an arena, and issue a challenge."}</p>
        </div>
        <div className="battle-page-status">
          <span>Active Records</span>
          <b>{String(activeBattleCount).padStart(2, "0")}</b>
        </div>
      </header>
      <nav className="battle-arena-view-nav" aria-label="Battle Arena views">
        <a className={activeView ? "" : "is-active"} href="#battle-arena" aria-current={activeView ? undefined : "page"}>CHALLENGE BOARD</a>
        <a className={activeView ? "is-active" : ""} href="#battle-arena/active" aria-current={activeView ? "page" : undefined}>ACTIVE BATTLE <b>{String(activeBattleCount).padStart(2, "0")}</b></a>
      </nav>
      <div className="battle-page-stack">
        {battleArenaUnlocked ? (
          <BattleArenaPanel
            account={account}
            registry={registry}
            archiveDispatchStatus={archiveDispatchStatus}
            battleArenaStatus={battleArenaStatus}
            creatorBattleQueueStatus={creatorBattleQueueStatus}
            activeMech={activeMech}
            targetChallengeSlug={battleArenaChallengeSlug}
            view={view}
          />
        ) : (
          <BattleArenaLockedPanel onboardingStatus={onboardingStatus} activeMech={activeMech} archiveDispatchStatus={archiveDispatchStatus} />
        )}
      </div>
    </main>
  );
}

function sceneStatusLabel(value) {
  return String(value || "not_started").replace(/_/g, " ").toUpperCase();
}

function buildCreatorQueueDraft(battle) {
  const chronicle = battle && battle.chronicle ? battle.chronicle : {};
  const scenePackage = battle && battle.scenePackage ? battle.scenePackage : {};
  return {
    sceneStatus: battle && battle.sceneStatus ? battle.sceneStatus : "not_started",
    scenePackageId: battle && battle.scenePackageId ? battle.scenePackageId : (scenePackage.id || ""),
    sceneInternalRef: battle && battle.sceneInternalRef ? battle.sceneInternalRef : (scenePackage.internalFile || ""),
    scenePublicUrl: battle && battle.scenePublicUrl ? battle.scenePublicUrl : (scenePackage.publicRoute || ""),
    adminNotes: battle && battle.adminNotes ? battle.adminNotes : "",
    winnerSide: chronicle.winnerSide || "challenger",
    resultSummary: chronicle.summary || "",
    battleLogLine: chronicle.battleLogLine || "",
    theaterFeatured: Boolean(battle && battle.theater && battle.theater.featured),
    theaterCuratorNote: battle && battle.theater && battle.theater.curatorNote ? battle.theater.curatorNote : ""
  };
}

function CreatorBattleQueuePanel({ creatorBattleQueueStatus, onQueueMutationComplete }) {
  const battles = Array.isArray(creatorBattleQueueStatus && creatorBattleQueueStatus.battles)
    ? creatorBattleQueueStatus.battles
    : [];
  const scenePackages = Array.isArray(creatorBattleQueueStatus && creatorBattleQueueStatus.scenePackages)
    ? creatorBattleQueueStatus.scenePackages
    : [];
  const [tokenInput, setTokenInput] = useState(() => (creatorBattleQueueStatus && creatorBattleQueueStatus.token) || "");
  const [drafts, setDrafts] = useState({});
  const [localError, setLocalError] = useState("");
  const isLocked = !creatorBattleQueueStatus || creatorBattleQueueStatus.status === "locked" || !creatorBattleQueueStatus.token;
  const busy = Boolean(creatorBattleQueueStatus && creatorBattleQueueStatus.actionBusy);
  const battleSignature = battles.map((battle) => [
    battle.id,
    battle.sceneStatus,
    battle.scenePackageId,
    battle.scenePackage && battle.scenePackage.id,
    battle.scenePackage && battle.scenePackage.publicRoute,
    battle.sceneInternalRef,
    battle.scenePublicUrl,
    battle.adminNotes,
    battle.status,
    battle.releasedAt,
    battle.theater && battle.theater.published,
    battle.theater && battle.theater.featured,
    battle.theater && battle.theater.curatorNote
  ].join(":")).join("|");

  useEffect(() => {
    if (creatorBattleQueueStatus && creatorBattleQueueStatus.token) {
      setTokenInput(creatorBattleQueueStatus.token);
    }
  }, [creatorBattleQueueStatus && creatorBattleQueueStatus.token]);

  useEffect(() => {
    const nextDrafts = {};
    battles.forEach((battle) => {
      nextDrafts[battle.id] = buildCreatorQueueDraft(battle);
    });
    setDrafts(nextDrafts);
  }, [battleSignature]);

  async function handleTokenSubmit(event) {
    event.preventDefault();
    if (!creatorBattleQueueStatus || typeof creatorBattleQueueStatus.saveToken !== "function") return;
    setLocalError("");
    try {
      await creatorBattleQueueStatus.saveToken(tokenInput);
    } catch (error) {
      setLocalError((error.message || "CREATOR TOKEN FAILED").toUpperCase());
    }
  }

  function updateDraft(battleId, field, value) {
    setDrafts((current) => ({
      ...current,
      [battleId]: {
        ...buildCreatorQueueDraft({}),
        ...(current[battleId] || {}),
        [field]: value
      }
    }));
  }

  async function handleProductionSave(battle) {
    if (!creatorBattleQueueStatus || !battle || typeof creatorBattleQueueStatus.updateProduction !== "function") return;
    const draft = drafts[battle.id] || buildCreatorQueueDraft(battle);
    setLocalError("");
    const patch = {
      sceneStatus: draft.sceneStatus,
      adminNotes: draft.adminNotes
    };
    try {
      await creatorBattleQueueStatus.updateProduction(battle.id, patch);
      if (typeof onQueueMutationComplete === "function") await onQueueMutationComplete();
    } catch (error) {
      setLocalError((error.message || "PRODUCTION UPDATE FAILED").toUpperCase());
    }
  }

  async function handleScenePackageAssign(battle) {
    if (!creatorBattleQueueStatus || !battle || typeof creatorBattleQueueStatus.assignScenePackage !== "function") return;
    const draft = drafts[battle.id] || buildCreatorQueueDraft(battle);
    const scenePackageId = String(draft.scenePackageId || "").trim();
    setLocalError("");
    if (!scenePackageId) {
      setLocalError("CHOOSE A SCENE PACKAGE FIRST");
      return;
    }
    try {
      await creatorBattleQueueStatus.assignScenePackage(battle.id, scenePackageId);
      if (typeof onQueueMutationComplete === "function") await onQueueMutationComplete();
    } catch (error) {
      setLocalError((error.message || "SCENE PACKAGE ASSIGNMENT FAILED").toUpperCase());
    }
  }

  async function handleRelease(battle) {
    if (!creatorBattleQueueStatus || !battle || typeof creatorBattleQueueStatus.releaseBattle !== "function") return;
    setLocalError("");
    try {
      await creatorBattleQueueStatus.releaseBattle(battle.id);
      if (typeof onQueueMutationComplete === "function") await onQueueMutationComplete();
    } catch (error) {
      setLocalError((error.message || "SCENE RELEASE FAILED").toUpperCase());
    }
  }

  async function handleResultSave(battle) {
    if (!creatorBattleQueueStatus || !battle || typeof creatorBattleQueueStatus.recordResult !== "function") return;
    const draft = drafts[battle.id] || buildCreatorQueueDraft(battle);
    setLocalError("");
    try {
      await creatorBattleQueueStatus.recordResult(battle.id, {
        winnerSide: draft.winnerSide,
        resultSummary: draft.resultSummary,
        battleLogLine: draft.battleLogLine
      });
      if (typeof onQueueMutationComplete === "function") await onQueueMutationComplete();
    } catch (error) {
      setLocalError((error.message || "RESULT RECORD FAILED").toUpperCase());
    }
  }

  async function handleTheaterPublish(battle, publish = true) {
    if (!creatorBattleQueueStatus || !battle || typeof creatorBattleQueueStatus.updateTheaterPublishing !== "function") return;
    const draft = drafts[battle.id] || buildCreatorQueueDraft(battle);
    setLocalError("");
    try {
      await creatorBattleQueueStatus.updateTheaterPublishing(battle.id, {
        publish,
        featured: Boolean(draft.theaterFeatured),
        curatorNote: draft.theaterCuratorNote
      });
      if (typeof onQueueMutationComplete === "function") await onQueueMutationComplete();
    } catch (error) {
      setLocalError((error.message || "THEATER PUBLISH FAILED").toUpperCase());
    }
  }

  if (isLocked && !creatorBattleQueuePanelRequested()) return null;

  return (
    <section id="battle-queue" className={"creator-battle-queue-panel" + (isLocked ? " is-locked" : "")} aria-label="Creator Battle Queue">
      <div className="creator-battle-queue-head">
        <div>
          <span>Creator Queue</span>
          <b>{isLocked ? "Creator Access Locked" : battles.length ? battles.length + " Battle" + (battles.length === 1 ? "" : "s") : "Queue Clear"}</b>
        </div>
        <form className="creator-battle-token" onSubmit={handleTokenSubmit}>
          <label>
            <span>Creator Passcode</span>
            <input
              type="password"
              value={tokenInput}
              onChange={(event) => setTokenInput(event.target.value)}
              placeholder="Creator publishing passcode"
              autoComplete="off"
            />
          </label>
          <button type="submit" className="btn" disabled={busy}>{isLocked ? "OPEN QUEUE" : "REFRESH"}</button>
          {!isLocked && (
            <button type="button" className="btn" onClick={() => creatorBattleQueueStatus.clearToken()} disabled={busy}>LOCK</button>
          )}
        </form>
      </div>

      {!isLocked && (
        <div className="creator-battle-production-deck">
          <div className="creator-battle-pipeline" aria-label="Creator production pipeline">
            {["Intake", "Scene Package", "Animation", "QA", "Release", "Chronicle"].map((stage) => (
              <span key={stage}>{stage}</span>
            ))}
          </div>
          <div className="creator-battle-queue-list">
            {battles.length ? battles.map((battle) => {
              const draft = drafts[battle.id] || buildCreatorQueueDraft(battle);
              const challengerName = battle.challenger && battle.challenger.organization
                ? battle.challenger.organization.name || battle.challenger.organization.callsign || "Challenger"
                : "Challenger";
              const defenderName = battle.defender && battle.defender.organization
                ? battle.defender.organization.name || battle.defender.organization.callsign || "Defender"
                : "Defender";
              const challengerMeka = battle.challenger && battle.challenger.selectedMechId ? battle.challenger.selectedMechId : "PENDING";
              const defenderMeka = battle.defender && battle.defender.selectedMechId ? battle.defender.selectedMechId : "PENDING";
              const selectedScenePackage = scenePackages.find((scenePackage) => scenePackage.id === draft.scenePackageId)
                || (battle && battle.scenePackage ? battle.scenePackage : null);
              const packageRoute = selectedScenePackage && selectedScenePackage.publicRoute
                ? selectedScenePackage.publicRoute
                : draft.scenePublicUrl;
              const packageInternalFile = selectedScenePackage && selectedScenePackage.internalFile
                ? selectedScenePackage.internalFile
                : draft.sceneInternalRef;
              const hasAssignedPackage = Boolean(battle.scenePackageId || (selectedScenePackage && selectedScenePackage.id));
              const hasPackageRoute = Boolean(String(packageRoute || "").trim());
              const packageStatus = selectedScenePackage && selectedScenePackage.status
                ? String(selectedScenePackage.status).replace(/_/g, " ").toUpperCase()
                : "PACKAGE PENDING";
              const canAssignScenePackage = Boolean(draft.scenePackageId) && battle.status !== "completed" && !busy;
              const canRelease = battle.status !== "released" && draft.sceneStatus === "ready" && hasAssignedPackage && hasPackageRoute;
              const canRecordResult = ["released", "completed"].includes(String(battle.status || "")) && !busy;
              const theaterPublished = Boolean(battle.theater && battle.theater.published);
              const canPublishTheater = battle.status === "completed" && battle.sceneStatus === "ready" && hasPackageRoute && !busy;
              return (
                <article className={"creator-battle-row is-" + String(battle.sceneStatus || "not_started").replace(/_/g, "-")} key={battle.id}>
                  <div className="creator-battle-summary">
                    <span>{battle.scheduledBattleDate ? formatBattleArenaDate(battle.scheduledBattleDate) : "DATE PENDING"}</span>
                    <b>{battle.arena ? battle.arena.name : "Arena Pending"}</b>
                    <em>{sceneStatusLabel(battle.sceneStatus)} / {String(battle.status || "scheduled").replace(/_/g, " ").toUpperCase()}</em>
                  </div>
                  <div className="creator-battle-matchup">
                    <div>
                      <span>{challengerName}</span>
                      <b>{challengerMeka}</b>
                    </div>
                    <strong>VS</strong>
                    <div>
                      <span>{defenderName}</span>
                      <b>{defenderMeka}</b>
                    </div>
                  </div>
                  <div className="creator-battle-production">
                    <label>
                      <span>Status</span>
                      <select value={draft.sceneStatus} onChange={(event) => updateDraft(battle.id, "sceneStatus", event.target.value)} disabled={busy}>
                        <option value="not_started">Not Started</option>
                        <option value="in_progress">In Progress</option>
                        <option value="ready">Ready</option>
                        <option value="blocked">Blocked</option>
                        <option value="overdue">Overdue</option>
                      </select>
                    </label>
                    <label>
                      <span>Internal File</span>
                      <input value={packageInternalFile || ""} readOnly placeholder="Package controls this file" disabled={busy} />
                    </label>
                    <div className={"creator-scene-package" + (hasAssignedPackage && hasPackageRoute ? " is-valid" : "")}>
                      <label>
                        <span>Scene Package</span>
                        <select value={draft.scenePackageId} onChange={(event) => updateDraft(battle.id, "scenePackageId", event.target.value)} disabled={busy || battle.status === "completed"}>
                          <option value="">Choose package</option>
                          {scenePackages.map((scenePackage) => (
                            <option value={scenePackage.id} key={scenePackage.id}>
                              {scenePackage.title || scenePackage.id} / {String(scenePackage.status || "draft").toUpperCase()}
                            </option>
                          ))}
                        </select>
                      </label>
                      <div className="creator-scene-package-readout">
                        <div>
                          <span>Obscured Route</span>
                          <b>{packageRoute || "ROUTE PENDING"}</b>
                        </div>
                        <div>
                          <span>Package State</span>
                          <b>{packageStatus}</b>
                        </div>
                        <em>{hasAssignedPackage && hasPackageRoute ? "PACKAGE ROUTE VALID" : "PACKAGE REQUIRED BEFORE RELEASE"}</em>
                      </div>
                      <div className="creator-battle-actions">
                        <button type="button" className="btn" onClick={() => handleScenePackageAssign(battle)} disabled={!canAssignScenePackage}>ASSIGN PACKAGE</button>
                      </div>
                    </div>
                    <label className="creator-battle-notes">
                      <span>Notes</span>
                      <textarea value={draft.adminNotes} onChange={(event) => updateDraft(battle.id, "adminNotes", event.target.value)} rows="2" disabled={busy} />
                    </label>
                    <div className="creator-battle-actions">
                      <button type="button" className="btn" onClick={() => handleProductionSave(battle)} disabled={busy}>SAVE</button>
                      <button type="button" className="btn primary" onClick={() => handleRelease(battle)} disabled={busy || !canRelease}>{battle.status === "released" ? "RELEASED" : "RELEASE"}</button>
                    </div>
                  </div>
                  <div className="creator-battle-result">
                    <label>
                      <span>Winner</span>
                      <select value={draft.winnerSide} onChange={(event) => updateDraft(battle.id, "winnerSide", event.target.value)} disabled={busy || battle.status === "completed"}>
                        <option value="challenger">{challengerMeka} / Challenger</option>
                        <option value="defender">{defenderMeka} / Defender</option>
                        <option value="draw">Draw</option>
                      </select>
                    </label>
                    <label>
                      <span>Battle Log Line</span>
                      <input value={draft.battleLogLine} onChange={(event) => updateDraft(battle.id, "battleLogLine", event.target.value)} placeholder="One-line chronicle hook" disabled={busy || battle.status === "completed"} />
                    </label>
                    <label className="creator-battle-result-summary">
                      <span>Result Summary</span>
                      <textarea value={draft.resultSummary} onChange={(event) => updateDraft(battle.id, "resultSummary", event.target.value)} rows="2" disabled={busy || battle.status === "completed"} />
                    </label>
                    <div className="creator-battle-actions">
                      <button type="button" className="btn primary" onClick={() => handleResultSave(battle)} disabled={!canRecordResult || battle.status === "completed"}>{battle.status === "completed" ? "RESULT FILED" : "FILE RESULT"}</button>
                    </div>
                  </div>
                  <div className={"creator-theater-publish" + (theaterPublished ? " is-published" : "")}>
                    <div>
                      <span>Battle Theater</span>
                      <b>{theaterPublished ? "Published to public Theater" : "Awaiting showcase approval"}</b>
                      <p>{theaterPublished ? "Spectators can discover this battle in the public Theater archive." : "Publish only after the scene, result, and chronicle are final."}</p>
                    </div>
                    <label>
                      <span>Featured</span>
                      <input
                        type="checkbox"
                        checked={Boolean(draft.theaterFeatured)}
                        onChange={(event) => updateDraft(battle.id, "theaterFeatured", event.target.checked)}
                        disabled={busy || theaterPublished}
                      />
                    </label>
                    <label className="creator-theater-note">
                      <span>Curator Note</span>
                      <textarea
                        value={draft.theaterCuratorNote}
                        onChange={(event) => updateDraft(battle.id, "theaterCuratorNote", event.target.value)}
                        rows="2"
                        disabled={busy || theaterPublished}
                        placeholder="Short public framing for spectators"
                      />
                    </label>
                    <div className="creator-battle-actions">
                      <button type="button" className="btn primary" onClick={() => handleTheaterPublish(battle, true)} disabled={!canPublishTheater || theaterPublished}>
                        {theaterPublished ? "IN THEATER" : "PUBLISH TO THEATER"}
                      </button>
                      {theaterPublished && (
                        <button type="button" className="btn" onClick={() => handleTheaterPublish(battle, false)} disabled={busy}>UNPUBLISH</button>
                      )}
                    </div>
                  </div>
                </article>
              );
            }) : (
              <div className="creator-battle-empty">
                <span>Production queue clear</span>
                <b>No scheduled Battle Arena scenes</b>
              </div>
            )}
            </div>
        </div>
      )}
      {(localError || (creatorBattleQueueStatus && creatorBattleQueueStatus.error)) && (
        <div className="battle-arena-error">{localError || creatorBattleQueueStatus.error}</div>
      )}
    </section>
  );
}

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 certificateTitle = payload && payload.title ? payload.title : "Ownership Certificate";
  const certificateLabel = payload && payload.certificateLabel ? payload.certificateLabel : "Registered Meka Deed";
  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>{certificateTitle}</span>
              <b>{dispatchCode}</b>
            </div>
            <div className="ownership-certificate-body">
              <div className="ownership-certificate-copy">
                <span>{certificateLabel}</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 certificate 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>{certificateTitle}</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 starterResultCopy = filter !== "all" || query
    ? visible.length + " SHOWN · " + filtered.length + " MATCHING · " + archiveRoster.length + " TOTAL"
    : visible.length + " SHOWN · " + archiveRoster.length + " TOTAL";
  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>

        {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>STARTER ARCHIVE · {starterResultCopy}</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 />
        <ViewportImage
          className="archive-card-meka-image"
          src={versionAssetUrl(mech.fullbody || mech.image)}
          alt={mech.codename + " full body"}
          rootMargin="200px 0px"
        />
      </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>

            <BattleAftermathDossierPanel mech={mech} archiveDispatchStatus={archiveDispatchStatus} />

            <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 }) {
  function handleSignInSuccess() {
    const signinReturnHash = readBattleArenaReturnHash();
    clearBattleArenaReturnHash();
    window.location.hash = signinReturnHash || "#top";
  }

  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={handleSignInSuccess} />
        </div>
      </div>
    </section>
  );
}

function BattleArenaInviteAuthBridge({ challengeSlug = "", view = "board" }) {
  const normalizedSlug = normalizeBattleArenaChallengeSlug(challengeSlug);
  const activeView = view === "active";
  const returnHash = normalizedSlug
    ? "#battle-arena/active/" + encodeURIComponent(normalizedSlug)
    : activeView ? "#battle-arena/active" : "#battle-arena";

  function handleSignInClick() {
    rememberBattleArenaReturnHash(returnHash);
  }

  return (
    <main id="battle-arena" className="battle-page battle-invite-auth-page" data-screen-label="Battle Invitation">
      <section className="battle-invite-auth-bridge" aria-label="Battle Arena invitation sign in">
        <div className="battle-invite-auth-copy">
          <span>{activeView ? "BATTLE ARENA INVITATION" : "BATTLE ARENA ACCESS"}</span>
          <h1>{activeView ? "Sign in to review this challenge" : "Sign in to open the Challenge Board"}</h1>
          <p>{activeView ? "This route is linked to an active Battle Arena challenge. Sign in with the participating organization account to respond, lock a Meka, or track production." : "The Challenge Board is available to signed-in organizations with Battle Arena access."}</p>
        </div>
        <div className="battle-invite-auth-panel">
          <span>Challenge route</span>
          <b>{normalizedSlug ? normalizedSlug : activeView ? "Active Battle route" : "Challenge Board route"}</b>
          <p>{activeView ? "Battle details stay sealed until the participating organization is verified." : "Opponent, Meka, and arena controls open after account verification."}</p>
          <a className="btn primary" href="#signin" onClick={handleSignInClick}>{activeView ? "SIGN IN TO REVIEW" : "SIGN IN TO CHALLENGE"}</a>
        </div>
      </section>
    </main>
  );
}

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, onDirectiveCompleted }) {
  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);
    if (action === "complete" && result && typeof onDirectiveCompleted === "function") {
      onDirectiveCompleted({ id: "open_command_channel", title: "Open command channel" }, result);
    }
    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, onDirectiveCompleted }) {
  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}
            onDirectiveCompleted={onDirectiveCompleted}
          />
        </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" || directive.id === "enter_official_battles")) 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 = 1800;
const DIRECTIVE_COMPLETION_RECENT_REPLAY_MS = 2 * 60 * 60 * 1000;
const DIRECTIVE_COMPLETION_REPLAY_STORAGE_PREFIX = "supermekabots.directiveReceipt.replayed.";
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 battleArenaTutorialUnlocked(onboardingStatus) {
  const onboarding = onboardingStatus && onboardingStatus.data ? onboardingStatus.data : onboardingStatus;
  return phaseOneDirectivesAreClear(onboarding);
}

function getBattleArenaTutorialLockState(onboardingStatus, starterMech, archiveDispatchStatus) {
  const onboarding = onboardingStatus && onboardingStatus.data ? onboardingStatus.data : onboardingStatus;
  const directive = getCurrentDirective(onboarding, starterMech, archiveDispatchStatus);
  const panelState = getDirectivePanelState(onboarding, directive);
  const lockedAction = getDirectiveLockedActionCopy(onboarding, directive);
  const lockedByGeneration = panelState === "locked";
  return {
    title: directive && directive.title ? directive.title : "Complete tutorial directives",
    copy: directive && directive.copy
      ? directive.copy
      : "Finish the previous operator tutorials before official Battle Arena participation unlocks.",
    targetHref: directive && directive.targetHref ? directive.targetHref : "#hangar",
    actionLabel: lockedByGeneration ? lockedAction.label : getDirectiveActionLabel(directive, panelState),
    actionHint: lockedByGeneration ? lockedAction.hint : "Official challenges unlock after Phase One tutorial directives are complete.",
    actionDisabled: lockedByGeneration,
    directive
  };
}

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: "ready",
    label: "Enter official battles",
    title: "Battle Arena ready",
    copy: "Official challenges are unlocked. Open Battle command to choose an opponent, inspect arena conditions, and issue a creator-reviewed challenge.",
    requiredAction: "open_battle_arena",
    targetHref: "#battle-arena",
    actionLabel: "OPEN BATTLE"
  };
}

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, battleArenaStatus, creatorBattleQueueStatus, 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 battleArenaHomeDirective = getPostLicenseArchiveDirective(
    onboardingStatus && onboardingStatus.data ? onboardingStatus.data : onboardingStatus,
    archiveDispatchStatus
  );
  const showBattleArenaHomeSection = Boolean(isSignedInDashboard && battleArenaHomeDirective);
  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>
      {showBattleArenaHomeSection && (
        <section className="section battle-arena-home-section" aria-label="Battle Arena command deck" data-screen-label="Battle Arena Command">
          <div className="section-inner">
            <BattleArenaLauncherCard
              battleArenaStatus={battleArenaStatus}
              onboardingStatus={onboardingStatus}
              activeMech={activeMech}
              archiveDispatchStatus={archiveDispatchStatus}
              ownedMechs={ownedMechs}
            />
          </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 Meka concept archive. Each entry
              starts as an <em>AI-generated concept</em> rendered through a tailored
              prompt I've been refining since 2024 — then that identity can expand into its full-body concept, pilot, lore, 3D model, and battle scene.
            </p>
            <p>
              The line has its own internal rules: every Meka has a distinct silhouette,
              every colorway uses no more than five hues, every entry has a named pilot,
              and each artifact reads as the same character whenever its lore, 3D model, or battle scene is added.
            </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><a href="#comms">COMMS</a></div>
      <div>© {new Date().getFullYear()} · AI-GENERATED CONCEPTS · NON-COMMERCIAL ARCHIVE</div>
    </footer>
  );
}

const ROUTE_SCROLL_TARGETS = new Set(["#hangar", "#generation", "#assistant-intro", "#registry", "#battle-theater", "#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 parseBattleArenaRouteHash(routeHash) {
  const hash = String(routeHash || "").trim();
  if (hash === "#battle-arena") return { routeHash: "#battle-arena", view: "board", challengeSlug: "" };
  if (hash === "#battle-arena/active") return { routeHash: "#battle-arena/active", view: "active", challengeSlug: "" };
  const activeSlugMatch = hash.match(/^#battle-arena\/active\/([^?#]+)$/i);
  if (activeSlugMatch) {
    return { routeHash: hash, view: "active", challengeSlug: normalizeBattleArenaChallengeSlug(activeSlugMatch[1]) };
  }
  const slugMatch = hash.match(/^#battle-arena\/([^?#]+)$/i);
  if (slugMatch) {
    return { routeHash: hash, view: "active", challengeSlug: normalizeBattleArenaChallengeSlug(slugMatch[1]) };
  }
  const queryMatch = hash.match(/^#battle-arena\?(?:.*&)?challenge=([^&]+)/i);
  if (queryMatch) {
    return { routeHash: hash, view: "active", challengeSlug: normalizeBattleArenaChallengeSlug(queryMatch[1]) };
  }
  return null;
}

function rememberBattleArenaReturnHash(returnHash) {
  if (typeof window === "undefined") return;
  const battleArenaRoute = parseBattleArenaRouteHash(returnHash);
  if (!battleArenaRoute) return;
  try {
    sessionStorage.setItem(BATTLE_ARENA_RETURN_HASH_STORAGE_KEY, returnHash);
  } catch (error) {}
}

function readBattleArenaReturnHash() {
  if (typeof window === "undefined") return "";
  try {
    const returnHash = sessionStorage.getItem(BATTLE_ARENA_RETURN_HASH_STORAGE_KEY) || "";
    return parseBattleArenaRouteHash(returnHash) ? returnHash : "";
  } catch (error) {
    return "";
  }
}

function clearBattleArenaReturnHash() {
  if (typeof window === "undefined") return;
  try {
    sessionStorage.removeItem(BATTLE_ARENA_RETURN_HASH_STORAGE_KEY);
  } catch (error) {}
}

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 [detailReturnHash, setDetailReturnHash] = useState("");
  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 battleArenaUnlocked = battleArenaTutorialUnlocked(onboardingStatus);
  const battleArenaStatus = useBattleArenaStatus(account, battleArenaUnlocked);
  const creatorBattleQueueStatus = useCreatorBattleQueueStatus(account);
  const battleTheaterStatus = useBattleTheaterStatus(account);
  const routeDirectiveCompletionRef = useRef("");
  const directiveReceiptTimerRef = useRef(null);
  const directiveReceiptQueueRef = useRef([]);
  const directiveReceiptSeenKeysRef = useRef(new Set());
  const directiveCompletionSnapshotReadyRef = useRef(false);
  const knownDirectiveCompletionKeysRef = useRef(new Set());
  const [directiveReceipt, setDirectiveReceipt] = useState(null);
  const routeIsSignup = routeHash === "#signup" || routeHash === "#founding";
  const routeIsSignin = routeHash === "#signin";
  const routeIsGeneration = routeHash === "#generation";
  const battleArenaRoute = parseBattleArenaRouteHash(routeHash);
  const routeIsBattleArena = Boolean(battleArenaRoute);
  const routeIsRegisteredOperators = routeHash === REGISTERED_OPERATORS_ROUTE;
  const routeIsDispatchArchive = routeHash === DISPATCH_ARCHIVE_ROUTE || (openId && detailReturnHash === DISPATCH_ARCHIVE_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 onboardingDirectiveItems = onboardingStatus.data && onboardingStatus.data.directives && Array.isArray(onboardingStatus.data.directives.items)
    ? onboardingStatus.data.directives.items
    : [];
  const onboardingDirectiveFingerprint = onboardingDirectiveItems
    .map((item) => [item && item.id, item && item.status, item && item.completedAt].join(":"))
    .join("|");
  const routeIsSignedOutHangar = routeHash === "#hangar" && showPublicEntry && (typeof window === "undefined" || window.location.hash === "#hangar");
  const routeIsDedicatedSignup = routeIsSignup || routeIsSignedOutHangar;
  const routeIsDedicatedAuth = routeIsDedicatedSignup || routeIsSignin;
  const routeIsBattleArenaInviteGate = routeIsBattleArena && showPublicEntry;
  const routeIsDedicatedBattleArena = routeIsBattleArena && !showPublicEntry;
  const routeBootPending = Boolean(routeBootHash);
  const routeIsDedicatedPage = routeIsDedicatedAuth || routeIsDedicatedBattleArena || routeIsBattleArenaInviteGate || routeIsRegisteredOperators || routeIsDispatchArchive;
  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 getDirectiveCompletionReceiptKey(directive) {
    if (!directive || !directive.id || (directive.status !== "complete" && !directive.completedAt)) return "";
    return [
      accountOrganization && accountOrganization.id ? accountOrganization.id : "organization",
      directive.id,
      directive.completedAt || "complete"
    ].join(":");
  }

  function getDirectiveCompletedAtMs(directive) {
    const completedAt = directive && directive.completedAt ? Date.parse(directive.completedAt) : NaN;
    return Number.isFinite(completedAt) ? completedAt : 0;
  }

  function getInitialRecentCompletedDirective(completedDirectives) {
    const serverNow = onboardingStatus.data && onboardingStatus.data.serverTime ? Date.parse(onboardingStatus.data.serverTime) : NaN;
    const referenceNow = Number.isFinite(serverNow) ? serverNow : Date.now();
    let latest = null;
    let latestMs = 0;
    completedDirectives.forEach((directive) => {
      const completedMs = getDirectiveCompletedAtMs(directive);
      if (!completedMs || completedMs > referenceNow || referenceNow - completedMs > DIRECTIVE_COMPLETION_RECENT_REPLAY_MS) return;
      if (completedMs >= latestMs) {
        latest = directive;
        latestMs = completedMs;
      }
    });
    return latest;
  }

  function hasReplayedInitialDirectiveReceipt(receiptKey) {
    if (typeof window === "undefined" || !window.sessionStorage || !receiptKey) return false;
    try {
      return window.sessionStorage.getItem(DIRECTIVE_COMPLETION_REPLAY_STORAGE_PREFIX + receiptKey) === "1";
    } catch (error) {
      return false;
    }
  }

  function rememberInitialDirectiveReceiptReplay(receiptKey) {
    if (typeof window === "undefined" || !window.sessionStorage || !receiptKey) return;
    try {
      window.sessionStorage.setItem(DIRECTIVE_COMPLETION_REPLAY_STORAGE_PREFIX + receiptKey, "1");
    } catch (error) {}
  }

  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 || "") : ""
    });
  }

  useEffect(() => {
    if (account.status !== "signed-in") {
      directiveCompletionSnapshotReadyRef.current = false;
      knownDirectiveCompletionKeysRef.current.clear();
      return;
    }
    if (!onboardingStatus.data || !onboardingStatus.data.directives) return;
    const completedDirectives = onboardingDirectiveItems.filter((item) => item && (item.status === "complete" || item.completedAt));
    const completedKeys = new Set(completedDirectives.map(getDirectiveCompletionReceiptKey).filter(Boolean));
    if (!directiveCompletionSnapshotReadyRef.current) {
      directiveCompletionSnapshotReadyRef.current = true;
      knownDirectiveCompletionKeysRef.current = completedKeys;
      const recentCompletedDirective = getInitialRecentCompletedDirective(completedDirectives);
      const recentReceiptKey = getDirectiveCompletionReceiptKey(recentCompletedDirective);
      if (recentReceiptKey && !hasReplayedInitialDirectiveReceipt(recentReceiptKey)) {
        rememberInitialDirectiveReceiptReplay(recentReceiptKey);
        queueDirectiveCompletionReceipt(recentCompletedDirective, onboardingStatus.data);
      }
      return;
    }
    completedDirectives.forEach((completedDirective) => {
      const receiptKey = getDirectiveCompletionReceiptKey(completedDirective);
      if (!receiptKey || knownDirectiveCompletionKeysRef.current.has(receiptKey)) return;
      knownDirectiveCompletionKeysRef.current.add(receiptKey);
      queueDirectiveCompletionReceipt(completedDirective, onboardingStatus.data);
    });
    knownDirectiveCompletionKeysRef.current = completedKeys;
  }, [
    account.status,
    accountOrganization && accountOrganization.id,
    onboardingDirectiveFingerprint
  ]);

  // 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);
        setDetailReturnHash("");
      } else if (ownership) {
        setOpenId(null);
        setOpenOrgId(null);
        setOpenOwnershipId(decodeURIComponent(ownership[1]));
        setDetailReturnHash("");
      } else {
        setOpenId(null);
        setOpenOrgId(null);
        setOpenOwnershipId(null);
        setDetailReturnHash("");
      }
    };
    checkHash();
    window.addEventListener("hashchange", checkHash);
    return () => window.removeEventListener("hashchange", checkHash);
  }, []);

  useEffect(() => {
    return () => {
      if (directiveReceiptTimerRef.current) window.clearTimeout(directiveReceiptTimerRef.current);
    };
  }, []);

  useEffect(() => {
    if (!directiveReceipt) {
      armDirectiveReceiptQueue(900);
    }
  }, [directiveReceipt && directiveReceipt.key]);

  useEffect(() => {
    if (routeIsBattleArenaInviteGate) {
      rememberBattleArenaReturnHash(routeHash);
    }
  }, [routeIsBattleArenaInviteGate, routeHash]);

  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);
    setDetailReturnHash("");
    if (directiveReceiptTimerRef.current) {
      window.clearTimeout(directiveReceiptTimerRef.current);
      directiveReceiptTimerRef.current = null;
    }
    directiveReceiptQueueRef.current = [];
    directiveReceiptSeenKeysRef.current.clear();
    directiveCompletionSnapshotReadyRef.current = false;
    knownDirectiveCompletionKeysRef.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 (!routeIsDedicatedBattleArena && !routeIsRegisteredOperators && !routeIsDispatchArchive) return;
    window.scrollTo({ top: 0, left: 0, behavior: "auto" });
    const root = document.getElementById("root");
    if (root) root.scrollTop = 0;
    if (!routeIsDedicatedBattleArena) return undefined;
    const settleTimer = window.setTimeout(() => {
      window.scrollTo({ top: 0, left: 0, behavior: "auto" });
      if (root) root.scrollTop = 0;
    }, 0);
    return () => window.clearTimeout(settleTimer);
  }, [routeHash, routeIsDedicatedBattleArena, routeIsRegisteredOperators, routeIsDispatchArchive]);

  useEffect(() => {
    if (routeIsDedicatedPage) return;
    const scrollTimer = window.setTimeout(() => {
      scrollToRouteHashSection(routeHash, "smooth");
    }, 0);
    return () => window.clearTimeout(scrollTimer);
  }, [routeHash, routeIsDedicatedPage]);

  const openDetail = (id, baseRouteHash = "") => {
    setDetailReturnHash(baseRouteHash === DISPATCH_ARCHIVE_ROUTE ? DISPATCH_ARCHIVE_ROUTE : "");
    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 = () => {
    const nextRouteHash = detailReturnHash;
    setDetailReturnHash("");
    if (nextRouteHash) {
      history.replaceState(null, "", window.location.pathname + window.location.search + nextRouteHash);
      setRouteHash(nextRouteHash);
    } else {
      history.replaceState(null, "", window.location.pathname + window.location.search);
      setRouteHash("");
    }
    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} archiveDispatchStatus={archiveDispatchStatus} />
        {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} />}
        {routeIsBattleArenaInviteGate && <BattleArenaInviteAuthBridge challengeSlug={battleArenaRoute.challengeSlug} view={battleArenaRoute.view} />}
        {routeIsDedicatedBattleArena && <BattleArenaPage
            account={account}
            registry={registry}
            archiveDispatchStatus={archiveDispatchStatus}
            battleArenaStatus={battleArenaStatus}
            creatorBattleQueueStatus={creatorBattleQueueStatus}
            battleTheaterStatus={battleTheaterStatus}
            onboardingStatus={onboardingStatus}
            battleArenaChallengeSlug={battleArenaRoute.challengeSlug}
            view={battleArenaRoute.view}
          />}
        {routeIsDispatchArchive && <DispatchArchivePage archiveDispatchStatus={archiveDispatchStatus} onOpenMeka={openDetail} />}
        {routeIsRegisteredOperators && <RegisteredOperatorsPage registry={registry} account={account} onOpenOrganization={openOrganizationDossier} />}
        {!routeIsDedicatedPage && (
          <>
            {showGenerationWaitingBay && <GenerationWaitingBay account={account} onboardingStatus={onboardingStatus} onDirectiveCompleted={queueDirectiveCompletionReceipt} />}
            {!showPublicEntry && <HangarBay onOpen={openDetail} onOpenOrganization={openOrganizationDossier} onOpenCertificate={openOwnershipCertificate} onOpenCertificateVault={openCertificateVault} engagement={engagement} account={account} registry={registry} onboardingStatus={onboardingStatus} archiveDispatchStatus={archiveDispatchStatus} battleArenaStatus={battleArenaStatus} creatorBattleQueueStatus={creatorBattleQueueStatus} onSignupStarterIntent={rememberSignupStarter} onDirectiveCompleted={queueDirectiveCompletionReceipt} onDispatchDirectiveCompleted={queueDispatchDirectiveCompletionReceipt} onRegistryClaim={openRegistryClaimCeremony} />}
            {showPublicEntry && <OrganizationDirectory registry={registry} account={account} onOpenOrganization={openOrganizationDossier} />}
            {showPublicEntry && <BattleTheaterPanel account={account} onboardingStatus={onboardingStatus} battleTheaterStatus={battleTheaterStatus} />}
            <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 />
          </>
        )}
        {!routeIsDedicatedAuth && <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 />);
