/* 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, useLayoutEffect, useMemo, useRef, useCallback, useId } = 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";
const FOUNDING_TRAINING_API_BASE_KEY = "supermekabots.foundingTraining.apiBase.v1";
const OPERATIONS_SIM_ARENA_STORAGE_KEY = "mek_ops_bg";
const OPERATIONS_SIM_ARENA_BACKGROUNDS = Object.freeze([
  "https://sin1.contabostorage.com/48ea6e0cdf344a96ad45b1c7eb1c766a:anomaliexperiment/assets/demos/bond-breach/20260825/cinematic-handoff-v2/backgrounds/central-jakarta-attacker.png",
  "https://sin1.contabostorage.com/48ea6e0cdf344a96ad45b1c7eb1c766a:anomaliexperiment/assets/demos/bond-breach/20260825/cinematic-handoff-v2/backgrounds/central-jakarta-defender.png",
  "demos/bond-breach/arena-reddune.png",
  "demos/bond-breach/arena-ikn.png"
]);
const FOUNDING_DOCTRINE_ICON_URLS = Object.freeze({
  Assault: ARCHIVE_ASSET_BASE_URL + "demos/bond-breach/20260815-selection/doctrine-assault.webp",
  Bastion: ARCHIVE_ASSET_BASE_URL + "demos/bond-breach/20260815-selection/doctrine-bastion.webp",
  Forge: ARCHIVE_ASSET_BASE_URL + "demos/bond-breach/20260815-selection/doctrine-forge.webp",
  Salvage: ARCHIVE_ASSET_BASE_URL + "demos/bond-breach/20260815-selection/doctrine-salvage.webp",
  Vector: ARCHIVE_ASSET_BASE_URL + "demos/bond-breach/20260815-selection/doctrine-vector.webp"
});
const BOND_BREACH_PLAYABLE_CARD_ART = Object.freeze({
  "MD-01": "md-01-skirret-card.png",
  "MD-02": "md-02-quill-card.png",
  "MD-03": "md-03-pyrax-card.png",
  "MD-04": "md-04-talvos-card.png",
  "MD-05": "md-05-serrak-card.png",
  "MD-06": "md-06-mothe-card.png",
  "MD-07": "md-07-bract-card.png",
  "MD-08": "md-08-redoubt-card.png",
  "MD-09": "md-09-hulder-card.png",
  "MK-01": "mecha-01-vorzak-card.png",
  "MK-02": "mecha-02-narlik-card.png",
  "MK-03": "mecha-03-sylvak-card.png",
  "MK-04": "mecha-04-zyntho-card.png",
  "MK-05": "mecha-05-phalen-card.png",
  "MK-06": "mecha-06-ravorn-card.png",
  "MK-07": "mecha-07-makros-card.png",
  "MK-08": "mecha-08-lazhul-card.png",
  "MK-09": "mecha-09-karnus-card.png",
  "MK-10": "mecha-10-javrek-card.png",
  "MK-11": "mecha-11-ithven-card.png",
  "MK-15": "mecha-15-elvran-card.png",
  "MK-17": "mecha-18-crelix-card.png"
});
const BOND_BREACH_CARD_ART_BASE_URL = ARCHIVE_ASSET_BASE_URL + "demos/bond-breach/20260814/";
const BOND_BREACH_CARD_ART_RELEASE_20260905 = Object.freeze({
  "MK-12": "mk-12-haemor-card.png",
  "MK-13": "mk-13-ghazor-card.png",
  "MK-14": "mk-14-falkor-card.png",
  "MK-16": "mk-16-dranik-card.png",
  "MK-18": "mk-18-baskor-card.png",
  "AD-W22-01": "ad-w22-01-azrhik-card.png",
  "AD-W22-02": "ad-w22-02-brolkh-card.png",
  "AD-W22-03": "ad-w22-03-chevor-card.png",
  "AD-W23-03": "ad-w23-03-feenar-card.png",
  "MD-20": "md-20-battery-eye-card.png",
  "MD-21": "md-21-iron-lift-card.png",
  "MD-22": "md-22-shopwall-card.png",
  "MD-23": "md-23-furnace-watch-card.png",
  "MD-24": "md-24-slag-ram-card.png",
  "MD-25": "md-25-aerogate-card.png",
  "MD-26": "md-26-breach-tow-card.png",
  "MD-27": "md-27-echo-wall-card.png",
  "MD-28": "md-28-relic-hauler-card.png",
  "MD-29": "md-29-crew-bulwark-card.png",
  "MD-30": "md-30-signal-aegis-card.png",
  "MD-31": "md-31-trace-recoverer-card.png",
  "MD-32": "md-32-quay-archer-card.png"
});
const BOND_BREACH_CARD_ART_RELEASE_20260905_BASE_URL = ARCHIVE_ASSET_BASE_URL + "tcg/releases/20260905-mk-md-illustrations-v1/card-art/";

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,
    cache: "no-store"
  });
  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 canonicalObjectStorageAssetUrl(value) {
  const raw = String(value || "").trim();
  const resolved = raw.startsWith("assets/")
    ? ARCHIVE_ASSET_BASE_URL + raw.slice("assets/".length)
    : raw;
  if (!resolved.startsWith(ARCHIVE_ASSET_BASE_URL)) return "";
  return versionAssetUrl(resolved);
}

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.
  }
}

let foundingJourneyLaunchEpoch = 0;

function invalidateFoundingJourneyLaunches() {
  foundingJourneyLaunchEpoch += 1;
}

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) => {
    invalidateFoundingJourneyLaunches();
    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) => {
    invalidateFoundingJourneyLaunches();
    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 () => {
    invalidateFoundingJourneyLaunches();
    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 deriveOwnershipRegistry(organizations) {
  return organizations.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 organizations = normalizeOrganizationRegistry(await publicApi("/organizations"));
      const next = {
        status: "ready",
        organizations,
        ownership: deriveOwnershipRegistry(organizations),
        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 useFoundingJourneyStatus(account) {
  const accountIdentity = [account && account.status, account && account.user && account.user.id, account && account.organization && account.organization.id].join(":");
  const createFoundingJourneyState = (identity, status = "idle") => ({
    identity,
    status,
    data: null,
    error: "",
    actionBusy: "",
    actionOwnerToken: 0,
    briefingRetry: null
  });
  const mountedRef = useRef(true);
  const requestEpochRef = useRef(0);
  const requestSequenceRef = useRef(0);
  const actionOwnerSequenceRef = useRef(0);
  const actionOwnerRef = useRef(null);
  const accountIdentityRef = useRef(accountIdentity);
  const callbackRequestEpoch = requestEpochRef.current;
  const [state, setState] = useState(() => createFoundingJourneyState(accountIdentity));

  function foundingJourneyLifecycleIsCurrent(identity, requestEpoch) {
    return mountedRef.current
      && identity === accountIdentityRef.current
      && requestEpoch === requestEpochRef.current;
  }

  function invalidateFoundingJourneyLifecycle() {
    requestEpochRef.current += 1;
    requestSequenceRef.current += 1;
    actionOwnerRef.current = null;
  }

  function beginFoundingJourneyRequest(identity = accountIdentity, requestEpoch = callbackRequestEpoch) {
    if (!foundingJourneyLifecycleIsCurrent(identity, requestEpoch)) return null;
    return {
      identity,
      epoch: requestEpoch,
      sequence: ++requestSequenceRef.current
    };
  }

  function foundingJourneyRequestIsCurrent(request) {
    return Boolean(request)
      && foundingJourneyLifecycleIsCurrent(request.identity, request.epoch)
      && request.sequence === requestSequenceRef.current;
  }

  function acquireFoundingJourneyAction(actionId, identity = accountIdentity, requestEpoch = callbackRequestEpoch) {
    if (!foundingJourneyLifecycleIsCurrent(identity, requestEpoch) || actionOwnerRef.current) return null;
    const owner = {
      token: ++actionOwnerSequenceRef.current,
      actionId,
      identity,
      epoch: requestEpoch
    };
    actionOwnerRef.current = owner;
    setState((current) => current.identity === identity ? {
      ...current,
      actionBusy: actionId,
      actionOwnerToken: owner.token,
      error: ""
    } : current);
    return owner;
  }

  function foundingJourneyActionIsCurrent(owner) {
    return Boolean(owner)
      && actionOwnerRef.current === owner
      && foundingJourneyLifecycleIsCurrent(owner.identity, owner.epoch);
  }

  function getFoundingJourneyActionOwner(identity, requestEpoch) {
    const owner = actionOwnerRef.current;
    return owner && foundingJourneyLifecycleIsCurrent(identity, requestEpoch) && owner.identity === identity && owner.epoch === requestEpoch
      ? owner
      : null;
  }

  function getFoundingJourneyActionState(identity, requestEpoch) {
    const owner = getFoundingJourneyActionOwner(identity, requestEpoch);
    return {
      actionBusy: owner ? owner.actionId : "",
      actionOwnerToken: owner ? owner.token : 0
    };
  }

  function clearFoundingJourneyAction(owner) {
    if (!foundingJourneyActionIsCurrent(owner)) return;
    actionOwnerRef.current = null;
    setState((current) => current.identity === owner.identity && current.actionOwnerToken === owner.token ? {
      ...current,
      actionBusy: "",
      actionOwnerToken: 0
    } : current);
  }

  async function loadFoundingJourney(identity = accountIdentity, requestEpoch = callbackRequestEpoch) {
    const request = beginFoundingJourneyRequest(identity, requestEpoch);
    if (!request) return null;
    if (!PUBLIC_API_BASE_URL || !account || account.status !== "signed-in") {
      setState(createFoundingJourneyState(identity));
      return null;
    }
    setState((current) => {
      if (current.identity !== identity) return current;
      return {
        ...current,
        status: current.data ? "ready" : "loading",
        error: "",
        ...getFoundingJourneyActionState(identity, requestEpoch)
      };
    });
    try {
      const data = await publicApi("/founding-journey/current");
      if (!foundingJourneyRequestIsCurrent(request)) return null;
      setState((current) => {
        return current.identity === identity ? {
          ...current,
          status: "ready",
          data,
          error: "",
          ...getFoundingJourneyActionState(identity, requestEpoch),
          briefingRetry: null
        } : current;
      });
      return data;
    } catch (error) {
      if (!foundingJourneyRequestIsCurrent(request)) return null;
      if (error.status === 404) {
        setState((current) => {
          return current.identity === identity ? {
            ...current,
            status: "disabled",
            data: null,
            error: "",
            ...getFoundingJourneyActionState(identity, requestEpoch)
          } : current;
        });
        return null;
      }
      setState((current) => ({
        ...current,
        status: current.data ? "ready" : "error",
        data: current.data,
        error: error.message || "Founding Journey unavailable",
        ...getFoundingJourneyActionState(identity, requestEpoch)
      }));
      return null;
    }
  }

  async function refreshFoundingDeckStatus() {
    const actionId = "refresh_founding_deck_status";
    const owner = acquireFoundingJourneyAction(actionId);
    if (!owner) return null;
    try {
      return await loadFoundingJourney(owner.identity, owner.epoch);
    } finally {
      clearFoundingJourneyAction(owner);
    }
  }

  async function runJourneyAction(actionId, path, body = {}) {
    const owner = acquireFoundingJourneyAction(actionId);
    if (!owner) return null;
    const request = beginFoundingJourneyRequest(owner.identity, owner.epoch);
    if (!request) {
      clearFoundingJourneyAction(owner);
      return null;
    }
    try {
      const data = await publicApi(path, { method: "POST", body: JSON.stringify(body) });
      if (!foundingJourneyRequestIsCurrent(request) || !foundingJourneyActionIsCurrent(owner)) return null;
      setState((current) => current.identity === owner.identity && current.actionOwnerToken === owner.token ? {
        ...current,
        status: "ready",
        data,
        error: "",
        actionBusy: owner.actionId,
        briefingRetry: null
      } : current);
      return data;
    } catch (error) {
      if (!foundingJourneyRequestIsCurrent(request) || !foundingJourneyActionIsCurrent(owner)) return null;
      const actionError = error.message || (actionId === "founding_deck_briefing" ? "Founding Deck Briefing update failed" : "Founding Journey action failed");
      const errorCode = error && (error.code || error.body && error.body.code);
      if (actionId === "assign_deployment" && ["FOUNDING_DECK_MATERIALIZATION_RETRY_REQUIRED", "FOUNDING_DECK_AUTHORITY_REPAIR_REQUIRED"].includes(errorCode)) {
        const recoveryRequest = beginFoundingJourneyRequest(owner.identity, owner.epoch);
        if (!recoveryRequest) return null;
        try {
          const data = await publicApi("/founding-journey/current");
          if (!foundingJourneyRequestIsCurrent(recoveryRequest) || !foundingJourneyActionIsCurrent(owner)) return null;
          const materializationStatus = data && data.foundingDeckMaterialization && data.foundingDeckMaterialization.status;
          const projectionDescribesMaterialization = ["pending", "blocked", "materialized"].includes(materializationStatus);
          setState((current) => current.identity === owner.identity && current.actionOwnerToken === owner.token ? {
            ...current,
            status: "ready",
            data,
            error: projectionDescribesMaterialization ? "" : actionError,
            actionBusy: owner.actionId,
            briefingRetry: null
          } : current);
          return null;
        } catch (recoveryError) {
          if (!foundingJourneyRequestIsCurrent(recoveryRequest) || !foundingJourneyActionIsCurrent(owner)) return null;
        }
      }
      setState((current) => current.identity === owner.identity && current.actionOwnerToken === owner.token ? {
        ...current,
        status: current.data ? "ready" : "error",
        error: actionError,
        actionBusy: owner.actionId,
        briefingRetry: actionId === "founding_deck_briefing" ? { action: body.action, step: body.step } : current.briefingRetry
      } : current);
      return null;
    } finally {
      clearFoundingJourneyAction(owner);
    }
  }

  async function recordFoundingDeckBriefing(action, step) {
    return runJourneyAction(
      "founding_deck_briefing",
      "/founding-journey/current/founding-deck-briefing",
      { action, step }
    );
  }

  useLayoutEffect(() => {
    mountedRef.current = true;
    return () => {
      mountedRef.current = false;
      invalidateFoundingJourneyLifecycle();
    };
  }, []);

  useLayoutEffect(() => {
    if (accountIdentityRef.current === accountIdentity) return;
    accountIdentityRef.current = accountIdentity;
    invalidateFoundingJourneyLifecycle();
    setState(createFoundingJourneyState(
      accountIdentity,
      PUBLIC_API_BASE_URL && account && account.status === "signed-in" ? "loading" : "idle"
    ));
  }, [accountIdentity]);

  useEffect(() => {
    loadFoundingJourney(accountIdentity, requestEpochRef.current);
  }, [accountIdentity]);

  const visibleState = state.identity === accountIdentity
    ? state
    : createFoundingJourneyState(
      accountIdentity,
      PUBLIC_API_BASE_URL && account && account.status === "signed-in" ? "loading" : "idle"
    );
  const { identity: _identity, actionOwnerToken: _actionOwnerToken, ...journeyState } = visibleState;
  return {
    ...journeyState,
    refresh: () => loadFoundingJourney(),
    refreshFoundingDeckStatus,
    recordFoundingDeckBriefing,
    recordPostDeploymentDebrief: (action, step) => runJourneyAction(
      "post_deployment_debrief",
      "/founding-journey/current/post-deployment-debrief",
      { action, step }
    ),
    reviewArsenalReward: () => runJourneyAction(
      "arsenal_reward_review",
      "/founding-journey/current/arsenal/reward-review"
    ),
    completeArsenalOrientation: () => runJourneyAction(
      "card_collection_review",
      "/founding-journey/current/arsenal/orientation/complete"
    ),
    completeDeckBriefing: () => runJourneyAction("briefing", "/founding-journey/current/deck-briefing/complete"),
    acceptChallenge: () => runJourneyAction("accept_challenge", "/founding-journey/current/challenge/accept"),
    verifyFoundingPackage: (expectedHandoffId) => runJourneyAction("verify_founding_package", "/founding-journey/current/training-handoff/deploy", { expectedHandoffId }),
    assignDeployment: (crewId, expectedHandoffId) => runJourneyAction(
      "assign_deployment",
      "/founding-journey/current/deployment-assignment",
      { crewId, expectedHandoffId }
    )
  };
}

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 reconcileBattleArenaMutationRefresh(current, refreshed) {
  if (!refreshed) {
    return {
      ...current,
      status: "error",
      error: current.error || "BATTLE ARENA SYNC REQUIRED",
      actionBusy: ""
    };
  }
  return {
    ...current,
    status: "ready",
    arenas: refreshed.arenas,
    battles: refreshed.battles,
    error: "",
    actionBusy: ""
  };
}

function useBattleArenaStatus(account, battleArenaUnlocked) {
  const actionBusyRef = useRef("");
  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 || actionBusyRef.current) return null;
    actionBusyRef.current = actionId;
    setState((current) => ({ ...current, actionBusy: actionId, error: "" }));
    try {
      const result = await publicApi(path, {
        method: "POST",
        body: JSON.stringify(body || {})
      });
      const refreshed = await loadBattleArenaStatus();
      setState((current) => reconcileBattleArenaMutationRefresh(current, refreshed));
      return result;
    } catch (error) {
      const refreshed = await loadBattleArenaStatus();
      setState((current) => ({
        ...reconcileBattleArenaMutationRefresh(current, refreshed),
        error: (error.message || "BATTLE ARENA ACTION FAILED").toUpperCase(),
        actionBusy: ""
      }));
      throw error;
    } finally {
      actionBusyRef.current = "";
    }
  }

  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, onSelectAdjacent, adjacentDisabled = false }) {
  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) {
    if (adjacentDisabled) return;
    if (onSelectAdjacent) {
      onSelectAdjacent(direction);
      return;
    }
    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)} disabled={adjacentDisabled}>
        <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)} disabled={adjacentDisabled}>
        <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 ArchiveStatusStrip({ compact = false }) {
  const total = MEKABOTS_BY_ID.length;
  const latest = MEKABOTS_BY_ID[0];
  return (
    <div className={compact ? "statusbar founding-command-archive-strip" : "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 StatusBar() {
  return <ArchiveStatusStrip />;
}

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, foundingJourneyStatus }) {
  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";
  const postFounding = foundingJourneyStatus && foundingJourneyStatus.data
    ? foundingJourneyStatus.data.postFounding
    : null;
  const arsenalVisible = Boolean(postFounding && postFounding.arsenal && postFounding.arsenal.status !== "locked");
  const operations = postFounding && postFounding.operations ? postFounding.operations : { status: "locked" };
  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 && arsenalVisible && <a href="#cardcollection">Arsenal</a>}
        {!signedOut && operations.status === "unlocked" && <a href="#operations">Operations</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="#founding-starter-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, foundingJourneyStatus }) {
  const counts = getEngagementCounts(engagement, account);
  const registryCount = getRegistryCount(registry);
  const signedOut = !account || account.status !== "signed-in";
  const postFounding = foundingJourneyStatus && foundingJourneyStatus.data
    ? foundingJourneyStatus.data.postFounding
    : null;
  const arsenalVisible = Boolean(postFounding && postFounding.arsenal && postFounding.arsenal.status !== "locked");
  const operations = postFounding && postFounding.operations ? postFounding.operations : { status: "locked" };
  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 && arsenalVisible && <a href="#cardcollection"><span>ARSENAL</span><b>CARDS</b></a>}
      {!signedOut && operations.status === "unlocked" && <a href="#operations"><span>OPERATIONS</span><b>FIELD</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, onClaimComplete, onDispatchDirectiveCompleted }) {
  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 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 OWNED UNIT"
        : 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 && onOpen) onOpen(targetMech.id);
      return;
    }
    if (progress.currentDirective && progress.currentDirective.targetHref) {
      activateDirectiveTarget(getArchiveDispatchRouteTarget(progress.currentDirective));
    }
  }

  return (
    <section className={"command-dispatch-panel is-" + status + (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>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>
          </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, onClaimComplete, 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">
      <header className="archive-dispatch-dock-head">
        <div><span>SECTION · 03.1 / THE INDEX</span><h3>THIS WEEK'S ARCHIVE DISPATCH</h3></div>
        <b>{dispatch.code} · {entries.length} FEATURED {entries.length === 1 ? "UNIT" : "UNITS"}</b>
      </header>
      <div className="archive-dispatch-dock-roster">
        <CommandDispatchPanel account={account} archiveDispatchStatus={archiveDispatchStatus} onOpen={onOpen} onClaimComplete={onClaimComplete} onDispatchDirectiveCompleted={onDispatchDirectiveCompleted} />
        {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>
      <p className="archive-dispatch-dock-note">Dispatch units are permanently locked out of starter selection. Weekly Archive Dispatch targets stay rare and never return to the founding pool.</p>
    </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 canonical = typeof MEKABOTS_DATA !== "undefined" ? MEKABOTS_DATA.find(entry => entry.id === String(mech?.id || "").toUpperCase()) : null;
  const catalogFacing = normalizeBattleArenaFacing(canonical?.cinematicAvatarFacing || 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() : "";
  const canonical = typeof MEKABOTS_DATA !== "undefined" ? MEKABOTS_DATA.find(entry => entry.id === id) : null;
  const registered = canonical?.presentationAssets?.mekaCinematic;
  if (registered) return versionAssetUrl(registered);
  if (!id || !BATTLE_ARENA_CINEMATIC_AVATAR_IDS.has(id)) return "";
  const assetPath = getBattleArenaCinematicAvatarPath(mech);
  return assetPath ? versionAssetUrl("assets/battle-theater/" + assetPath) : "";
}

const FOUNDING_JOURNEY_PILOT_FACE_BY_MEKA = Object.freeze({
  "MK-01": "assets/mecha-01-pilot-face.png",
  "MK-02": "assets/mecha-02-pilot-face.png",
  "MK-04": "assets/mecha-04-pilot-face.png",
  "MK-05": "assets/mecha-05-pilot-face.png",
  "MK-06": "assets/mecha-06-pilot-face.png",
  "MK-07": "assets/mecha-07-pilot-face.png",
  "MK-08": "assets/mecha-08-pilot-face.png",
  "MK-09": "assets/mecha-09-pilot-face.png",
  "MK-10": "assets/mecha-10-pilot-face.png",
  "MK-11": "assets/mecha-11-pilot-face.png",
  "MK-12": "assets/mecha-12-pilot-face.png",
  "MK-13": "assets/mecha-13-pilot-face.png",
  "MK-16": "assets/mecha-16-pilot-face.png",
  "MK-18": "assets/mecha-18-pilot-face.png"
});

function getFoundingJourneyPilotFaceSource(mekaId, fallbackSource) {
  const id = String(mekaId || "").toUpperCase();
  const canonicalMeka = typeof MEKABOTS_DATA !== "undefined" ? MEKABOTS_DATA.find(entry => entry.id === id) : null;
  const assetPath = canonicalMeka?.presentationAssets?.pilotFace || FOUNDING_JOURNEY_PILOT_FACE_BY_MEKA[id];
  return assetPath ? versionAssetUrl(assetPath) : fallbackSource;
}

function getCrewPilotFaceSource(crew) {
  return getFoundingJourneyPilotFaceSource(crew?.signatureMeka?.id || crew?.signatureMeka?.code, crew?.pilot?.faceImage || crew?.pilot?.image || "");
}

function getCrewPilotSceneSource(crew) {
  const id = String(crew?.signatureMeka?.id || crew?.signatureMeka?.code || "").toUpperCase();
  const canonical = typeof MEKABOTS_DATA !== "undefined" ? MEKABOTS_DATA.find(entry => entry.id === id) : null;
  const scene = canonical?.presentationAssets?.pilotScene || crew?.presentationCapabilities?.roles?.pilotScene?.url || crew?.pilot?.cinematicImage;
  return scene ? versionAssetUrl(scene) : getCrewPilotFaceSource(crew);
}

function getFoundingChallengeArenaName(challenge) {
  const name = challenge && challenge.arena && typeof challenge.arena.name === "string" ? challenge.arena.name.trim() : "";
  return name ? name.toUpperCase() : "ARCHIVE TRAINING GRID";
}

function FoundingChallengeOpponentVisual({ challenge, opponentMekaImage, opponentPilotImage, opponentMonogram }) {
  const [mekaFailed, setMekaFailed] = useState(false);
  const [pilotFailed, setPilotFailed] = useState(false);
  const opponent = challenge && challenge.opponent ? challenge.opponent : {};
  const meka = opponent.meka || {};
  const pilot = opponent.pilot || {};

  return (
    <figure className="claude-founding-challenger-figure" aria-label="Opponent Meka and Pilot visual">
      {opponentMekaImage && !mekaFailed ? (
        <img className="meka" data-asset-role="opponent-meka" data-source-aspect="16:9" data-rendered-crop="2.08:1 cover, center" src={opponentMekaImage} alt={meka.id + " " + meka.codename} onError={() => setMekaFailed(true)} />
      ) : <div className="claude-founding-opponent-media-fallback" data-asset-role="opponent-meka" role="img" aria-label={(meka.id || "Opponent Meka") + " visual data pending"}><span>VISUAL DATA PENDING</span><b>{meka.id || "OPPONENT MEKA"}</b></div>}
      <div className="claude-founding-challenger-badge">
        <div className="claude-founding-crest">{opponent.crestUrl ? <img data-asset-role="organization-crest" data-source-aspect="1:1" data-rendered-crop="1:1 contain" src={opponent.crestUrl} alt={opponent.organizationName + " crest"} /> : <b>{opponentMonogram}</b>}</div>
        <span>CHALLENGER<b>{opponent.organizationName}</b></span>
      </div>
      <figcaption className="claude-founding-unit-label"><span>CHALLENGE TARGET</span><b>{meka.id} / {meka.codename}</b></figcaption>
      <div className="claude-founding-pilot-badge">
        {opponentPilotImage && !pilotFailed ? (
          <img data-asset-role="opponent-pilot-face" data-source-aspect="1:1" data-rendered-crop="1:1 cover, center" src={opponentPilotImage} alt={pilot.callsign + " Pilot portrait"} onError={() => setPilotFailed(true)} />
        ) : <div className="claude-founding-pilot-fallback" data-asset-role="opponent-pilot-face" role="img" aria-label={(pilot.callsign || "Opponent Pilot") + " visual data pending"}>VISUAL DATA PENDING</div>}
        <span>OPPONENT PILOT<b>{pilot.callsign}</b></span>
      </div>
    </figure>
  );
}

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 deriveChallengeChannelState({ foundingJourneyStatus, battleArenaStatus, now = new Date().toISOString() } = {}) {
  const foundingStatus = foundingJourneyStatus && foundingJourneyStatus.status
    ? foundingJourneyStatus.status
    : "idle";
  const arenaStatus = battleArenaStatus && battleArenaStatus.status
    ? battleArenaStatus.status
    : "idle";
  if (foundingStatus !== "ready") {
    const foundingError = foundingJourneyStatus && foundingJourneyStatus.error ? foundingJourneyStatus.error : "";
    const kind = foundingStatus === "loading" || foundingStatus === "idle"
      ? "syncing"
      : foundingStatus === "offline"
        ? "offline"
        : foundingStatus === "locked"
          ? "locked"
          : "unavailable";
    return {
      kind,
      active: null,
      awaitingCount: 0,
      overflowCount: 0,
      officialInvites: [],
      officialDeployments: [],
      error: foundingError
    };
  }
  const journey = foundingStatus === "ready"
    ? foundingJourneyStatus.data || null
    : null;
  const officialBattles = arenaStatus === "ready" && Array.isArray(battleArenaStatus && battleArenaStatus.battles)
    ? battleArenaStatus.battles
    : [];
  const incomingOfficialBattles = officialBattles.length
    ? battleArenaStatus.battles
      .filter((battle) => {
        if (!battle || battle.status !== "invited" || battle.viewerSide !== "defender") return false;
        const expiresAtMs = Date.parse(battle.expiresAt || "");
        const nowMs = Date.parse(now || "");
        return !Number.isFinite(expiresAtMs) || !Number.isFinite(nowMs) || expiresAtMs > nowMs;
      })
      .sort((left, right) => {
        const leftExpiry = Date.parse(left.expiresAt || "");
        const rightExpiry = Date.parse(right.expiresAt || "");
        const safeLeft = Number.isFinite(leftExpiry) ? leftExpiry : Number.POSITIVE_INFINITY;
        const safeRight = Number.isFinite(rightExpiry) ? rightExpiry : Number.POSITIVE_INFINITY;
        return safeLeft - safeRight;
      })
    : [];
  const officialDeployments = officialBattles.filter((battle) => (
    battle &&
    battle.status === "selection_pending" &&
    battle.viewerSide === "defender" &&
    !(battle.defender && battle.defender.selectedMechId)
  ));
  const foundingDeployment = Boolean(journey && journey.stage === "deployment_assignment_required" && journey.challenge);
  const foundingChallenge = Boolean(journey && journey.stage === "challenge_received" && journey.challenge);
  const active = foundingChallenge
    ? journey.challenge
    : incomingOfficialBattles[0]
      ? incomingOfficialBattles[0]
      : foundingDeployment
        ? journey.challenge
        : officialDeployments[0] || null;
  const kind = foundingChallenge
    ? "founding_challenge"
    : incomingOfficialBattles[0]
        ? "official_invite"
        : foundingDeployment
          ? "founding_deployment"
          : officialDeployments[0]
            ? "official_deployment"
            : "";
  const foundingCount = foundingDeployment || foundingChallenge ? 1 : 0;
  const awaitingCount = foundingCount + incomingOfficialBattles.length + officialDeployments.length;
  if (kind) {
    return {
      kind,
      active,
      awaitingCount,
      overflowCount: Math.max(0, awaitingCount - 1),
      officialInvites: incomingOfficialBattles,
      officialDeployments
    };
  }

  const foundingError = foundingJourneyStatus && foundingJourneyStatus.error ? foundingJourneyStatus.error : "";
  const arenaError = battleArenaStatus && battleArenaStatus.error ? battleArenaStatus.error : "";
  const unavailable = foundingStatus === "error" || arenaStatus === "error";
  const offline = foundingStatus === "offline" || arenaStatus === "offline";
  const locked = foundingStatus === "locked" || arenaStatus === "locked";
  const syncing = [foundingStatus, arenaStatus].some((status) => status === "idle" || status === "loading");
  const authoritative = foundingStatus === "ready" && arenaStatus === "ready";
  return {
    kind: unavailable ? "unavailable" : offline ? "offline" : locked ? "locked" : syncing ? "syncing" : authoritative ? "empty" : "unavailable",
    active: null,
    awaitingCount: 0,
    overflowCount: 0,
    officialInvites: [],
    officialDeployments: [],
    error: foundingError || arenaError
  };
}

async function performChallengeChannelPrimaryAction({ channel, onAcceptBattle, onOpenFoundingJourney } = {}) {
  if (!channel || !channel.active) return null;
  if (channel.kind === "official_invite") {
    if (typeof onAcceptBattle !== "function") throw new Error("OFFICIAL CHALLENGE ACCEPT IS UNAVAILABLE");
    return onAcceptBattle(channel.active.id);
  }
  if (channel.kind === "founding_challenge" || channel.kind === "founding_deployment") {
    if (typeof onOpenFoundingJourney !== "function") throw new Error("FOUNDING JOURNEY IS UNAVAILABLE");
    await onOpenFoundingJourney(channel.kind === "founding_deployment" ? "assignment" : "challenge");
    return channel.active;
  }
  return null;
}

function ChallengeChannelCard({ battleArenaStatus, foundingJourneyStatus, onOpenFoundingJourney, onAcceptBattle, onRetry }) {
  const channel = deriveChallengeChannelState({ foundingJourneyStatus, battleArenaStatus });
  const [localError, setLocalError] = useState("");
  const actionBusy = Boolean(battleArenaStatus && battleArenaStatus.actionBusy);

  async function handleOfficialAccept() {
    setLocalError("");
    try {
      await performChallengeChannelPrimaryAction({ channel, onAcceptBattle, onOpenFoundingJourney });
    } catch (error) {
      setLocalError((error && error.message ? error.message : "CHALLENGE ACCEPT FAILED").toUpperCase());
    }
  }

  function handleFoundingPrimary() {
    setLocalError("");
    try {
      performChallengeChannelPrimaryAction({ channel, onAcceptBattle, onOpenFoundingJourney });
    } catch (error) {
      setLocalError((error && error.message ? error.message : "FOUNDING JOURNEY UNAVAILABLE").toUpperCase());
    }
  }

  async function retryChannelSync() {
    setLocalError("");
    if (typeof onRetry !== "function") return;
    try {
      await onRetry();
    } catch (error) {
      setLocalError((error && error.message ? error.message : "CHALLENGE CHANNEL SYNC FAILED").toUpperCase());
    }
  }

  if (["syncing", "unavailable", "locked", "offline"].includes(channel.kind)) {
    const stateCopy = channel.kind === "syncing"
      ? { signal: "Challenge Channel / Sync", title: "CHANNEL SYNCING", copy: "Checking Founding directives and official battle signals." }
      : channel.kind === "locked"
        ? { signal: "Challenge Channel / Locked", title: "CHANNEL LOCKED", copy: "Complete the current operator directives to unlock official battle commands." }
        : channel.kind === "offline"
          ? { signal: "Challenge Channel / Offline", title: "CHANNEL OFFLINE", copy: "The Archive link is offline. Reconnect the local API, then retry synchronization." }
          : { signal: "Challenge Channel / Unavailable", title: "CHANNEL UNAVAILABLE", copy: channel.error || "Challenge data could not be synchronized." };
    return (
      <aside className={"challenge-channel-card is-state is-" + channel.kind} aria-label="Challenge Channel" aria-live="polite" aria-busy={channel.kind === "syncing" ? "true" : undefined}>
        <div className="challenge-channel-state-signal" aria-hidden="true"><i></i><i></i><i></i></div>
        <div className="challenge-channel-state-copy">
          <span>{stateCopy.signal}</span>
          <h3>{stateCopy.title}</h3>
          <p>{stateCopy.copy}</p>
          {localError && <em role="alert">{localError}</em>}
        </div>
        {(channel.kind === "unavailable" || channel.kind === "offline") && (
          <div className="challenge-channel-state-actions">
            <button type="button" className="btn primary" onClick={retryChannelSync}>RETRY SYNC</button>
          </div>
        )}
      </aside>
    );
  }

  if (channel.kind === "empty") {
    return (
      <aside className="challenge-channel-card is-empty" aria-label="Challenge Channel">
        <div className="challenge-channel-empty-signal" aria-hidden="true"><i></i><i></i><i></i></div>
        <div className="challenge-channel-empty-copy">
          <span>Challenge Channel / Standby</span>
          <h3>CHALLENGE CHANNEL CLEAR</h3>
          <p>No one is waiting for your response.</p>
        </div>
        <div className="challenge-channel-empty-actions">
          <b>00 AWAITING RESPONSE</b>
        </div>
      </aside>
    );
  }

  const isFounding = channel.kind === "founding_challenge" || channel.kind === "founding_deployment";
  const challenge = isFounding ? channel.active : null;
  const battle = !isFounding ? channel.active : null;
  const officialOpponent = battle ? getBattleArenaOpponent(battle) : null;
  const opponentOrganization = isFounding
    ? null
    : officialOpponent && officialOpponent.organization ? officialOpponent.organization : null;
  const opponentName = isFounding
    ? challenge.opponent.organizationName
    : getBattleArenaParticipantLabel(officialOpponent, "Opponent pending");
  const opponentMech = isFounding
    ? findMechById(challenge.opponent.meka.id)
    : officialOpponent && officialOpponent.selectedMechId
      ? findMechById(officialOpponent.selectedMechId)
      : null;
  const opponentPilot = isFounding
    ? challenge.opponent.pilot
    : opponentMech && opponentMech.pilot ? opponentMech.pilot : null;
  const opponentPilotImage = opponentMech
    ? getFoundingJourneyPilotFaceSource(opponentMech.id, "")
    : "";
  const opponentPilotCinematicImage = opponentMech?.pilotImage || opponentPilot?.cinematicImage || opponentPilot?.selectImage || opponentPilot?.image || opponentPilotImage;
  const opponentMekaIllustration = opponentMech?.fullbody || opponentMech?.image || "";
  const crestSource = isFounding
    ? challenge.opponent.crestUrl || ""
    : getOrganizationPreviewSource(opponentOrganization);
  const monogram = String(opponentName || "ORG")
    .split(/\s+/)
    .filter(Boolean)
    .map((word) => word[0])
    .join("")
    .slice(0, 3)
    .toUpperCase();
  const arena = isFounding ? challenge.arena || null : battle.arena || null;
  const formatLabel = isFounding ? "FOUNDING TRAINING" : "OFFICIAL CHALLENGE";
  const stakesLabel = isFounding ? "NO RANKED STAKES" : "BATTLE RECORD";
  const primaryLabel = channel.kind === "founding_deployment"
    ? "ASSIGN CREW"
    : channel.kind === "official_deployment"
      ? "LOCK MEKA"
      : "ACCEPT CHALLENGE";
  const detailHref = isFounding ? "#hangar" : battleArenaBattleHref(battle);
  const queuedOfficialInvites = (channel.officialInvites || [])
    .filter((item) => !battle || item.id !== battle.id)
    .map((item) => {
      const participant = getBattleArenaOpponent(item);
      const organizationName = getBattleArenaParticipantLabel(participant, "Opponent pending");
      const mech = participant?.selectedMechId ? findMechById(participant.selectedMechId) : null;
      return {
        id: item.id,
        kind: "official_invite",
        eyebrow: "OFFICIAL",
        title: organizationName,
        detail: mech ? mech.id + " / " + mech.codename : "UNIT CONFIDENTIAL",
        href: battleArenaBattleHref(item),
      };
    });
  const queueItems = [{
    id: channel.active?.id || channel.kind,
    kind: channel.kind,
    eyebrow: isFounding ? "TRAINING" : "PRIORITY",
    title: opponentMech ? opponentMech.codename : opponentName,
    detail: (arena?.name || formatLabel) + (opponentPilot?.callsign ? " · " + opponentPilot.callsign : ""),
    href: detailHref,
    active: true,
  }, ...queuedOfficialInvites].slice(0, 2);
  const queueCount = Math.max(channel.awaitingCount || 0, queueItems.length);
  const showChallengeQueue = queueItems.length > 1;

  async function handleQueueAction(item) {
    if (item.active) {
      if (channel.kind === "official_invite") await handleOfficialAccept();
      else if (isFounding) handleFoundingPrimary();
      return;
    }
    if (item.kind !== "official_invite" || typeof onAcceptBattle !== "function") return;
    setLocalError("");
    try {
      await onAcceptBattle(item.id);
    } catch (error) {
      setLocalError((error?.message || "CHALLENGE ACCEPT FAILED").toUpperCase());
    }
  }

  return (
    <aside className={"challenge-channel-card is-active is-" + channel.kind.replace(/_/g, "-") + (!showChallengeQueue ? " is-single-challenge" : "")} aria-label="Challenge Channel">
      <figure className="challenge-channel-cinematic-pilot challenge-channel-target">
        {opponentPilotCinematicImage
          ? <img data-asset-role="opponent-pilot-cinematic" src={opponentPilotCinematicImage} alt={(opponentPilot?.callsign || opponentName) + " challenger Pilot"} />
          : <div className="challenge-channel-asset-unavailable">PILOT FACE UNAVAILABLE</div>}
        <figcaption>{opponentPilot?.callsign || "CHALLENGER"}</figcaption>
      </figure>
      <section className="challenge-channel-command challenge-channel-brief" aria-label="Priority challenge brief">
        <span className="challenge-channel-command-kicker">ϟ ADVENTURE CAMPAIGN · NEW TRANSMISSION</span>
        <h3><span>{opponentName}</span><em>CHALLENGES YOU</em></h3>
        <div className="challenge-channel-command-identity">
          {opponentPilotImage
            ? <img src={opponentPilotImage} alt="" aria-hidden="true" />
            : crestSource
              ? <img src={crestSource} alt="" aria-hidden="true" />
              : <b aria-hidden="true">{monogram}</b>}
          <p>{opponentPilot?.callsign || "PILOT PENDING"} · {opponentPilot?.person || opponentName} · FIELDS {opponentMech ? opponentMech.id + " " + opponentMech.codename : "UNIT CONFIDENTIAL"}</p>
        </div>
        <div className="challenge-channel-actions">
          {channel.kind === "official_invite" ? (
            <button type="button" className="btn primary" onClick={handleOfficialAccept} disabled={actionBusy}>{actionBusy ? "ACCEPTING..." : primaryLabel}</button>
          ) : channel.kind === "official_deployment" ? (
            <a className="btn primary" href={detailHref}>{primaryLabel}</a>
          ) : (
            <button type="button" className="btn primary" onClick={handleFoundingPrimary}>{primaryLabel}</button>
          )}
          <span>REWARD · {opponentMech ? opponentMech.id + " IMPRINT DATA" : stakesLabel}</span>
        </div>
        {(localError || battleArenaStatus?.error) && <div className="challenge-channel-action-error" role="alert">{localError || battleArenaStatus.error}</div>}
      </section>
      {showChallengeQueue && <section className="challenge-channel-queue" aria-label="Challenge queue">
        {opponentMekaIllustration
          ? <img className="challenge-channel-queue-art" data-asset-role="opponent-meka-illustration" src={opponentMekaIllustration} alt="" aria-hidden="true" />
          : <div className="challenge-channel-queue-art is-pending" aria-hidden="true">MEKA VISUAL PENDING</div>}
        <div className="challenge-channel-queue-content">
          <header><span>CHALLENGE QUEUE</span><b>{String(queueCount).padStart(2, "0")} PENDING</b></header>
          <div className="challenge-channel-queue-list">{queueItems.map((item) => (
            <article key={item.kind + ":" + item.id} className={item.active ? "is-active" : ""}>
              <span>{item.eyebrow}</span>
              <div><b>{item.title}</b><small>{item.detail}</small></div>
              {item.kind === "official_deployment"
                ? <a href={item.href}>OPEN</a>
                : <button type="button" onClick={() => handleQueueAction(item)} disabled={actionBusy}>{item.active ? primaryLabel.replace(" CHALLENGE", "") : "ACCEPT"}</button>}
            </article>
          ))}</div>
        </div>
      </section>}
    </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 RegistryClaimCeremonyGate({ claim, account, assistantIntro, assistantIntroStatus = "ready", onClose, onOpenCertificate, onViewHangar, onContinueArchive }) {
  const ownership = claim && claim.ownership;
  const starterCeremony = Boolean(claim && claim.ceremonyMode === "starter" || ownership && ownership.ownershipClass === "starter");
  const assistantStateLoading = ["idle", "loading", "checking"].includes(String(assistantIntroStatus || "").toLowerCase());
  const assistantFullscreenActive = Boolean(assistantIntro && assistantIntro.ready && !assistantIntro.finished);
  if (!claim || starterCeremony && (assistantStateLoading || assistantFullscreenActive)) return null;
  return <RegistryClaimCeremony claim={claim} account={account} onClose={onClose} onOpenCertificate={onOpenCertificate} onViewHangar={onViewHangar} onContinueArchive={onContinueArchive} />;
}

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 archiveDispatchHasPublicEntries(archiveDispatchStatus) {
  const { dispatch, entries } = getArchiveDispatchBundle(archiveDispatchStatus);
  return Boolean(dispatch && entries.length);
}

function ArchiveSection({ onOpen, engagement, engagementDispatch, account, registry, archiveDispatchStatus, onClaimComplete, 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} onClaimComplete={onClaimComplete} onDispatchDirectiveCompleted={onDispatchDirectiveCompleted} />}

        <section id="founding-starter-archive" 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 getOrganizationDossierRoster(entry, archiveDispatchStatus, isMine) {
  if (!entry || !entry.organization) return [];
  const starterMechId = String(entry.starterMechId || entry.organization.starterMechId || "").trim().toUpperCase();
  const ownedMechIds = Array.isArray(entry.ownedMechIds) ? entry.ownedMechIds : [];
  const rosterIds = [starterMechId, ...ownedMechIds]
    .map((id) => String(id || "").trim().toUpperCase())
    .filter((id, index, list) => id && list.indexOf(id) === index);
  const ownerships = isMine && Array.isArray(archiveDispatchStatus && archiveDispatchStatus.ownerships)
    ? archiveDispatchStatus.ownerships
    : [];

  return rosterIds.map((mechId) => {
    const mech = findMechById(mechId);
    if (!mech) return null;
    const isStarter = mechId === starterMechId;
    const ownership = isStarter
      ? null
      : ownerships.find((candidate) => candidate && String(candidate.mechId || "").toUpperCase() === mechId) || null;
    return {
      mech,
      sourceType: isStarter ? "founding" : "archive_dispatch",
      sourceLabel: isStarter ? "FOUNDING CLAIM" : "ARCHIVE DISPATCH",
      pilotFace: getFoundingJourneyPilotFaceSource(mechId, ""),
      ownershipSerial: ownership && ownership.ownershipSerial ? ownership.ownershipSerial : "",
      claimedAt: ownership && ownership.claimedAt ? ownership.claimedAt : ""
    };
  }).filter(Boolean);
}

function OrganizationDossier({ organizationId, registry, account, archiveDispatchStatus, 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";
  const roster = getOrganizationDossierRoster(entry, archiveDispatchStatus, isMine);
  const rosterIdentity = roster.map((record) => record.mech.id).join("|");
  const [selectedMechId, setSelectedMechId] = useState(() => roster[0] ? roster[0].mech.id : "");
  const rosterStripRef = useRef(null);

  useEffect(() => {
    setSelectedMechId((current) => roster.some((record) => record.mech.id === current)
      ? current
      : roster[0] ? roster[0].mech.id : "");
  }, [organizationId, rosterIdentity]);

  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]);

  const selectedIndex = Math.max(0, roster.findIndex((record) => record.mech.id === selectedMechId));
  const selectedRecord = roster[selectedIndex] || null;
  const dispatchCount = roster.filter((record) => record.sourceType === "archive_dispatch").length;

  function selectRosterRecord(nextIndex) {
    if (!roster.length) return;
    const boundedIndex = Math.max(0, Math.min(roster.length - 1, nextIndex));
    const nextRecord = roster[boundedIndex];
    setSelectedMechId(nextRecord.mech.id);
    window.requestAnimationFrame(() => {
      const options = rosterStripRef.current ? rosterStripRef.current.querySelectorAll('[role="option"]') : [];
      const option = options[boundedIndex];
      if (option && typeof option.scrollIntoView === "function") option.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
    });
  }

  function handleRosterKeyDown(event) {
    let nextIndex = selectedIndex;
    if (event.key === "ArrowRight" || event.key === "ArrowDown") nextIndex += 1;
    else if (event.key === "ArrowLeft" || event.key === "ArrowUp") nextIndex -= 1;
    else if (event.key === "Home") nextIndex = 0;
    else if (event.key === "End") nextIndex = roster.length - 1;
    else return;
    event.preventDefault();
    selectRosterRecord(nextIndex);
    const options = rosterStripRef.current ? rosterStripRef.current.querySelectorAll('[role="option"]') : [];
    if (options[Math.max(0, Math.min(roster.length - 1, nextIndex))]) options[Math.max(0, Math.min(roster.length - 1, nextIndex))].focus();
  }

  if (!organization) {
    return (
      <div className="detail registry-dossier-shell" data-screen="registry-details" data-screen-label="Operator Dossier">
        <nav className="registry-dossier-nav">
          <button type="button" onClick={onClose}>◂ BACK TO REGISTRY</button>
          <span>OPERATOR DOSSIER</span>
          <b className="is-error">{registry.status === "loading" ? "SYNCING" : "NOT FOUND"}</b>
        </nav>
        <div className="registry-dossier-state">
          <span>ORGANIZATION REGISTRY</span>
          <h2>Operator Not Found</h2>
          <p>The requested organization dossier is not available in the current registry snapshot.</p>
        </div>
      </div>
    );
  }

  return (
    <div className="detail registry-dossier-shell" data-screen="registry-details" data-organization-id={organization.id} data-roster-count={roster.length} data-screen-label={"Operator Dossier · " + organization.name}>
      <nav className="registry-dossier-nav">
        <button type="button" onClick={onClose}>◂ BACK TO REGISTRY</button>
        <span>OPERATOR DOSSIER</span>
        <b>{isMine ? "YOUR ORGANIZATION" : "REGISTERED OPERATOR"}</b>
      </nav>

      <div className="registry-dossier-scroll">
        <header className="registry-dossier-identity">
          <span className="registry-dossier-watermark" aria-hidden="true">DOSSIER</span>
          <div className="registry-dossier-crest" data-asset-role="organization-crest">
            <img src={getOrganizationPreviewSource(organization)} alt={organization.name + " crest"} />
          </div>
          <div className="registry-dossier-identity-copy">
            <h1>{organization.name}</h1>
            <p>“{getOrganizationMottoText(organization)}”</p>
            <div className="registry-dossier-identity-meta">
              <span>CALLSIGN <b>{organization.callsign || "PENDING"}</b></span>
              <span><b className="is-active">{String(entry.status || "registered").toUpperCase()} REGISTRATION</b></span>
              <span>FOUNDED <b>{getOrganizationFoundedLabel(organization)}</b></span>
            </div>
            <div className="registry-dossier-founding-badge">FOUNDING MEKA · <b>{starter ? starter.id + " / " + starter.codename : "PENDING ASSIGNMENT"}</b></div>
          </div>
          <div className="registry-dossier-own-summary">
            <b>{String(roster.length).padStart(2, "0")} LICENSED UNITS</b>
            <span>{starter ? "01 FOUNDING" : "STARTER PENDING"}</span>
            <span className={dispatchCount ? "has-dispatch" : ""}>{dispatchCount ? String(dispatchCount).padStart(2, "0") + " ARCHIVE DISPATCH" : "NO ARCHIVE DISPATCH UNITS CLAIMED"}</span>
          </div>
        </header>

        <div className="registry-dossier-section-heading"><b>02</b> OPERATOR RECORD <span></span> <b>03</b> PUBLIC DOCTRINE &amp; LORE</div>
        <section className="registry-dossier-lower-grid">
          <div className="registry-dossier-operator-record">
            <div className="registry-dossier-kv-list">
              <div><span>PUBLIC OWNER</span><b>{entry.owner ? "@" + String(entry.owner.username || "UNKNOWN").replace(/^@/, "") : "UNKNOWN"}</b></div>
              <div><span>CALLSIGN</span><b>{organization.callsign || "PENDING"}</b></div>
              <div><span>FOUNDED</span><b>{getOrganizationFoundedLabel(organization)}</b></div>
              <div><span>LOGO GENERATION</span><b>{String(organization.logoStatus || "local-draft").toUpperCase()}</b></div>
              <div><span>REGISTRATION</span><b>{String(entry.status || "registered").toUpperCase()}</b></div>
            </div>
            <div className="registry-dossier-assistant organization-assistant-card">
              <div className="registry-dossier-assistant-avatar" data-asset-role="virtual-assistant">
                <img src={getAssistantAvatarSource(organization)} alt={assistantName + " virtual assistant"} loading="lazy" />
              </div>
              <div>
                <span>VIRTUAL ASSISTANT</span>
                <h3>{assistantName}</h3>
                <p>“{lore.assistantLine}”</p>
                <b>{assistantAvatarStatus === "generated" ? "COMMAND CHANNEL ONLINE" : "AVATAR " + assistantAvatarStatus.toUpperCase()}</b>
              </div>
            </div>
            <div className="registry-dossier-ownership">
              <span>OWNERSHIP</span>
              <b>{isMine ? "OWNED BY YOU" : "PUBLIC OPERATOR"}</b>
              <p>
                {isMine
                  ? "This organization is linked to your account. Its complete licensed roster includes the Founding unit and every Archive Dispatch claim on file."
                  : "This organization appears in the public registry. Its complete licensed roster includes the Founding unit and every Archive Dispatch claim on file."}
              </p>
            </div>
          </div>
          <div className="registry-dossier-lore">
            <span>OPERATOR LORE</span>
            <h2>{lore.title}</h2>
            <p>{lore.summary}</p>
            <ol>
              {lore.doctrineLines.map((line, index) => (
                <li key={line}><b>{String(index + 1).padStart(2, "0")}</b><span>{line}</span></li>
              ))}
            </ol>
          </div>
        </section>

        <div className="registry-dossier-section-heading"><b>04</b> LICENSED ROSTER <span className="registry-dossier-roster-count">{roster.length ? String(roster.length).padStart(2, "0") + " UNITS ON FILE" : "PENDING ASSIGNMENT"}</span></div>
        <div className="registry-dossier-roster-nav">
          <button type="button" aria-label="Previous units" onClick={() => selectRosterRecord(selectedIndex - 1)}>◂</button>
          <div className="registry-dossier-roster-strip" ref={rosterStripRef} role="listbox" aria-label="Licensed Meka roster" tabIndex={0} onKeyDown={handleRosterKeyDown}>
            {roster.length ? roster.map((record, index) => {
              const selected = record.mech.id === (selectedRecord && selectedRecord.mech.id);
              return (
                <button
                  type="button"
                  className={selected ? "is-selected" : ""}
                  role="option"
                  aria-selected={selected}
                  tabIndex={selected ? 0 : -1}
                  data-owned-mech-id={record.mech.id}
                  data-ownership-source={record.sourceType}
                  key={record.mech.id}
                  onClick={() => selectRosterRecord(index)}
                  onKeyDown={handleRosterKeyDown}
                >
                  <span className="registry-dossier-roster-state">{selected ? "SELECTED" : "OWNED"}</span>
                  <span className="registry-dossier-roster-thumb"><HangarPreviewImage mech={record.mech} alt={record.mech.codename + " roster preview"} /></span>
                  <span className="registry-dossier-roster-copy">
                    <em>{record.sourceType === "founding" ? "FOUNDING UNIT" : "ARCHIVE DISPATCH"}</em>
                    <b>{record.mech.codename}</b>
                    <small>{record.mech.id} · PILOT {record.mech.pilot ? record.mech.pilot.callsign : "UNASSIGNED"}</small>
                  </span>
                </button>
              );
            }) : (
              <div className="registry-dossier-roster-empty"><b>NO STARTER UNIT ASSIGNED</b><p>This organization is registered, but no valid licensed unit record is available.</p></div>
            )}
          </div>
          <button type="button" aria-label="Next units" onClick={() => selectRosterRecord(selectedIndex + 1)}>▸</button>
        </div>

        {selectedRecord ? (
          <section className="registry-dossier-feature" data-selected-mech-id={selectedRecord.mech.id}>
            <figure className="registry-dossier-feature-stage">
              <div className="registry-dossier-stage-art" data-asset-role="roster-meka">
                <HangarPreviewImage mech={selectedRecord.mech} alt={selectedRecord.mech.codename + " roster art"} />
              </div>
              <figcaption>
                <span>{selectedRecord.sourceType === "founding" ? "FOUNDING UNIT · OWNED FRAME · ORGANIZATION STARTER" : "ARCHIVE DISPATCH"}</span>
                <b>{selectedRecord.mech.id} / {selectedRecord.mech.codename}</b>
              </figcaption>
            </figure>
            <div className="registry-dossier-unit-record">
              <div className="registry-dossier-pilot">
                <div className="registry-dossier-pilot-face" data-asset-role="roster-pilot-face">
                  {selectedRecord.pilotFace
                    ? <img src={selectedRecord.pilotFace} alt={(selectedRecord.mech.pilot ? selectedRecord.mech.pilot.callsign : "Assigned Pilot") + " face"} loading="eager" decoding="async" />
                    : <span>CANONICAL PILOT FACE UNAVAILABLE</span>}
                </div>
                <div><span>ATTACHED PILOT</span><b>{selectedRecord.mech.pilot ? selectedRecord.mech.pilot.callsign : "UNASSIGNED"}</b></div>
              </div>
              <div className="registry-dossier-kv-list is-unit">
                <div><span>DESIGNATION</span><b>{selectedRecord.mech.id}</b></div>
                <div><span>CODENAME</span><b>{selectedRecord.mech.codename}</b></div>
              </div>
              <p className="registry-dossier-unit-brief">{selectedRecord.mech.brief}</p>
              <div className="registry-dossier-source">
                <span>OWNERSHIP SOURCE</span>
                <b>{selectedRecord.sourceLabel}</b>
                {selectedRecord.ownershipSerial && <small>{selectedRecord.ownershipSerial}{selectedRecord.claimedAt ? " · CLAIMED " + new Date(selectedRecord.claimedAt).toLocaleDateString() : ""}</small>}
              </div>
              <button type="button" className="registry-dossier-open" data-cta="open-meka-dossier" onClick={() => onOpenMech(selectedRecord.mech.id)}>
                {selectedRecord.sourceType === "founding" ? "OPEN STARTER MEKA" : "OPEN MEKA DOSSIER"}
              </button>
            </div>
          </section>
        ) : null}
      </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, direction = 1) {
  const starterRoster = candidateMechs && candidateMechs.length ? candidateMechs : MEKABOTS_BY_ID;
  const currentIndex = Math.max(0, starterRoster.findIndex((mech) => mech.id === currentId));
  const step = direction < 0 ? -1 : 1;
  for (let offset = 1; offset <= starterRoster.length; offset += 1) {
    const index = (currentIndex + step * offset + starterRoster.length) % starterRoster.length;
    const mech = starterRoster[index];
    if (!getStarterClaimAvailability(mech.id, registry, accountOrganization).blocked) return mech.id;
  }
  return 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,
  registry,
  accountOrganization,
  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 nextAvailableId = findNextAvailableStarterId(activeMech && activeMech.id, registry, accountOrganization, STARTER_PREVIEW_ROSTER);
  const adjacentDisabled = Boolean(disabled || !nextAvailableId || nextAvailableId === (activeMech && 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 (disabled || !nextId || !onSelectStarter) return;
    onSelectStarter(nextId);
  }

  function selectAvailableStarter(direction) {
    if (adjacentDisabled) return;
    selectStarter(findNextAvailableStarterId(activeMech && activeMech.id, registry, accountOrganization, STARTER_PREVIEW_ROSTER, direction));
  }

  function handleSelectionKeyDown(event) {
    const isPreviousKey = event.key === "ArrowLeft";
    const isNextKey = event.key === "ArrowRight";
    if (!isPreviousKey && !isNextKey) return;
    event.preventDefault();
    const direction = isPreviousKey ? -1 : 1;
    selectAvailableStarter(direction);
  }

  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} onSelectAdjacent={selectAvailableStarter} adjacentDisabled={adjacentDisabled} />
        <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={adjacentDisabled}>
                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}
          registry={registry}
          accountOrganization={accountOrganization}
          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: String(start.label || (start.targetType === "assistant_avatar" ? "GENERATE ASSISTANT AVATAR" : "GENERATE FOUNDING CREST")).toUpperCase()
  };
  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;
  const onboarding = onboardingStatus && onboardingStatus.data;
  const localRuntime = location.hostname === "localhost" || location.hostname === "127.0.0.1";
  const assistantIntroPending = Boolean(onboarding && onboarding.assistantIntro && onboarding.assistantIntro.ready && !onboarding.assistantIntro.finished);
  if (assistantIntroPending) return true;
  const organization = getAccountOrganization(account) || (onboarding && onboarding.organization) || null;
  const localDeterministicIdentityAvailable = Boolean(
    localRuntime &&
    organization &&
    getOrganizationPreviewSource(organization) &&
    getAssistantAvatarSource(organization)
  );
  if (localDeterministicIdentityAvailable || (localRuntime && onboarding && onboarding.assistantIntro && onboarding.assistantIntro.finished)) return false;
  if (onboardingStatus && (onboardingStatus.status === "idle" || onboardingStatus.status === "loading" || onboardingStatus.status === "error")) return true;
  if (!onboarding) return false;
  return onboarding.phase !== "complete";
}

function CommandDialogueSequence({
  id,
  ariaLabel,
  className = "",
  lines,
  stepIndex,
  assistantName,
  avatarSource,
  busy,
  primaryLabel,
  onAdvance,
  error = "",
  skipLabel = "",
  onSkip
}) {
  const activeLine = lines[stepIndex] || lines[0];
  const activeStep = String(stepIndex + 1);
  const totalSteps = String(lines.length);
  const briefingProgress = Math.max(0, Math.min(100, ((stepIndex + 1) / Math.max(lines.length, 1)) * 100));
  const isComplete = stepIndex >= lines.length - 1;

  function handlePrimary(event) {
    event.stopPropagation();
    if (!busy) onAdvance();
  }

  function handleSkip(event) {
    event.stopPropagation();
    if (!busy && onSkip) onSkip();
  }

  function handleKeyDown(event) {
    if (event.key === "Escape" && onSkip) {
      event.preventDefault();
      if (!busy) onSkip();
      return;
    }
    if (event.key === "Enter" || event.key === " " || event.key === "ArrowRight") {
      event.preventDefault();
      if (!busy) onAdvance();
    }
  }

  return (
    <section
      id={id}
      className={"assistant-fullscreen-briefing" + (className ? " " + className : "")}
      aria-label={ariaLabel}
      aria-modal="true"
      role="dialog"
      data-complete={String(isComplete)}
      tabIndex={0}
      onKeyDown={handleKeyDown}
    >
      <header className="assistant-fullscreen-briefing__header">
        <div className="assistant-fullscreen-briefing__eyebrow">COMMAND BRIEFING · {assistantName}</div>
        {skipLabel && (
          <button type="button" className="assistant-fullscreen-briefing__skip assistant-intro-skip-link" onClick={handleSkip} disabled={Boolean(busy)}>
            {skipLabel} ×
          </button>
        )}
      </header>

      <div
        className="assistant-fullscreen-briefing__stage"
        tabIndex={0}
        aria-label="Advance command briefing"
        onClick={() => { if (!busy) onAdvance(); }}
      >
        {avatarSource
          ? <img className="assistant-fullscreen-briefing__portrait" src={avatarSource} alt={assistantName + " virtual assistant portrait"} loading="eager" decoding="async" />
          : <div className="assistant-fullscreen-briefing__portrait assistant-avatar-loading"><i></i><i></i><i></i><b>AVATAR READY</b></div>}
        <div className="assistant-fullscreen-briefing__portrait-vignette" aria-hidden="true"></div>

        <article className="assistant-fullscreen-dialogue" aria-live="polite" style={{ "--briefing-progress": briefingProgress + "%" }}>
          <div className="assistant-fullscreen-dialogue__meta">
            <div className="assistant-fullscreen-dialogue__speaker">{assistantName}</div>
            <div className="assistant-fullscreen-dialogue__progress">
              <span data-step>{activeStep}</span><span aria-hidden="true">/</span><span data-total>{totalSteps}</span>
            </div>
          </div>
          <div className="assistant-fullscreen-dialogue__body">
            <p className="assistant-fullscreen-dialogue__copy">{activeLine}</p>
            {error && (
              <div className="command-dialogue-error" role="alert">
                <b>SYNC INTERRUPTED</b>
                <span>{error} Use <strong>{primaryLabel}</strong> again to retry this step.</span>
              </div>
            )}
          </div>
        </article>
      </div>

      <footer className="assistant-fullscreen-briefing__footer">
        <button type="button" className="assistant-fullscreen-briefing__continue assistant-intro-primary" onClick={handlePrimary} disabled={Boolean(busy)}>
          {busy ? "SYNCING..." : primaryLabel === "ENTER HANGAR" ? "ENTER HANGAR ▸" : "CLICK OR TAP TO ADVANCE ▸"}
        </button>
      </footer>
    </section>
  );
}

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 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 skipAssistantIntro() {
    syncAssistantIntro("skip", introStep);
  }

  return (
    <CommandDialogueSequence
      id="assistant-intro"
      ariaLabel="Virtual assistant introduction"
      lines={lines}
      stepIndex={introStep}
      assistantName={assistantName}
      avatarSource={avatarSource}
      busy={isBusy}
      primaryLabel={assistantIntroPrimaryLabel}
      onAdvance={advanceAssistantDialogue}
      skipLabel="SKIP INTRO"
      onSkip={skipAssistantIntro}
    />
  );
}

function getFoundingDeckBriefingDialogue(organization, foundingMech) {
  const organizationName = organization && organization.name ? organization.name : "Your organization";
  const foundingMekaLabel = foundingMech ? foundingMech.id + " / " + foundingMech.codename : "your Founding Meka";
  return [
    {
      line: "First deployment recorded. " + organizationName + " has now seen BOND//BREACH in motion. Let's lock the field principles before reviewing the battle record.",
      cta: "REVIEW FORMAT"
    },
    {
      line: "BOND//BREACH is the Archive's official tactical battle format. You command a 40-card deck made from Meka records, support units, and battle directives.",
      cta: "CONTINUE"
    },
    {
      line: "Your Pilot stays at the center of it. Pair them with a compatible MK to form a Bond and unlock that Meka's True Bond. Break through the opponent's Armor, then land one direct hit to finish the match.",
      cta: "CONTINUE"
    },
    {
      line: "Your first field package was built around " + foundingMekaLabel + ". The cards were tactical records; your licensed Mekas remained the machines you own. Next, review what that deployment recorded.",
      cta: "CONTINUE DEBRIEF"
    }
  ];
}

function shouldShowFoundingDeckBriefing(foundingJourneyStatus, suppressed, onboardingStatus) {
  const briefing = foundingJourneyStatus && foundingJourneyStatus.data && foundingJourneyStatus.data.briefing;
  const assistantIntro = onboardingStatus && onboardingStatus.data && onboardingStatus.data.assistantIntro;
  const assistantIntroActive = Boolean(assistantIntro && assistantIntro.ready && !assistantIntro.finished);
  return Boolean(
    !suppressed
    && !assistantIntroActive
    && foundingJourneyStatus.status === "ready"
    && foundingJourneyStatus.data.stage === "training_complete"
    && briefing
    && (briefing.status === "available" || briefing.status === "in_progress")
  );
}

function FoundingDeckBriefingSequence({ account, foundingMech, journeyStatus, onComplete }) {
  const organization = getAccountOrganization(account) || {};
  const briefing = journeyStatus && journeyStatus.data && journeyStatus.data.briefing ? journeyStatus.data.briefing : {};
  const dialogue = getFoundingDeckBriefingDialogue(organization, foundingMech);
  const persistedStep = Math.max(0, Math.min(dialogue.length, Number(briefing.step || 0)));
  const stepIndex = Math.max(0, persistedStep - 1);
  const busy = Boolean(journeyStatus && journeyStatus.actionBusy);
  const briefingRetry = journeyStatus && journeyStatus.briefingRetry;

  useEffect(() => {
    if (briefing.status !== "available" || persistedStep !== 0 || busy || briefingRetry) return;
    journeyStatus.recordFoundingDeckBriefing("seen", 1);
  }, [briefing.status, persistedStep, organization.id, busy, briefingRetry]);

  async function advanceFoundingDeckBriefing() {
    if (busy) return;
    if (briefingRetry) {
      const next = await journeyStatus.recordFoundingDeckBriefing(briefingRetry.action, briefingRetry.step);
      if (next && briefingRetry.action === "complete" && typeof onComplete === "function") onComplete(next);
      return;
    }
    if (stepIndex >= dialogue.length - 1) {
      const next = await journeyStatus.recordFoundingDeckBriefing("complete", dialogue.length);
      if (next && typeof onComplete === "function") onComplete(next);
      return;
    }
    await journeyStatus.recordFoundingDeckBriefing("advance", stepIndex + 2);
  }

  return (
    <CommandDialogueSequence
      id="founding-deck-briefing"
      ariaLabel="Post-game BOND//BREACH field lesson"
      className="founding-deck-briefing-sequence"
      lines={dialogue.map((item) => item.line)}
      stepIndex={stepIndex}
      assistantName={organization.assistantName || "MIRA"}
      avatarSource={getAssistantAvatarSource(organization)}
      busy={busy}
      primaryLabel={dialogue[stepIndex].cta}
      onAdvance={advanceFoundingDeckBriefing}
      error={journeyStatus && journeyStatus.error ? journeyStatus.error : ""}
    />
  );
}

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: "#founding-starter-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 = normalizeDirectiveTargetHref(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 getFoundingJourneyDirective(journey) {
  if (!journey || !journey.briefing) return null;
  if (journey.stage === "starter_deck_ready") {
    return {
      id: "open_founding_command_channel",
      status: "available",
      label: "Open Command Channel",
      title: "Challenge channel ready",
      copy: "Review the incoming challenge, choose one licensed Crew, and verify the issued Founding Package.",
      requiredAction: "open_founding_command_channel",
      targetHref: "#hangar",
      actionLabel: "OPEN FOUNDING JOURNEY",
      foundingJourneyView: "challenge"
    };
  }
  if (
    journey.stage === "training_complete"
    && (journey.briefing.status === "available" || journey.briefing.status === "in_progress")
  ) {
    return {
      id: "review_bond_breach_field_lesson",
      status: "available",
      label: "Review BOND//BREACH field lesson",
      title: "First deployment field lesson",
      copy: "Your first gameplay is recorded. Review the BOND//BREACH principles you just used before opening the battle acquisition debrief.",
      requiredAction: "review_bond_breach_field_lesson",
      targetHref: "#hangar",
      actionLabel: "OPEN FIELD LESSON"
    };
  }
  if (journey.stage === "starter_deck_acquired") {
    return {
      id: "receive_founding_challenge",
      status: "available",
      label: "Receive Founding challenge",
      title: "Challenge channel ready",
      copy: "Your historical Founding package remains registered. Continue through the current Challenge, Crew Selection, and Issuance Review sequence.",
      requiredAction: "receive_founding_challenge",
      targetHref: "#hangar",
      actionLabel: "VIEW CHALLENGE",
      foundingJourneyView: "challenge"
    };
  }
  if (journey.stage === "challenge_received") {
    return {
      id: "enter_official_battles",
      status: "available",
      label: "Enter official battles",
      title: "Incoming Challenge",
      copy: "A first official challenge is waiting. Review the opponent and assigned training arena before entering BOND//BREACH.",
      requiredAction: "view_founding_challenge",
      targetHref: "#hangar",
      actionLabel: "VIEW CHALLENGE",
      foundingJourneyView: "challenge"
    };
  }
  if (journey.stage === "deployment_assignment_required") {
    const crewCount = Array.isArray(journey.eligibleCrews) ? journey.eligibleCrews.length : 0;
    const countLabel = crewCount === 2 ? "Two" : String(crewCount || "Multiple");
    return {
      id: "assign_founding_deployment",
      status: "available",
      label: "Assign Founding deployment",
      title: "Deployment assignment required",
      copy: countLabel + " licensed crews are ready. Choose who will represent your organization in the Archive Training Grid.",
      requiredAction: "assign_founding_deployment",
      targetHref: "#hangar",
      actionLabel: "ASSIGN CREW",
      foundingJourneyView: "assignment"
    };
  }
  const materializationStage = ["challenge_accepted", "training_complete"].includes(journey.stage);
  if (materializationStage && journey.foundingDeckMaterialization?.status === "blocked") {
    return {
      id: "review_founding_deck_authority_repair",
      status: "blocked",
      label: "Review Deployment Package repair",
      title: "Deployment Package repair required",
      copy: "Your Crew selection is preserved, but Command could not verify the paired 40-card Deck. Battle remains locked until the package is repaired.",
      requiredAction: "review_founding_deck_authority_repair",
      targetHref: "#hangar",
      actionLabel: "VIEW REPAIR DETAILS",
      foundingJourneyView: "receipt"
    };
  }
  if (journey.stage === "training_complete" && journey.foundingDeckMaterialization?.status === "pending") {
    return {
      id: "refresh_completed_founding_deck",
      status: "available",
      label: "Refresh completed Founding Deck status",
      title: "Deck status refresh required",
      copy: "First Deployment is complete. Command is rechecking the issued 40-card Deck; refresh its status without resubmitting your Crew selection.",
      requiredAction: "refresh_completed_founding_deck",
      targetHref: "#hangar",
      actionLabel: "REFRESH DECK STATUS",
      foundingJourneyView: "receipt"
    };
  }
  if (materializationStage && journey.foundingDeckMaterialization?.status === "pending") {
    return {
      id: "complete_founding_deck_issuance",
      status: "available",
      label: "Complete Founding Deck issuance",
      title: "Deck issuance pending",
      copy: "Your Crew selection is preserved, but the issued 40-card Deck still requires verification before training can begin.",
      requiredAction: "complete_founding_deck_issuance",
      targetHref: "#hangar",
      actionLabel: "COMPLETE ISSUANCE",
      foundingJourneyView: "receipt"
    };
  }
  if (journey.stage === "challenge_accepted") {
    return {
      id: "resume_founding_training",
      status: "available",
      label: "Resume Founding training",
      title: "Training handoff ready",
      copy: "Your accepted Archive Training Grid handoff is preserved. Resume BOND//BREACH without selecting a Pilot, deck, opponent, or Arena.",
      requiredAction: "resume_founding_training",
      targetHref: "#hangar",
      actionLabel: "RESUME TRAINING",
      foundingJourneyView: "receipt"
    };
  }
  return null;
}

function getAuthoritativeFoundingJourneyDirective(foundingJourneyStatus) {
  if (!foundingJourneyStatus || foundingJourneyStatus.status !== "ready") return null;
  const journey = foundingJourneyStatus.data;
  const eligibility = journey && journey.eligibility;
  const ownedMekaCount = Number(eligibility && eligibility.ownedMekaCount);
  const requiredMekaCount = Number(eligibility && eligibility.requiredMekaCount);
  if (!Number.isFinite(ownedMekaCount) || !Number.isFinite(requiredMekaCount) || requiredMekaCount < 1) return null;
  if (ownedMekaCount < requiredMekaCount) return null;
  return getFoundingJourneyDirective(journey);
}

function getCurrentDirective(onboarding, starterMech, archiveDispatchStatus, foundingJourneyStatus) {
  const current = onboarding && onboarding.directives && onboarding.directives.current
    ? onboarding.directives.current
    : null;
  if (current) return current;
  const nextArchiveDirective = getPostLicenseArchiveDirective(onboarding, archiveDispatchStatus, foundingJourneyStatus);
  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();
  if (target === "#index") return "#founding-starter-archive";
  if (target === "#arsenal" || target === "#arsenal/collection") return "#cardcollection";
  if (target === "#arsenal/decks") return "#deckbay";
  return 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 && ["license_more_mekas", "review_founding_deck_primer", "review_founding_deck_manifest", "enter_official_battles"].includes(directive.id)) 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."
  };
}

const PHASE_ONE_DIRECTIVE_MUTATIONS = Object.freeze({
  open_command_channel: "seen",
  inspect_starter_dossier: "complete",
  review_combat_profile: "complete",
  browse_weekly_drop: "complete",
  visit_registry: "complete"
});

function getDirectiveMutationAction(directive) {
  if (!directive || directive.status === "idle" || directive.status === "upcoming" || directive.status === "locked") return "";
  return PHASE_ONE_DIRECTIVE_MUTATIONS[directive.id] || "";
}

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 { progress } = getArchiveDispatchBundle(archiveDispatchStatus);
  const currentDispatchDirective = progress && progress.currentDirective ? progress.currentDirective : null;
  let targetHref = currentDispatchDirective ? getArchiveDispatchRouteTarget(currentDispatchDirective) : "#archive-dispatch";
  let actionLabel = "OPEN DISPATCH";
  let copy = "Complete the current Archive Dispatch directives to license another Meka.";

  if (progress && progress.status === "reward_ready") {
    targetHref = "#hangar";
    actionLabel = "CLAIM MEKA";
    copy = "License Authority is full. Claim your selected Meka before the current dispatch closes.";
  } else if (progress && progress.status === "retarget_required") {
    copy = "Your previous target was secured by another operator. Select a new target in the current dispatch and reverify target-specific proof.";
  } else if (currentDispatchDirective && currentDispatchDirective.label) {
    copy = "Next dispatch step: " + currentDispatchDirective.label + ". Complete the current dispatch to license another 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, foundingJourneyStatus) {
  if (!phaseOneDirectivesAreClear(onboarding)) return null;
  if (!foundingJourneyStatus || foundingJourneyStatus.status !== "ready") return null;
  const foundingDirective = getAuthoritativeFoundingJourneyDirective(foundingJourneyStatus);
  if (foundingDirective) return foundingDirective;
  const journey = foundingJourneyStatus.data;
  if (!journey || journey.stage !== "training_complete") return null;
  const postFounding = journey.postFounding;
  const action = postFounding && postFounding.actions ? postFounding.actions.primary : null;
  if (!postFounding || !action) return null;
  const presentations = {
    continue_post_deployment_debrief: {
      title: "Deployment debrief ready",
      copy: "Return to your organization channel for the Battle Record, acquisition receipt, and next command briefing."
    },
    review_arsenal_reward: {
      title: "Combat Imprint briefing",
      copy: "Open the Combat Imprint Ledger and follow the instructed action for your recorded target."
    },
    open_guided_deck_bay: {
      title: "Deployment Package briefing",
      copy: "Complete the guided Deck Bay sequence: edit to 40 cards, pair compatible Crew, and activate the package."
    },
    review_card_collection: {
      title: "Card Collection briefing",
      copy: "Review the playable card library to complete Arsenal orientation and release Operations access."
    },
    open_operations: {
      title: "Operations unlocked",
      copy: "Training, Challenge Channel, and future Nusantara Campaign deployments are now routed through Operations."
    }
  };
  const presentation = presentations[action.id] || presentations.continue_post_deployment_debrief;
  return {
    id: action.id,
    status: "ready",
    label: presentation.title,
    title: presentation.title,
    copy: presentation.copy,
    requiredAction: action.id,
    targetHref: action.targetHref,
    actionLabel: action.label
  };
}

function useTcgCollection(account, enabled, projectedCollection, refreshKey = "") {
  const accountIdentity = [account && account.status, account && account.user && account.user.id, account && account.organization && account.organization.id].join(":");
  const identity = enabled && account && account.status === "signed-in" ? accountIdentity : "";
  const identityRef = useRef(identity);
  const requestEpochRef = useRef(0);
  const [state, setState] = useState(() => ({ identity: "", refreshKey: "", status: "idle", source: "", cards: [], pendingMeka: [], notice: "", error: "" }));
  if (identityRef.current !== identity) {
    identityRef.current = identity;
    requestEpochRef.current += 1;
  }

  const load = useCallback(async () => {
    const requestEpoch = ++requestEpochRef.current;
    if (!identity) {
      setState({ identity: "", refreshKey: "", status: "idle", source: "", cards: [], pendingMeka: [], notice: "", error: "" });
      return null;
    }
    setState((current) => {
      const preserveReadyGrid = current.identity === identity && Boolean(current.source);
      return {
        identity,
        refreshKey,
        status: "loading",
        source: preserveReadyGrid ? current.source : "",
        cards: preserveReadyGrid ? current.cards : [],
        pendingMeka: preserveReadyGrid ? current.pendingMeka : [],
        notice: preserveReadyGrid ? current.notice : "",
        error: ""
      };
    });
    try {
      const data = await publicApi("/tcg/collection");
      if (requestEpoch !== requestEpochRef.current || identityRef.current !== identity) return null;
      if (!data || !Array.isArray(data.cards)) throw Object.assign(new Error("Card Collection unavailable"), { status: 503 });
      const next = {
        identity,
        refreshKey,
        status: "ready",
        source: data.source || "organization_collection",
        cards: Array.isArray(data && data.cards) ? data.cards : [],
        pendingMeka: Array.isArray(data && data.pendingMeka) ? data.pendingMeka : [],
        notice: "",
        error: ""
      };
      setState(next);
      return next;
    } catch (error) {
      if (requestEpoch !== requestEpochRef.current || identityRef.current !== identity) return null;
      const fallbackAvailable = projectedCollection
        && projectedCollection.source === "founding_journey_snapshot"
        && Array.isArray(projectedCollection.cards);
      const endpointUnavailable = !Number.isInteger(error && error.status)
        || error.status === 404
        || error.status >= 500;
      if (fallbackAvailable && endpointUnavailable) {
        const next = {
          identity,
          refreshKey,
          status: "ready",
          source: "founding_journey_snapshot_fallback",
          cards: projectedCollection.cards,
          pendingMeka: Array.isArray(projectedCollection.pendingMeka) ? projectedCollection.pendingMeka : [],
          notice: "TRANSITIONAL FOUNDING SNAPSHOT / Canonical Card Collection unavailable.",
          error: ""
        };
        setState(next);
        return next;
      }
      setState({ identity, refreshKey, status: "error", source: "", cards: [], pendingMeka: [], notice: "", error: error.message || "Card Collection unavailable" });
      return null;
    }
  }, [identity, projectedCollection, refreshKey]);

  useEffect(() => { void load(); }, [load]);
  const visibleState = state.identity === identity
    ? state
    : { identity, refreshKey, status: identity ? "loading" : "idle", source: "", cards: [], pendingMeka: [], notice: "", error: "" };
  return { ...visibleState, refresh: load };
}

function DirectiveCompletionTransmission({ receipt, onDismiss, elevated = false }) {
  if (!receipt) return null;
  return (
    <aside className={"directive-completion-transmission" + (elevated ? " is-elevated" : "")} 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, foundingJourneyStatus) {
  const onboarding = onboardingStatus && onboardingStatus.data ? onboardingStatus.data : null;
  const directive = getCurrentDirective(onboarding, starterMech, archiveDispatchStatus, foundingJourneyStatus);
  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,
  foundingJourneyStatus,
  avatarSource,
  assistantLoading = false,
  avatarLoadingTitle = "AVATAR STANDBY",
  avatarLoadingLine = "WAITING FOR FINAL AVATAR",
  onDirectiveCompleted,
  onDispatchDirectiveCompleted,
  onFoundingJourneyDirective
}) {
  const { directive, panelState, title, copy, targetHref, isBusy, statusLabel, actionDisabled, actionLabel, actionHint } = getDirectivePresentation(onboardingStatus, starterMech, archiveDispatchStatus, foundingJourneyStatus);
  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 (directive.foundingJourneyView && typeof onFoundingJourneyDirective === "function") {
      onFoundingJourneyDirective(directive.foundingJourneyView);
      return;
    }
    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>
  );
}

const OBJECTIVE_COMMAND_VISIBLE_EXPANSION_LIMIT = 2;

function getExpansionObjectiveModels(onboardingStatus, archiveDispatchStatus) {
  const state = getLicenseMoreMekasObjectiveState(onboardingStatus, archiveDispatchStatus);
  const directive = getLicenseMoreMekasDirective(onboardingStatus, archiveDispatchStatus);
  const { progress } = getArchiveDispatchBundle(archiveDispatchStatus);
  const authority = Math.max(0, Number(progress && progress.licenseAuthority || 0));
  const target = Math.max(1, Number(progress && progress.licenseAuthorityTarget || 100));
  const ownedDispatchCount = getDispatchClaimOwnerships(archiveDispatchStatus).length;
  const directiveHistory = getArchiveDispatchObjectiveHistory(progress);
  let copy = "Optional Archive Dispatch unlocks after the current Main Objective. Your Founding Journey does not wait for it.";
  let telemetry = "OPTIONAL";
  if (state === "active" && directive) {
    copy = directive.copy;
    telemetry = "LA " + authority + " / " + target;
  } else if (state === "complete") {
    copy = ownedDispatchCount > 0
      ? "Archive Dispatch Meka secured. Your licensed roster now includes " + ownedDispatchCount + " expansion unit" + (ownedDispatchCount === 1 ? "." : "s.")
      : "This Archive Dispatch license cycle is complete. Your Founding Journey remains available independently.";
    telemetry = "LICENSED";
  }
  return [
    {
      id: "license_more_mekas",
      title: "License more Mekas",
      copy,
      state,
      statusLabel: state === "complete" ? "COMPLETE" : (state === "active" ? "AVAILABLE" : "OPTIONAL"),
      telemetry,
      directive,
      directiveHistory
    }
  ];
}

function getArchiveDispatchObjectiveHistory(progress) {
  const source = Array.isArray(progress && progress.directives) ? progress.directives : [];
  if (!source.length) return null;
  const directives = source.map((directive) => ({
    id: directive.id,
    label: directive.label,
    status: directive.complete && !directive.invalidatedAt ? "complete" : "pending",
    actor: "operator",
    completedAt: directive.complete && !directive.invalidatedAt ? directive.completedAt || null : null,
    invalidatedAt: directive.invalidatedAt || null
  }));
  const completedDirectiveCount = directives.filter((directive) => directive.status === "complete").length;
  const completed = completedDirectiveCount === directives.length;
  return {
    id: "license_more_mekas",
    title: "License More Mekas",
    status: completed ? "complete" : "active",
    completedAt: completed ? directives[directives.length - 1]?.completedAt || null : null,
    completedDirectiveCount,
    totalDirectiveCount: directives.length,
    directives,
    missionRecord: null
  };
}

function getCombatImprintObjectiveModel(foundingJourneyStatus) {
  const journey = foundingJourneyStatus && foundingJourneyStatus.data;
  const reward = journey && journey.postFounding && journey.postFounding.reward;
  const target = reward && reward.targetMeka;
  if (!reward || !target || reward.combatPrintGranted || Number(reward.imprint || 0) >= 100) return null;
  const imprintProgress = Math.max(0, Number(reward.imprint || 0));
  const imprintDirectives = [
    { id: "combat_imprint_source_recorded", label: "Opponent battle data recorded", status: "complete", actor: "system", completedAt: journey.trainingCompletedAt || null },
    { id: "combat_imprint_threshold_reached", label: "Combat Imprint reaches 100 / 100", status: imprintProgress >= 100 ? "complete" : "pending", actor: "operator", completedAt: imprintProgress >= 100 ? journey.trainingCompletedAt || null : null },
    { id: "combat_print_registered", label: "Playable Combat Print registered", status: reward.combatPrintAvailable ? "complete" : "pending", actor: "system", completedAt: reward.combatPrintAvailable ? journey.trainingCompletedAt || null : null }
  ];
  const completedDirectiveCount = imprintDirectives.filter((directive) => directive.status === "complete").length;
  return {
    id: "complete_combat_imprint_" + String(target.id || "target").toLowerCase(),
    group: "optional",
    title: "Complete " + [target.id, target.codename].filter(Boolean).join(" / ") + " Combat Imprint",
    copy: "Win a future rematch to complete this target. This objective does not block Arsenal or Operations progression.",
    statusLabel: "OPTIONAL",
    telemetry: String(imprintProgress).padStart(3, "0") + " / 100",
    blocking: false,
    targetHref: "#arsenal/imprints",
    actionLabel: "VIEW IMPRINT",
    directiveHistory: {
      id: "complete_combat_imprint",
      title: "Complete Combat Imprint",
      status: "active",
      completedAt: null,
      completedDirectiveCount,
      totalDirectiveCount: imprintDirectives.length,
      directives: imprintDirectives,
      missionRecord: null
    }
  };
}

function getObjectiveCenterGroups(onboardingStatus, archiveDispatchStatus, foundingJourneyStatus) {
  const journey = foundingJourneyStatus && foundingJourneyStatus.data;
  const postFounding = journey && journey.postFounding;
  const directiveHistory = journey && journey.directiveHistory;
  const firstDeploymentHistory = directiveHistory && directiveHistory.firstDeployment;
  const arsenalActivationHistory = directiveHistory && directiveHistory.arsenalActivation;
  const mainDirective = getPostLicenseArchiveDirective(
    onboardingStatus && onboardingStatus.data,
    archiveDispatchStatus,
    foundingJourneyStatus
  );
  const mainDirectiveHistory = journey && journey.stage === "training_complete"
    ? arsenalActivationHistory
    : firstDeploymentHistory;
  const mainObjective = mainDirective ? {
    id: mainDirective.id,
    group: "main",
    title: mainDirective.title || mainDirective.label,
    copy: mainDirective.copy,
    statusLabel: "CURRENT",
    telemetry: "MAIN OBJECTIVE",
    blocking: true,
    targetHref: mainDirective.targetHref,
    actionLabel: mainDirective.actionLabel,
    directiveHistory: mainDirectiveHistory
  } : {
    id: "archive_stable",
    group: "main",
    title: "Archive stable",
    copy: "Complete the current onboarding directive to reveal the next Main Objective.",
    statusLabel: "STANDBY",
    telemetry: "MAIN OBJECTIVE",
    blocking: true,
    targetHref: "#hangar",
    actionLabel: "RETURN TO MY HANGAR",
    directiveHistory: firstDeploymentHistory
  };
  const imprintObjective = getCombatImprintObjectiveModel(foundingJourneyStatus);
  const licenseObjectiveModel = getExpansionObjectiveModels(onboardingStatus, archiveDispatchStatus)[0];
  const licenseObjective = licenseObjectiveModel && licenseObjectiveModel.state !== "complete" ? {
    ...licenseObjectiveModel,
    group: "optional",
    blocking: false,
    targetHref: licenseObjectiveModel.directive?.targetHref || "#dispatches",
    actionLabel: licenseObjectiveModel.directive?.actionLabel || "VIEW DISPATCH"
  } : null;
  const firstDeploymentObjective = firstDeploymentHistory && firstDeploymentHistory.status === "complete" ? {
    id: firstDeploymentHistory.id,
    group: "completed",
    title: firstDeploymentHistory.title,
    copy: "FIRST OFFICIAL BATTLE RECORDED",
    statusLabel: "COMPLETED",
    telemetry: String(firstDeploymentHistory.completedDirectiveCount) + " / " + String(firstDeploymentHistory.totalDirectiveCount) + " DIRECTIVES COMPLETE",
    directiveHistory: firstDeploymentHistory
  } : null;
  const arsenalOrientationObjective = postFounding && postFounding.phase === "complete" ? {
    id: "arsenal_orientation",
    group: "completed",
    title: "Arsenal Orientation",
    copy: "A legal deployment deck was activated and Operations access was released.",
    statusLabel: "COMPLETED",
    telemetry: arsenalActivationHistory
      ? String(arsenalActivationHistory.completedDirectiveCount) + " / " + String(arsenalActivationHistory.totalDirectiveCount) + " DIRECTIVES COMPLETE"
      : "40 / 40",
    directiveHistory: arsenalActivationHistory
  } : null;
  const completedLicenseObjective = licenseObjectiveModel && licenseObjectiveModel.state === "complete" ? {
    ...licenseObjectiveModel,
    group: "completed",
    statusLabel: "COMPLETED",
    blocking: false
  } : null;
  return {
    main: [mainObjective],
    optional: [imprintObjective, licenseObjective].filter(Boolean),
    repeatable: [],
    completed: [firstDeploymentObjective, arsenalOrientationObjective, completedLicenseObjective].filter(Boolean)
  };
}

function formatObjectiveMissionTimestamp(value) {
  const timestamp = new Date(value);
  if (!value || Number.isNaN(timestamp.getTime())) return "TIMESTAMP UNAVAILABLE";
  const date = new Intl.DateTimeFormat("en-US", {
    month: "short",
    day: "2-digit",
    year: "numeric",
    timeZone: "UTC"
  }).format(timestamp).toUpperCase();
  const time = new Intl.DateTimeFormat("en-GB", {
    hour: "2-digit",
    minute: "2-digit",
    hour12: false,
    timeZone: "UTC"
  }).format(timestamp);
  return date + " · " + time + " UTC";
}

function getObjectiveDirectiveDisplayStatus(history, directive, index) {
  if (directive.invalidatedAt) return "current";
  if (directive.status === "complete") return "complete";
  const directives = Array.isArray(history && history.directives) ? history.directives : [];
  const firstIncompleteIndex = directives.findIndex((item) => item.status !== "complete" || item.invalidatedAt);
  return index === firstIncompleteIndex ? "current" : "locked";
}

function ObjectiveDirectiveSummary({ history }) {
  if (!history || !Array.isArray(history.directives) || !history.directives.length) return null;
  return (
    <ol className="objective-directive-summary" aria-label={history.title + " directive summary"}>
      {history.directives.map((directive, index) => {
        const displayStatus = getObjectiveDirectiveDisplayStatus(history, directive, index);
        return (
          <li data-status={displayStatus} key={directive.id}>
            <span aria-hidden="true">{displayStatus === "complete" ? "✓" : String(index + 1).padStart(2, "0")}</span>
            <b>{directive.label}</b>
            <em>{displayStatus === "complete" ? "COMPLETE" : (displayStatus === "current" ? (directive.invalidatedAt ? "REVERIFY" : "CURRENT") : "LOCKED")}</em>
          </li>
        );
      })}
    </ol>
  );
}

function ObjectiveMissionLedger({ objective, regionId }) {
  const missionRecord = objective.missionRecord;
  if (!objective || !Array.isArray(objective.directives) || !objective.directives.length) return null;
  const rewardStatus = String(missionRecord && missionRecord.rewardStatus || "").trim().toLowerCase();
  const imprint = String(Math.max(0, Number(missionRecord && missionRecord.imprint || 0))).padStart(3, "0") + " / 100";
  let rewardLabel = "NO REWARD ISSUED";
  let rewardDetail = imprint + " · NO PLAYABLE PRINT ISSUED";
  if (missionRecord && (missionRecord.combatPrintGranted || rewardStatus === "acquired")) {
    rewardLabel = "PLAYABLE COMBAT PRINT ISSUED";
    rewardDetail = imprint + " · PLAYABLE PRINT REGISTERED · HANGAR MEKA LICENSE UNCHANGED";
  } else if (rewardStatus === "partial") {
    rewardLabel = "PARTIAL COMBAT IMPRINT RECORDED";
    rewardDetail = imprint + " · NOT PLAYABLE YET · HANGAR MEKA LICENSE UNCHANGED";
  } else if (rewardStatus === "mastered") {
    rewardLabel = "IMPRINT MASTERED / PRE-EXISTING PRINT";
    rewardDetail = imprint + " · DUPLICATE PRINT NOT ISSUED · HANGAR MEKA LICENSE UNCHANGED";
  } else if (rewardStatus === "holding") {
    rewardLabel = "COMBAT PRINT ISSUANCE HELD";
    rewardDetail = imprint + " · RECEIPT HELD FOR REVIEW";
  }
  const target = missionRecord && missionRecord.opponent
    ? [missionRecord.opponent.id, missionRecord.opponent.codename].filter(Boolean).join(" / ")
    : "TARGET NOT RECORDED";
  const opponentOrganization = missionRecord && missionRecord.opponent && missionRecord.opponent.organizationName;
  const arena = missionRecord && missionRecord.arena && (missionRecord.arena.name || missionRecord.arena.id);

  return (
    <section
      className="objective-mission-ledger"
      id={regionId}
      role="region"
      aria-label={objective.title + " Directive Ledger"}
    >
      <header className="objective-mission-ledger-head">
        <div><span>COMMAND ARCHIVE / DIRECTIVE HISTORY</span><h3>{objective.status === "complete" ? "Operational ledger" : "Active directive ledger"}</h3></div>
        <b>{String(objective.completedDirectiveCount).padStart(2, "0")} / {String(objective.totalDirectiveCount).padStart(2, "0")}</b>
      </header>
      <ol className="objective-mission-timeline" role="list" aria-label="Objective directives">
        {objective.directives.map((directive, index) => {
          const displayStatus = getObjectiveDirectiveDisplayStatus(objective, directive, index);
          return (
          <li className="objective-mission-directive" role="listitem" data-status={displayStatus} key={directive.id}>
            <div className="objective-mission-directive-status" aria-label={displayStatus}>
              <span aria-hidden="true">{displayStatus === "complete" ? "✓" : (displayStatus === "current" ? "●" : "—")}</span>
              <b>{String(index + 1).padStart(2, "0")}</b>
            </div>
            <div className="objective-mission-directive-copy">
              <strong>{directive.label}</strong>
              <span>{displayStatus === "complete" ? "DIRECTIVE COMPLETE" : (displayStatus === "current" ? (directive.invalidatedAt ? "DIRECTIVE REQUIRES REVERIFICATION" : "CURRENT DIRECTIVE") : "QUEUED DIRECTIVE")}</span>
            </div>
            {directive.actor && <em>{directive.actor === "system" ? "SYSTEM ASSIGNED" : String(directive.actor).toUpperCase()}{directive.completedAtProvenance === "legacy_inferred_from_operator_action" ? " · LEGACY / INFERRED" : ""}</em>}
            <time dateTime={directive.completedAt || undefined}>{displayStatus === "complete" ? formatObjectiveMissionTimestamp(directive.completedAt) : (displayStatus === "current" ? (directive.invalidatedAt ? "REVERIFICATION REQUIRED" : "AWAITING OPERATOR ACTION") : "LOCKED UNTIL PREVIOUS DIRECTIVE")}</time>
          </li>
        );})}
      </ol>
      {missionRecord && <div className="objective-mission-record">
        <header><span>IMMUTABLE MISSION RECORD</span><b>{missionRecord.rewardReceiptId || "RECEIPT NOT RECORDED"}</b></header>
        <dl>
          <div className="is-result"><dt>BATTLE RESULT</dt><dd>{missionRecord.result === "win" ? "VICTORY" : "DEFEAT"}</dd></div>
          <div><dt>TARGET</dt><dd>{target}{opponentOrganization && <small>{opponentOrganization}</small>}</dd></div>
          <div><dt>ARENA</dt><dd>{arena || "ARENA NOT RECORDED"}</dd></div>
          <div className="is-reward"><dt>REWARD RECEIPT</dt><dd>{rewardLabel}<small>{rewardDetail}</small></dd></div>
          <div><dt>COMPLETED</dt><dd><time dateTime={missionRecord.completedAt || undefined}>{formatObjectiveMissionTimestamp(missionRecord.completedAt)}</time></dd></div>
        </dl>
      </div>}
    </section>
  );
}

function CommandPageShell({ className = "", eyebrow, title, summary, children }) {
  return (
    <main className={"post-founding-page command-page-shell" + (className ? " " + className : "")}>
      <header className="post-founding-page-head command-page-shell-head">
        <div><span>{eyebrow}</span><h1>{title}</h1><p>{summary}</p></div>
      </header>
      {children}
    </main>
  );
}

function ObjectiveCenterPage({ account, onboardingStatus, archiveDispatchStatus, foundingJourneyStatus }) {
  const [expandedMissionId, setExpandedMissionId] = useState("");
  const signedIn = Boolean(account && account.status === "signed-in");
  if (!signedIn) {
    return (
      <main className="post-founding-page objective-center-page">
        <div className="post-founding-page-locked">
          <span>OBJECTIVE CENTER / AUTHORIZATION REQUIRED</span>
          <h1>Sign in to review your organization objectives.</h1>
          <a className="btn primary" href="#signin">SIGN IN TO VIEW OBJECTIVES</a>
        </div>
      </main>
    );
  }
  const groups = getObjectiveCenterGroups(onboardingStatus, archiveDispatchStatus, foundingJourneyStatus);
  const sections = [
    { id: "main", label: "MAIN", items: groups.main, emptyTitle: "NO MAIN OBJECTIVE", emptyCopy: "Return to My Hangar to refresh Command directives." },
    { id: "optional", label: "OPTIONAL", items: groups.optional, emptyTitle: "NO OPTIONAL OBJECTIVES", emptyCopy: "Optional pursuits will appear here when they become available." },
    { id: "repeatable", label: "REPEATABLE", items: groups.repeatable, emptyTitle: "NO REPEATABLE OBJECTIVES AVAILABLE", emptyCopy: "New repeatable assignments will appear here when Operations publishes them." },
    { id: "completed", label: "COMPLETED", items: groups.completed, emptyTitle: "NO COMPLETED RECORDS", emptyCopy: "Completed objectives will be archived here." }
  ];
  function toggleMissionRecord(objectiveId, trigger) {
    if (trigger) trigger.focus({ preventScroll: true });
    setExpandedMissionId((currentId) => currentId === objectiveId ? "" : objectiveId);
    window.requestAnimationFrame(() => {
      if (trigger) trigger.focus({ preventScroll: true });
    });
  }
  return (
    <CommandPageShell className="objective-center-page" eyebrow="COMMAND / OBJECTIVE CENTER" title="Objectives" summary="Main progression, optional pursuits, repeatable assignments, and completed records in one command view.">
      <div className="objective-center-groups">
        {sections.map((section) => (
          <section className={"objective-center-group is-" + section.id} key={section.id} aria-labelledby={"objective-group-" + section.id}>
            <header><span id={"objective-group-" + section.id}>{section.label}</span><b>{String(section.items.length).padStart(2, "0")}</b></header>
            {section.items.length ? section.items.map((objective) => {
              const hasDirectiveHistory = Boolean(objective.directiveHistory && Array.isArray(objective.directiveHistory.directives) && objective.directiveHistory.directives.length);
              const missionRegionId = "objective-mission-" + objective.id;
              const missionExpanded = hasDirectiveHistory && expandedMissionId === objective.id;
              return (
                <article className={"objective-center-row" + (hasDirectiveHistory ? " is-expandable" : "")} key={objective.id}>
                  <div className="objective-center-copy"><span>{objective.statusLabel}</span><h2>{objective.title}</h2><p>{objective.copy}</p></div>
                  <div className="objective-center-telemetry"><b>{objective.telemetry}</b>{objective.blocking === false && <em>DOES NOT BLOCK PROGRESSION</em>}</div>
                  <div className="objective-center-actions">
                    {objective.targetHref && <a className="btn" href={objective.targetHref}>{objective.actionLabel || "OPEN OBJECTIVE"}</a>}
                    {hasDirectiveHistory && (
                    <button
                      type="button"
                      className="btn objective-mission-trigger"
                      aria-expanded={missionExpanded}
                      aria-controls={missionRegionId}
                      onClick={(event) => toggleMissionRecord(objective.id, event.currentTarget)}
                    >
                      {missionExpanded ? "CLOSE DIRECTIVE LEDGER" : "OPEN DIRECTIVE LEDGER"}
                    </button>
                    )}
                  </div>
                  {hasDirectiveHistory && <ObjectiveDirectiveSummary history={objective.directiveHistory} />}
                  {missionExpanded && <ObjectiveMissionLedger objective={objective.directiveHistory} regionId={missionRegionId} />}
                </article>
              );
            }) : <div className="objective-center-empty"><b>{section.emptyTitle}</b><p>{section.emptyCopy}</p></div>}
          </section>
        ))}
      </div>
    </CommandPageShell>
  );
}

function getObjectiveCommandProgress(foundingJourneyStatus, main) {
  const journey = foundingJourneyStatus && foundingJourneyStatus.data;
  const directiveHistory = journey && journey.directiveHistory;
  const history = journey && journey.stage === "training_complete"
    ? directiveHistory && directiveHistory.arsenalActivation
    : directiveHistory && directiveHistory.firstDeployment;
  const canonicalDirectives = Array.isArray(history && history.directives) ? history.directives : [];
  const fallbackDirectives = canonicalDirectives.length || !main.directive ? [] : [{
    id: main.directive.id,
    label: main.title,
    status: main.panelState === "idle" ? "complete" : "pending",
    invalidatedAt: null
  }];
  const source = canonicalDirectives.length ? canonicalDirectives : fallbackDirectives;
  const directives = source.map((directive, index) => ({
    ...directive,
    displayStatus: getObjectiveDirectiveDisplayStatus({ directives: source }, directive, index)
  }));
  const completedDirectiveCount = directives.filter((directive) => directive.displayStatus === "complete").length;
  const totalDirectiveCount = directives.length;
  const percent = totalDirectiveCount ? Math.round((completedDirectiveCount / totalDirectiveCount) * 100) : 0;
  const complete = totalDirectiveCount > 0 && completedDirectiveCount === totalDirectiveCount;
  return {
    code: history && history.id === "deployment_package_activation" ? "M02" : "M01",
    title: history && history.title ? history.title : main.title,
    statusLabel: complete ? "COMPLETE" : (totalDirectiveCount ? "IN PROGRESS" : "STANDBY"),
    directives,
    completedDirectiveCount,
    totalDirectiveCount,
    percent
  };
}

function ObjectiveCommandPanel({ onboardingStatus, starterMech, archiveDispatchStatus, foundingJourneyStatus }) {
  const main = getDirectivePresentation(onboardingStatus, starterMech, archiveDispatchStatus, foundingJourneyStatus);
  const progress = getObjectiveCommandProgress(foundingJourneyStatus, main);
  const expansionObjectives = getExpansionObjectiveModels(onboardingStatus, archiveDispatchStatus)
    .slice(0, OBJECTIVE_COMMAND_VISIBLE_EXPANSION_LIMIT);

  return (
    <section className="objective-command-panel" aria-label="Objective Command">
      <div className="objective-command-head">
        <span>OBJECTIVE COMMAND</span>
        <b>MISSION STACK</b>
      </div>
      <div className={"objective-command-main is-" + main.panelState}>
        <div className="objective-command-section-label">
          <span>◆ MAIN OBJECTIVE · {progress.code}</span>
          <b>{progress.statusLabel}</b>
        </div>
        <h3>{progress.title}</h3>
        <ol className="objective-command-directive-list" aria-label={progress.title + " directive progress"}>
          {progress.directives.map((directive) => (
            <li data-status={directive.displayStatus} aria-current={directive.displayStatus === "current" ? "step" : undefined} key={directive.id}>
              <span aria-hidden="true">{directive.displayStatus === "complete" ? "✓" : (directive.displayStatus === "current" ? "•" : "—")}</span>
              <b>{directive.label}</b>
            </li>
          ))}
        </ol>
        <div
          className="objective-command-progress"
          role="progressbar"
          aria-label="Main objective directives complete"
          aria-valuemin="0"
          aria-valuemax={progress.totalDirectiveCount}
          aria-valuenow={progress.completedDirectiveCount}
        >
          <i style={{ width: progress.percent + "%" }}></i>
        </div>
        <p className="objective-command-progress-label">{progress.completedDirectiveCount} / {progress.totalDirectiveCount} DIRECTIVES COMPLETE</p>
      </div>
      <div className="objective-command-expansion">
        <div className="objective-command-section-label">
          <span>AVAILABLE OPTIONAL</span>
          <b>{String(expansionObjectives.length).padStart(2, "0")} LISTED</b>
        </div>
        <div className="objective-command-expansion-list">
          {expansionObjectives.map((objective, index) => {
            const stateClass = objective.state === "complete" ? " is-complete" : (objective.state === "future" ? " is-future" : " is-active");
            return (
              <article className={"objective-command-expansion-row" + stateClass} key={objective.id}>
                <span className="objective-command-expansion-index">E{String(index + 1).padStart(2, "0")}</span>
                <div>
                  <div className="objective-command-expansion-title">
                    <h4>{objective.title}</h4>
                    <em>{objective.statusLabel}</em>
                  </div>
                  <p>{objective.copy}</p>
                </div>
                <div className="objective-command-expansion-action">
                  <b>{objective.telemetry}</b>
                </div>
              </article>
            );
          })}
        </div>
      </div>
      <a className="objective-command-view-all" href="#objectives">VIEW ALL OBJECTIVES</a>
    </section>
  );
}

function VirtualAssistantAvatarDialogue({ account, organization, starterMech, onboardingStatus, onboarding, archiveDispatchStatus, foundingJourneyStatus, onDirectiveCompleted, onDispatchDirectiveCompleted, onFoundingJourneyDirective }) {
  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, foundingJourneyStatus);
  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}
          foundingJourneyStatus={foundingJourneyStatus}
          avatarSource={avatarSource}
          assistantLoading={showAssistantLoading}
          avatarLoadingTitle={avatarLoadingTitle}
          avatarLoadingLine={avatarLoadingLine}
          onDirectiveCompleted={onDirectiveCompleted}
          onDispatchDirectiveCompleted={onDispatchDirectiveCompleted}
          onFoundingJourneyDirective={onFoundingJourneyDirective}
        />
        <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 resolveFoundingDeckCardArt(entry) {
  if (!entry) return "";
  const code = String(entry.code || entry.id || "").trim().toUpperCase();
  const currentIllustration = BOND_BREACH_CARD_ART_RELEASE_20260905[code];
  if (currentIllustration) return versionAssetUrl(BOND_BREACH_CARD_ART_RELEASE_20260905_BASE_URL + currentIllustration);
  const playableAsset = BOND_BREACH_PLAYABLE_CARD_ART[code];
  if (playableAsset) return versionAssetUrl(BOND_BREACH_CARD_ART_BASE_URL + playableAsset);
  const candidate = String(entry.artUrl || entry.art || "").trim();
  const trustedCardArtPrefixes = [
    BOND_BREACH_CARD_ART_BASE_URL,
    ARCHIVE_ASSET_BASE_URL + "demos/bond-breach/20260826/card-art-release-01/",
    ARCHIVE_ASSET_BASE_URL + "demos/bond-breach/20260827/command-card-art-release-02/",
    ARCHIVE_ASSET_BASE_URL + "tcg/releases/",
  ];
  const trustedCandidate = trustedCardArtPrefixes.some(prefix => candidate.toLowerCase().startsWith(prefix.toLowerCase()));
  if (trustedCandidate && /-card\.(?:png|webp)(?:[?#]|$)/i.test(candidate)) {
    return versionAssetUrl(candidate);
  }
  return "";
}

function getFoundingGameplayDoctrineColor(doctrine) {
  return ({ Assault: "#d24a43", Bastion: "#e8c447", Forge: "#d87932", Salvage: "#a370d8", Vector: "#4cc8d9" })[doctrine] || "#8a8779";
}

function foundingGameplayCardKeywords(entry) {
  const keywords = [];
  const rules = Array.isArray(entry && entry.rulesText) ? entry.rulesText : [];
  for (const rule of rules) {
    const text = String(rule || "").trim();
    if (/^Rush[.!]?$/i.test(text) && !keywords.includes("RUSH")) keywords.push("RUSH");
    if (/^Intercept[.!]?$/i.test(text) && !keywords.includes("INTERCEPT")) keywords.push("INTERCEPT");
    const breach = text.match(/^Breach\s+(\d+)[.!]?$/i);
    if (breach && !keywords.includes("BREACH " + breach[1])) keywords.push("BREACH " + breach[1]);
    if (entry && entry.kind === "command" && /^Armor Trigger(?:\b|:)/i.test(text) && !keywords.includes("ARMOR TRIGGER")) {
      keywords.push("ARMOR TRIGGER");
    }
  }
  return keywords.join(" · ");
}

function FoundingGameplayCardVisual({ entry }) {
  const art = resolveFoundingDeckCardArt(entry) || canonicalObjectStorageAssetUrl(entry.artUrl || entry.art);
  const color = getFoundingGameplayDoctrineColor(entry.doctrine);
  const keyword = foundingGameplayCardKeywords(entry);
  return (
    <div className="founding-gameplay-card" data-card-id={entry.code} style={{ "--founding-card-doctrine": color }}>
      <div className="founding-gameplay-card-doctrine-bar"></div>
      <div className="founding-gameplay-card-meta"><span>{String(entry.doctrine || "CMD").slice(0,3).toUpperCase()}</span><b>{entry.cost == null ? "—" : entry.cost}</b></div>
      <div className="founding-gameplay-card-art" style={art ? { backgroundImage: "url(\"" + art + "\")" } : undefined}><span>{art ? "" : entry.kind === "command" ? "CMD" : entry.code}</span></div>
      <div className="founding-gameplay-card-title"><b>{entry.name}</b><strong>{entry.power == null ? "—" : entry.power}</strong></div>
      <div className="founding-gameplay-card-keywords">{keyword}</div>
    </div>
  );
}

function FoundingGameplayCardFocus({ entry, art: suppliedArt, dialogRef, onKeyDown }) {
  const art = suppliedArt || resolveFoundingDeckCardArt(entry);
  const color = getFoundingGameplayDoctrineColor(entry.doctrine);
  const traits = Array.isArray(entry.traits) ? entry.traits.join(" / ") : "";
  const rules = Array.isArray(entry.rulesText) ? entry.rulesText : [];
  return (
    <aside
      data-card-focus
      ref={dialogRef}
      className="claude-founding-card-focus"
      role="dialog"
      aria-modal="true"
      aria-labelledby="claude-founding-card-focus-title"
      tabIndex={-1}
      style={{ "--founding-card-doctrine": color }}
      onKeyDown={onKeyDown}
    >
      <div className="founding-gameplay-card-focus-doctrine-bar"></div>
      <div className="founding-gameplay-card-focus-meta">
        <span>{String(entry.doctrine || "COMMAND").toUpperCase() + " · " + (entry.kind === "command" ? "COMMAND" : "MEKA")}</span>
        <b>{entry.cost == null ? "COMMAND" : "COST " + entry.cost}</b>
      </div>
      <div className="founding-gameplay-card-focus-art" style={art ? { backgroundImage: "url(\"" + art + "\")" } : undefined}><span>{art ? "" : entry.code}</span></div>
      <div className="founding-gameplay-card-focus-title">
        <span>{entry.code}</span>
        <h4 id="claude-founding-card-focus-title">{entry.name}</h4>
        <b>{traits}</b>
      </div>
      <div className="founding-gameplay-card-focus-keywords">{rules.map((rule) => <p key={rule}>{rule}</p>)}</div>
      <div className="founding-gameplay-card-focus-power"><span>FOUNDING STARTER ARCHIVE · {entry.code}</span>{entry.power != null && <b>POWER <strong>{entry.power}</strong></b>}</div>
    </aside>
  );
}

function getFoundingJourneyDefaultViewedStep(stage) {
  if (["challenge_accepted", "training_complete"].includes(stage)) return 3;
  if (stage === "deployment_assignment_required") return 2;
  return 1;
}

function getFoundingJourneyMaxViewedStep(stage) {
  if (["challenge_accepted", "training_complete"].includes(stage)) return 3;
  if (stage === "deployment_assignment_required") return 2;
  return 1;
}

function resolveFoundingJourneyRequestedStep(requestedView, defaultViewedStep, maxViewedStep) {
  const requestedSteps = {
    challenge: 1,
    assignment: 2,
    receipt: 3
  };
  const requestedStep = requestedSteps[requestedView];
  const safeDefault = Math.max(1, Math.min(defaultViewedStep, maxViewedStep));
  if (!Number.isInteger(requestedStep) || requestedStep > maxViewedStep) return safeDefault;
  return requestedStep;
}

function FoundingJourneyProgress({ stage, viewedStep, maxViewedStep, onSelectStep, interactive = true }) {
  const items = ["CHALLENGE", "CREW SELECTION", "ISSUANCE REVIEW"];
  const authoritativeStep = getFoundingJourneyDefaultViewedStep(stage, false);
  if (!interactive) {
    return (
      <div aria-label="Founding Journey progress status" className="claude-founding-progress is-recovery" role="status">
        {items.map((label, index) => (
          <div key={label} className={index + 1 < authoritativeStep ? "is-complete" : ""}>
            <span>{String(index + 1).padStart(2, "0")}</span>
            <b>{label}</b>
            <em>RECOVERY</em>
          </div>
        ))}
      </div>
    );
  }
  return (
    <nav aria-label="Founding Journey progress" className="claude-founding-progress" style={{ display: "flex", borderBottom: "1px solid #23252b" }}>
      {items.map((label, index) => {
        const step = index + 1;
        const unlocked = step <= maxViewedStep;
        const stepIsActive = step === viewedStep;
        const stepIsComplete = step < authoritativeStep;
        const state = stepIsComplete ? "COMPLETE" : stepIsActive ? "CURRENT" : unlocked ? "OPEN" : "LOCKED";
        return (
          <button
            type="button"
            key={label}
            className={(stepIsComplete ? "is-complete" : "") + (stepIsActive ? " is-active" : "")}
            aria-current={stepIsActive ? "step" : undefined}
            disabled={!unlocked}
            tabIndex={unlocked ? undefined : -1}
            onClick={() => onSelectStep(step)}
            style={{
              flex: 1,
              minWidth: 0,
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              gap: 9,
              padding: "11px 14px",
              borderRight: step === items.length ? "none" : "1px solid #23252b",
              borderTop: 0,
              borderBottom: 0,
              borderLeft: 0,
              cursor: unlocked ? "pointer" : "default",
              background: stepIsActive ? "#e8c447" : "transparent",
              color: stepIsActive ? "#121006" : stepIsComplete ? "#8a8779" : "#4f4d46",
              fontFamily: "'IBM Plex Mono', monospace",
              fontSize: 10,
              letterSpacing: 2,
              textTransform: "uppercase"
            }}
          >
            <span>{String(step).padStart(2, "0")}</span>
            <b>{label}</b>
            <em>{state}</em>
          </button>
        );
      })}
    </nav>
  );
}

function FoundingCommandShell({ organization = {}, stage, viewedStep, maxViewedStep, onSelectStep, onReturn, statusLabel, children, dock, progressMode = "interactive" }) {
  return (
    <section
      className={"founding-command-shell claude-founding-command stage-" + (stage || "starter_deck_ready")}
      aria-label="Founding Journey"
      data-screen="founding-command-channel"
      data-claude-founding-journey="true"
      data-semantic-hook="founding-journey-command"
      data-handoff-state={stage}
      data-founding-journey-stage={stage}
    >
      <div className="claude-founding-scanlines" aria-hidden="true"></div>
      <ArchiveStatusStrip compact />
      <header className="founding-command-header">
        <button className="founding-command-return" type="button" onClick={onReturn}>MY HANGAR</button>
        <div className="founding-command-identity"><span>COMMAND CHANNEL / FOUNDING JOURNEY</span><h2>{organization.name || "ORGANIZATION DATA PENDING"}</h2></div>
        <b className="founding-command-link-state">{statusLabel || "ARCHIVE LINK ONLINE"}</b>
      </header>
      <FoundingJourneyProgress stage={stage} viewedStep={viewedStep} maxViewedStep={maxViewedStep} onSelectStep={onSelectStep || (() => {})} interactive={progressMode !== "recovery"} />
      <div className="founding-command-body">{children}</div>
      {dock}
    </section>
  );
}

function FoundingAssistantStrip({ organization, signal = "ONBOARDING LINK", title, children }) {
  const assistantName = String(organization.assistantName || "").trim() || "ASSISTANT DATA PENDING";
  const avatarSource = organization.avatarUrl ? versionAssetUrl(organization.avatarUrl) : "";
  return (
    <div className="claude-founding-assistant" style={{ display: "flex", alignItems: "center", gap: 12, padding: "9px 22px", borderBottom: "1px solid #23252b", background: "rgba(76,200,217,.04)" }}>
      {avatarSource
        ? <img data-asset-role="virtual-assistant" data-source-aspect="1:1" data-rendered-crop="1:1 cover, center" src={avatarSource} alt={assistantName + " virtual assistant"} loading="eager" decoding="async" />
        : <div className="founding-assistant-art-pending" data-asset-state="missing" aria-label="Assistant visual data pending">VISUAL DATA PENDING</div>}
      <div style={{ minWidth: 0 }}>
        <span style={{ fontFamily: "'IBM Plex Mono', monospace", fontSize: 8.5, letterSpacing: 2.5, color: "#4cc8d9" }}>{assistantName} / {signal}</span>
        {title && <b>{title}</b>}
        <p style={{ margin: "2px 0 0", fontFamily: "'IBM Plex Mono', monospace", fontSize: 11.5, lineHeight: 1.5, color: "#c9c4b4" }}>{children}</p>
      </div>
    </div>
  );
}

function FoundingGuidancePanel({ organization = {}, scope = "founding", messages = [], contextKey }) {
  const steps = Array.isArray(messages) && messages.length ? messages : [{ title: "GUIDANCE DATA PENDING", copy: "Command guidance is unavailable. Return to My Hangar and try again." }];
  const [messageIndex, setMessageIndex] = useState(0);
  const [dismissed, setDismissed] = useState(false);
  const assistantName = String(organization.assistantName || "").trim() || "ASSISTANT DATA PENDING";
  const avatarSource = organization.avatarUrl ? versionAssetUrl(organization.avatarUrl) : "";
  const message = steps[messageIndex % steps.length];

  useEffect(() => {
    setMessageIndex(0);
    setDismissed(false);
  }, [contextKey]);

  function advanceGuidance() {
    if (dismissed) return;
    setMessageIndex((current) => (current + 1) % steps.length);
  }

  function handleGuidanceKeyDown(event) {
    if (dismissed || (event.key !== "Enter" && event.key !== " ")) return;
    event.preventDefault();
    advanceGuidance();
  }

  function dismissGuidance(event) {
    event.stopPropagation();
    setDismissed(true);
  }

  return (
    <aside
      className={"founding-guidance-panel" + (dismissed ? " is-dismissed" : "")}
      data-guidance-scope={scope}
      aria-label={assistantName + " guidance"}
      role={dismissed ? undefined : "button"}
      tabIndex={dismissed ? -1 : 0}
      onClick={advanceGuidance}
      onKeyDown={handleGuidanceKeyDown}
    >
      {dismissed ? (
        <button type="button" className="founding-guidance-reopen" data-guidance-action="reopen" aria-label={"Reopen " + assistantName + " guidance"} onClick={() => setDismissed(false)}>
          {avatarSource
            ? <img data-asset-role="virtual-assistant" src={avatarSource} alt="" aria-hidden="true" />
            : <span className="founding-guidance-avatar-pending" aria-hidden="true">VISUAL<br />PENDING</span>}
          <span>REOPEN GUIDANCE</span>
        </button>
      ) : (
        <>
          <header className="founding-guidance-head">
            <div className="founding-guidance-avatar">
              {avatarSource
                ? <img data-asset-role="virtual-assistant" data-source-aspect="1:1" data-rendered-crop="1:1 cover, center" src={avatarSource} alt={assistantName + " virtual assistant"} loading="eager" decoding="async" />
                : <span className="founding-guidance-avatar-pending" data-asset-state="missing">VISUAL DATA PENDING</span>}
            </div>
            <div className="founding-guidance-identity">
              <b>{assistantName}</b>
              <span>ONBOARDING LINK · {messageIndex + 1} / {steps.length}</span>
            </div>
          </header>
          <div className="founding-guidance-copy" aria-live="polite" aria-label={[message.title, message.copy].filter(Boolean).join(". ")}>
            <p aria-hidden="true">{message.copy}</p>
          </div>
          <footer className="founding-guidance-footer founding-guidance-actions">
            <span data-guidance-action="advance" tabIndex={-1}>TAP TO ADVANCE ▶</span>
            <button type="button" data-guidance-action="dismiss" onClick={dismissGuidance}>DISMISS</button>
          </footer>
        </>
      )}
    </aside>
  );
}

function FoundingDoctrinePair({ starterDeck }) {
  const doctrines = starterDeck && Array.isArray(starterDeck.primaryDoctrines) && starterDeck.primaryDoctrines.length === 2
    ? starterDeck.primaryDoctrines
    : [];
  if (doctrines.length !== 2) {
    return <div className="claude-founding-doctrine-error" role="alert">DOCTRINE IDENTITY PENDING</div>;
  }
  return (
    <div className="claude-founding-doctrines" aria-label={doctrines.join(" and ") + " doctrine deck"}>
      {doctrines.map((doctrine) => (
        <div className="claude-founding-doctrine" key={doctrine}>
          <img src={versionAssetUrl(FOUNDING_DOCTRINE_ICON_URLS[doctrine])} alt="" aria-hidden="true" />
          <span>{doctrine.toUpperCase()}</span>
          <b>{starterDeck.doctrineCounts && starterDeck.doctrineCounts[doctrine] || 0} CARDS</b>
        </div>
      ))}
    </div>
  );
}

function foundingTrueBondEffectText(effect) {
  if (!effect || typeof effect !== "object") return "EFFECT DATA PENDING";
  const quantity = Number(effect.count ?? effect.amount ?? 1);
  const count = Number.isFinite(quantity) && quantity > 0 ? quantity : 1;
  const plural = count === 1 ? "" : "s";
  if (effect.op === "draw") return "Draw " + count + " card" + plural + " from your deck.";
  if (effect.op === "ready") {
    if (effect.target === "reactor") return "Ready " + count + " Reactor" + plural + ".";
    if (effect.target === "one_other_friendly_meka") return "Ready " + count + " other friendly Meka" + plural + ".";
    if (effect.target === "one_friendly_meka") return "Ready " + count + " friendly Meka" + plural + ".";
    if (effect.target === "self" || effect.target === "bonded_meka") return "Ready your Signature Meka.";
  }
  if (effect.op === "modify_power") {
    const amount = Number(effect.amount ?? effect.count ?? 0);
    const signedAmount = amount > 0 ? "+" + amount : String(amount);
    const target = effect.target === "one_friendly_meka" ? "1 friendly Meka" : "your Signature Meka";
    const duration = effect.duration === "this_turn" ? " this turn" : (effect.duration === "this_attack" ? " during this attack" : "");
    return "Give " + target + " " + signedAmount + " Power" + duration + ".";
  }
  if (effect.op === "grant_keyword" && String(effect.keyword || "").trim()) return "Your Signature Meka gains " + String(effect.keyword).trim() + ".";
  if (effect.op === "return_from_scrap") {
    const kind = effect.cardKind === "meka" ? "Meka" : "card";
    const cost = Number.isInteger(effect.maxCost) ? " with Cost " + effect.maxCost + " or less" : "";
    const target = effect.excludeSelf ? (count === 1 ? "another " + kind : count + " other " + kind + plural) : count + " " + kind + plural;
    return (effect.optional ? "You may return " : "Return ") + target + cost + " from your Scrap to your hand.";
  }
  if (effect.op === "put_scrap_in_reactor") return (effect.optional ? "You may put " : "Put ") + count + " card" + plural + " from your Scrap into your Reactor" + (effect.tapped ? " tapped" : "") + ".";
  if (effect.op === "prevent_intercept" && effect.target === "one_enemy_meka") return "Choose 1 enemy Meka; it cannot Intercept " + (effect.duration === "this_attack" ? "during this attack" : "this turn") + ".";
  if (effect.op === "tap" && effect.target === "one_enemy_meka") return "Tap " + count + " enemy Meka" + plural + ".";
  if (effect.text) return String(effect.text);
  return "EFFECT DATA PENDING";
}

function foundingManifestKindLabel(kind) {
  if (kind === "mk") return "FOUNDING MEKA";
  if (kind === "md") return "MEKA FRAMES";
  return "COMMANDS";
}

function FoundingDeckManifest({ starterDeck, onClose }) {
  const entries = Array.isArray(starterDeck && starterDeck.entries) ? starterDeck.entries : [];
  const [focusedCode, setFocusedCode] = useState("");
  const manifestRef = useRef(null);
  const closeRef = useRef(null);
  const cardFocusRef = useRef(null);
  const cardFocusOpenerRef = useRef(null);
  const focusedCard = entries.find((entry) => entry.code === focusedCode) || null;
  const focusedCardArt = resolveFoundingDeckCardArt(focusedCard);
  const groups = ["mk", "md", "command"].map((kind) => ({
    kind,
    entries: entries.filter((entry) => entry.kind === kind)
  }));

  useEffect(() => {
    if (closeRef.current) closeRef.current.focus();
  }, []);

  useEffect(() => {
    if (!focusedCard || !cardFocusRef.current) return;
    cardFocusRef.current.focus();
  }, [focusedCode]);

  function openCardFocus(entry) {
    cardFocusOpenerRef.current = document.activeElement;
    setFocusedCode(entry.code);
  }

  function closeCardFocus() {
    setFocusedCode("");
    window.requestAnimationFrame(() => {
      if (cardFocusOpenerRef.current && typeof cardFocusOpenerRef.current.focus === "function") cardFocusOpenerRef.current.focus();
    });
  }

  function handleCardFocusKeyDown(event) {
    if (event.key === "Escape") {
      event.preventDefault();
      event.stopPropagation();
      closeCardFocus();
      return;
    }
    if (event.key !== "Tab" || !cardFocusRef.current) return;
    event.preventDefault();
    cardFocusRef.current.focus();
  }

  function handleManifestKeyDown(event) {
    if (event.key === "Escape") {
      event.preventDefault();
      event.stopPropagation();
      onClose();
      return;
    }
    if (event.key !== "Tab" || !manifestRef.current || focusedCard) return;
    const controls = [...manifestRef.current.querySelectorAll('button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])')];
    if (!controls.length) return;
    const first = controls[0];
    const last = controls[controls.length - 1];
    if (event.shiftKey && document.activeElement === first) {
      event.preventDefault();
      last.focus();
    } else if (!event.shiftKey && document.activeElement === last) {
      event.preventDefault();
      first.focus();
    }
  }

  return (
    <div className="claude-founding-manifest-backdrop" onClick={onClose}>
      <section
        ref={manifestRef}
        className="claude-founding-manifest"
        role="dialog"
        aria-modal="true"
        aria-label="Founding Deck manifest"
        onClick={(event) => event.stopPropagation()}
        onKeyDown={handleManifestKeyDown}
      >
        <header className="claude-founding-manifest-head">
          <div><span>DECK MANIFEST / {starterDeck.name}</span><h3>Full Manifest · {starterDeck.total || 40} Cards · {entries.length} Unique Prints</h3></div>
          <div className="claude-founding-manifest-head-actions">
            <b className="claude-founding-manifest-total">{starterDeck.total || 40} CARDS</b>
            <button ref={closeRef} type="button" className="claude-founding-manifest-close" onClick={onClose}>CLOSE</button>
          </div>
        </header>
        <div className="claude-founding-manifest-body">
          <div className="claude-founding-manifest-groups">
            {groups.map((group) => (
              <section key={group.kind} className={"claude-founding-manifest-group kind-" + group.kind}>
                <header>
                  <span>{foundingManifestKindLabel(group.kind)}</span>
                  <b>{group.entries.reduce((sum, entry) => sum + entry.quantity, 0)} {group.entries.reduce((sum, entry) => sum + entry.quantity, 0) === 1 ? "CARD" : "CARDS"}</b>
                </header>
                <div className="claude-founding-manifest-grid">
                  {group.entries.map((entry) => (
                    <button
                      type="button"
                      className={"claude-founding-manifest-card" + (focusedCode === entry.code ? " is-focused" : "")}
                      key={entry.code}
                      onClick={() => openCardFocus(entry)}
                    >
                      <FoundingGameplayCardVisual entry={entry} />
                      <div className="claude-founding-manifest-card-quantity"><span>{foundingManifestKindLabel(entry.kind)}</span><b>x{entry.quantity}</b></div>
                    </button>
                  ))}
                </div>
              </section>
            ))}
          </div>
          {focusedCard && (
            <div className="claude-founding-card-focus-backdrop" onClick={closeCardFocus}>
              <FoundingGameplayCardFocus entry={focusedCard} art={focusedCardArt} dialogRef={cardFocusRef} onKeyDown={handleCardFocusKeyDown} />
            </div>
          )}
        </div>
        <footer className="claude-founding-manifest-foot">
          <span>FOUNDING STARTER / SEALED</span>
          <b>Starter prints use the sealed deck copy exemption. Constructed decks use the normal four-copy limit.</b>
        </footer>
      </section>
    </div>
  );
}

function getFoundingMekaPrintEntries(entries) {
  const playableEntries = Array.isArray(entries)
    ? entries.filter((entry) => entry && ["mk", "md"].includes(entry.kind))
    : [];
  const entryByCode = new Map();
  for (const entry of playableEntries) {
    const key = String(entry.code || "").trim().toUpperCase();
    if (!key) continue;
    const existing = entryByCode.get(key);
    if (existing) {
      existing.quantity += Number(entry.quantity || 0);
      continue;
    }
    entryByCode.set(key, { ...entry, code: key, quantity: Number(entry.quantity || 0) });
  }
  return [...entryByCode.values()];
}

function getFoundingCommandPrintEntries(entries) {
  const playableEntries = Array.isArray(entries)
    ? entries.filter((entry) => entry && entry.kind === "command")
    : [];
  const entryByCode = new Map();
  for (const entry of playableEntries) {
    const key = String(entry.code || "").trim().toUpperCase();
    if (!key) continue;
    const existing = entryByCode.get(key);
    if (existing) {
      existing.quantity += Number(entry.quantity || 0);
      continue;
    }
    entryByCode.set(key, { ...entry, code: key, quantity: Number(entry.quantity || 0) });
  }
  return [...entryByCode.values()];
}

function getFoundingTrueBondRules(entry, protocol) {
  const label = String(protocol && protocol.label || "").trim();
  if (!label) return [];
  const prefix = ("TRUE BOND // " + label + ":").toLowerCase();
  const rules = Array.isArray(entry && entry.rulesText) ? entry.rulesText : [];
  return rules
    .map((rule) => String(rule || "").trim())
    .filter((rule) => rule.toLowerCase().startsWith(prefix));
}

function getFoundingPilotDeckSync(crew, entries, trueBondPossible) {
  const bondTraits = [...new Set((Array.isArray(crew?.pilot?.bondTraits) ? crew.pilot.bondTraits : [])
    .map((trait) => String(trait || "").trim().toUpperCase())
    .filter(Boolean))];
  const mekaEntries = Array.isArray(entries) ? entries : [];
  const mekaCopies = mekaEntries.reduce((sum, entry) => sum + Number(entry?.quantity || 0), 0);
  if (!bondTraits.length || !mekaCopies) {
    return {
      ready: false,
      percentage: 0,
      percentageLabel: "PENDING",
      matchedCopies: 0,
      mekaCopies,
      grade: "SYNC DATA PENDING",
      color: "#565349",
      traitLabel: bondTraits.join(" / ")
    };
  }
  const matchedCopies = mekaEntries.reduce((sum, entry) => {
    const entryTraits = (Array.isArray(entry?.traits) ? entry.traits : [])
      .map((trait) => String(trait || "").trim().toUpperCase());
    return sum + (entryTraits.some((trait) => bondTraits.includes(trait)) ? Number(entry?.quantity || 0) : 0);
  }, 0);
  const percentage = Math.min(100, Math.round((trueBondPossible ? 55 : 10) + (matchedCopies / mekaCopies) * 45));
  return {
    ready: true,
    percentage,
    percentageLabel: percentage + "%",
    matchedCopies,
    mekaCopies,
    grade: trueBondPossible ? "TRUE BOND POSSIBLE" : percentage >= 35 ? "TRAIT SYNC ONLY" : "LOW COMPATIBILITY",
    color: trueBondPossible ? "#5da864" : percentage >= 35 ? "#e8c447" : "#d24a43",
    traitLabel: bondTraits.join(" / ")
  };
}

function getFoundingCrewDeckSync(crew) {
  const code = (value) => String(value || "").trim().toUpperCase();
  const entries = getFoundingMekaPrintEntries(crew?.trainingLoadout?.entries);
  const signatureMeka = entries.find((entry) => code(entry?.code) === code(crew?.signatureMeka?.id));
  const protocol = crew?.signatureTrueBond || {};
  const trueBondPossible = Boolean(
    protocol.label
    && protocol.timing
    && code(protocol.pilotCode) === code(crew?.pilot?.id)
    && getFoundingTrueBondRules(signatureMeka, protocol).length > 0
  );
  return getFoundingPilotDeckSync(crew, entries, trueBondPossible);
}

function FoundingPublicationArt({ entry }) {
  const art = resolveFoundingDeckCardArt(entry);
  const [failedSource, setFailedSource] = useState("");
  const failed = Boolean(art && failedSource === art);

  useEffect(() => {
    setFailedSource("");
  }, [art]);

  return (
    <figure
      className="crew-assignment-card-publication-art"
      aria-label={entry.code + " gameplay publication art"}
      data-publication-state={!art ? "missing" : failed ? "error" : "ready"}
    >
      {art && !failed
        ? <img data-publication-art src={art} alt={entry.code + " " + entry.name + " gameplay publication card"} loading="eager" decoding="async" onError={() => setFailedSource(art)} />
        : <span>VISUAL DATA PENDING</span>}
    </figure>
  );
}

function FoundingDeploymentAssignment({ organization, journey, busy, error, onAssign, onRefresh, onReturn, viewedStep = 2, maxViewedStep = 2, onSelectJourneyStep, locked = false }) {
  const eligibleCrews = Array.isArray(journey && journey.eligibleCrews) ? journey.eligibleCrews : [];
  const assignedCrewId = journey && journey.battleAssignment ? journey.battleAssignment.crewId : "";
  const [selectedCrewId, setSelectedCrewId] = useState(() => assignedCrewId || (eligibleCrews[0] && eligibleCrews[0].crewId) || "");
  const [focusedMekaCode, setFocusedMekaCode] = useState("");
  const [focusedCommandCode, setFocusedCommandCode] = useState("");
  const [refreshing, setRefreshing] = useState(false);
  const crewRailRef = useRef(null);
  const crewAssetPreloadsRef = useRef([]);

  useEffect(() => {
    setSelectedCrewId((current) => {
      if (eligibleCrews.some((crew) => crew.crewId === current)) return current;
      return assignedCrewId || (eligibleCrews[0] && eligibleCrews[0].crewId) || "";
    });
  }, [assignedCrewId, eligibleCrews.map((crew) => crew.crewId).join("|")]);

  useEffect(() => {
    const assetUrls = eligibleCrews.flatMap((candidate) => [getCrewPilotFaceSource(candidate), candidate.signatureMeka.image]).filter(Boolean);
    const preloaders = assetUrls.map((assetUrl) => {
      const image = new Image();
      image.src = assetUrl;
      if (typeof image.decode === "function") image.decode().catch(() => {});
      return image;
    });
    crewAssetPreloadsRef.current = preloaders;
    return () => {
      if (crewAssetPreloadsRef.current === preloaders) crewAssetPreloadsRef.current = [];
    };
  }, [eligibleCrews.map((candidate) => [candidate.crewId, getCrewPilotFaceSource(candidate), candidate.signatureMeka.image].join(":" )).join("|")]);

  const crew = eligibleCrews.find((candidate) => candidate.crewId === selectedCrewId) || eligibleCrews[0] || null;
  const loadout = crew && crew.trainingLoadout ? crew.trainingLoadout : {};
  const starterProgram = crew && crew.starterProgram ? crew.starterProgram : {};
  const hasValidDoctrines = Boolean(Array.isArray(loadout.primaryDoctrines) && loadout.primaryDoctrines.length === 2);
  const doctrines = hasValidDoctrines
    ? loadout.primaryDoctrines
    : [];
  const manifestEntries = Array.isArray(loadout.entries) ? loadout.entries : [];
  const mekaEntries = getFoundingMekaPrintEntries(manifestEntries);
  const commandEntries = getFoundingCommandPrintEntries(manifestEntries);
  const signatureMekaEntry = mekaEntries.find((entry) => String(entry.code || "").toUpperCase() === String(crew && crew.signatureMeka && crew.signatureMeka.id || "").toUpperCase()) || null;
  const defaultMeka = signatureMekaEntry || mekaEntries[0] || null;
  const focusedMeka = mekaEntries.find((entry) => entry.code === focusedMekaCode) || defaultMeka;
  const focusedCommand = commandEntries.find((entry) => entry.code === focusedCommandCode) || null;
  const focusedMekaIsSignature = Boolean(focusedMeka && String(focusedMeka.code || "").toUpperCase() === String(crew && crew.signatureMeka && crew.signatureMeka.id || "").toUpperCase());
  const manifestTotal = manifestEntries.reduce((sum, entry) => sum + Number(entry && entry.quantity || 0), 0);
  const protocol = crew && crew.signatureTrueBond ? crew.signatureTrueBond : {};
  const signatureTrueBondRules = getFoundingTrueBondRules(signatureMekaEntry, protocol);
  const hasValidProtocol = Boolean(
    protocol.label
    && protocol.timing
    && String(protocol.pilotCode || "").toUpperCase() === String(crew && crew.pilot && crew.pilot.id || "").toUpperCase()
    && signatureTrueBondRules.length > 0
  );
  const deckSync = getFoundingPilotDeckSync(crew, mekaEntries, hasValidProtocol);
  const hasValidLoadout = Number(loadout.cardCount) === 40 && manifestTotal === 40 && manifestEntries.length > 0;
  useEffect(() => {
    setFocusedMekaCode(defaultMeka ? defaultMeka.code : "");
    setFocusedCommandCode("");
  }, [crew && crew.crewId, defaultMeka && defaultMeka.code]);

  function selectCrew(nextCrewId) {
    if (busy || locked) return;
    if (!eligibleCrews.some((candidate) => candidate.crewId === nextCrewId)) return;
    setSelectedCrewId(nextCrewId);
  }

  function handleCrewRailKeyDown(event, index) {
    if (busy || locked) return;
    let nextIndex = index;
    if (event.key === "ArrowDown") nextIndex = Math.min(eligibleCrews.length - 1, index + 1);
    else if (event.key === "ArrowUp") nextIndex = Math.max(0, index - 1);
    else if (event.key === "Home") nextIndex = 0;
    else if (event.key === "End") nextIndex = eligibleCrews.length - 1;
    else return;
    event.preventDefault();
    const nextCrew = eligibleCrews[nextIndex];
    if (!nextCrew) return;
    selectCrew(nextCrew.crewId);
    const options = crewRailRef.current ? crewRailRef.current.querySelectorAll('[role="option"]') : [];
    if (options[nextIndex]) options[nextIndex].focus();
  }

  async function refreshCrews() {
    if (refreshing || typeof onRefresh !== "function") return;
    setRefreshing(true);
    try {
      await onRefresh();
    } finally {
      setRefreshing(false);
    }
  }

  if (!crew) {
    return (
      <FoundingCommandShell organization={organization} stage={journey && journey.stage} viewedStep={viewedStep} maxViewedStep={maxViewedStep} onSelectStep={onSelectJourneyStep} onReturn={onReturn} dock={<footer className="founding-command-dock crew-assignment-dock"><button type="button" className="crew-assignment-primary" onClick={refreshCrews} disabled={refreshing}>{refreshing ? "REFRESHING..." : "REFRESH CREWS"}</button></footer>}>
        <main className="crew-assignment-screen is-pending" data-screen="crew-assignment" data-context="post-challenge-acceptance" data-founding-journey-stage="deployment_assignment_required">
          <div className="crew-assignment-scan" aria-hidden="true"></div>
          <section className="crew-assignment-pending" role="region" aria-label="Deployment assignment status">
            <span>CREW DATA PENDING</span>
            <p>Command cannot open training until a complete licensed Crew is available.</p>
            {error && <p className="crew-assignment-error" role="alert">{error}</p>}
          </section>
        </main>
      </FoundingCommandShell>
    );
  }

  const assistantCount = eligibleCrews.length === 1 ? "One" : eligibleCrews.length === 2 ? "Two" : String(eligibleCrews.length);
  const crewGuidanceMessages = [
    { title: "SELECT A LICENSED CREW", copy: assistantCount + " licensed " + (eligibleCrews.length === 1 ? "Crew is" : "Crews are") + " ready. Current selection: " + crew.pilot.callsign + " with " + crew.signatureMeka.id + " / " + crew.signatureMeka.codename + "." },
    { title: "CREW = PILOT + SIGNATURE MEKA", copy: "Choose the pairing whose playstyle, Bond Traits, and True Bond protocol fit how you want to answer the challenge." },
    { title: "A DECK CONTAINS EXACTLY 40 CARDS", copy: "Inspect the Meka and Command cards in the selected Deck. The Pilot remains outside those 40 cards." },
    { title: "VERIFY YOUR DEPLOYMENT PACKAGE", copy: "DEPLOYMENT PACKAGE = CREW + DECK. Confirm both Doctrines, the True Bond protocol, and the exact " + manifestTotal + " / 40 manifest." },
    { title: "ISSUE THE PACKAGE", copy: "Lock this Crew to issue its Deck and form the Deployment Package for the upcoming battle." }
  ];

  return (
    <FoundingCommandShell organization={organization} stage={journey && journey.stage} viewedStep={viewedStep} maxViewedStep={maxViewedStep} onSelectStep={onSelectJourneyStep} onReturn={onReturn} dock={<footer className="founding-command-dock crew-assignment-dock"><div><span>DEPLOYMENT PACKAGE</span><b>{crew.pilot.callsign} + {crew.signatureMeka.id} / {crew.signatureMeka.codename} · {starterProgram.name || "DECK DATA PENDING"}</b></div><button type="button" className={"crew-assignment-primary" + (busy ? " is-loading" : "")} data-cta="lock_founding_crew" onClick={() => onAssign(crew.crewId)} disabled={busy || locked || !hasValidDoctrines || !hasValidLoadout || !hasValidProtocol}>{locked ? "PACKAGE ISSUED" : busy ? "ISSUING..." : assignedCrewId ? "UPDATE CREW & DECK" : "LOCK THIS CREW & ISSUE DECK"}</button></footer>}>
    <>
    <main className="crew-assignment-screen" data-screen="crew-assignment" data-context="post-challenge-acceptance" data-founding-journey-stage="deployment_assignment_required" data-selected-crew={crew.crewId}>
      <div className="crew-assignment-scan" aria-hidden="true"></div>

      <section className="crew-assignment-grid founding-crew-layout">
        <aside className="crew-assignment-rail" ref={crewRailRef} role="listbox" aria-label="Eligible Crews" aria-busy={busy}>
          <header><span>LICENSED CREWS</span><b>{String(eligibleCrews.length).padStart(2, "0")} READY</b></header>
          <div className="crew-assignment-rail-list">
            {eligibleCrews.map((candidate, index) => {
              const selected = candidate.crewId === crew.crewId;
              const candidateSync = getFoundingCrewDeckSync(candidate);
              return (
                <button
                  type="button"
                  role="option"
                  aria-selected={selected}
                  tabIndex={selected ? 0 : -1}
                  disabled={busy || locked}
                  className={"crew-assignment-rail-row" + (selected ? " is-selected" : "")}
                  key={candidate.crewId}
                  data-crew-id={candidate.crewId}
                  data-crew-source={candidate.sourceType}
                  onClick={() => selectCrew(candidate.crewId)}
                  onKeyDown={(event) => handleCrewRailKeyDown(event, index)}
                >
                  <span className="crew-assignment-rail-face" data-asset-role="crew-pilot-face">
                    {getCrewPilotFaceSource(candidate)
                      ? <img src={getCrewPilotFaceSource(candidate)} alt={candidate.pilot.callsign + " Pilot face"} loading="eager" decoding="async" style={{ objectPosition: candidate.pilot.faceImagePosition || "center 20%" }} />
                      : <span className="crew-assignment-pilot-face-missing" data-asset-state="missing" aria-label={candidate.pilot.callsign + " Pilot face unavailable"}>PLT</span>}
                  </span>
                  <span className="crew-assignment-rail-copy">
                    <em>{candidate.sourceLabel || candidate.sourceType}</em>
                    <b>{candidate.pilot.callsign}</b>
                    <small>{candidate.signatureMeka.id} / {candidate.signatureMeka.codename}</small>
                  </span>
                  <span className="crew-assignment-rail-status">
                    <strong>{selected ? "SELECTED" : "READY"}</strong>
                    <b>SYNC {candidateSync.ready ? candidateSync.percentageLabel : "PENDING"}</b>
                  </span>
                </button>
              );
            })}
          </div>
          <p className="crew-assignment-rail-helper">CREW = PILOT + SIGNATURE MEKA. DEPLOYMENT PACKAGE = CREW + SEALED 40-CARD DECK.</p>
        </aside>

        <p className="crew-assignment-announcement" role="status" aria-live="polite" aria-atomic="true">Selected {crew.pilot.callsign} with {crew.signatureMeka.id} {crew.signatureMeka.codename}.</p>
        <figure className="crew-assignment-meka-stage">
          <div className="crew-assignment-meka-hero">
            <div className="crew-assignment-meka-visual" data-asset-role="crew-meka"><img data-asset-role="deployment-meka" src={crew.signatureMeka.image} alt={crew.signatureMeka.id + " " + crew.signatureMeka.codename} loading="eager" decoding="async" /></div>
            <figcaption><span>SIGNATURE MEKA</span><b>{crew.signatureMeka.id} / {crew.signatureMeka.codename}</b></figcaption>
          </div>
          <section className="crew-assignment-meka-catalog" aria-label={crew.pilot.callsign + " Meka cards in selected deck"}>
            <header>
              <div><span>MEKA PRINTS / SELECTED DECK · INSPECT BEFORE CREW LOCK</span></div>
              <strong>{mekaEntries.reduce((sum, entry) => sum + Number(entry.quantity || 0), 0)} MEKA CARDS</strong>
            </header>
            <div className="crew-assignment-meka-browser">
              <div className="crew-assignment-meka-card-list founding-meka-prints-grid" data-meka-prints-grid role="list" aria-label="Inspectable Meka prints">
                {mekaEntries.map((entry) => (
                  <button
                    type="button"
                    role="listitem"
                    key={entry.code}
                    className={!focusedCommand && focusedMeka && focusedMeka.code === entry.code ? "is-selected" : ""}
                    data-crew-meka-card={entry.code}
                    data-card-code={entry.code}
                    aria-pressed={focusedMekaCode === entry.code}
                    aria-label={entry.code + " " + entry.name + ", x" + entry.quantity + " in deck"}
                    onClick={() => {
                      setFocusedMekaCode(entry.code);
                      setFocusedCommandCode("");
                    }}
                  >
                    <div className="crew-assignment-meka-card-art"><FoundingPublicationArt entry={entry} /><span>{entry.code} {entry.name}</span></div>
                    <span>{"x" + entry.quantity + " IN DECK"}</span>
                  </button>
                ))}
              </div>
            </div>
          </section>
          <section className="crew-assignment-meka-catalog crew-assignment-command-catalog" aria-label={crew.pilot.callsign + " Command cards in selected deck"}>
            <header>
              <div><span>COMMAND CARDS / SELECTED DECK · INSPECT BEFORE CREW LOCK</span></div>
              <strong>{commandEntries.reduce((sum, entry) => sum + Number(entry.quantity || 0), 0)} COMMAND CARDS</strong>
            </header>
            <div className="crew-assignment-meka-browser">
              <div className="crew-assignment-meka-card-list founding-command-prints-grid" data-command-prints-grid role="list" aria-label="Inspectable Command cards">
                {commandEntries.map((entry) => (
                  <button
                    type="button"
                    role="listitem"
                    key={entry.code}
                    className={focusedCommand && focusedCommand.code === entry.code ? "is-selected" : ""}
                    data-crew-command-card={entry.code}
                    data-card-code={entry.code}
                    aria-pressed={focusedCommandCode === entry.code}
                    aria-label={entry.code + " " + entry.name + ", x" + entry.quantity + " in deck"}
                    onClick={() => {
                      setFocusedMekaCode("");
                      setFocusedCommandCode(entry.code);
                    }}
                  >
                    <div className="crew-assignment-meka-card-art"><FoundingPublicationArt entry={entry} /><span>{entry.code} {entry.name}</span></div>
                    <span>{"x" + entry.quantity + " IN DECK"}</span>
                  </button>
                ))}
              </div>
            </div>
          </section>
          {focusedCommand ? (
            <article className="crew-assignment-card-dossier" data-command-print-inspector aria-live="polite" aria-label={focusedCommand.name + " card details"} style={{ "--founding-card-doctrine": getFoundingGameplayDoctrineColor(focusedCommand.doctrine) }}>
              <div className="crew-assignment-card-dossier-art-source" aria-hidden="true"><FoundingPublicationArt entry={focusedCommand} /></div>
              <div className="crew-assignment-card-dossier-copy">
                <header className="crew-assignment-card-dossier-meta"><span>{String(focusedCommand.doctrine || "DOCTRINE PENDING").toUpperCase()} / COMMAND</span><strong>x{focusedCommand.quantity} IN DECK</strong></header>
                <div className="crew-assignment-card-dossier-title"><small>{focusedCommand.code}</small><h4>{focusedCommand.name}</h4><span>{Array.isArray(focusedCommand.traits) && focusedCommand.traits.length ? focusedCommand.traits.join(" / ") : "TACTICAL SUPPORT"}</span></div>
                <div className="crew-assignment-card-dossier-stats"><span>COST <b>{focusedCommand.cost == null ? "—" : focusedCommand.cost}</b></span></div>
                <p className="crew-assignment-card-rules">{(Array.isArray(focusedCommand.rulesText) && focusedCommand.rulesText.length ? focusedCommand.rulesText : ["GAMEPLAY RULES PENDING"]).join(" · ")}</p>
                <small>COMMAND SUPPORT PRINT</small>
              </div>
            </article>
          ) : focusedMeka && (
            <article className="crew-assignment-card-dossier" data-meka-print-inspector aria-live="polite" aria-label={focusedMeka.name + " card details"} style={{ "--founding-card-doctrine": getFoundingGameplayDoctrineColor(focusedMeka.doctrine) }}>
              <div className="crew-assignment-card-dossier-art-source" aria-hidden="true"><FoundingPublicationArt entry={focusedMeka} /></div>
              <div className="crew-assignment-card-dossier-copy">
                <header className="crew-assignment-card-dossier-meta"><span>{String(focusedMeka.doctrine || "DOCTRINE PENDING").toUpperCase()} / MEKA</span><strong>x{focusedMeka.quantity} IN DECK</strong></header>
                <div className="crew-assignment-card-dossier-title"><small>{focusedMeka.code}</small><h4>{focusedMeka.name}</h4><span>{Array.isArray(focusedMeka.traits) && focusedMeka.traits.length ? focusedMeka.traits.join(" / ") : "NO PRINTED TRAITS"}</span></div>
                <div className="crew-assignment-card-dossier-stats"><span>COST <b>{focusedMeka.cost == null ? "—" : focusedMeka.cost}</b></span><span>POWER <b>{focusedMeka.power == null ? "—" : focusedMeka.power}</b></span></div>
                <p className="crew-assignment-card-rules">{(Array.isArray(focusedMeka.rulesText) && focusedMeka.rulesText.length ? focusedMeka.rulesText : ["GAMEPLAY RULES PENDING"]).join(" · ")}</p>
                <small>{focusedMekaIsSignature ? crew.pilot.callsign + " SIGNATURE PAIR" : "COMPATIBLE DECK FRAME"}</small>
              </div>
            </article>
          )}
        </figure>

        <div className="crew-assignment-intel" key={crew.crewId} aria-label={crew.pilot.callsign + " deployment preview"}>
            <div className="crew-assignment-pilot">
              <div data-asset-role="crew-pilot-face">
                {getCrewPilotFaceSource(crew)
                  ? <img data-asset-role="deployment-pilot-face" src={getCrewPilotFaceSource(crew)} alt={crew.pilot.callsign + " Pilot face"} loading="eager" decoding="async" style={{ objectPosition: crew.pilot.faceImagePosition || "center 20%" }} />
                  : <span className="crew-assignment-pilot-face-missing" data-asset-state="missing" aria-label={crew.pilot.callsign + " Pilot face unavailable"}>PLT</span>}
              </div>
              <div><span>DEPLOYMENT PILOT</span><h4>{crew.pilot.callsign}</h4><p>{crew.pilot.name}</p><small>PILOT ROLE / {crew.pilot.role || (Array.isArray(crew.pilot.traits) && crew.pilot.traits.length ? crew.pilot.traits.join(" / ") : "LICENSED OPERATOR")}</small></div>
            </div>
            <p className="crew-assignment-playstyle">{crew.playstyle}</p>
            <section className="crew-assignment-deck-sync" aria-label="Pilot and Deck Sync">
              <header><span>PILOT ✕ DECK SYNC</span><b style={{ color: deckSync.color }}>{deckSync.ready ? deckSync.percentageLabel : "PENDING"}</b></header>
              <div
                className="crew-assignment-deck-sync-meter"
                role="progressbar"
                aria-label={crew.pilot.callsign + " Pilot and Deck Sync"}
                aria-valuemin={0}
                aria-valuemax={100}
                aria-valuenow={deckSync.ready ? deckSync.percentage : undefined}
                aria-valuetext={deckSync.ready ? deckSync.percentageLabel + ", " + deckSync.grade : "Sync data pending"}
              >
                <span style={{ width: deckSync.ready ? deckSync.percentageLabel : "0%", background: deckSync.color, boxShadow: "0 0 8px " + deckSync.color }}></span>
              </div>
              <footer><b style={{ color: deckSync.color }}>{deckSync.grade}</b><span>{deckSync.ready ? deckSync.matchedCopies + " / " + deckSync.mekaCopies + " MEKA MATCH " + deckSync.traitLabel : "SYNC DATA PENDING"}</span></footer>
            </section>
            <section className="crew-assignment-protocol">
              <span>SIGNATURE PROTOCOL</span>
              <h5>TRUE BOND // {String(protocol.label || "PROTOCOL PENDING").toUpperCase()}</h5>
              <p>{crew.pilot.callsign} + {crew.signatureMeka.id} — {signatureTrueBondRules.length ? signatureTrueBondRules.join(" ") : "TRUE BOND EFFECT DATA PENDING"}</p>
              {signatureTrueBondRules.length > 0 && <ol>{signatureTrueBondRules.map((rule) => <li key={rule}>{rule}</li>)}</ol>}
            </section>
            <section className="crew-assignment-program">
              <span>TRAINING PROGRAM</span>
              <h5>{starterProgram.name || "DECK DATA PENDING"}</h5>
              {doctrines.length === 2 ? (
                <div className="crew-assignment-doctrines" aria-label={doctrines.join(" and ") + " doctrines"}>
                  {doctrines.map((doctrine) => (
                    <div key={doctrine}>
                      <img src={versionAssetUrl(FOUNDING_DOCTRINE_ICON_URLS[doctrine])} alt="" aria-hidden="true" />
                      <span>{String(doctrine).toUpperCase()}</span>
                    </div>
                  ))}
                </div>
              ) : <div className="crew-assignment-integrity" role="alert">TWO-DOCTRINE PROGRAM REQUIRED</div>}
              <div className="crew-assignment-verification"><span>40-CARD TRAINING DECK</span><b>{hasValidLoadout ? "DECK VERIFIED" : "DECK DATA PENDING"}</b></div>
              <div className="crew-assignment-manifest" aria-label={crew.pilot.callsign + " exact 40-card manifest"}>
                <header><span>EXACT MANIFEST</span><b>{manifestTotal} / 40</b></header>
                {manifestEntries.map((entry) => (
                  <div key={entry.code}><span>{entry.code}</span><b>{entry.name}</b><strong>x{entry.quantity}</strong></div>
                ))}
              </div>
              {(!hasValidDoctrines || !hasValidLoadout || !hasValidProtocol) && <p className="crew-assignment-integrity" role="alert">PACKAGE INTEGRITY REQUIRED · {!hasValidDoctrines ? "2 DOCTRINES" : !hasValidProtocol ? "TRUE BOND" : "40 CARDS"}</p>}
            </section>
        </div>
      </section>

      {error && <div className="crew-assignment-error-bar"><p role="alert"><strong>ISSUANCE FAILED —</strong> {error} YOUR CREW SELECTION IS PRESERVED. RETRY ISSUANCE.</p></div>}
    </main>
    <FoundingGuidancePanel organization={organization} scope="crew-selection" messages={crewGuidanceMessages} contextKey={[crew.crewId, manifestTotal].join(":")} />
    </>
    </FoundingCommandShell>
  );
}

function FoundingDeckMaterializationState({ organization, journey, busy, error, onRetry, onReturn }) {
  const starterDeck = journey && journey.starterDeck || {};
  const pilot = starterDeck.pilot || {};
  const meka = starterDeck.signatureMeka || starterDeck.foundingMeka || {};
  const blocked = journey?.foundingDeckMaterialization?.status === "blocked";
  const completed = journey?.stage === "training_complete";
  return (
    <FoundingCommandShell organization={organization} stage={journey && journey.stage} viewedStep={getFoundingJourneyDefaultViewedStep(journey && journey.stage)} maxViewedStep={getFoundingJourneyMaxViewedStep(journey && journey.stage)} onReturn={onReturn} statusLabel="CREW LOCK PRESERVED" progressMode="recovery">
      <main className={"crew-assignment-screen " + (blocked ? "is-blocked" : "is-pending")} data-screen={blocked ? "founding-materialization-blocked" : "founding-materialization-pending"} data-founding-journey-stage={journey && journey.stage}>
      <section className="crew-assignment-pending" role="status" aria-live="polite">
        <p>{blocked ? "PACKAGE VERIFICATION FAILED" : completed ? "TRAINING COMPLETE / DECK STATUS REQUIRED" : "DECK ISSUANCE IN PROGRESS"}</p>
        <h2>{blocked ? "DEPLOYMENT PACKAGE REPAIR REQUIRED" : completed ? "DECK STATUS REFRESH REQUIRED" : "DECK ISSUANCE PENDING"}</h2>
        <span>{pilot.callsign || pilot.name || "LOCKED PILOT"} / {meka.id || "SIGNATURE MEKA"} {meka.codename ? `/ ${meka.codename}` : ""}</span>
        <p>{blocked
          ? "Your Crew selection is preserved, but the Deployment Package could not be verified. Battle remains locked while Command repairs the Deck."
          : completed
            ? "First Deployment is complete. Refresh the Deck status without selecting your Crew again; training will not reopen."
            : "Your Crew selection is preserved, but its 40-card Deck has not finished issuing. Battle remains locked until this Deployment Package is ready."}</p>
        {!blocked && error && <p className="crew-assignment-error" role="alert">{error}</p>}
        <div>
          {!blocked && !completed && <button className="crew-assignment-primary" data-cta="retry_founding_deck_issuance" disabled={busy} onClick={onRetry}>{busy ? "ISSUING..." : "RETRY ISSUANCE"}</button>}
          {!blocked && completed && <button className="crew-assignment-primary" data-cta="refresh_founding_deck_status" disabled={busy} onClick={onRetry}>{busy ? "REFRESHING..." : "REFRESH DECK STATUS"}</button>}
        </div>
      </section>
      </main>
    </FoundingCommandShell>
  );
}

function foundingIssuedPackageCode(value) {
  return String(value || "").trim().toUpperCase();
}

function isFoundingMaterializedIssuanceProjection(journey) {
  return Boolean(
    journey
    && journey.stage === "challenge_accepted"
    && journey.foundingDeckMaterialization?.status === "materialized"
    && journey.starterDeck
  );
}

function selectFoundingIssuanceReceiptAuthority(journey, issuanceReceipt) {
  return isFoundingMaterializedIssuanceProjection(journey) ? journey : issuanceReceipt;
}

function getFoundingIssuedPackageReceipt(journey) {
  const starterDeck = journey && journey.starterDeck && typeof journey.starterDeck === "object" ? journey.starterDeck : {};
  const assignment = journey && journey.battleAssignment && typeof journey.battleAssignment === "object" ? journey.battleAssignment : {};
  const pilot = starterDeck.pilot && typeof starterDeck.pilot === "object" ? starterDeck.pilot : {};
  const meka = starterDeck.signatureMeka && typeof starterDeck.signatureMeka === "object" ? starterDeck.signatureMeka : {};
  const protocol = starterDeck.signatureTrueBond && typeof starterDeck.signatureTrueBond === "object" ? starterDeck.signatureTrueBond : {};
  const entries = Array.isArray(starterDeck.entries) ? starterDeck.entries : [];
  const primaryDoctrines = Array.isArray(starterDeck.primaryDoctrines) ? starterDeck.primaryDoctrines : [];
  const protocolEffects = Array.isArray(protocol.effects) ? protocol.effects : [];
  const total = entries.reduce((sum, entry) => sum + Number(entry && entry.quantity || 0), 0);
  const errors = [];
  const crewId = String(starterDeck.crewId || "").trim();
  const loadoutId = String(starterDeck.trainingLoadoutId || "").trim();
  const issuedAt = String(starterDeck.grantedAt || "").trim();
  const signatureMekaCodes = new Set([meka.id, meka.code].map(foundingIssuedPackageCode).filter(Boolean));
  const signatureMekaEntries = entries.filter((entry) => signatureMekaCodes.has(foundingIssuedPackageCode(entry && entry.code)));

  if (!crewId || !loadoutId || !String(starterDeck.catalogRelease || "").trim() || !String(starterDeck.issuanceId || "").trim() || !issuedAt) {
    errors.push("ISSUANCE METADATA MISSING");
  }
  if (!String(starterDeck.name || "").trim()) {
    errors.push("ISSUED PACKAGE NAME MISSING");
  }
  if (!foundingIssuedPackageCode(pilot.id) || !String(pilot.callsign || "").trim() || !String(pilot.name || "").trim()) {
    errors.push("PILOT READBACK INVALID");
  }
  if (!foundingIssuedPackageCode(meka.id) || !String(meka.codename || "").trim()) {
    errors.push("SIGNATURE MEKA READBACK INVALID");
  }
  if (
    !String(protocol.label || "").trim()
    || !String(protocol.timing || "").trim()
    || foundingIssuedPackageCode(protocol.pilotCode) !== foundingIssuedPackageCode(pilot.id)
    || !protocolEffects.length
    || protocolEffects.some((effect) => !effect || !String(effect.op || "").trim())
  ) {
    errors.push("TRUE BOND READBACK INVALID");
  }
  if (primaryDoctrines.length !== 2 || new Set(primaryDoctrines.map((doctrine) => String(doctrine || "").trim())).size !== 2 || primaryDoctrines.some((doctrine) => !String(doctrine || "").trim())) {
    errors.push("DOCTRINE READBACK INVALID");
  }
  if (Number(starterDeck.cardCount ?? starterDeck.total) !== 40 || total !== 40 || !entries.length || entries.some((entry) => !entry || !String(entry.code || "").trim() || !String(entry.name || "").trim() || Number(entry.quantity || 0) <= 0)) {
    errors.push("40-CARD MANIFEST READBACK INVALID");
  }
  if (signatureMekaEntries.length !== 1 || Number(signatureMekaEntries[0] && signatureMekaEntries[0].quantity) !== 1) {
    errors.push("SIGNATURE MEKA MANIFEST INVALID");
  }
  if (
    assignment.crewId !== crewId
    || foundingIssuedPackageCode(assignment.pilotId) !== foundingIssuedPackageCode(pilot.id)
    || foundingIssuedPackageCode(assignment.mekaId) !== foundingIssuedPackageCode(meka.id)
    || assignment.trainingLoadoutId !== loadoutId
    || String(assignment.assignedAt || "") !== issuedAt
    || String(journey && journey.starterDeckGrantedAt || "") !== issuedAt
  ) {
    errors.push("ASSIGNMENT AUTHORITY DOES NOT MATCH ISSUED PACKAGE");
  }

  return { valid: errors.length === 0, errors, starterDeck, assignment, pilot, meka, protocol, protocolEffects, entries, primaryDoctrines, total };
}

function getFoundingIssuanceDeploymentContext(journey) {
  const challengerName = String(journey?.challenge?.opponent?.organizationName || "").trim().toUpperCase();
  const arenaName = String(journey?.challenge?.arena?.name || "").trim().toUpperCase();
  return {
    valid: Boolean(challengerName && arenaName),
    challengerName: challengerName || "CHALLENGE DETAILS REQUIRED",
    arenaName: arenaName || "ARENA DETAILS REQUIRED"
  };
}

function FoundingCrewIssuanceReceipt({ organization, journey, busy, error, onContinue, onRetry, onReturn, viewedStep = 3, maxViewedStep = 3, onSelectJourneyStep }) {
  const receipt = getFoundingIssuedPackageReceipt(journey);
  const { valid, errors, starterDeck, pilot, meka, entries, primaryDoctrines, total } = receipt;
  const deploymentContext = getFoundingIssuanceDeploymentContext(journey);
  const { challengerName, arenaName } = deploymentContext;
  const deploymentReady = valid && deploymentContext.valid;
  const receiptGuidanceMessages = [
    { title: "PACKAGE ISSUED", copy: (starterDeck.name || "Your Founding Deck") + " is now paired with the Crew selected in Tab 02." },
    { title: "CONFIRM YOUR CREW", copy: "Pilot " + (pilot.callsign || "data pending") + " deploys with " + (meka.id || "the Signature Meka") + (meka.codename ? " / " + meka.codename : "") + "." + (journey.deploymentEditable ? " To change your choice, return to Tab 02 and update your Crew before deploying." : "") },
    { title: "VERIFY THE DECK", copy: "Confirm both Doctrines and all " + total + " / 40 cards before deployment." },
    { title: deploymentReady ? "READY TO DEPLOY" : "PACKAGE VERIFICATION REQUIRED", copy: deploymentReady ? "Deploy against " + challengerName + " in " + arenaName + " when you are ready." : "Battle remains locked until the Crew, Deck, challenger, and Arena details are complete." }
  ];

  return (
    <FoundingCommandShell organization={organization} stage={journey && journey.stage} viewedStep={viewedStep} maxViewedStep={maxViewedStep} onSelectStep={onSelectJourneyStep} onReturn={onReturn} statusLabel={deploymentReady ? "ARCHIVE LINK ONLINE" : "DEPLOYMENT LOCKED"} dock={<footer className="founding-command-dock founding-issuance-receipt-dock"><div className="founding-issuance-receipt-context"><b>VS {challengerName} · {arenaName}</b></div><button type="button" className="crew-assignment-primary" data-cta="deploy_to_arena" onClick={onContinue} disabled={busy || !deploymentReady}>DEPLOY TO ARENA ▶</button></footer>}>
    <>
    <main className="founding-issuance-receipt" data-screen="founding-issuance-receipt" data-receipt-readback="immutable" data-founding-journey-stage={journey && journey.stage}>
      <div className="crew-assignment-scan" aria-hidden="true"></div>
      <section className="founding-issuance-receipt-body">
        <div className="founding-issuance-receipt-seal" role="status" aria-live="polite" aria-atomic="true"><span>PACKAGE ISSUED</span><b>{total}<em> / 40</em></b><strong>{valid ? "PACKAGE VERIFIED" : "VERIFICATION REQUIRED"}</strong></div>
        <div className="founding-issuance-receipt-package">
          <header><span>DEPLOYMENT PACKAGE / ISSUED</span><h3>{starterDeck.name || "DECK DATA REQUIRED"}</h3></header>
          <dl>
            <div><dt>PILOT</dt><dd>{pilot.callsign || pilot.id || "PILOT DATA REQUIRED"}</dd></div>
            <div><dt>SIGNATURE MEKA</dt><dd>{meka.id || "MEKA DATA REQUIRED"} / {meka.codename || "CODENAME REQUIRED"}</dd></div>
            <div><dt>DECK</dt><dd>{starterDeck.name || "DECK DATA REQUIRED"}</dd></div>
            <div><dt>STATUS</dt><dd>{deploymentReady ? "READY TO DEPLOY" : "VERIFICATION REQUIRED"}</dd></div>
          </dl>
          <div className="founding-issuance-receipt-doctrines" aria-label={(primaryDoctrines.length ? primaryDoctrines.join(" and ") : "Missing") + " sealed doctrines"}>
            <span>DOCTRINES</span>
            <div>{primaryDoctrines.map((doctrine) => <b key={doctrine} style={{ "--founding-card-doctrine": getFoundingGameplayDoctrineColor(doctrine) }}>{doctrine}</b>)}</div>
            <em className="founding-issuance-receipt-manifest-summary">{valid ? "PACKAGE VERIFIED" : "VERIFICATION REQUIRED"} · {total} / 40</em>
          </div>
          <div className="founding-issuance-receipt-manifest" aria-label="Issued exact manifest">{entries.map((entry) => <span key={entry.code}><b>{entry.code}</b><i>{entry.name}</i><strong>x{entry.quantity}</strong></span>)}</div>
          {!valid && <div className="crew-assignment-integrity" role="alert"><b>PACKAGE VERIFICATION REQUIRED</b><p>{errors.join(" · ")}. Refresh the issued Deployment Package before battle.</p><button type="button" className="crew-assignment-secondary" data-cta="refresh_founding_package_readback" onClick={onRetry} disabled={busy}>{busy ? "REFRESHING..." : "REFRESH PACKAGE"}</button></div>}
          {valid && !deploymentContext.valid && <div className="crew-assignment-integrity" role="alert"><b>CHALLENGE DETAILS REQUIRED</b><p>Command must restore the challenger and Arena details before battle.</p><button type="button" className="crew-assignment-secondary" data-cta="refresh_founding_deployment_context" onClick={onRetry} disabled={busy}>{busy ? "REFRESHING..." : "REFRESH CHALLENGE"}</button></div>}
          {error && <p className="founding-issuance-receipt-error" role="alert">{error}</p>}
        </div>
      </section>
    </main>
    <FoundingGuidancePanel organization={organization} scope="issuance-review" messages={receiptGuidanceMessages} contextKey={[starterDeck.crewId, starterDeck.grantedAt, valid, total].join(":")} />
    </>
    </FoundingCommandShell>
  );
}

function FoundingJourneyOverlay({ children, onClose, canDismiss = true }) {
  const dialogRef = useRef(null);

  function getDialogControls() {
    if (!dialogRef.current) return [];
    return [...dialogRef.current.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), [tabindex]:not([tabindex="-1"])')];
  }

  function focusFirstDialogControl() {
    const controls = getDialogControls();
    if (controls[0]) controls[0].focus();
  }

  useEffect(() => {
    const root = document.documentElement;
    const previousRootOverflow = root.style.overflow;
    const previousOverflow = document.body.style.overflow;
    const previousFocus = document.activeElement;
    root.style.overflow = "hidden";
    document.body.style.overflow = "hidden";
    window.requestAnimationFrame(focusFirstDialogControl);
    const onKeyDown = (event) => {
      if (event.key === "Escape" && canDismiss) {
        event.preventDefault();
        onClose();
        return;
      }
      if (event.key !== "Tab" || !dialogRef.current) return;
      const controls = getDialogControls();
      if (!controls.length) return;
      const first = controls[0];
      const last = controls[controls.length - 1];
      if (!dialogRef.current.contains(document.activeElement)) {
        event.preventDefault();
        (event.shiftKey ? last : first).focus();
      } else if (event.shiftKey && document.activeElement === first) {
        event.preventDefault();
        last.focus();
      } else if (!event.shiftKey && document.activeElement === last) {
        event.preventDefault();
        first.focus();
      }
    };
    document.addEventListener("keydown", onKeyDown);
    return () => {
      document.removeEventListener("keydown", onKeyDown);
      root.style.overflow = previousRootOverflow;
      document.body.style.overflow = previousOverflow;
      if (previousFocus && typeof previousFocus.focus === "function") previousFocus.focus();
    };
  }, [canDismiss, onClose]);

  useEffect(() => {
    if (!dialogRef.current || dialogRef.current.contains(document.activeElement)) return;
    focusFirstDialogControl();
  });

  return ReactDOM.createPortal(
    <div className="founding-journey-overlay" role="dialog" aria-modal="true" aria-label="Founding Journey" style={{ minHeight: "100vh", display: "grid", placeItems: "center", padding: "36px 24px", background: "radial-gradient(ellipse at 50% 42%,#10131c,#04050a 65%)" }}>
      <div className="founding-journey-overlay-shell" ref={dialogRef}>
        <div className="founding-journey-overlay-content">{children}</div>
      </div>
    </div>,
    document.body
  );
}

function FoundingJourneyExperience({ account, journeyStatus, view, onViewChange, onClose }) {
  const [launchRecovery, setLaunchRecovery] = useState(null);
  const [issuanceReceipt, setIssuanceReceipt] = useState(null);
  const mountedRef = useRef(true);
  const launchAttemptRef = useRef(0);
  const accountIdentity = [account && account.status, account && account.user && account.user.id, account && account.organization && account.organization.id].join(":");
  const launchAccountIdentityRef = useRef(accountIdentity);
  if (launchAccountIdentityRef.current !== accountIdentity) {
    launchAccountIdentityRef.current = accountIdentity;
    launchAttemptRef.current += 1;
  }
  useEffect(() => () => {
    mountedRef.current = false;
    launchAttemptRef.current += 1;
  }, []);
  useEffect(() => {
    setLaunchRecovery(null);
    setIssuanceReceipt(null);
  }, [accountIdentity]);

  const journey = launchRecovery ? launchRecovery.journey : journeyStatus && journeyStatus.data;
  const receiptAuthority = selectFoundingIssuanceReceiptAuthority(journey, issuanceReceipt);
  const organization = getAccountOrganization(account) || {};
  const challenge = journey && journey.challenge;
  const busy = Boolean(journeyStatus && journeyStatus.actionBusy);
  const assistantName = String(organization.assistantName || "").trim() || "ASSISTANT DATA PENDING";
  const journeyStage = journey && journey.stage || "starter_deck_ready";
  const defaultViewedStep = getFoundingJourneyDefaultViewedStep(journeyStage);
  const maxViewedStep = getFoundingJourneyMaxViewedStep(journeyStage);
  const requestedViewedStep = resolveFoundingJourneyRequestedStep(view, defaultViewedStep, maxViewedStep);
  const viewedJourneyIdentity = accountIdentity + ":" + String(journey && journey.starterDeck && journey.starterDeck.name || "pending");
  const [viewedStep, setViewedStep] = useState(requestedViewedStep);
  const viewedJourneyIdentityRef = useRef(viewedJourneyIdentity);
  const viewedJourneyStageRef = useRef(journeyStage);

  useEffect(() => {
    const identityChanged = viewedJourneyIdentityRef.current !== viewedJourneyIdentity;
    const stageChanged = viewedJourneyStageRef.current !== journeyStage;
    viewedJourneyIdentityRef.current = viewedJourneyIdentity;
    viewedJourneyStageRef.current = journeyStage;
    if (identityChanged || stageChanged) {
      setViewedStep(requestedViewedStep);
      return;
    }
    setViewedStep(requestedViewedStep);
  }, [viewedJourneyIdentity, journeyStage, defaultViewedStep, maxViewedStep, requestedViewedStep]);

  function launchAttemptIsCurrent(attempt, sessionEpoch) {
    return mountedRef.current
      && attempt === launchAttemptRef.current
      && sessionEpoch === foundingJourneyLaunchEpoch;
  }

  function recordLaunchRecovery(next, attempt, sessionEpoch) {
    if (!launchAttemptIsCurrent(attempt, sessionEpoch)) return;
    setLaunchRecovery({
      journey: next,
      error: "Training was accepted, but BOND//BREACH could not open. Select RETRY LAUNCH to continue."
    });
  }

  function launchFoundingTraining(next, attempt, sessionEpoch) {
    if (!launchAttemptIsCurrent(attempt, sessionEpoch)) return;
    try {
      sessionStorage.setItem(FOUNDING_TRAINING_API_BASE_KEY, PUBLIC_API_BASE_URL || "/api");
      if (!launchAttemptIsCurrent(attempt, sessionEpoch)) return;
      window.location.assign("/battle/bond-breach/?mode=founding");
    } catch (error) {
      recordLaunchRecovery(next, attempt, sessionEpoch);
    }
  }

  async function acceptChallenge() {
    const attempt = ++launchAttemptRef.current;
    const sessionEpoch = foundingJourneyLaunchEpoch;
    const next = await journeyStatus.acceptChallenge();
    if (!launchAttemptIsCurrent(attempt, sessionEpoch)) return;
    if (!next) return;
    if (next.stage === "training_complete") {
      onClose();
      return;
    }
    if (next.stage === "deployment_assignment_required") {
      onViewChange("assignment");
      return;
    }
    if (next.stage !== "challenge_accepted" || next.foundingDeckMaterialization?.status !== "materialized") return;
    setIssuanceReceipt(next);
    onViewChange("receipt");
  }

  async function assignDeployment(crewId) {
    const attempt = ++launchAttemptRef.current;
    const sessionEpoch = foundingJourneyLaunchEpoch;
    const next = await journeyStatus.assignDeployment(crewId, journey?.trainingHandoff?.id);
    if (!launchAttemptIsCurrent(attempt, sessionEpoch)) return;
    if (!next) return;
    if (next.stage === "training_complete") {
      onClose();
      return;
    }
    if (next.stage !== "challenge_accepted" || next.foundingDeckMaterialization?.status !== "materialized") return;
    setIssuanceReceipt(next);
    onViewChange("receipt");
  }

  async function retryFoundingDeckMaterialization() {
    if (journey?.stage === "training_complete") {
      const next = await journeyStatus.refreshFoundingDeckStatus();
      if (next?.stage === "training_complete" && next.foundingDeckMaterialization?.status === "materialized") onClose();
      return next;
    }
    const lockedCrewId = journey?.foundingDeckMaterialization?.crewId || journey?.battleAssignment?.crewId || "";
    if (!lockedCrewId) return;
    return assignDeployment(lockedCrewId);
  }

  function continueFoundingHandoff() {
    const next = receiptAuthority;
    if (!next || next.stage !== "challenge_accepted" || next.foundingDeckMaterialization?.status !== "materialized" || !getFoundingIssuedPackageReceipt(next).valid || !getFoundingIssuanceDeploymentContext(next).valid) return;
    const attempt = ++launchAttemptRef.current;
    const sessionEpoch = foundingJourneyLaunchEpoch;
    void (async () => {
      const verified = await journeyStatus.verifyFoundingPackage(next.trainingHandoff?.id);
      if (!launchAttemptIsCurrent(attempt, sessionEpoch) || !verified) return;
      launchFoundingTraining(verified, attempt, sessionEpoch);
    })();
  }

  function selectViewedStep(step) {
    if (step < 1 || step > maxViewedStep) return;
    setViewedStep(step);
    if (step === 1) onViewChange("challenge");
    if (step === 2) onViewChange("assignment");
    if (step === 3) onViewChange("receipt");
  }

  if (!journey) {
    return (
      <FoundingCommandShell organization={organization} stage="starter_deck_ready" viewedStep={1} maxViewedStep={1} onReturn={onClose} statusLabel="OPENING ARCHIVE LINK">
        <div className="founding-journey-loading"><span></span><b>OPENING COMMAND CHANNEL</b></div>
      </FoundingCommandShell>
    );
  }

  const opponentMeka = challenge ? findMechById(challenge.opponent.meka.id) : null;
  const opponentMekaImage = getBattleArenaCinematicAvatarSource(opponentMeka) || (challenge && challenge.opponent.meka.image) || "";
  const opponentPilotImage = challenge
    ? getFoundingJourneyPilotFaceSource(challenge.opponent.meka.id, challenge.opponent.pilot.portrait)
    : "";
  const opponentMonogram = challenge
    ? String(challenge.opponent.organizationName || "ORG").split(/\s+/).filter(Boolean).map((word) => word[0]).join("").slice(0, 3).toUpperCase()
    : "ORG";

  const materializationStage = ["challenge_accepted", "training_complete"].includes(journey.stage);
  const materializationPending = materializationStage
    && journey.foundingDeckMaterialization?.status === "pending";
  const materializationBlocked = materializationStage
    && journey.foundingDeckMaterialization?.status === "blocked";
  if (materializationPending || materializationBlocked) {
    return (
      <FoundingDeckMaterializationState
        organization={organization}
        journey={journey}
        busy={busy}
        error={journeyStatus.error}
        onRetry={materializationPending ? retryFoundingDeckMaterialization : null}
        onReturn={onClose}
      />
    );
  }

  const authoritativeReceipt = isFoundingMaterializedIssuanceProjection(receiptAuthority) ? receiptAuthority : null;
  if (authoritativeReceipt && viewedStep === 3) {
    return (
      <FoundingCrewIssuanceReceipt
        organization={organization}
        journey={authoritativeReceipt}
        busy={busy}
        error={journeyStatus.error || (launchRecovery && launchRecovery.error)}
        onContinue={continueFoundingHandoff}
        onRetry={journeyStatus.refreshFoundingDeckStatus}
        onReturn={onClose}
        viewedStep={viewedStep}
        maxViewedStep={maxViewedStep}
        onSelectJourneyStep={selectViewedStep}
      />
    );
  }

  if (viewedStep === 2 && (journey.stage === "deployment_assignment_required" || authoritativeReceipt)) {
    return (
      <FoundingDeploymentAssignment
        organization={organization}
        journey={authoritativeReceipt || journey}
        busy={busy}
        error={journeyStatus.error}
        onAssign={assignDeployment}
        onRefresh={journeyStatus.refresh}
        onReturn={onClose}
        viewedStep={viewedStep}
        maxViewedStep={maxViewedStep}
        onSelectJourneyStep={selectViewedStep}
        locked={Boolean(authoritativeReceipt) && authoritativeReceipt.deploymentEditable !== true}
      />
    );
  }

  const assistantCopy = viewedStep === 2
      ? <>Choose one complete Crew. Inspect its Pilot, Signature Meka, Meka prints, Doctrines, True Bond protocol, and exact manifest before issuance.</>
      : challenge ? <>{challenge.opponent.organizationName} has requested a training match. A completed battle record can reconstruct a playable Combat Print; the opponent retains its Meka.</> : <>CHALLENGE DETAILS PENDING.</>;
  const challengeGuidance = challenge ? [
    { title: "READ THE CHALLENGE", copy: challenge.opponent.organizationName + " has requested a Founding Training match in " + getFoundingChallengeArenaName(challenge) + ". This battle has no ranked stakes." },
    { title: "A DECK CONTAINS EXACTLY 40 CARDS", copy: "Your Pilot accompanies the Crew outside the Deck and is never shuffled into those 40 cards." },
    { title: "BOND YOUR CREW", copy: "Bond Traits connect a Pilot to a Signature Meka. Their True Bond protocol activates when Bond is full." },
    { title: "ACCEPT TO CHOOSE YOUR CREW", copy: "Accepting opens Crew Selection. Your Deck is not issued until you lock one complete Crew." },
    { title: "EARN A COMBAT PRINT", copy: "Completing the battle can reconstruct a playable Combat Print from the opponent. Their Meka License remains theirs." }
  ] : [];
  const challengeArenaName = getFoundingChallengeArenaName(challenge);
  const challengeDock = viewedStep === 1 && challenge ? (
    <footer className="founding-command-dock claude-founding-footer is-challenge">
      {journey.stage === "challenge_received" ? (
        <aside>
          <button type="button" className="claude-founding-secondary" data-cta="decide_later" onClick={onClose} disabled={busy}>DECIDE LATER</button>
          <button type="button" className="claude-founding-primary" data-cta="accept_challenge" data-transition="deployment_assignment_required" onClick={acceptChallenge} disabled={busy}>{busy ? "ACCEPTING..." : "ACCEPT CHALLENGE & PICK YOUR CREW"}</button>
        </aside>
      ) : <b className="claude-founding-readonly-state">CHALLENGE REVIEW ONLY</b>}
    </footer>
  ) : null;

  return (
    <FoundingCommandShell organization={organization} stage={journey.stage} viewedStep={viewedStep} maxViewedStep={maxViewedStep} onSelectStep={selectViewedStep} onReturn={onClose} dock={challengeDock}>
      {!(viewedStep === 1 && challenge) && (
        <FoundingAssistantStrip organization={organization}>{assistantCopy}</FoundingAssistantStrip>
      )}
      {viewedStep === 1 && challenge && (
        <>
          <section className="claude-founding-step claude-founding-challenge" aria-labelledby="founding-challenge-title">
            <div className="claude-founding-challenge-narrative">
              <div className="claude-founding-challenge-signal">
                <span>CHALLENGE CHANNEL / PRIORITY SIGNAL</span>
                <b>{journey.stage === "challenge_received" ? "AWAITING RESPONSE" : "REVIEW ONLY"}</b>
              </div>
              <h3 id="founding-challenge-title">INCOMING CHALLENGE.</h3>
              <p>{challenge.opponent.organizationName} has issued your first official challenge.</p>
              <dl className="claude-founding-challenge-readouts">
                <div><dt>FORMAT</dt><dd>FOUNDING TRAINING</dd></div>
                <div><dt>ARENA</dt><dd>{challengeArenaName}</dd></div>
              </dl>
            </div>
            <FoundingChallengeOpponentVisual
              key={[challenge.opponent.meka.id, opponentMekaImage, challenge.opponent.pilot.callsign, opponentPilotImage].join(":")}
              challenge={challenge}
              opponentMekaImage={opponentMekaImage}
              opponentPilotImage={opponentPilotImage}
              opponentMonogram={opponentMonogram}
            />
          </section>
          <FoundingGuidancePanel organization={organization} scope="challenge" messages={challengeGuidance} contextKey={[journey.stage, challenge.opponent.organizationName, challenge.opponent.meka.id].join(":")} />
        </>
      )}

      {journey.stage !== "deployment_assignment_required" && (launchRecovery ? launchRecovery.error : journeyStatus.error) && <div className="claude-founding-error" role="alert">{launchRecovery ? launchRecovery.error : journeyStatus.error}</div>}
    </FoundingCommandShell>
  );
}

function PostDeploymentDebrief({ account, journeyStatus }) {
  const journey = journeyStatus && journeyStatus.data;
  const postFounding = journey && journey.postFounding;
  const organization = getAccountOrganization(account) || {};
  const debrief = postFounding && postFounding.debrief;
  const reward = postFounding && postFounding.reward;
  const seenRef = useRef(false);

  useEffect(() => {
    if (!debrief || debrief.status === "complete" || seenRef.current || Number(debrief.step || 0) !== 0 || journeyStatus.actionBusy) return;
    seenRef.current = true;
    void journeyStatus.recordPostDeploymentDebrief("seen", 1);
  }, [debrief && debrief.step, debrief && debrief.status, journeyStatus.actionBusy]);

  if (!postFounding || !debrief || debrief.status === "complete") return null;

  const visibleStep = Math.max(1, Number(debrief.step || 0));
  const won = Boolean(reward && reward.outcome === "win");
  const combatPrintGranted = Boolean(reward && reward.combatPrintGranted);
  const combatPrintAvailable = Boolean(reward && reward.combatPrintAvailable);
  const targetName = reward && reward.targetMeka
    ? [reward.targetMeka.id, reward.targetMeka.codename].filter(Boolean).join(" / ")
    : "OPPONENT MEKA";
  const steps = [
    {
      kicker: "FIRST DEPLOYMENT / RECORDED",
      title: won ? "Victory entered in your Battle Record." : "Defeat entered in your Battle Record.",
      copy: "First Deployment is complete. Your Main Objective continues to Arsenal orientation.",
      actionLabel: "VIEW BATTLE ACQUISITION"
    },
    {
      kicker: "BATTLE ACQUISITION",
      title: combatPrintGranted
        ? targetName + " Combat Print issued."
        : (combatPrintAvailable ? targetName + " Combat Print already in Arsenal." : String(reward && reward.imprint || 0).padStart(3, "0") + " / 100 Combat Imprint recorded."),
      copy: combatPrintGranted
        ? "A playable card was issued to Arsenal. The opponent Meka and Meka License did not transfer."
        : combatPrintAvailable
          ? "The playable card remains in Card Collection. No duplicate card or Meka License was issued."
        : "No playable card or Meka License was issued. A rematch is optional and does not block progression.",
      actionLabel: "VIEW NEXT MAIN OBJECTIVE"
    },
    {
      kicker: "NEXT MAIN OBJECTIVE",
      title: "Deployment Package assigned.",
      copy: won
        ? "Your Combat Print is ready. Return to My Hangar, then follow the Combat Imprints directive to continue."
        : "Your Combat Imprint is recorded. Return to My Hangar, then follow the Combat Imprints directive to continue.",
      actionLabel: won ? "REVIEW COMBAT PRINT" : "REVIEW COMBAT IMPRINT"
    }
  ];
  const content = steps[Math.min(steps.length - 1, visibleStep - 1)];

  async function continueDebrief() {
    if (journeyStatus.actionBusy) return;
    if (visibleStep < Number(debrief.totalSteps || 3)) {
      await journeyStatus.recordPostDeploymentDebrief("advance", visibleStep + 1);
      return;
    }
    await journeyStatus.recordPostDeploymentDebrief("complete", visibleStep);
    activateDirectiveTarget("#hangar");
  }

  async function skipDebrief() {
    if (journeyStatus.actionBusy) return;
    await journeyStatus.recordPostDeploymentDebrief("skip", debrief.totalSteps || 3);
    activateDirectiveTarget("#hangar");
  }

  return (
    <CommandDialogueSequence
      id="post-deployment-briefing"
      ariaLabel="Post-deployment virtual assistant debrief"
      className="post-deployment-briefing"
      lines={steps.map((step) => step.kicker + ". " + step.title + " " + step.copy)}
      stepIndex={Math.min(steps.length - 1, visibleStep - 1)}
      assistantName={organization.assistantName || "VIRTUAL ASSISTANT"}
      avatarSource={getAssistantAvatarSource(organization)}
      busy={Boolean(journeyStatus.actionBusy)}
      primaryLabel={visibleStep >= steps.length ? "ENTER HANGAR" : content.actionLabel}
      onAdvance={continueDebrief}
      error={journeyStatus.error || ""}
      skipLabel="SKIP DEBRIEF"
      onSkip={skipDebrief}
    />
  );
}

function crewLoadoutDeckHref(deckId) {
  return "#deckbay/deck/" + encodeURIComponent(String(deckId || ""));
}

function parseDeckBayRouteDeckId(routeHash) {
  const match = String(routeHash || "").match(/^#deckbay\/deck\/(.+)$/);
  if (!match) return "";
  try { return decodeURIComponent(match[1]); } catch { return ""; }
}

function deriveCrewLoadoutGroups({ decks = [], crews = [], crewTemplates = [], activePackage = null, pairedEvidence = null, cards = [], resolveArt = () => "" } = {}) {
  const records = Array.isArray(decks) ? decks : [];
  const cardByCode = new Map((Array.isArray(cards) ? cards : []).map((card) => [String(card?.code || card?.definition?.code || "").toUpperCase(), card]));
  const pairingByDeckId = new Map();
  groupDecksByPilotAuthority(records, crews, activePackage, pairedEvidence, crewTemplates).forEach((group) => {
    if (group.crew) group.decks.forEach((deck) => pairingByDeckId.set(String(deck.id), { crew: group.crew }));
  });

  const groupsByCrewId = new Map();
  records.forEach((deck) => {
    const pairing = pairingByDeckId.get(String(deck?.id || ""));
    if (!pairing) return;
    const entries = Array.isArray(deck?.entries) ? deck.entries : [];
    const count = entries.reduce((sum, entry) => sum + Number(entry?.quantity || 0), 0);
    const arts = entries.map((entry, index) => {
      const code = String(entry?.code || "").toUpperCase();
      const card = cardByCode.get(code) || entry;
      const definition = card?.definition || {};
      const kind = String(card?.kind || definition.kind || entry?.kind || "").toLowerCase();
      return {
        art: String(resolveArt(card, entry) || ""),
        kindRank: kind === "mk" || code.startsWith("MK-") ? 1 : 0,
        cost: Number(card?.cost ?? definition.cost ?? entry?.cost ?? 0),
        index
      };
    }).filter((item) => item.art).sort((left, right) => right.kindRank - left.kindRank || right.cost - left.cost || left.index - right.index).slice(0, 4).map((item) => item.art);
    const crewId = String(pairing.crew?.crewId || "");
    if (!groupsByCrewId.has(crewId)) groupsByCrewId.set(crewId, { crew: pairing.crew, allDecks: [] });
    groupsByCrewId.get(crewId).allDecks.push({ ...deck, count, ready: count === 40, arts });
  });

  return [...groupsByCrewId.values()].map((group) => ({
    crew: group.crew,
    decks: group.allDecks.slice(0, 3),
    moreCount: Math.max(0, group.allDecks.length - 3)
  }));
}

function CrewLoadoutArtFan({ arts, deckName }) {
  const visibleArts = Array.isArray(arts) ? arts : [];
  return <div className="crew-loadout-art-fan" aria-hidden="true">
    {visibleArts.length ? visibleArts.map((src, index) => {
      const denominator = Math.max(visibleArts.length - 1, 1);
      return <img key={src + index} src={src} alt="" loading="lazy" decoding="async" style={{ "--crew-art-left": `${14 + index * 72 / denominator}%`, "--crew-art-angle": `${(index - (visibleArts.length - 1) / 2) * 7}deg` }} />;
    }) : <span>{deckName ? "DECK ART PENDING" : "NO DECK ART"}</span>}
  </div>;
}

function CrewLoadoutDeckCard({ deck }) {
  return <a className="crew-loadout-deck-card" href={crewLoadoutDeckHref(deck.id)} aria-label={`Open ${deck.name || "Deck"} in Deck Bay`}>
    <CrewLoadoutArtFan arts={deck.arts} deckName={deck.name} />
    <div className="crew-loadout-deck-meta"><div><b>{deck.name || "UNTITLED DECK"}</b><small>{deck.count} / 40</small></div><span className={deck.ready ? "is-ready" : "is-draft"}>{deck.ready ? "READY" : "DRAFT"}</span></div>
  </a>;
}

function CrewLoadoutsSection({ deckState, packageState, collectionState }) {
  const pairedEvidence = getCompletedDirectiveEvidence(packageState?.directives, "post_founding.compatible_crew_paired");
  const groups = deriveCrewLoadoutGroups({
    decks: deckState?.decks,
    crews: packageState?.eligibleCrews,
    crewTemplates: packageState?.crewTemplates,
    activePackage: packageState?.activePackage,
    pairedEvidence,
    cards: collectionState?.cards,
    resolveArt: (card, entry) => resolveFoundingDeckCardArt(collectionCardGameplayEntry(card || entry))
  });
  const loading = [deckState?.status, packageState?.status, collectionState?.status].some((status) => status === "loading" || status === "idle");
  const error = deckState?.error || packageState?.error || collectionState?.error;
  return <section className="section crew-loadouts-section" aria-labelledby="crew-loadouts-title" data-screen-label="Crew Loadouts">
    <div className="section-inner crew-loadouts-inner">
      <header className="crew-loadouts-head"><div><span>CREW LOADOUTS</span><h2 id="crew-loadouts-title">Paired Decks per Pilot</h2></div><a href="#deckbay">OPEN DECK BAY →</a></header>
      {loading ? <div className="crew-loadouts-state" role="status">SYNCING CREW LOADOUTS…</div>
        : error ? <div className="crew-loadouts-state is-error" role="alert"><b>CREW LOADOUTS UNAVAILABLE</b><span>{error}</span></div>
          : groups.length ? <div className="crew-loadout-list">{groups.map((group) => {
            const pilot = group.crew?.pilot || {};
            const portrait = getCrewPilotFaceSource(group.crew) || pilot.faceImage || pilot.selectImage || pilot.cinematicImage || pilot.image || "";
            return <article className="crew-loadout-pilot-row" key={group.crew?.crewId || pilot.callsign}>
              <figure className="crew-loadout-pilot">{portrait ? <img src={portrait} alt={`${pilot.callsign || pilot.name || "Pilot"} portrait`} loading="lazy" decoding="async" style={{ objectPosition: pilot.faceImagePosition || "center 14%" }} /> : <span>VISUAL DATA PENDING</span>}<figcaption><small>PILOT</small><b>{pilot.callsign || pilot.name || "UNNAMED PILOT"}</b></figcaption></figure>
              <div className="crew-loadout-decks">{group.decks.map((deck) => <CrewLoadoutDeckCard key={deck.id} deck={deck} />)}{group.moreCount > 0 && <a className="crew-loadout-more" href="#deckbay">+{group.moreCount} MORE<span>OPEN IN DECK BAY</span></a>}</div>
            </article>;
          })}</div>
          : <div className="crew-loadouts-state"><b>NO PAIRED DECK LOADOUTS</b><span>Pair a Pilot with a legal Deck in Deck Bay to register it here.</span></div>}
    </div>
  </section>;
}

function ArsenalHangarSection({ postFounding }) {
  if (!postFounding || !postFounding.arsenal || postFounding.arsenal.status === "locked") return null;
  const phase = postFounding.phase;
  return (
    <section id="arsenal-launch" className="section post-founding-home-section" aria-label="Arsenal">
      <div className="section-inner">
        <div className="section-head"><div><div className="label">SECTION · 02 / ASSET CONTROL</div><h2>Arsenal</h2></div><div className="right">COLLECTION · IMPRINTS · DECK BAY</div></div>
        <div className="post-founding-launch-grid">
          <a href="#cardcollection" className="post-founding-launch-card"><span>CARD COLLECTION</span><h3>Review owned prints</h3><p>Inspect every playable card registered to this organization.</p><b>{phase === "card_collection_orientation" ? "CURRENT OBJECTIVE" : "OPEN COLLECTION"}</b></a>
          <a href="#arsenal/imprints" className="post-founding-launch-card"><span>COMBAT IMPRINTS</span><h3>Track imprint progress</h3><p>See partial progress toward opponent Combat Prints.</p><b>{phase === "combat_imprints_orientation" ? "CURRENT OBJECTIVE" : "OPEN IMPRINT LEDGER →"}</b></a>
          <a href="#deckbay" className="post-founding-launch-card"><span>DECK BAY</span><h3>Assemble your 40</h3><p>Build and register legal Decks from your Card Collection.</p><b>{phase === "deck_bay_orientation" ? "CURRENT OBJECTIVE" : "OPEN DECK BAY →"}</b></a>
        </div>
      </div>
    </section>
  );
}

function selectNextOperationsSimArena() {
  try {
    const previous = Number.parseInt(window.localStorage.getItem(OPERATIONS_SIM_ARENA_STORAGE_KEY) || "-1", 10);
    const next = ((Number.isFinite(previous) ? previous : -1) + 1) % OPERATIONS_SIM_ARENA_BACKGROUNDS.length;
    window.localStorage.setItem(OPERATIONS_SIM_ARENA_STORAGE_KEY, String(next));
    return OPERATIONS_SIM_ARENA_BACKGROUNDS[next];
  } catch {
    return OPERATIONS_SIM_ARENA_BACKGROUNDS[Math.floor(Math.random() * OPERATIONS_SIM_ARENA_BACKGROUNDS.length)];
  }
}

function OperationsHangarSection({ postFounding }) {
  if (!postFounding || !postFounding.arsenal || postFounding.arsenal.status === "locked") return null;
  const unlocked = postFounding.operations && postFounding.operations.status === "unlocked";
  const arenaBackground = useMemo(selectNextOperationsSimArena, []);
  return (
    <section id="operations-launch" className={"section post-founding-home-section operations-home" + (unlocked ? " is-unlocked" : " is-locked")} aria-label="Operations Sim" data-operations-status={unlocked ? "unlocked" : "locked"}>
      <div className="section-inner">
        <a className="operations-sim-banner" href="#operations" aria-label={unlocked ? "Open Operations Sim" : "Open Operations Sim access requirements"}>
          <span className="operations-sim-arena" role="img" aria-label="Operations battle arena" style={{ backgroundImage: `url("${arenaBackground}")` }} />
          <span className="operations-sim-scrim" aria-hidden="true" />
          <span className="operations-sim-scanlines" aria-hidden="true" />
          <span className="operations-sim-copy">
            <span className="operations-sim-kicker">SECTION · 03 / FIELD COMMAND</span>
            <h2>OPERATIONS SIM</h2>
            <span className="operations-sim-subtitle">Training matches, challenges, and campaign battles run from here.</span>
          </span>
          <span className="operations-sim-cta" aria-hidden="true">OPEN OPERATIONS SIM →</span>
        </a>
      </div>
    </section>
  );
}

function buildCardInspectionStorageKey(organizationId, receiptId, cardCode) {
  const organization = String(organizationId || "").trim();
  const receipt = String(receiptId || "").trim();
  const code = String(cardCode || "").trim().toUpperCase();
  return organization && receipt && code ? `supermekabots.arsenal.printInspected.${organization}.${receipt}.${code}` : "";
}

function readCardInspectionMarker(storage, key) {
  if (!storage || !key) return false;
  try { return storage.getItem(key) === "inspected"; } catch { return false; }
}

function writeCardInspectionMarker(storage, key) {
  if (!storage || !key) return false;
  try { storage.setItem(key, "inspected"); return true; } catch { return false; }
}

function getCardInspectionStorage() {
  try { return typeof window !== "undefined" ? window.sessionStorage : null; } catch { return null; }
}

function buildCollectionTutorialStorageKey(organizationId) {
  const organization = String(organizationId || "").trim();
  return organization ? `supermekabots.arsenal.collectionBriefing.v2.${organization}` : "";
}

function readCollectionTutorialCompletion(storage, key) {
  if (!storage || !key) return false;
  try { return storage.getItem(key) === "complete"; } catch { return false; }
}

function writeCollectionTutorialCompletion(storage, key) {
  if (!storage || !key) return false;
  try { storage.setItem(key, "complete"); return true; } catch { return false; }
}

function getCollectionTutorialStorage() {
  try { return typeof window !== "undefined" ? window.localStorage : null; } catch { return null; }
}

function getCollectionCardSources(card) {
  const canonicalSources = Array.isArray(card && card.acquisitionSources)
    ? card.acquisitionSources
    : [];
  const normalizedSources = canonicalSources.map((value) => String(value || "").trim().toUpperCase()).reduce((sources, value) => {
    if (value === "FOUNDING_DECK" && !sources.includes("founding_deck")) sources.push("founding_deck");
    if (value === "COMBAT_PRINT" && !sources.includes("combat_print")) sources.push("combat_print");
    if (value === "ARCHIVE_DISPATCH" && !sources.includes("archive_dispatch")) sources.push("archive_dispatch");
    if (value === "UNKNOWN" && !sources.includes("unknown")) sources.push("unknown");
    return sources;
  }, []);
  if (normalizedSources.length > 0) return normalizedSources;

  const acquisitionSource = String(card && card.acquisitionSource || "").trim().toUpperCase();
  if (acquisitionSource === "FOUNDING_DECK") return ["founding_deck"];
  if (acquisitionSource === "COMBAT_PRINT") return ["combat_print"];
  if (acquisitionSource === "ARCHIVE_DISPATCH") return ["archive_dispatch"];
  if (acquisitionSource) return ["unknown"];

  const provenance = card && card.provenance;
  const source = String(card && card.source || "").trim().toLowerCase();
  if ((provenance && provenance.sourceType === "first_deployment") || ["founding_combat_print", "existing_combat_print", "combat_print"].includes(source)) return ["combat_print"];
  if (["founding_deck", "founding_starter_deck", "starter_meka"].includes(source)) return ["founding_deck"];
  if (source === "archive_dispatch") return ["archive_dispatch"];
  return ["unknown"];
}

function getCollectionSourceLabel(card) {
  const labels = getCollectionCardSources(card).map((source) => {
    if (source === "founding_deck") return "FOUNDING DECK";
    if (source === "combat_print") return "COMBAT PRINT";
    if (source === "archive_dispatch") return "ARCHIVE DISPATCH";
    return "SOURCE UNAVAILABLE";
  });
  return labels.join(" / ");
}

function collectionRulesText(definition) {
  const rules = definition && (definition.rulesText || definition.ability);
  if (Array.isArray(rules)) return rules.join(" ");
  return rules || "Canonical card record registered.";
}

function collectionTelemetry(cards) {
  const collection = Array.isArray(cards) ? cards.filter(Boolean) : [];
  return {
    uniquePrints: collection.length,
    totalCopies: collection.reduce((total, card) => total + Math.max(0, Number(card.quantity) || 0), 0)
  };
}

function matchesCollectionKind(card, kind) {
  const selected = String(kind || "all").toLowerCase();
  const cardKind = String(card && card.kind || "").toLowerCase();
  if (selected === "all") return cardKind === "mk" || cardKind === "md" || cardKind === "command";
  if (selected === "meka") return cardKind === "mk" || cardKind === "md";
  if (selected === "command") return cardKind === "command";
  return false;
}

function hasCompletedFeatureTutorial(progress, feature) {
  const phase = typeof progress === "string" ? progress : progress?.phase;
  const completionField = { combat_imprints: "rewardReviewedAt", deck_bay: "orientationCompletedAt", card_collection: "collectionReviewedAt" }[feature];
  if (completionField && progress?.arsenal?.[completionField] && !(feature === "deck_bay" && progress?.arsenal?.legacyEvidence)) return true;
  const phases = ["post_deployment_debrief", "combat_imprints_orientation", "deck_bay_orientation", "card_collection_orientation", "complete"];
  const featurePhase = {
    combat_imprints: "combat_imprints_orientation",
    deck_bay: "deck_bay_orientation",
    card_collection: "card_collection_orientation"
  }[feature];
  const currentIndex = phases.indexOf(String(phase || ""));
  const featureIndex = phases.indexOf(featurePhase || "");
  return currentIndex >= 0 && featureIndex >= 0 && currentIndex > featureIndex;
}

function useCompletedTutorialEntry(identity, completed, resolved = true, active = true) {
  const entryRef = useRef(null);
  const normalizedIdentity = String(identity || "anonymous");
  if (!active) {
    entryRef.current = null;
    return { identity: normalizedIdentity, resolved: false, completedAtEntry: false };
  }
  if (!entryRef.current || entryRef.current.identity !== normalizedIdentity) {
    entryRef.current = { identity: normalizedIdentity, resolved: Boolean(resolved), completedAtEntry: Boolean(resolved && completed) };
  } else if (resolved && !entryRef.current.resolved) {
    entryRef.current = { identity: normalizedIdentity, resolved: true, completedAtEntry: Boolean(completed) };
  }
  return entryRef.current;
}

function filterAndSortCollectionCards(cards, filters) {
  const search = String(filters.search || "").trim().toLocaleLowerCase();
  const filtered = (Array.isArray(cards) ? cards : []).filter((card) => {
    const definition = card && card.definition ? card.definition : {};
    const searchable = `${card.code || ""} ${definition.name || ""} ${collectionRulesText(definition)}`.toLocaleLowerCase();
    return (!search || searchable.includes(search))
      && matchesCollectionKind(card, filters.kind)
      && (filters.doctrine === "all" || String(definition.doctrine || "").toLowerCase() === String(filters.doctrine || "").toLowerCase());
  });
  const compareCode = (left, right) => String(left.code || "").localeCompare(String(right.code || ""));
  const compareName = (left, right) => String(left.definition?.name || left.code || "").localeCompare(String(right.definition?.name || right.code || "")) || compareCode(left, right);
  const compareOptionalNumber = (field, left, right) => {
    const leftValue = Number(left.definition && left.definition[field]);
    const rightValue = Number(right.definition && right.definition[field]);
    const leftKnown = Number.isFinite(leftValue);
    const rightKnown = Number.isFinite(rightValue);
    if (leftKnown !== rightKnown) return leftKnown ? -1 : 1;
    return leftKnown ? leftValue - rightValue : 0;
  };
  return filtered.sort((left, right) => {
    if (filters.sort === "name") return compareName(left, right);
    if (filters.sort === "power") return compareOptionalNumber("power", left, right) || compareName(left, right);
    return compareOptionalNumber("cost", left, right) || compareName(left, right);
  });
}

function filterAndSortDeckCollectionCards(cards, filters) {
  const search = String(filters.search || "").trim().toLocaleLowerCase();
  const filtered = (Array.isArray(cards) ? cards : []).filter((card) => {
    const definition = card && card.definition ? card.definition : {};
    const searchable = `${card.code || ""} ${definition.name || ""}`.toLocaleLowerCase();
    return (!search || searchable.includes(search))
      && (filters.type === "all" || String(card.kind || "").toLowerCase() === filters.type)
      && (filters.source === "all" || getCollectionCardSources(card).includes(filters.source))
      && (filters.doctrine === "all" || String(definition.doctrine || "") === filters.doctrine);
  });
  const compareCode = (left, right) => String(left.code || "").localeCompare(String(right.code || ""));
  return filtered.sort((left, right) => {
    const leftDefinition = left.definition || {};
    const rightDefinition = right.definition || {};
    if (filters.sort === "name") return String(leftDefinition.name || left.code || "").localeCompare(String(rightDefinition.name || right.code || "")) || compareCode(left, right);
    if (filters.sort === "code") return compareCode(left, right);
    if (filters.sort === "cost") return Number(leftDefinition.cost || 0) - Number(rightDefinition.cost || 0) || compareCode(left, right);
    const leftRecent = Date.parse(left.acquiredAt || "");
    const rightRecent = Date.parse(right.acquiredAt || "");
    const leftKnown = Number.isFinite(leftRecent);
    const rightKnown = Number.isFinite(rightRecent);
    if (leftKnown !== rightKnown) return leftKnown ? -1 : 1;
    return (leftKnown ? rightRecent - leftRecent : 0) || compareCode(left, right);
  });
}

function useTcgDeckMembership(account, enabled) {
  const organizationIdentity = enabled && account && account.status === "signed-in"
    ? String(account.organization && account.organization.id || "")
    : "";
  const requestEpochRef = useRef(0);
  const [state, setState] = useState(() => ({ identity: "", status: "idle", counts: new Map(), error: "" }));

  useEffect(() => {
    const requestEpoch = ++requestEpochRef.current;
    let cancelled = false;
    if (!organizationIdentity) {
      setState({ identity: "", status: "idle", counts: new Map(), error: "" });
      return () => { cancelled = true; };
    }
    setState({ identity: organizationIdentity, status: "loading", counts: new Map(), error: "" });
    void (async () => {
      try {
        const data = await publicApi("/tcg/decks");
        if (cancelled || requestEpoch !== requestEpochRef.current) return;
        const deckIdsByCode = new Map();
        for (const deck of Array.isArray(data && data.decks) ? data.decks : []) {
          if (!deck || !deck.id) continue;
          const codes = new Set((Array.isArray(deck.entries) ? deck.entries : []).map((entry) => String(entry && entry.code || "").trim().toUpperCase()).filter(Boolean));
          for (const code of codes) {
            if (!deckIdsByCode.has(code)) deckIdsByCode.set(code, new Set());
            deckIdsByCode.get(code).add(deck.id);
          }
        }
        setState({ identity: organizationIdentity, status: "ready", counts: new Map([...deckIdsByCode].map(([code, deckIds]) => [code, deckIds.size])), error: "" });
      } catch (error) {
        if (cancelled || requestEpoch !== requestEpochRef.current) return;
        setState({ identity: organizationIdentity, status: "error", counts: new Map(), error: error.message || "Deck membership unavailable" });
      }
    })();
    return () => { cancelled = true; };
  }, [organizationIdentity]);

  return state.identity === organizationIdentity
    ? state
    : { identity: organizationIdentity, status: organizationIdentity ? "loading" : "idle", counts: new Map(), error: "" };
}

function SecondaryTabs({ label, tabs }) {
  const scrollerRef = useRef(null);
  const tabRefs = useRef(new Map());
  const activeTabHref = (tabs.find((tab) => tab.active) || {}).href || "";
  const layoutFingerprint = tabs.map((tab, index) => [index, tab.href, tab.label, tab.active ? "active" : "inactive"].join("\u001f")).join("\u001e");

  useLayoutEffect(() => {
    const scroller = scrollerRef.current;
    const activeTab = tabRefs.current.get(activeTabHref);
    if (!scroller || !activeTab) return undefined;

    const revealActiveTab = () => {
      const scrollerRect = scroller.getBoundingClientRect();
      const activeRect = activeTab.getBoundingClientRect();
      const visibleLeft = scrollerRect.left + scroller.clientLeft;
      const visibleRight = visibleLeft + scroller.clientWidth;
      const delta = activeRect.left < visibleLeft
        ? activeRect.left - visibleLeft
        : activeRect.right > visibleRight
          ? activeRect.right - visibleRight
          : 0;
      if (!delta) return;
      const maxScrollLeft = Math.max(0, scroller.scrollWidth - scroller.clientWidth);
      scroller.scrollLeft = Math.max(0, Math.min(maxScrollLeft, scroller.scrollLeft + delta));
    };
    revealActiveTab();

    let frame = 0;
    const scheduleActiveTabReveal = () => {
      window.cancelAnimationFrame(frame);
      frame = window.requestAnimationFrame(revealActiveTab);
    };

    const resizeObserver = typeof ResizeObserver === "function" ? new ResizeObserver(scheduleActiveTabReveal) : null;
    if (resizeObserver) {
      resizeObserver.observe(scroller);
      for (const tab of tabRefs.current.values()) resizeObserver.observe(tab);
    } else window.addEventListener("resize", scheduleActiveTabReveal);
    return () => {
      window.cancelAnimationFrame(frame);
      if (resizeObserver) resizeObserver.disconnect();
      else window.removeEventListener("resize", scheduleActiveTabReveal);
    };
  }, [layoutFingerprint]);

  return (
    <nav ref={scrollerRef} className="post-founding-tabs command-section-tabs" aria-label={label}>
      {tabs.map((tab) => <a ref={(node) => node ? tabRefs.current.set(tab.href, node) : tabRefs.current.delete(tab.href)} key={tab.href} className={tab.active ? "is-active" : ""} aria-current={tab.active ? "page" : undefined} href={tab.href}>{tab.label}</a>)}
    </nav>
  );
}

function DeckCollectionToolbar({ filters, doctrines, resultCount, onChange }) {
  function update(key, value) { onChange({ ...filters, [key]: value }); }
  const typeFilters = [{ value: "all", label: "ALL" }, { value: "mk", label: "MEKA" }, { value: "md", label: "MD" }, { value: "command", label: "COMMAND" }];
  const doctrineFilters = [{ value: "all", label: "ALL" }, ...doctrines.map((doctrine) => ({ value: doctrine, label: doctrine.toUpperCase() }))];
  const group = (label, key, items) => <div className="deck-collection-segment-group" role="group" aria-label={label}>{items.map((item) => <button type="button" key={item.value} className={filters[key] === item.value ? "is-active" : ""} aria-pressed={filters[key] === item.value} onClick={() => update(key, item.value)}>{item.label}</button>)}</div>;
  return (
    <div className="collection-toolbar" aria-label="Deck Builder Card Collection controls">
      <span className="deck-collection-toolbar-label">COLLECTION</span>
      {group("Filter Card Collection by type", "type", typeFilters)}
      {group("Filter Card Collection by doctrine", "doctrine", doctrineFilters)}
      <label className="collection-search"><span className="sr-only">SEARCH CARD COLLECTION</span><input name="collection-search" aria-label="Search Card Collection by name, code, or ability" type="search" value={filters.search} onChange={(event) => update("search", event.target.value)} placeholder="SEARCH NAME / ABILITY…" /></label>
      <output className="sr-only" aria-live="polite">{String(resultCount).padStart(2, "0")} PRINTS</output>
    </div>
  );
}

function CollectionToolbar({ filters, onChange }) {
  function update(key, value) { onChange({ ...filters, [key]: value }); }
  const kindFilters = [
    { value: "all", label: "ALL" },
    { value: "meka", label: "MEKA" },
    { value: "command", label: "COMMAND" }
  ];
  const canonicalDoctrines = [
    { value: "assault", label: "ASSAULT" },
    { value: "bastion", label: "BASTION" },
    { value: "vector", label: "VECTOR" },
    { value: "forge", label: "FORGE" },
    { value: "salvage", label: "SALVAGE" }
  ];
  const doctrineFilters = [
    { value: "all", label: "ALL" },
    ...canonicalDoctrines
  ];
  const sortFilters = [
    { value: "cost", label: "BY COST" },
    { value: "power", label: "BY POWER" },
    { value: "name", label: "A–Z" }
  ];
  const controlGroup = (label, items, key) => (
    <div className="collection-segment-group" role="group" aria-label={label}>
      {items.map((item) => <button key={item.value} type="button" className={filters[key] === item.value ? "is-active" : ""} aria-pressed={filters[key] === item.value} onClick={() => update(key, item.value)}>{item.label}</button>)}
    </div>
  );
  return (
    <div className="collection-toolbar collection-toolbar-v2" aria-label="Card Collection controls">
      {controlGroup("Filter Card Collection by kind", kindFilters, "kind")}
      {controlGroup("Filter Card Collection by doctrine", doctrineFilters, "doctrine")}
      {controlGroup("Sort Card Collection", sortFilters, "sort")}
      <label className="collection-search"><span className="sr-only">SEARCH CARD COLLECTION</span><input name="collection-search" aria-label="Search Card Collection by name, code, or ability" type="search" value={filters.search} onChange={(event) => update("search", event.target.value)} placeholder="SEARCH NAME / ABILITY…" /></label>
    </div>
  );
}

function CardCollectionHeader({ telemetry }) {
  return (
    <header className="card-collection-v2-header">
      <div className="card-collection-v2-brand">
        <a className="card-collection-back-control" href="#hangar" aria-label="Back to My Hangar">◂ MY HANGAR</a>
        <div><span>SUPER MEKABOTS TCG · BOND//BREACH</span><h2>CARD COLLECTION</h2></div>
      </div>
      <dl aria-label="Collection totals">
        <div><dt>UNIQUE PRINTS</dt><dd>{telemetry.uniquePrints}</dd></div>
        <div><dt>TOTAL COPIES</dt><dd>{telemetry.totalCopies}</dd></div>
      </dl>
    </header>
  );
}

function RestrictedTutorialGuard({ active, highlightActive = active, allowedSelectors = [], highlightSelectors = allowedSelectors, children, onBlockedChange }) {
  const clearTimerRef = useRef(null);
  const guardRef = useRef(null);
  useEffect(() => () => {
    clearTimeout(clearTimerRef.current);
    onBlockedChange?.(false);
  }, [onBlockedChange]);

  useEffect(() => {
    if (active) return;
    onBlockedChange?.(false);
  }, [active, onBlockedChange]);

  useLayoutEffect(() => {
    const root = guardRef.current;
    if (!root) return undefined;
    const clearTargets = () => root.querySelectorAll('[data-restricted-tutorial-target="true"]').forEach((node) => node.removeAttribute("data-restricted-tutorial-target"));
    clearTargets();
    if (!highlightActive) return clearTargets;
    highlightSelectors.forEach((selector) => {
      try {
        root.querySelectorAll(selector).forEach((node) => {
          if (node.matches(':disabled, [aria-disabled="true"]')) return;
          node.setAttribute("data-restricted-tutorial-target", "true");
        });
      } catch {}
    });
    return clearTargets;
  });

  function handleClickCapture(event) {
    if (!active) return;
    const control = event.target && event.target.closest
      ? event.target.closest("a, button, input, select, textarea, [role='button']")
      : null;
    if (!control) return;
    const permitted = allowedSelectors.some((selector) => {
      try { return control.matches(selector) || Boolean(control.closest(selector)); }
      catch { return false; }
    });
    if (permitted) {
      clearTimeout(clearTimerRef.current);
      onBlockedChange?.(false);
      return;
    }
    event.preventDefault();
    event.stopPropagation();
    onBlockedChange?.(true);
    clearTimeout(clearTimerRef.current);
    clearTimerRef.current = setTimeout(() => {
      onBlockedChange?.(false);
    }, 2200);
  }

  return <div ref={guardRef} className="restricted-tutorial-guard" onClickCapture={handleClickCapture} data-restricted-tutorial={active ? "active" : undefined}>
    {children}
  </div>;
}

function CardCollectionAssistant({ account, telemetry, tutorialStep, onAdvance, onDismiss, onReopen, minimized = false, restricted = false, completedThisVisit = false, showRestrictedNudge = false }) {
  const organization = account && account.organization ? account.organization : {};
  const assistantName = organization.assistantName || "ANVILGEIST";
  const avatar = organization.avatarUrl ? getAssistantAvatarSource(organization) : "";
  const steps = [
    { copy: `This is your CARD COLLECTION, Commander. ${telemetry.uniquePrints} unique prints and ${telemetry.totalCopies} total copies are registered to your organization.`, instruction: "SELECT NEXT TO CONTINUE." },
    { copy: "Use the filters up top to sift by kind or doctrine, sort by cost, power, or name, or search by name and ability. Prints marked NEW arrived recently.", instruction: "SELECT NEXT TO CONTINUE." },
    { copy: "Open any card to inspect its full Archive record: stats, keywords, rules, and how many persisted Decks include that print.", instruction: "SELECT A HIGHLIGHTED CARD TO OPEN ITS ARCHIVE RECORD." },
    { copy: "That is the whole library. When you are ready to build with these prints, head to DECK BAY.", instruction: "CLOSE THE CARD RECORD, THEN SELECT FINISH." }
  ];
  const activeStep = steps[tutorialStep] || steps[0];
  const actionLabel = completedThisVisit ? "" : tutorialStep >= steps.length - 1 ? "FINISH" : tutorialStep === 2 ? "" : "NEXT";
  if (minimized) return (
    <button type="button" className="collection-assistant-minimized" data-tutorial-assistant-control="reopen" aria-label={"Open " + assistantName + " Collection briefing"} onClick={onReopen}>
      {avatar ? <img src={avatar} alt="" /> : <span>AI</span>}
    </button>
  );
  return (
    <aside className="collection-assistant-guide" aria-label={assistantName + " Collection briefing"} aria-live="polite">
      <header>
        <div className="collection-assistant-avatar" aria-hidden="true">{avatar ? <img src={avatar} alt="" /> : <span>AI</span>}</div>
        <div><b>{assistantName}</b><span>COLLECTION BRIEFING · {tutorialStep + 1} / {steps.length}</span></div>
      </header>
      <p>{activeStep.copy}</p>
      {restricted && <strong className="restricted-tutorial-instruction">{activeStep.instruction}</strong>}
      {restricted && showRestrictedNudge && <div className="restricted-tutorial-panel-nudge" role="status">⚠ FOLLOW THE HIGHLIGHTED INSTRUCTION</div>}
      <footer>
        {actionLabel && <button type="button" className="collection-assistant-next" onClick={onAdvance}>{actionLabel}</button>}
        <button type="button" className="tutorial-assistant-dismiss" data-tutorial-assistant-control="dismiss" aria-label="Minimize Collection briefing" onClick={onDismiss}>DISMISS</button>
      </footer>
    </aside>
  );
}

function ArsenalAssistantGuide({ account, view, collectionCount, deckCount }) {
  const organization = account && account.organization ? account.organization : {};
  const assistantName = organization.assistantName || "ANVILGEIST";
  const avatar = organization.avatarUrl ? getAssistantAvatarSource(organization) : "";
  const collectionView = view === "collection";
  const imprintView = view === "imprints";
  const title = collectionView ? "YOUR PRINTS ARE READY TO INSPECT." : imprintView ? "THIS LEDGER TRACKS OPPONENT BATTLE DATA." : "BUILD ONE LEGAL 40-CARD DEPLOYMENT DECK.";
  const copy = collectionView
    ? `You own ${collectionCount} registered card print${collectionCount === 1 ? "" : "s"}. Select any card for its full rules and provenance, then open Deck Bay when you are ready to build.`
    : imprintView
      ? "A partial Imprint is progress only. At 100 / 100, its Combat Print appears in Card Collection and can be added to a legal deck. The opponent Meka License is never transferred."
      : `You have ${deckCount} saved deck record${deckCount === 1 ? "" : "s"}. Choose a deck, use + on owned cards to add them, use − to remove them, then save at exactly 40 / 40.`;
  return (
    <aside className="arsenal-assistant-guide" aria-label={assistantName + " Arsenal guidance"}>
      <div className="arsenal-assistant-avatar" aria-hidden="true">{avatar ? <img src={avatar} alt="" /> : <span>AI</span>}</div>
      <div><span>{assistantName} / ARSENAL LINK</span><h2>{title}</h2><p>{copy}</p></div>
      <div className="arsenal-assistant-steps" aria-label="Recommended steps">
        {collectionView ? <><b>01 INSPECT A CARD</b><b>02 OPEN DECK BAY</b></> : imprintView ? <><b>01 READ PROGRESS</b><b>02 REACH 100 / 100</b></> : <><b>01 CHOOSE OR CREATE</b><b>02 ADD / REMOVE PRINTS</b><b>03 SAVE AT 40 / 40</b></>}
      </div>
      {collectionView && <a className="btn primary" href="#deckbay">OPEN DECK BAY</a>}
      {imprintView && <a className="btn" href="#cardcollection">VIEW PLAYABLE PRINTS</a>}
    </aside>
  );
}

function collectionCardGameplayEntry(card) {
  const definition = card && card.definition ? card.definition : {};
  return {
    ...definition,
    code: card && card.code || definition.code || "CARD",
    kind: card && card.kind || definition.kind || "command",
    name: definition.name || card && card.code || "UNKNOWN PRINT",
    artUrl: definition.sourceArtUrl || definition.art || ""
  };
}

function ArsenalCardPrint({ card, selected, isNew, deckMembershipCount, onSelect, buttonRef }) {
  const definition = card && card.definition ? card.definition : {};
  const ownedCopies = Math.max(0, Number(card && card.quantity) || 0);
  const gameplayEntry = collectionCardGameplayEntry(card);
  const doctrine = String(definition.doctrine || "").trim();
  const doctrineColor = getFoundingGameplayDoctrineColor(doctrine);
  const art = resolveFoundingDeckCardArt(gameplayEntry) || canonicalObjectStorageAssetUrl(definition.sourceArtUrl);
  const keywords = foundingGameplayCardKeywords(gameplayEntry);
  const rules = collectionRulesText(definition);
  const kindLabel = String(card.kind || "").toLowerCase() === "command" ? "COMMAND" : String(card.code || "MEKA").toUpperCase();
  return (
    <button ref={buttonRef} type="button" className={"arsenal-card-print" + (selected ? " is-selected" : "") + (isNew ? " is-new" : "")} data-card-code={card.code} aria-haspopup="dialog" aria-label={`Open ${definition.name || card.code} archive record. Owned ${ownedCopies}.`} onClick={() => onSelect(card.code)}>
      <span className="collection-card-face" style={{ "--collection-card-doctrine": doctrineColor }}>
        {isNew && <span className="arsenal-card-new">NEW</span>}
        <span className="collection-card-face-head"><b>{definition.cost == null ? "" : definition.cost}</b><span>{kindLabel} · {doctrine ? doctrine.toUpperCase() : "UNASSIGNED"}</span></span>
        <span className="collection-card-face-art">{art && <img src={art} alt={(definition.name || card.code) + " artwork"} />}</span>
        <span className="collection-card-face-title"><b>{definition.name || card.code}</b><strong>{definition.power == null ? "" : definition.power}</strong></span>
        <span className="collection-card-face-rules">{[keywords, rules].filter(Boolean).join(" · ")}</span>
      </span>
      <span className="arsenal-card-owned"><b>OWNED</b><span aria-hidden="true">{Array.from({ length: ownedCopies }, (_, index) => <i key={index} className={index < deckMembershipCount ? "is-used" : ""}></i>)}</span></span>
    </button>
  );
}

function CardInspector({ card, deckMembershipCount, membershipStatus, onClose, onPrevious, onNext }) {
  const [failedArt, setFailedArt] = useState("");
  const dialogRef = useRef(null);
  const onCloseRef = useRef(onClose);
  onCloseRef.current = onClose;

  useEffect(() => {
    if (!card) return undefined;
    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    dialogRef.current?.querySelector("button")?.focus();
    const handleKeyDown = (event) => {
      if (event.key === "Escape") {
        event.preventDefault();
        onCloseRef.current();
        return;
      }
      if (event.key !== "Tab" || !dialogRef.current) return;
      const focusable = [...dialogRef.current.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), [tabindex]:not([tabindex="-1"])')];
      if (!focusable.length) return;
      const first = focusable[0];
      const last = focusable[focusable.length - 1];
      if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); }
      else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }
    };
    document.addEventListener("keydown", handleKeyDown);
    return () => {
      document.removeEventListener("keydown", handleKeyDown);
      document.body.style.overflow = previousOverflow;
    };
  }, [card && card.code]);

  if (!card) return null;
  const definition = card.definition || {};
  const gameplayEntry = collectionCardGameplayEntry(card);
  const art = resolveFoundingDeckCardArt(gameplayEntry) || canonicalObjectStorageAssetUrl(definition.sourceArtUrl);
  const doctrine = String(definition.doctrine || "").trim();
  const rawRules = definition.rulesText || definition.ability;
  const rules = (Array.isArray(rawRules) ? rawRules : rawRules ? [rawRules] : []).map((rule) => String(rule || "").trim()).filter(Boolean);
  const keywords = foundingGameplayCardKeywords(gameplayEntry).split(" · ").map((keyword) => keyword.trim()).filter(Boolean);
  const traits = (Array.isArray(definition.traits) ? definition.traits : definition.traits ? [definition.traits] : []).map((trait) => String(trait || "").trim()).filter(Boolean);
  const flavor = String(definition.flavorText || definition.flavor || "").trim();
  const collector = String(definition.collectorNumber || definition.collector || card.code || "").trim();
  return (
    <div className="card-inspector-overlay" onMouseDown={(event) => { if (event.target === event.currentTarget) onClose(); }}>
      <section ref={dialogRef} className="card-inspector-modal" role="dialog" aria-modal="true" aria-labelledby="card-inspector-title" style={{ "--command-inspector-doctrine": getFoundingGameplayDoctrineColor(doctrine) }}>
        <article className="card-inspector-record">
          <div className="card-inspector-doctrine-bar"></div>
          <header><span>{doctrine ? doctrine.toUpperCase() : "DOCTRINE DATA PENDING"}</span><b>{definition.cost == null ? "COST DATA PENDING" : "COST " + definition.cost}</b></header>
          <figure>{art && failedArt !== art ? <img src={art} alt={(definition.name || card.code) + " canonical gameplay art"} onError={() => setFailedArt(art)} /> : <div className="card-inspector-art-pending" data-art-state="pending"><span>VISUAL DATA</span><b>VISUAL DATA PENDING</b></div>}</figure>
          <section className="card-inspector-record-copy">
            <span>{String(card.kind || "CARD").toUpperCase()} · {card.code}</span>
            <h2 id="card-inspector-title">{definition.name || card.code}</h2>
            {traits.length > 0 && <p>{traits.join(" · ")}</p>}
          </section>
          {keywords.length > 0 && <ul className="card-inspector-keywords" aria-label="Card keywords">{keywords.map((keyword) => <li key={keyword}>{keyword}</li>)}</ul>}
          <section className="card-inspector-rules"><span>RULES</span>{rules.length ? rules.map((rule, index) => <p key={index + ":" + rule}>{rule}</p>) : <p>{collectionRulesText(definition)}</p>}</section>
          <footer>{flavor && <em>{flavor}</em>}<div><span>{collector}</span>{definition.power != null && <b>POWER <strong>{definition.power}</strong></b>}</div></footer>
        </article>
        <aside className="card-inspector-archive">
          <section><span>ARCHIVE RECORD</span><dl><div><dt>OWNED</dt><dd>{card.quantity}</dd></div><div><dt>IN DECKS</dt><dd>{membershipStatus === "ready" ? deckMembershipCount : membershipStatus === "error" ? "UNAVAILABLE" : "SYNCING"}</dd></div><div><dt>FREE</dt><dd>{membershipStatus === "ready" ? Math.max(0, Number(card.quantity || 0) - deckMembershipCount) : membershipStatus === "error" ? "UNAVAILABLE" : "SYNCING"}</dd></div><div><dt>KIND</dt><dd>{String(card.kind || "CARD").toUpperCase()}</dd></div><div><dt>DOCTRINE</dt><dd>{doctrine ? doctrine.toUpperCase() : "UNASSIGNED"}</dd></div></dl></section>
          {flavor && <section><span>FIELD NOTE</span><p><em>“{flavor}”</em></p></section>}
          <nav aria-label="Browse filtered card records"><button type="button" aria-label="PREVIOUS PRINT" onClick={onPrevious}>← PREV</button><button type="button" aria-label="NEXT PRINT" onClick={onNext}>NEXT →</button></nav>
        </aside>
      </section>
    </div>
  );
}

function DeckBuilderCardInspector({ card, onClose }) {
  const [failedArt, setFailedArt] = useState("");
  if (!card) return null;
  const definition = card.definition || {};
  const gameplayEntry = collectionCardGameplayEntry(card);
  const art = resolveFoundingDeckCardArt(gameplayEntry) || canonicalObjectStorageAssetUrl(definition.sourceArtUrl);
  const rawRules = definition.rulesText || definition.ability;
  const rules = (Array.isArray(rawRules) ? rawRules : rawRules ? [rawRules] : [])
    .map((rule) => String(rule || "").trim())
    .filter(Boolean);
  const explicitKeywords = (Array.isArray(definition.keywords) ? definition.keywords : definition.keywords ? [definition.keywords] : [])
    .flatMap((keyword) => String(keyword || "").split(/[·,/]/))
    .map((keyword) => keyword.trim().toUpperCase())
    .filter(Boolean);
  const inferredKeywords = foundingGameplayCardKeywords({ ...gameplayEntry, rulesText: rules })
    .split(" · ")
    .map((keyword) => keyword.trim())
    .filter(Boolean);
  const keywords = [...new Set([...explicitKeywords, ...inferredKeywords])];
  const traits = (Array.isArray(definition.traits) ? definition.traits : definition.traits ? [definition.traits] : [])
    .map((trait) => String(trait || "").trim())
    .filter(Boolean);
  const trueBondRule = rules.find((rule) => /^TRUE BOND\s*\/\//i.test(rule)) || "";
  const trueBondMatch = trueBondRule.match(/^TRUE BOND\s*\/\/\s*([^:]+?)(?::\s*(.*))?$/i);
  const structuredTrueBond = definition.trueBond || definition.signatureTrueBond || null;
  const trueBondName = trueBondMatch?.[1]?.trim() || String(structuredTrueBond?.name || "").trim();
  const trueBondDetail = trueBondMatch?.[2]?.trim() || String(structuredTrueBond?.text || structuredTrueBond?.rulesText || structuredTrueBond?.effect || "").trim();
  const normalizeRuleToken = (rule) => String(rule || "").trim().replace(/[.!]+$/, "").replace(/\s+/g, " ").toUpperCase();
  const keywordRuleTokens = new Set(keywords.map(normalizeRuleToken));
  const ordinaryRules = rules.filter((rule) => rule !== trueBondRule && !keywordRuleTokens.has(normalizeRuleToken(rule)));
  const flavor = String(definition.flavorText || definition.flavor || "").trim();
  const collector = String(definition.collectorNumber || definition.collector || "").trim();
  const doctrine = String(definition.doctrine || "").trim();
  return (
    <article className="deck-builder-inspector-record" aria-label={(definition.name || card.code) + " Deck card record"} style={{ "--command-inspector-doctrine": getFoundingGameplayDoctrineColor(doctrine) }}>
      <div className="deck-inspector-doctrine-bar" aria-hidden="true" />
      <header className="deck-inspector-record-header"><span>{doctrine ? doctrine.toUpperCase() : "DOCTRINE DATA PENDING"}</span><b className="deck-inspector-cost">{definition.cost == null ? "COST DATA PENDING" : "COST " + definition.cost}</b></header>
      <figure className="deck-inspector-art">{art && failedArt !== art ? <img src={art} alt={(definition.name || card.code) + " canonical gameplay art"} onError={() => setFailedArt(art)} /> : <div className="card-inspector-art-pending" data-art-state="pending"><span>VISUAL DATA PENDING</span></div>}</figure>
      <section className="deck-inspector-record-copy"><span className="deck-inspector-code">{card.code}</span><h2 className="deck-inspector-title">{definition.name || card.code}</h2>{traits.length > 0 && <p>{traits.join(" · ")}</p>}</section>
      {keywords.length > 0 && <ul className="deck-inspector-keywords" aria-label="Card keywords">{keywords.map((keyword) => <li key={keyword}>{keyword}</li>)}</ul>}
      {(ordinaryRules.length > 0 || trueBondName || trueBondDetail || flavor) && <section className="deck-inspector-rules-panel" aria-label="Authoritative gameplay rules">
        <div className="deck-inspector-rules">{ordinaryRules.map((rule, index) => <p key={index + ":" + rule}>{rule}</p>)}</div>
        {(trueBondName || trueBondDetail) && <p className="deck-inspector-true-bond"><strong>TRUE BOND — {trueBondName}{trueBondDetail ? ": " : ""}</strong>{trueBondDetail}</p>}
        {flavor && <p className="deck-inspector-flavor">{flavor}</p>}
      </section>}
      <footer className="deck-inspector-record-footer"><span className="deck-inspector-collector">{collector}</span>{definition.power != null && <b className="deck-inspector-power">POWER <strong>{definition.power}</strong></b>}</footer>
      <button type="button" className="sr-only" onClick={onClose}>CLOSE CARD PREVIEW</button>
    </article>
  );
}

function trapModalTabFocus(event, root) {
  if (event.key !== "Tab" || !root) return;
  const controls = [...root.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')]
    .filter((node) => !node.hidden && node.getAttribute?.("aria-hidden") !== "true");
  if (!controls.length) return;
  const first = controls[0];
  const last = controls[controls.length - 1];
  const active = document.activeElement;
  if (!controls.includes(active)) {
    event.preventDefault();
    (event.shiftKey ? last : first).focus();
  } else if (event.shiftKey && active === first) {
    event.preventDefault();
    last.focus();
  } else if (!event.shiftKey && active === last) {
    event.preventDefault();
    first.focus();
  }
}

function useCombatImprints(account, enabled) {
  const organizationIdentity = enabled && account && account.status === "signed-in"
    ? String(account.organization && account.organization.id || "")
    : "";
  const requestEpochRef = useRef(0);
  const [state, setState] = useState(() => ({ identity: "", status: "idle", combatImprints: [], error: "" }));

  useEffect(() => {
    const requestEpoch = ++requestEpochRef.current;
    let cancelled = false;
    if (!organizationIdentity) {
      setState({ identity: "", status: "idle", combatImprints: [], error: "" });
      return () => { cancelled = true; };
    }
    setState({ identity: organizationIdentity, status: "loading", combatImprints: [], error: "" });
    void (async () => {
      try {
        const data = await publicApi("/tcg/combat-imprints");
        if (cancelled || requestEpoch !== requestEpochRef.current) return;
        setState({
          identity: organizationIdentity,
          status: "ready",
          combatImprints: Array.isArray(data && data.combatImprints) ? data.combatImprints : [],
          error: ""
        });
      } catch (error) {
        if (cancelled || requestEpoch !== requestEpochRef.current) return;
        setState({ identity: organizationIdentity, status: "error", combatImprints: [], error: error.message || "Combat Imprint Ledger unavailable" });
      }
    })();
    return () => { cancelled = true; };
  }, [organizationIdentity]);

  return state.identity === organizationIdentity
    ? state
    : { identity: organizationIdentity, status: organizationIdentity ? "loading" : "idle", combatImprints: [], error: "" };
}

function CombatImprintsAssistant({ account, restricted = false, completed = false, completionResolved = true, tutorialStep = 0, onTutorialStepChange, onPresentationChange, showRestrictedNudge = false, actionLabel = "" }) {
  const organization = account && account.organization ? account.organization : {};
  const assistantName = organization.assistantName || "ANVILGEIST";
  const avatar = organization.avatarUrl ? getAssistantAvatarSource(organization) : "";
  const organizationId = String(organization.id || "local").trim();
  const storageKey = `supermekabots.arsenal.imprintLedgerBriefing.v1.${organizationId}`;
  const completedEntry = useCompletedTutorialEntry(organizationId, completed, completionResolved);
  const completedAtEntry = completedEntry.completedAtEntry;
  const [guide, setGuide] = useState(() => ({ step: 0, minimized: false }));
  const restrictedEntryRef = useRef("");
  const messages = [
    { copy: "This is the COMBAT IMPRINT LEDGER, Commander. Every opponent Meka you battle leaves battle data here. Win a match to record 100; lose and we still salvage 50.", instruction: "SELECT NEXT TO CONTINUE." },
    { copy: "At 100 / 100 the Archive issues a COMBAT PRINT: a playable copy in your Card Collection. The opponent keeps their License; you gain the print.", instruction: "SELECT NEXT TO CONTINUE." },
    { copy: actionLabel === "ADD TO A DECK" ? "Partial Imprints are progress, not products. This Combat Print is complete and ready for Deck Bay." : "Partial Imprints are progress, not products. Rematch the same target to finish its scan.", instruction: actionLabel ? `SELECT ${actionLabel} NOW.` : "WAIT FOR THE HIGHLIGHTED TARGET ACTION TO BECOME AVAILABLE." }
  ];
  const visibleStep = restricted ? tutorialStep : guide.step;

  useEffect(() => {
    onPresentationChange?.({ step: visibleStep, expanded: !completedAtEntry && !guide.minimized });
  }, [completedAtEntry, guide.minimized, onPresentationChange, visibleStep]);

  useEffect(() => {
    try {
      if (completed) window.localStorage.setItem(storageKey, "complete");
      if (completedAtEntry) setGuide({ step: 0, minimized: true });
    } catch {
      if (completedAtEntry) setGuide({ step: 0, minimized: true });
    }
  }, [storageKey, completed, completedAtEntry]);

  useLayoutEffect(() => {
    const restrictedEntryKey = restricted ? organizationId : "";
    const enteredRestrictedTutorial = Boolean(restrictedEntryKey && restrictedEntryRef.current !== restrictedEntryKey);
    restrictedEntryRef.current = restrictedEntryKey;
    if (enteredRestrictedTutorial) setGuide({ step: 0, minimized: false });
  }, [organizationId, restricted]);

  function minimizeGuide() {
    setGuide((current) => ({ ...current, minimized: true }));
  }

  function completeGuide() {
    try { window.localStorage.setItem(storageKey, "complete"); } catch {}
    setGuide((current) => ({ ...current, minimized: true }));
  }

  function advanceGuide() {
    if (restricted) {
      onTutorialStepChange?.(Math.min(messages.length - 1, visibleStep + 1));
      return;
    }
    if (guide.step >= messages.length - 1) {
      completeGuide();
      return;
    }
    setGuide((current) => ({ ...current, step: current.step + 1 }));
  }

  if (completedAtEntry) return null;

  if (guide.minimized) {
    return (
      <button type="button" className="combat-imprints-v2-assistant-minimized" data-tutorial-assistant-control="reopen" aria-label="Open Imprint Ledger briefing" onClick={() => setGuide((current) => ({ ...current, minimized: false }))}>
        {avatar ? <img src={avatar} alt="" /> : <span>AI</span>}
      </button>
    );
  }

  return (
    <aside className="combat-imprints-v2-assistant" aria-label={assistantName + " Imprint Ledger briefing"} aria-live="polite">
      <header>
        <div className="combat-imprints-v2-assistant-avatar" aria-hidden="true">{avatar ? <img src={avatar} alt="" /> : <span>AI</span>}</div>
        <div><b>{assistantName}</b><span>IMPRINT LEDGER BRIEFING · {visibleStep + 1} / {messages.length}</span></div>
      </header>
      <p>{messages[visibleStep].copy}</p>
      {restricted && <strong className="restricted-tutorial-instruction">{messages[visibleStep].instruction}</strong>}
      {showRestrictedNudge && <div className="restricted-tutorial-panel-nudge" role="status">⚠ FOLLOW THE HIGHLIGHTED INSTRUCTION</div>}
      <footer>
        {visibleStep < messages.length - 1 && <button type="button" className="combat-imprints-v2-assistant-next" onClick={advanceGuide}>NEXT</button>}
        {!restricted && visibleStep === messages.length - 1 && <button type="button" className="combat-imprints-v2-assistant-next" onClick={completeGuide}>UNDERSTOOD</button>}
        <button type="button" className="tutorial-assistant-dismiss" data-tutorial-assistant-control="dismiss" aria-label="Minimize Combat Imprint briefing" onClick={minimizeGuide}>DISMISS</button>
      </footer>
    </aside>
  );
}

function CombatImprintLedger({ account, ledger, ledgerRef, restrictedTutorial = false, tutorialComplete = false, tutorialCompletionResolved = true, reward, onReviewReward }) {
  const entries = Array.isArray(ledger && ledger.combatImprints) ? ledger.combatImprints : [];
  const [tutorialStep, setTutorialStep] = useState(0);
  const [assistantPresentation, setAssistantPresentation] = useState({ step: 0, expanded: false });
  const [tutorialBlocked, setTutorialBlocked] = useState(false);
  const issuedCount = entries.filter((entry) => entry && entry.playable === true).length;
  const inProgressCount = entries.filter((entry) => !entry || entry.playable !== true).length;
  const formatDate = (value) => {
    const timestamp = Date.parse(value || "");
    return Number.isFinite(timestamp)
      ? new Date(timestamp).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }).toUpperCase()
      : "UPDATE TIME UNAVAILABLE";
  };

  const targetCode = String(reward && reward.targetMeka && (reward.targetMeka.cardCode || reward.targetMeka.id) || "").toUpperCase();
  const tutorialTargetEntry = entries.find((entry) => String(entry && entry.target && (entry.target.cardCode || entry.target.id) || "").toUpperCase() === targetCode);
  const tutorialActionLabel = tutorialTargetEntry?.playable === true ? "ADD TO A DECK" : tutorialTargetEntry?.nextAction?.optional ? "REMATCH TARGET" : "";
  const allowedSelectors = [
    "[data-tutorial-assistant-control]",
    ...(tutorialStep < 2
      ? [".combat-imprints-v2-assistant-next"]
      : ["[data-post-founding-imprint-action='true']"])
  ];
  const visibleTutorialStep = restrictedTutorial ? tutorialStep : assistantPresentation.step;
  const highlightSelectors = visibleTutorialStep < 2
    ? [".combat-imprints-v2-assistant-next:not([disabled])"]
    : restrictedTutorial
      ? ["[data-post-founding-imprint-action='true']"]
      : [".combat-imprints-v2-action a"];

  async function followImprintAction(event, playable) {
    if (!restrictedTutorial) return;
    event.preventDefault();
    if (playable) {
      const next = await onReviewReward?.();
      if (next) activateDirectiveTarget("#deckbay");
      return;
    }
    try { sessionStorage.setItem(FOUNDING_TRAINING_API_BASE_KEY, PUBLIC_API_BASE_URL || "/api"); } catch {}
    window.location.assign("/battle/bond-breach/?mode=founding&rematch=1");
  }

  return (
    <RestrictedTutorialGuard active={restrictedTutorial} highlightActive={restrictedTutorial || assistantPresentation.expanded} allowedSelectors={allowedSelectors} highlightSelectors={highlightSelectors} onBlockedChange={setTutorialBlocked}>
    <section ref={ledgerRef} tabIndex={-1} className="combat-imprints-v2" aria-label="Combat Imprint Ledger" aria-busy={ledger && ledger.status === "loading"}>
      <header className="combat-imprints-v2-header">
        <div className="combat-imprints-v2-brand">
          <a href="#hangar">◂ MY HANGAR</a>
          <div><span>SUPER MEKABOTS TCG · BOND//BREACH · ARSENAL</span><h1>COMBAT IMPRINTS</h1></div>
        </div>
      </header>
      <div className="combat-imprints-v2-body">
        <div className="combat-imprints-v2-summary">
          <div><span>OPPONENT BATTLE-DATA RECORDS</span><h2>COMBAT IMPRINT LEDGER</h2><p>Battle data recorded from opponent encounters. Reach 100 / 100 to issue a playable Combat Print into your Card Collection. The opponent Meka License is never transferred; partial Imprints stay non-playable.</p></div>
          <div className="combat-imprints-v2-stats" aria-label="Combat Imprint totals">
            <div><span>TARGETS</span><b>{String(entries.length).padStart(2, "0")}</b></div>
            <div><span>PRINTS ISSUED</span><b>{String(issuedCount).padStart(2, "0")}</b></div>
            <div><span>IN PROGRESS</span><b>{String(inProgressCount).padStart(2, "0")}</b></div>
          </div>
        </div>
        {ledger && ledger.status === "loading" && <div className="combat-imprints-v2-state" role="status">SYNCING COMBAT IMPRINTS...</div>}
        {ledger && ledger.status === "error" && <div className="combat-imprints-v2-state is-error" role="alert"><b>COMBAT IMPRINT LEDGER UNAVAILABLE</b><span>{ledger.error || "The organization ledger could not be read."}</span></div>}
        {ledger && ledger.status === "ready" && entries.length === 0 && <div className="combat-imprints-v2-state"><b>NO COMBAT IMPRINTS RECORDED</b><span>Opponent battle data will appear here after a qualifying encounter.</span></div>}
        {entries.length > 0 && <div className="combat-imprints-v2-rows" aria-label="Recorded Combat Imprints">
          {entries.map((entry) => {
            const target = entry && entry.target ? entry.target : {};
            const source = entry && entry.lastSource ? entry.lastSource : {};
            const art = canonicalObjectStorageAssetUrl(target.artUrl);
            const metadataUnavailable = target.metadataStatus === "unavailable";
            const progressInvalid = entry.progressStatus === "invalid";
            const progressValue = progressInvalid ? null : Number(entry.progress || 0);
            const playable = entry.playable === true;
            const completePending = entry.status === "complete" && !playable;
            const tone = progressInvalid || completePending ? "danger" : playable ? "complete" : "progress";
            const chip = progressInvalid ? "DATA INVALID" : completePending ? "ISSUANCE PENDING" : playable ? "PRINT ISSUED" : "SCANNING";
            const status = progressInvalid ? "DATA UNAVAILABLE" : completePending ? "COMPLETE / PRINT PENDING" : playable ? "COMPLETE" : "IN PROGRESS";
            const playability = progressInvalid ? "NOT PLAYABLE / INVALID IMPRINT DATA" : playable ? "COMBAT PRINT ALREADY IN CARD COLLECTION" : "NOT PLAYABLE / PRINT NOT ISSUED";
            const sourceIdentity = [source.opponentOrganizationName, source.arenaName].filter(Boolean).join(" · ") || [source.type, source.key].filter(Boolean).join(" · ") || "SOURCE RECORD UNAVAILABLE";
            const sourceBattle = [source.arenaName, source.result].filter(Boolean).join(" / ") || [source.type, source.key].filter(Boolean).join(" / ") || "SOURCE BATTLE UNAVAILABLE";
            const actionHref = playable ? "#deckbay" : entry.nextAction && entry.nextAction.href;
            const actionLabel = playable ? "ADD TO A DECK" : entry.nextAction && entry.nextAction.optional ? "REMATCH TARGET" : "";
            const actionCopy = progressInvalid
              ? "Archive progress is invalid. No action is available until this record is repaired."
              : completePending
                ? "Imprint complete. Combat Print issuance is still pending Archive verification."
                : playable
                  ? "Print issued. Add it to a deck from the Deck Bay, or inspect it in your Card Collection."
                  : entry.nextAction && entry.nextAction.optional
                    ? "Rematch this target to record the remaining battle data and issue the print."
                    : "Partial data is safely recorded. No rematch route is currently available.";
            return (
              <article className={"combat-imprints-v2-row is-" + tone} key={[target.id, source.key].filter(Boolean).join(":") || String(entries.indexOf(entry))}>
                <figure className="combat-imprints-v2-figure">
                  {art ? <img src={art} alt={(target.name || target.id) + " target art"} loading="lazy" decoding="async" /> : <div><span>CANONICAL TARGET ART</span><b>{metadataUnavailable ? "TARGET METADATA UNAVAILABLE" : "ART UNAVAILABLE"}</b></div>}
                  {!playable && !progressInvalid && <i aria-hidden="true" />}
                  <span>{chip}</span>
                </figure>
                <div className="combat-imprints-v2-identity">
                  <span>{target.id || "TARGET ID UNAVAILABLE"} · TARGET</span>
                  <h3>{target.name || "TARGET METADATA UNAVAILABLE"}</h3>
                  <b>STATUS / {status}</b>
                  <small>{sourceIdentity.toUpperCase()}</small>
                </div>
                <div className="combat-imprints-v2-progress">
                  <div><span>IMPRINT PROGRESS</span><b>{progressInvalid ? "PROGRESS UNAVAILABLE" : String(progressValue).padStart(3, "0") + " / 100"}</b></div>
                  {progressInvalid ? <div className="combat-imprints-v2-progress-unavailable" role="status">METER UNAVAILABLE</div> : <div className="combat-imprints-v2-meter" role="progressbar" aria-label={(target.id || "Target") + " Combat Imprint progress"} aria-valuemin="0" aria-valuemax="100" aria-valuenow={progressValue}><i style={{ "--combat-imprint-progress": progressValue + "%" }} /></div>}
                  <strong>{playability}</strong>
                  <dl><div><dt>SOURCE BATTLE</dt><dd>{sourceBattle.toUpperCase()}</dd></div><div><dt>LAST UPDATE</dt><dd><time dateTime={entry.updatedAt || undefined}>{formatDate(entry.updatedAt)}</time></dd></div></dl>
                </div>
                <div className="combat-imprints-v2-action">
                  <span>NEXT STEP</span><p>{actionCopy}</p>
                  {actionHref && actionLabel && <a className={playable ? "is-primary" : "is-danger"} href={actionHref} data-post-founding-imprint-action={restrictedTutorial && String(target.cardCode || target.id || "").toUpperCase() === targetCode ? "true" : undefined} onClick={(event) => restrictedTutorial && String(target.cardCode || target.id || "").toUpperCase() === targetCode ? followImprintAction(event, playable) : undefined}>{actionLabel}</a>}
                </div>
              </article>
            );
          })}
        </div>}
        <p className="combat-imprints-v2-note">A COMPLETE IMPRINT ISSUES A COMBAT PRINT — A PLAYABLE COPY IN YOUR CARD COLLECTION. WIN AGAINST THE TARGET TO RECORD 100, LOSE TO RECORD 50. REPEAT DATA CONVERTS TO PARTS.</p>
      </div>
      <CombatImprintsAssistant account={account} restricted={restrictedTutorial} completed={tutorialComplete} completionResolved={tutorialCompletionResolved} tutorialStep={tutorialStep} onTutorialStepChange={setTutorialStep} onPresentationChange={setAssistantPresentation} showRestrictedNudge={restrictedTutorial && tutorialBlocked} actionLabel={tutorialActionLabel} />
    </section>
    </RestrictedTutorialGuard>
  );
}

function cloneDeckEntries(entries) {
  return (Array.isArray(entries) ? entries : []).map((entry) => ({ code: entry.code, kind: entry.kind, quantity: Number(entry.quantity || 0) })).filter((entry) => entry.code && entry.quantity > 0);
}

function useTcgDecks(account, enabled) {
  const accountIdentity = [account && account.status, account && account.user && account.user.id, account && account.organization && account.organization.id].join(":");
  const identity = enabled && account && account.status === "signed-in" ? accountIdentity : "";
  const identityRef = useRef(identity);
  const requestEpochRef = useRef(0);
  const mutationEpochRef = useRef(0);
  const [state, setState] = useState(() => ({ identity: "", status: "idle", decks: [], error: "", actionBusy: "" }));
  if (identityRef.current !== identity) {
    identityRef.current = identity;
    requestEpochRef.current += 1;
    mutationEpochRef.current += 1;
  }
  const isCurrent = useCallback((expectedIdentity, expectedMutationEpoch) => identityRef.current === expectedIdentity && mutationEpochRef.current === expectedMutationEpoch, []);
  const load = useCallback(async ({ actionBusy = "" } = {}) => {
    const requestEpoch = ++requestEpochRef.current;
    const mutationEpoch = mutationEpochRef.current;
    if (!identity) { setState({ identity: "", status: "idle", decks: [], error: "", actionBusy: "" }); return []; }
    setState((current) => current.identity === identity ? { ...current, status: "loading", error: "", actionBusy } : { identity, status: "loading", decks: [], error: "", actionBusy });
    try {
      const data = await publicApi("/tcg/decks");
      const decks = Array.isArray(data && data.decks) ? data.decks : [];
      if (requestEpoch === requestEpochRef.current && isCurrent(identity, mutationEpoch)) setState((current) => ({ ...current, identity, status: "ready", decks, error: "", actionBusy: "" }));
      return decks;
    } catch (error) {
      if (requestEpoch === requestEpochRef.current && isCurrent(identity, mutationEpoch)) setState((current) => ({ ...current, identity, status: "error", decks: current.decks, error: error.message || "Deck library unavailable", actionBusy: "" }));
      return [];
    }
  }, [identity, isCurrent]);
  useEffect(() => { void load(); }, [load]);
  const reconcileConflict = useCallback(async (error, expectedIdentity, expectedMutationEpoch, affectedDeckId) => {
    const code = error && (error.code || error.body && error.body.code);
    if (!["TCG_DECK_REVISION_CONFLICT", "DECK_ILLEGAL"].includes(code) || !isCurrent(expectedIdentity, expectedMutationEpoch)) return false;
    const legality = error && error.body && error.body.legality;
    if (legality) setState((current) => current.identity === expectedIdentity ? { ...current, decks: current.decks.map((deck) => deck.id === (error.body && error.body.deckId || affectedDeckId) ? { ...deck, legality } : deck) } : current);
    mutationEpochRef.current += 1;
    await load({ actionBusy: "reconcile" });
    return true;
  }, [isCurrent, load]);
  const createDeck = useCallback(async (name, entries = []) => {
    const mutationEpoch = ++mutationEpochRef.current;
    const expectedIdentity = identity;
    if (!expectedIdentity) return null;
    setState((current) => current.identity === expectedIdentity ? { ...current, actionBusy: "create", error: "" } : current);
    try {
      const data = await publicApi("/tcg/decks", { method: "POST", body: JSON.stringify({ name, deckType: "constructed", entries: cloneDeckEntries(entries) }) });
      const deck = data && data.deck;
      if (deck && isCurrent(expectedIdentity, mutationEpoch)) setState((current) => current.identity === expectedIdentity ? { ...current, status: "ready", decks: [...current.decks, deck], actionBusy: "", error: "" } : current);
      return deck && isCurrent(expectedIdentity, mutationEpoch) ? deck : null;
    } catch (error) { if (isCurrent(expectedIdentity, mutationEpoch)) setState((current) => current.identity === expectedIdentity ? { ...current, actionBusy: "", error: error.message || "Deck could not be created" } : current); return null; }
  }, [identity, isCurrent]);
  const saveDeck = useCallback(async (deckId, draft) => {
    const mutationEpoch = ++mutationEpochRef.current;
    const expectedIdentity = identity;
    if (!expectedIdentity) return null;
    setState((current) => current.identity === expectedIdentity ? { ...current, actionBusy: "save:" + deckId, error: "" } : current);
    try {
      const data = await publicApi("/tcg/decks/" + encodeURIComponent(deckId), { method: "PATCH", body: JSON.stringify({ name: draft.name, entries: cloneDeckEntries(draft.entries) }) });
      const deck = data && data.deck;
      if (deck && isCurrent(expectedIdentity, mutationEpoch)) setState((current) => current.identity === expectedIdentity ? { ...current, decks: current.decks.map((item) => item.id === deck.id ? deck : item), actionBusy: "", error: "" } : current);
      return deck && isCurrent(expectedIdentity, mutationEpoch) ? deck : null;
    } catch (error) { if (!await reconcileConflict(error, expectedIdentity, mutationEpoch, deckId) && isCurrent(expectedIdentity, mutationEpoch)) setState((current) => current.identity === expectedIdentity ? { ...current, actionBusy: "", error: error.message || "Deck could not be saved" } : current); return null; }
  }, [identity, isCurrent, reconcileConflict]);
  const deleteDeck = useCallback(async (deckId) => {
    const mutationEpoch = ++mutationEpochRef.current;
    const expectedIdentity = identity;
    if (!expectedIdentity) return false;
    setState((current) => current.identity === expectedIdentity ? { ...current, actionBusy: "delete:" + deckId, error: "" } : current);
    try {
      const data = await publicApi("/tcg/decks/" + encodeURIComponent(deckId), { method: "DELETE" });
      const deleted = Boolean(data && data.deleted === true && data.deckId === deckId);
      if (deleted && isCurrent(expectedIdentity, mutationEpoch)) setState((current) => current.identity === expectedIdentity ? { ...current, decks: current.decks.filter((item) => item.id !== deckId), actionBusy: "", error: "" } : current);
      return deleted && isCurrent(expectedIdentity, mutationEpoch);
    } catch (error) {
      if (!await reconcileConflict(error, expectedIdentity, mutationEpoch, deckId) && isCurrent(expectedIdentity, mutationEpoch)) setState((current) => current.identity === expectedIdentity ? { ...current, actionBusy: "", error: error.message || "Deck could not be deleted" } : current);
      return false;
    }
  }, [identity, isCurrent, reconcileConflict]);
  return state.identity === identity ? { ...state, load, createDeck, saveDeck, deleteDeck } : { identity, status: identity ? "loading" : "idle", decks: [], error: "", actionBusy: "", load, createDeck, saveDeck, deleteDeck };
}

function useDeploymentPackage(account, enabled) {
  const accountIdentity = [account && account.status, account && account.user && account.user.id, account && account.organization && account.organization.id].join(":");
  const identity = enabled && account && account.status === "signed-in" ? accountIdentity : "";
  const identityRef = useRef(identity);
  const transitionEpochRef = useRef(0);
  const [state, setState] = useState(() => ({ identity: "", status: "idle", activePackage: null, eligibleCrews: [], crewTemplates: [], compatibility: [], directives: [], error: "", actionBusy: "" }));
  if (identityRef.current !== identity) {
    identityRef.current = identity;
    transitionEpochRef.current += 1;
  }
  const isCurrentTransition = useCallback((token) => identityRef.current === token.identity && transitionEpochRef.current === token.epoch, []);
  const load = useCallback(async () => {
    if (!identity) { setState({ identity: "", status: "idle", activePackage: null, eligibleCrews: [], crewTemplates: [], compatibility: [], directives: [], error: "", actionBusy: "" }); return null; }
    setState((current) => current.identity === identity ? { ...current, status: "loading", error: "" } : { identity, status: "loading", activePackage: null, eligibleCrews: [], crewTemplates: [], compatibility: [], directives: [], error: "", actionBusy: "" });
    try {
      const data = await publicApi("/tcg/deployment-package");
      if (identityRef.current === identity) setState({ identity, status: "ready", activePackage: data && data.activePackage || null, eligibleCrews: Array.isArray(data && data.eligibleCrews) ? data.eligibleCrews : [], crewTemplates: Array.isArray(data && data.crewTemplates) ? data.crewTemplates : [], compatibility: Array.isArray(data && data.compatibility) ? data.compatibility : [], directives: Array.isArray(data && data.directives) ? data.directives : [], error: "", actionBusy: "" });
      return data;
    } catch (error) { if (identityRef.current === identity) setState((current) => ({ ...current, identity, status: "error", error: error.message || "Deployment Package unavailable", actionBusy: "" })); return null; }
  }, [identity]);
  useEffect(() => { void load(); }, [load]);
  const transition = useCallback(async (action, path, body, failureMessage = "Deployment Package action failed") => {
    if (!identity) return null;
    const token = { identity, epoch: transitionEpochRef.current + 1 };
    transitionEpochRef.current = token.epoch;
    setState((current) => ({ ...current, actionBusy: action, error: "" }));
    try {
      const options = { method: "POST" };
      if (body !== undefined) options.body = JSON.stringify(body);
      const data = await publicApi(path, options);
      if (!isCurrentTransition(token)) return null;
      await load();
      if (!isCurrentTransition(token)) return null;
      return data;
    } catch (error) { if (isCurrentTransition(token)) setState((current) => ({ ...current, actionBusy: "", error: error.message || failureMessage })); return null; }
  }, [identity, isCurrentTransition, load]);
  const completeBriefing = useCallback(() => transition("briefing", "/tcg/deployment-package/briefing/complete", undefined, "Deck Bay briefing could not be completed"), [transition]);
  const prepareDeck = useCallback((deckId, deckRevision) => transition("prepare", "/tcg/deployment-package/deck/prepare", { deckId, deckRevision }), [transition]);
  const pairCrew = useCallback((deckId, crewId, deckRevision) => transition("pair", "/tcg/deployment-package/crew/pair", { deckId, crewId, deckRevision }), [transition]);
  const activate = useCallback((deckId, crewId, deckRevision) => transition("activate", "/tcg/deployment-package/activate", { deckId, crewId, deckRevision }, "Deployment Package could not be activated"), [transition]);
  return state.identity === identity ? { ...state, load, completeBriefing, prepareDeck, pairCrew, activate } : { identity, status: identity ? "loading" : "idle", activePackage: null, eligibleCrews: [], crewTemplates: [], compatibility: [], directives: [], error: "", actionBusy: "", load, completeBriefing, prepareDeck, pairCrew, activate };
}

function buildQuantityControlId(label, control) {
  const canonicalCode = label == null ? "" : String(label);
  const encodedCode = canonicalCode === ""
    ? "empty"
    : Array.from(canonicalCode).map((character) => "u" + character.codePointAt(0).toString(16).padStart(6, "0")).join("-");
  const controlSuffix = String(control || "control").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "control";
  return "quantity-control-" + controlSuffix + "-" + encodedCode;
}

function getQuantityControlState({ label, quantity, addDisabled, readOnly }) {
  const atZero = Number(quantity || 0) < 1;
  const removeDisabled = Boolean(readOnly || atZero);
  const addControlDisabled = Boolean(readOnly || addDisabled);
  const removeReason = readOnly ? "SEALED DECK / MANIFEST LOCKED" : atZero ? "REMOVE CONTROL LOCKED / NO PRINTS IN DECK" : "";
  const addReason = readOnly ? "SEALED DECK / MANIFEST LOCKED" : addDisabled ? "ADD CONTROL LOCKED / ADD OWNED PRINTS FROM COLLECTION" : "";
  return {
    remove: { disabled: removeDisabled, reason: removeReason, reasonId: buildQuantityControlId(label, "remove") },
    add: { disabled: addControlDisabled, reason: addReason, reasonId: buildQuantityControlId(label, "add") }
  };
}

function getDeckSourceAddState({ code, kind, ownedQuantity, currentQuantity, readOnly }) {
  const canonicalCode = code == null ? "" : String(code);
  const normalizedCode = canonicalCode.toUpperCase();
  const normalizedKind = String(kind || "").toLowerCase();
  const owned = Math.max(0, Number(ownedQuantity || 0));
  const current = Math.max(0, Number(currentQuantity || 0));
  const copyLimit = normalizedKind === "mk" ? 1 : 4;
  const reason = readOnly
    ? "SEALED DECK / COLLECTION ADD LOCKED"
    : !normalizedCode
      ? "ADD CONTROL LOCKED / PRINT ID UNAVAILABLE"
      : owned < 1
        ? "ADD CONTROL LOCKED / NO OWNED PRINTS"
        : current >= copyLimit
          ? (normalizedKind === "mk" ? "ADD CONTROL LOCKED / MK COPY LIMIT REACHED" : "ADD CONTROL LOCKED / COPY LIMIT REACHED")
          : current >= owned
            ? "ADD CONTROL LOCKED / OWNED COPY LIMIT REACHED"
            : "";
  return { disabled: Boolean(reason), reason, reasonId: buildQuantityControlId(canonicalCode, "source-add") };
}

function isDeckPlayableCollectionCard(card) {
  const kind = String(card && card.kind || "").toLowerCase();
  if (!["mk", "md", "command"].includes(kind) || card?.playable === false || card?.partial === true || String(card?.status || "").toLowerCase() === "partial") return false;
  const source = String(card?.acquisitionSource || card?.source || "").toLowerCase();
  if (source === "combat_imprint") return false;
  const progress = Number(card?.imprintProgress);
  return !Number.isFinite(progress) || progress >= 100;
}

function getDeckEditorLocalPrecheck(entries, cards) {
  const manifest = cloneDeckEntries(entries);
  const cardByCode = new Map((Array.isArray(cards) ? cards : []).filter(isDeckPlayableCollectionCard).map((card) => [String(card.code || "").toUpperCase(), card]));
  const total = manifest.reduce((sum, entry) => sum + Number(entry.quantity || 0), 0);
  const blockers = [];
  if (total !== 40) blockers.push({ code: "TOTAL_REQUIRED", message: total < 40 ? `${40 - total} more card${40 - total === 1 ? "" : "s"} required.` : `${total - 40} card${total - 40 === 1 ? "" : "s"} must be removed.` });
  for (const entry of manifest) {
    const card = cardByCode.get(String(entry.code || "").toUpperCase());
    const quantity = Number(entry.quantity || 0);
    const owned = Number(card?.quantity || 0);
    const copyLimit = String(card?.kind || entry.kind || "").toLowerCase() === "mk" ? 1 : 4;
    if (!card || owned < 1) blockers.push({ code: "OWNERSHIP_REQUIRED", message: `${entry.code} has no owned playable print.` });
    else if (quantity > owned) blockers.push({ code: "OWNED_COPY_LIMIT", message: `${entry.code} exceeds the owned quantity.` });
    if (quantity > copyLimit) blockers.push({ code: "COPY_LIMIT", message: `${entry.code} exceeds the ${copyLimit}-copy limit.` });
  }
  return { ready: blockers.length === 0, total, blockers };
}

function QuantityStepper({ label, quantity, onAdd, onRemove, addDisabled, readOnly, locked }) {
  const controls = locked
    ? {
        remove: { disabled: true, reason: "DECK UPDATE IN PROGRESS / CONTROL LOCKED", reasonId: buildQuantityControlId(label, "remove") },
        add: { disabled: true, reason: "DECK UPDATE IN PROGRESS / CONTROL LOCKED", reasonId: buildQuantityControlId(label, "add") }
      }
    : getQuantityControlState({ label, quantity, addDisabled, readOnly });
  return <div className="deck-quantity-stepper" aria-label={label}><button type="button" onClick={onRemove} disabled={controls.remove.disabled} aria-describedby={controls.remove.disabled ? controls.remove.reasonId : undefined} aria-label={"Remove one " + label}>−</button><b>{quantity}</b><button type="button" onClick={onAdd} disabled={controls.add.disabled} aria-describedby={controls.add.disabled ? controls.add.reasonId : undefined} aria-label={"Add one " + label}>+</button>{controls.remove.reason && <span className="quantity-control-reason" id={controls.remove.reasonId}>{controls.remove.reason}</span>}{controls.add.reason && <span className="quantity-control-reason" id={controls.add.reasonId}>{controls.add.reason}</span>}</div>;
}

function getDeckLegalityBusyStatus(busy) {
  const action = String(busy || "");
  if (!action) return "";
  if (action.startsWith("save:")) return "SAVING DECK / SERVER LEGALITY PENDING";
  if (["prepare", "pair", "activate", "briefing"].includes(action)) return "UPDATING DEPLOYMENT PACKAGE / AUTHORITATIVE STATUS PENDING";
  return "UPDATING DECK LIBRARY / DECK ACTIONS TEMPORARILY UNAVAILABLE";
}

function DeckLegalitySummary({ deck, entries, cards, changed, onSave, onAssemble, busy, compact = false }) {
  const localPrecheck = getDeckEditorLocalPrecheck(entries, cards);
  const legality = !changed && deck && deck.legality ? deck.legality : null;
  const savedLegal = Boolean(legality && legality.legal);
  const ready = changed ? localPrecheck.ready : savedLegal;
  const blockers = changed ? localPrecheck.blockers : Array.isArray(legality && legality.violations) ? legality.violations : [];
  const violationCount = blockers.length;
  const savedStatus = savedLegal ? "BATTLE READY" : blockers.length ? "INCOMPLETE DECK" : legality ? "SERVER LEGALITY UNAVAILABLE" : "SERVER LEGALITY PENDING";
  const busyStatus = getDeckLegalityBusyStatus(busy);
  const busyStatusId = useId();
  return (
    <aside className={"deck-legality-summary" + (compact ? " is-compact" : "")} data-legality-ledger={compact ? "compact" : "full"} aria-live={compact ? "off" : "polite"} aria-busy={busyStatus ? "true" : undefined} tabIndex="-1">
      <span>{changed ? "LOCAL PRECHECK / SERVER VALIDATES ON SAVE" : "SERVER LEGALITY"}</span>
      <b className={ready ? "is-legal" : "is-invalid"}>{localPrecheck.total} / 40</b>
      <strong>{changed ? ready ? "UNSAVED CHANGES / BATTLE READY / SAVE TO VALIDATE" : "UNSAVED CHANGES / DRAFT BLOCKERS REMAIN" : savedStatus}</strong>
      {compact
        ? <p className="deck-legality-flow-disclosure">{violationCount ? violationCount + " BLOCKER" + (violationCount === 1 ? "" : "S") : changed ? "LOCAL CHECK READY" : savedLegal ? "SERVER VERIFIED" : legality ? "SERVER DETAILS UNAVAILABLE" : "SERVER RESULT PENDING"} / FULL LEDGER IN PAGE FLOW</p>
        : blockers.length
          ? <ul>{blockers.map((item, index) => <li key={[item.code, item.cardCode, index].join(":")}><b>{String(item.code || "BLOCKER").replaceAll("_", " ")}</b><span>{item.message}</span></li>)}</ul>
          : changed
            ? <p>Local count, ownership, and copy limits are ready. Save to request the authoritative server result.</p>
            : savedLegal
              ? <p>The saved revision passed the authoritative server legality check.</p>
              : legality
                ? <p>SERVER LEGALITY UNAVAILABLE / The saved result returned no blocker details. Refresh Deck Bay or edit and save this Deck to request validation.</p>
                : <p>SERVER LEGALITY PENDING / Refresh Deck Bay or edit and save this Deck to request validation.</p>}
      {busyStatus && <p className="deck-legality-busy" id={busyStatusId} role="status">{busyStatus}</p>}
      <div>
        <button type="button" className="btn primary" onClick={onSave} disabled={Boolean(deck && deck.deckType === "sealed") || !changed || Boolean(busy)} aria-describedby={busyStatus ? busyStatusId : undefined}>{ready ? "SAVE BATTLE-READY DECK" : "SAVE DRAFT"}</button>
        {savedLegal && !changed && onAssemble && <button type="button" className="btn primary" onClick={onAssemble} disabled={Boolean(busy)}>ASSEMBLE DEPLOYMENT PACKAGE</button>}
      </div>
      {savedLegal && !changed && <p className="deck-ready-note">SAVED REVISION AVAILABLE FOR DEPLOYMENT PACKAGE PREPARATION.</p>}
    </aside>
  );
}

function encodeDeckTransfer(source, cardCode) {
  return JSON.stringify({ version: 1, source, cardCode: String(cardCode || "").toUpperCase() });
}

function decodeDeckTransfer(event) {
  try {
    const value = JSON.parse(event.dataTransfer.getData("application/x-supermekabots-deck-card"));
    return value && value.version === 1 && (value.source === "collection" || value.source === "manifest") && value.cardCode ? value : null;
  } catch { return null; }
}

function deckEntriesChanged(before, after) {
  return JSON.stringify(cloneDeckEntries(before)) !== JSON.stringify(cloneDeckEntries(after));
}

function DeckBuilderCard({ card, quantity, readOnly, busy, onAdd, onRemove, onInspect, onDragStart, onDragEnd }) {
  const addState = getDeckSourceAddState({ code: card.code, kind: card.kind, ownedQuantity: card.quantity, currentQuantity: quantity, readOnly });
  const busyReasonId = buildQuantityControlId(card.code, "workflow");
  const visibleLimit = busy ? "DECK UPDATE IN PROGRESS" : addState.reason ? addState.reason.replace("ADD CONTROL LOCKED / ", "") : "";
  const copyLimit = String(card.kind || "").toLowerCase() === "mk" ? 1 : 4;
  const libraryRemaining = Math.max(0, Number(card.quantity || 0) - Number(quantity || 0));
  const authorityLabel = `${String(card.kind || "CARD").toUpperCase()} / ${card.code} / ${getCollectionSourceLabel(card)} / OWNED ${Number(card.quantity || 0)} / IN DECK ${Number(quantity || 0)}`;
  return (
    <article className="deck-builder-card" data-card-code={card.code} draggable={!busy && !addState.disabled} aria-describedby={busy ? busyReasonId : undefined} onDragStart={(event) => { if (busy) { event.preventDefault(); return; } event.dataTransfer.effectAllowed = "copy"; event.dataTransfer.setData("application/x-supermekabots-deck-card", encodeDeckTransfer("collection", card.code)); onDragStart?.("collection"); }} onDragEnd={onDragEnd}>
      <button type="button" className="deck-builder-card-focus" data-deck-inspect-trigger="collection" data-card-code={card.code} onClick={() => onInspect(card.code, "collection")} aria-label={`Inspect ${card.code}, ${card.definition?.name || card.code}. ${authorityLabel}.`}>
        <FoundingGameplayCardVisual entry={collectionCardGameplayEntry(card)} />
        <span>INSPECT CARD</span>
      </button>
      <div className="deck-builder-card-classification"><b>{String(card.kind || "CARD").toUpperCase()}</b><span>{getCollectionSourceLabel(card)}</span></div>
      <div className="deck-builder-card-meta"><b>OWNED {card.quantity}</b><span>IN DECK {quantity || 0}</span></div>
      <div className="deck-builder-card-controls">
        <button type="button" onClick={onRemove} disabled={busy || readOnly || !quantity} aria-describedby={busy ? busyReasonId : undefined} aria-label={"Remove one " + card.code}>−</button>
        <strong data-deck-quantity={Number(quantity || 0)}><span>DECK {quantity || 0}/{copyLimit}</span><small>LIB {libraryRemaining}/{Number(card.quantity || 0)}</small></strong>
        <button type="button" onClick={onAdd} disabled={busy || addState.disabled} aria-describedby={busy ? busyReasonId : addState.disabled ? addState.reasonId : undefined} aria-label={"Add " + card.code}>+</button>
      </div>
      {busy ? <span className="quantity-control-reason" id={busyReasonId}>DECK UPDATE IN PROGRESS / CONTROL LOCKED</span> : addState.reason && <span className="quantity-control-reason" id={addState.reasonId}>{addState.reason}</span>}
      {visibleLimit && <span className="deck-builder-card-limit" aria-live="polite">{visibleLimit}</span>}
    </article>
  );
}

function mutateDeckEntries(entries, card, delta, readOnly) {
  const currentEntries = cloneDeckEntries(entries);
  const code = String(card && card.code || "").toUpperCase();
  if (!code || readOnly || !delta) return currentEntries;
  const current = currentEntries.find((entry) => entry.code === code);
  if (delta > 0) {
    const state = getDeckSourceAddState({ code, kind: card && card.kind, ownedQuantity: card && card.quantity, currentQuantity: current && current.quantity, readOnly });
    if (state.disabled) return currentEntries;
    return current ? currentEntries.map((entry) => entry.code === code ? { ...entry, quantity: entry.quantity + 1 } : entry) : [...currentEntries, { code, kind: card.kind, quantity: 1 }];
  }
  if (!current) return currentEntries;
  return currentEntries.map((entry) => entry.code === code ? { ...entry, quantity: entry.quantity - 1 } : entry).filter((entry) => entry.quantity > 0);
}

function DeckCollectionSource({ cards, status, error, onRetry, filters, onFiltersChange, entries, onChangeEntries, readOnly, busy, onInspect, onDragStart, onDragEnd }) {
  const canonicalPlayableCards = useMemo(() => cards.filter(isDeckPlayableCollectionCard), [cards]);
  const doctrines = useMemo(() => [...new Set(canonicalPlayableCards.map((card) => card && card.definition && card.definition.doctrine).filter(Boolean))].sort((a, b) => a.localeCompare(b)), [canonicalPlayableCards]);
  const playableCards = useMemo(() => filterAndSortDeckCollectionCards(canonicalPlayableCards, filters), [canonicalPlayableCards, filters]);
  const entryByCode = new Map(entries.map((entry) => [entry.code, entry]));
  function add(card) { if (!busy) onChangeEntries(mutateDeckEntries(entries, card, 1, readOnly)); }
  function remove(card) { if (!busy) onChangeEntries(mutateDeckEntries(entries, card, -1, readOnly)); }
  return <section className="deck-collection-source" aria-label="Card Collection">
    {status === "loading" && !canonicalPlayableCards.length && <div className="arsenal-state-panel" role="status">SYNCING PLAYABLE COLLECTION...</div>}
    {status === "error" && <div className="arsenal-state-panel is-error" role="alert"><b>PLAYABLE COLLECTION UNAVAILABLE</b><span>{error || "Card Collection unavailable"}</span><button type="button" className="btn" onClick={onRetry}>RETRY PLAYABLE COLLECTION</button></div>}
    {status !== "error" && (status !== "loading" || canonicalPlayableCards.length > 0) && <><DeckCollectionToolbar filters={filters} doctrines={doctrines} resultCount={playableCards.length} onChange={onFiltersChange} />{status === "loading" && <div className="arsenal-state-panel" role="status">SYNCING PLAYABLE COLLECTION...</div>}<div className="deck-builder-card-grid">{playableCards.map((card) => { const current = entryByCode.get(card.code); return <DeckBuilderCard key={card.code} card={card} quantity={current && current.quantity || 0} readOnly={readOnly} busy={busy} onInspect={onInspect} onAdd={() => add(card)} onRemove={() => remove(card)} onDragStart={onDragStart} onDragEnd={onDragEnd} />; })}{status === "ready" && !canonicalPlayableCards.length && <div className="arsenal-state-panel"><b>NO PLAYABLE PRINTS REGISTERED</b><span>The canonical Card Collection returned no owned MK, MD, or Command prints.</span></div>}{status === "ready" && canonicalPlayableCards.length > 0 && !playableCards.length && <div className="arsenal-state-panel">NO PLAYABLE PRINTS MATCH THESE CONTROLS.</div>}</div></>}
  </section>;
}

function DeckManifestEditor({ deck, entries, cards, changed, busy, onChangeEntries, onNameChange, onInspect, onDragStart, onDragEnd, onSave, onRegister, paired, active, pairingPanel }) {
  const cardByCode = new Map(cards.map((card) => [card.code, card]));
  const readOnly = deck.deckType === "sealed";
  const deckTotal = entries.reduce((sum, entry) => sum + Number(entry.quantity || 0), 0);
  const deckKindCounts = entries.reduce((counts, entry) => {
    const kind = String(cardByCode.get(entry.code)?.kind || entry.kind || "other").toLowerCase();
    counts[kind] = (counts[kind] || 0) + Number(entry.quantity || 0);
    return counts;
  }, {});
  const localPrecheck = getDeckEditorLocalPrecheck(entries, cards);
  const legal = changed ? localPrecheck.ready : Boolean(deck.legality?.legal);
  const saveLabel = changed ? (legal ? "SAVE DECK · 40 / 40" : `SAVE DRAFT · ${deckTotal} / 40`) : active ? "DECK REGISTERED — BATTLE READY" : legal && paired ? "REGISTER DECK — BATTLE READY" : legal ? "SAVED · PAIR A PILOT TO DEPLOY" : `SAVE DRAFT · ${deckTotal} / 40`;
  const saveAction = !changed && legal && paired ? onRegister : onSave;
  const saveDisabled = Boolean(busy || deck.deckType === "sealed" && !legal || !changed && (!legal || !paired || active));
  const manifestGroups = [
    { kind: "mk", label: "MK" },
    { kind: "md", label: "MD" },
    { kind: "command", label: "COMMAND" },
    { kind: "other", label: "OTHER" }
  ].map((group) => ({ ...group, entries: entries.filter((entry) => { const kind = String(cardByCode.get(entry.code)?.kind || entry.kind || "other").toLowerCase(); return group.kind === "other" ? !["mk", "md", "command"].includes(kind) : kind === group.kind; }) })).filter((group) => group.entries.length);
  function changeQuantity(code, delta) { const card = cardByCode.get(code); const next = mutateDeckEntries(entries, { ...card, code, kind: card?.kind || entries.find((entry) => entry.code === code)?.kind, quantity: card?.quantity || 0 }, delta, readOnly); if (deckEntriesChanged(entries, next)) onChangeEntries(next); }
  return <section className="deck-manifest-editor" aria-label="Deck Manifest">
    <header>
      {readOnly
        ? <div className="deck-manifest-name"><span>DECK NAME</span><h2>{deck.name}</h2></div>
        : <label><span>DECK NAME</span><input className="deck-manifest-name-input" maxLength="28" value={deck.name} onChange={(event) => { if (!busy) onNameChange(event.target.value.toUpperCase()); }} disabled={busy} /></label>}
      <div className="deck-manifest-doctrines">{[...new Set(entries.map((entry) => cardByCode.get(entry.code)?.definition?.doctrine).filter(Boolean))].map((doctrine) => <img key={doctrine} src={FOUNDING_DOCTRINE_ICON_URLS[doctrine]} alt={doctrine + " Doctrine"} />)}<span>{[...new Set(entries.map((entry) => cardByCode.get(entry.code)?.definition?.doctrine).filter(Boolean))].join(" · ").toUpperCase() || "NO DOCTRINE YET"}</span></div>
      <div className="deck-manifest-count-bar" aria-hidden="true"><i style={{ width: Math.min(100, deckTotal / 40 * 100) + "%" }} /></div>
      <div className="deck-manifest-count"><span>{(deckKindCounts.mk || 0) + (deckKindCounts.md || 0)} MEKA · {deckKindCounts.command || 0} COMMAND</span><strong>{legal ? paired ? "BATTLE READY" : "PAIR A PILOT TO DEPLOY" : `${Math.max(0, 40 - deckTotal)} MORE NEEDED`}</strong></div>
    </header>
    <div className="deck-manifest-rows">{manifestGroups.map((group) => <section className="deck-manifest-group" key={group.kind} aria-label={group.label + " manifest cards"}><h4>{group.label} · {group.entries.reduce((sum, entry) => sum + Number(entry.quantity || 0), 0)}</h4>{group.entries.map((entry) => { const card = cardByCode.get(entry.code); const addState = getDeckSourceAddState({ code: entry.code, kind: card && card.kind || entry.kind, ownedQuantity: card && card.quantity || 0, currentQuantity: entry.quantity, readOnly }); return <article key={entry.code} className="deck-manifest-row" data-card-code={entry.code} draggable={!readOnly && !busy} aria-describedby={busy ? "deck-editor-workflow-lock" : undefined} onDragStart={(event) => { if (busy) { event.preventDefault(); return; } event.dataTransfer.effectAllowed = "move"; event.dataTransfer.setData("application/x-supermekabots-deck-card", encodeDeckTransfer("manifest", entry.code)); onDragStart?.("manifest"); }} onDragEnd={onDragEnd}><button type="button" className="deck-manifest-card-thumb" data-deck-inspect-trigger="manifest-thumb" data-card-code={entry.code} onClick={() => onInspect(entry.code, "manifest-thumb")} aria-label={"Inspect manifest card " + entry.code}>{card && <FoundingGameplayCardVisual entry={collectionCardGameplayEntry(card)} />}</button><button type="button" className="deck-manifest-card-copy" data-deck-inspect-trigger="manifest-copy" data-card-code={entry.code} onClick={() => onInspect(entry.code, "manifest-copy")}><span>{String(card?.kind || entry.kind || "card").toUpperCase()} / {entry.code}</span><b>{card && card.definition && card.definition.name || entry.code}</b><small>IN DECK {entry.quantity} / OWNED {card && card.quantity || 0}</small>{!readOnly && addState.reason && <em className="deck-manifest-row-limit">{addState.reason.replace("ADD CONTROL LOCKED / ", "")}</em>}</button><QuantityStepper label={entry.code} quantity={entry.quantity} readOnly={readOnly} locked={busy} addDisabled={addState.disabled} onAdd={() => changeQuantity(entry.code, 1)} onRemove={() => changeQuantity(entry.code, -1)} /></article>; })}</section>)}{!entries.length && <div className="arsenal-state-panel"><b>EMPTY CONSTRUCTED DRAFT</b><span>Choose an owned card from Card Collection and press +. Added cards appear here immediately.</span></div>}</div>
    {pairingPanel}
    <footer className="deck-manifest-legality-dock">{localPrecheck.blockers.length > 0 && deckTotal >= 40 && <p className="deck-manifest-warning">⚠ {localPrecheck.blockers[0].message}</p>}<div className="deck-manifest-save-target"><button type="button" className="deck-manifest-save" onClick={saveAction} disabled={saveDisabled}>{saveLabel}</button></div></footer>
  </section>;
}

function PackageIdentityImage({ src, alt, pending }) {
  const [failedSource, setFailedSource] = useState("");
  const ready = Boolean(src && failedSource !== src);
  return ready
    ? <img src={src} alt={alt} onError={() => setFailedSource(src)} />
    : <span className="package-identity-image-pending" data-package-visual-state="pending">{pending}</span>;
}

function formatTrueBondTiming(trueBond) {
  const timing = String(trueBond?.timing || "").trim();
  return timing ? timing.replaceAll("_", " ").toUpperCase() : "TIMING UNAVAILABLE";
}

function DeploymentPackageAssembly({ deck, entries, changed, crew, compatibility, activePackage }) {
  const total = (Array.isArray(entries) ? entries : []).reduce((sum, entry) => sum + Number(entry?.quantity || 0), 0);
  const savedLegal = !changed && deck?.legality?.legal === true;
  const signatureCode = String(crew?.signatureMeka?.code || crew?.signatureMeka?.id || "").toUpperCase();
  const canonicalMeka = MEKABOTS_BY_ID.find((meka) => String(meka?.id || "").toUpperCase() === signatureCode) || null;
  const pilotCallsign = crew?.pilot?.callsign || crew?.pilot?.name || "SELECT CREW";
  const mekaName = crew?.signatureMeka?.codename || crew?.signatureMeka?.name || canonicalMeka?.codename || "SIGNATURE MEKA PENDING";
  const pilotImage = getCrewPilotFaceSource(crew) || canonicalMeka?.pilotImage || "";
  const mekaImage = crew?.signatureMeka?.image || crew?.signatureMeka?.fullbody || canonicalMeka?.fullbody || canonicalMeka?.image || "";
  const trueBond = crew?.trueBond || crew?.signatureTrueBond || null;
  const trueBondName = trueBond?.name || "PAIR A COMPATIBLE CREW";
  const trueBondTiming = formatTrueBondTiming(trueBond);
  const activeSelection = Boolean(activePackage && deck && activePackage.deckId === deck.id && String(activePackage.deckRevision || "") === String(deck.updatedAt || "") && (!crew || activePackage.crewId === crew.crewId));
  const packageState = activeSelection ? "active" : compatibility?.ready ? "compatible" : "incomplete";
  return <section className="deployment-package-assembly" aria-label="Deployment Package assembly" data-package-state={packageState} aria-live="polite">
    <header><div><span>PACKAGE DOCK / LINKED ASSETS</span><h3>{activeSelection ? "ACTIVE PACKAGE" : "PACKAGE ASSEMBLY"}</h3></div><b>{activeSelection ? "OPERATIONS LINKED" : compatibility?.ready ? "COMPATIBLE" : "ASSEMBLY REQUIRED"}</b></header>
    <div className="deployment-package-chain" role="list" aria-label="Linked Deployment Package members">
      <article className="deployment-package-slot" data-package-slot="deck" data-slot-state={savedLegal ? "ready" : "pending"} role="listitem">
        <figure className="deployment-package-deck-gauge" aria-hidden="true"><strong>{String(total).padStart(2, "0")}</strong><span>/ 40</span></figure>
        <div><span>01 / DECK</span><b>{deck?.name || "SELECT DECK"}</b><small>{changed ? "UNSAVED REVISION" : savedLegal ? "SAVED / LEGAL" : "LEGAL DECK REQUIRED"}</small></div>
      </article>
      <article className="deployment-package-slot" data-package-slot="pilot" data-slot-state={crew ? "ready" : "pending"} role="listitem">
        <figure><PackageIdentityImage src={pilotImage} alt={pilotCallsign + " Pilot portrait"} pending="VISUAL DATA PENDING" /></figure>
        <div><span>02 / PILOT</span><b>{pilotCallsign}</b><small>{crew ? "CREW IDENTITY LOCKED" : "SELECT CREW"}</small></div>
      </article>
      <article className="deployment-package-slot" data-package-slot="meka" data-slot-state={compatibility?.ready ? "ready" : crew ? "blocked" : "pending"} role="listitem">
        <figure><PackageIdentityImage src={mekaImage} alt={(signatureCode || "Signature Meka") + " Signature Meka / " + mekaName} pending="VISUAL DATA PENDING" /></figure>
        <div><span>03 / SIGNATURE MEKA</span><b>{signatureCode ? signatureCode + " / " + mekaName : mekaName}</b><small>TRUE BOND · {trueBondName} · TIMING · {trueBondTiming}</small></div>
      </article>
    </div>
    <footer><span>ONE DEPLOYMENT PACKAGE</span><b>{deck?.name || "DECK"} + {pilotCallsign} + {signatureCode || "MEKA"}</b></footer>
  </section>;
}

function getDeckBayDefaultDeckId(decks) {
  const records = Array.isArray(decks) ? decks : [];
  const editable = records.find((deck) => deck && deck.deckType === "constructed");
  return editable && editable.id || records[0] && records[0].id || "";
}

function createDeckBayDraft(identity, deck) {
  if (!deck) return null;
  const name = deck.name || "Constructed Deck";
  const entries = cloneDeckEntries(deck.entries);
  return { identity, deckId: deck.id, name, entries, baseline: JSON.stringify({ name: deck.name || "", entries }) };
}

function getDeckBayGuidanceStep(tutorialState, observableState) {
  tutorialState = tutorialState || {};
  observableState = observableState || {};
  const completed = new Set(Array.isArray(tutorialState.completedSteps) ? tutorialState.completedSteps : []);
  const signatureCode = String(observableState.tutorialSignatureCode || "").trim().toUpperCase();
  const signatureSelector = signatureCode
    ? `.deck-builder-card[data-card-code="${signatureCode.replace(/["\\]/g, "\\$&")}"] [aria-label="Add ${signatureCode.replace(/["\\]/g, "\\$&")}"]`
    : '[aria-label^="Add "]';
  const crewStep = observableState.pairingCinematic
    ? { id: "crew", copy: "PAIRING CONFIRMED. TAP OR PRESS ENTER on the highlighted confirmation to return to the Deck Manifest.", cta: "SHOW PAIRING CONFIRMATION", mode: "editor", selectors: [".deck-pairing-cinematic"], highlightSelectors: [".deck-pairing-cinematic"] }
    : observableState.pilotPickerOpen
      ? { id: "crew", copy: `SELECT THE HIGHLIGHTED COMPATIBLE PILOT. The chosen Pilot is authorized because ${signatureCode || "their Signature Meka"} is already in this Deck.`, cta: "SHOW COMPATIBLE PILOT", mode: "editor", selectors: [".deck-pilot-picker-row.is-ready:not(:disabled)"], highlightSelectors: [".deck-pilot-picker-row.is-ready:not(:disabled)"] }
      : observableState.pairingConfirmed
        ? { id: "crew", copy: "PILOT PAIRED. SELECT THE HIGHLIGHTED REGISTER DECK — BATTLE READY button to finish this tutorial.", cta: "SHOW REGISTER DECK", mode: "editor", selectors: [".deck-manifest-save:not([disabled])"], highlightSelectors: [".deck-manifest-save-target:has(.deck-manifest-save:not([disabled]))"] }
        : { id: "crew", copy: `SELECT THE HIGHLIGHTED PAIR A PILOT button. You will then choose a compatible Pilot whose Signature Meka (${signatureCode || "shown in the roster"}) is already in this Deck.`, cta: "SHOW PAIR A PILOT", mode: "editor", selectors: [".deck-pilot-pairing-empty:not([disabled])"], highlightSelectors: [".deck-pilot-pairing-empty:not([disabled])"] };
  const steps = [
    { id: "create", copy: "SELECT + NEW DECK. We will build a fresh Constructed Deck from zero; your sealed Founding Deck will stay unchanged.", cta: "SHOW + NEW DECK", mode: "library", selectors: [".deck-library-create"], highlightSelectors: [".deck-library-create:not([disabled])"] },
    { id: "rename", copy: "ENTER A DECK NAME in the highlighted field. Give this new Constructed Deck a name before assembling its manifest.", cta: "SHOW DECK NAME", mode: "editor", selectors: [".deck-manifest-name-input:not([disabled])"], highlightSelectors: [".deck-manifest-name-input:not([disabled])"] },
    { id: "signature", copy: `SELECT THE HIGHLIGHTED + CONTROL for ${signatureCode || "a Pilot's Signature Meka"}. A Pilot can only pair with a Deck containing their Signature Meka, which enables that Meka's True Bond.`, cta: signatureCode ? `SHOW ADD ${signatureCode}` : "SHOW SIGNATURE MEKA", mode: "editor", selectors: [signatureSelector], highlightSelectors: [`${signatureSelector}:not([disabled])`] },
    { id: "build", copy: "BUILD THIS NEW DECK TO EXACTLY 40 CARDS. Use + or − to set copy quantities, or drag owned prints between Card Collection and the Deck Manifest. MK cards allow 1 copy; other prints allow up to 4 owned copies.", cta: "SHOW CARD CONTROLS", mode: "editor", selectors: ['[aria-label^="Add "]', '[aria-label^="Remove one "]', ".deck-bay-collection-pane", ".deck-bay-manifest-pane"], highlightSelectors: ['[aria-label^="Add "]:not([disabled])'] },
    { id: "save", copy: "Complete exactly 40 cards, then SELECT THE HIGHLIGHTED SAVE DRAFT control.", cta: "SHOW SAVE CONTROL", mode: "editor", selectors: [".deck-manifest-save"], highlightSelectors: [".deck-manifest-save-target:has(.deck-manifest-save:not([disabled]))"] },
    crewStep
  ];
  const index = steps.findIndex((step) => !completed.has(step.id));
  if (index < 0 || observableState.activePackageCurrent && completed.has("activate")) return { id: "complete", copy: "BATTLE READY. Your registered Deck and paired Pilot are ready for the field. SELECT RETURN TO MY HANGAR.", cta: "", mode: "editor", selectors: [], highlightSelectors: [], progress: "6 / 6" };
  return { ...steps[index], progress: `${index + 1} / 6` };
}

function getCompletedDirectiveEvidence(directives, directiveId) {
  const directive = (Array.isArray(directives) ? directives : []).find((item) => String(item?.directiveId || item?.id || "") === directiveId && (item?.status === "complete" || item?.completedAt));
  return directive && directive.evidence && typeof directive.evidence === "object" ? directive.evidence : null;
}

function DeckBayGuidancePanel({ mode, tutorialState, observableState, onDismiss, onReopen, onAcknowledgeBriefing, restricted = false, showRestrictedNudge = false }) {
  const step = getDeckBayGuidanceStep(tutorialState, observableState);
  const assistantName = observableState.assistantName || "MIRA";
  if (tutorialState.dismissed) return <button type="button" className="deck-bay-tutorial-reopen" data-tutorial-assistant-control="reopen" onClick={onReopen} title="Open the Deck Bay briefing" aria-label={"Open " + assistantName + " Deck Bay Virtual Assistant"}><PackageIdentityImage src={observableState.assistantAvatar} alt="" pending="VA" /></button>;
  return <aside className="deck-bay-tutorial" aria-label="Deck Bay Virtual Assistant" aria-live="polite" data-mode={mode} data-can-reopen={Boolean(onReopen)}>
    <header className="deck-bay-tutorial-head"><div className="deck-bay-tutorial-avatar"><PackageIdentityImage src={observableState.assistantAvatar} alt={assistantName + " Virtual Assistant portrait"} pending="VA" /></div><div><b>{assistantName}</b><small className="deck-bay-tutorial-progress">DECK BAY BRIEFING · {step.progress}</small></div></header>
    {observableState.briefingComplete && <span className="deck-briefing-status">DECK BAY BRIEFING REVIEWED</span>}
    <p>{observableState.briefingComplete ? step.copy : "SELECT ACKNOWLEDGE BRIEFING to review how a saved legal Deck, Pilot, and Signature Meka become one Deployment Package."}</p>
    {restricted && showRestrictedNudge && <div className="restricted-tutorial-panel-nudge" role="status">⚠ FOLLOW THE HIGHLIGHTED INSTRUCTION</div>}
    <div className="deck-bay-tutorial-actions">
      {!observableState.briefingComplete
        ? <button type="button" className="deck-bay-tutorial-cta" onClick={onAcknowledgeBriefing} disabled={observableState.busy}>ACKNOWLEDGE BRIEFING</button>
        : step.id !== "complete"
          ? <button type="button" className="deck-bay-tutorial-cta" onClick={() => observableState.onFocusTarget(step)} disabled={observableState.busy}>{step.cta}</button>
          : restricted && <a className="deck-bay-tutorial-cta" href="#hangar">RETURN TO MY HANGAR</a>}
      <button type="button" className="tutorial-assistant-dismiss deck-bay-tutorial-dismiss" data-tutorial-assistant-control="dismiss" aria-label="Minimize Deck Bay briefing" onClick={onDismiss}>DISMISS</button>
    </div>
  </aside>;
}

function DeckBayWorkbench({ deckState, packageState, collection, postFounding, organization, requestedDeckId = "", onActivated, onDirectiveNotice, onRegisterRouteGuard }) {
  const [deckBayMode, setDeckBayMode] = useState("library");
  const [selectedId, setSelectedId] = useState("");
  const [draft, setDraft] = useState(null);
  const [filters, setFilters] = useState(() => ({ search: "", type: "all", source: "all", doctrine: "all", sort: "recent" }));
  const [selectedCard, setSelectedCard] = useState({ code: "", trigger: "" });
  const [deleteConfirmId, setDeleteConfirmId] = useState("");
  const [actionNotice, setActionNotice] = useState("");
  const [selectedCrewId, setSelectedCrewId] = useState("");
  const [tutorialSteps, setTutorialSteps] = useState(() => new Set());
  const [tutorialDeckId, setTutorialDeckId] = useState("");
  const [tutorialStepsKey, setTutorialStepsKey] = useState("");
  const [tutorialDismissed, setTutorialDismissed] = useState(false);
  const [tutorialReplayRequested, setTutorialReplayRequested] = useState(false);
  const [tutorialBlocked, setTutorialBlocked] = useState(false);
  const [preparedRevision, setPreparedRevision] = useState("");
  const [pairedRevision, setPairedRevision] = useState("");
  const [pairedCrewId, setPairedCrewId] = useState("");
  const [reviewedRevision, setReviewedRevision] = useState("");
  const [pilotPickerOpen, setPilotPickerOpen] = useState(false);
  const [pairingCinematic, setPairingCinematic] = useState(null);
  const [workflowBusy, setWorkflowBusy] = useState(false);
  const workflowBusyRef = useRef(false);
  const allowedRouteHashRef = useRef("");
  const activeDragSourceRef = useRef("");
  const inspectorRef = useRef(null);
  const [tutorialHydratedKey, setTutorialHydratedKey] = useState("");
  const restrictedTutorialStartedRef = useRef(false);
  const requestedDeckRouteRef = useRef("");
  const deckBayIdentityRef = useRef(deckState.identity);
  const decks = deckState.decks;
  const selectedDeckRecord = decks.find((deck) => deck.id === selectedId) || null;
  const selectedDeck = draft && draft.identity === deckState.identity && draft.deckId === selectedId ? selectedDeckRecord : null;
  const changed = Boolean(draft && draft.baseline !== JSON.stringify({ name: draft.name, entries: draft.entries }));
  const deckBayBusy = workflowBusy || Boolean(deckState.actionBusy) || Boolean(packageState.actionBusy);
  const selectedBuilderCard = collection.cards.find((card) => card.code === selectedCard.code) || null;
  const preparedEvidence = getCompletedDirectiveEvidence(packageState.directives, "post_founding.battle_ready_deck_prepared");
  const pairedEvidence = getCompletedDirectiveEvidence(packageState.directives, "post_founding.compatible_crew_paired");
  const restoredPreparedRevision = selectedDeck && preparedEvidence && String(preparedEvidence.deckId || "") === String(selectedDeck.id) && String(preparedEvidence.deckRevision || "") === String(selectedDeck.updatedAt || "") ? selectedDeck.updatedAt : "";
  const restoredPairedCrewId = String(selectedDeck?.pairedCrewId || "") || (selectedDeck && pairedEvidence && String(pairedEvidence.deckId || "") === String(selectedDeck.id) && String(pairedEvidence.deckRevision || "") === String(selectedDeck.updatedAt || "") ? String(pairedEvidence.crewId || "") : "");
  const effectiveSelectedCrewId = selectedCrewId || restoredPairedCrewId;
  const selectedCrew = packageState.eligibleCrews.find((crew) => crew.crewId === effectiveSelectedCrewId) || null;
  const effectivePreparedRevision = preparedRevision === selectedDeck?.updatedAt ? preparedRevision : restoredPreparedRevision;
  const restoredPairedRevision = restoredPairedCrewId && restoredPairedCrewId === effectiveSelectedCrewId ? selectedDeck?.updatedAt || "" : "";
  const effectivePairedRevision = pairedRevision === selectedDeck?.updatedAt && pairedCrewId === effectiveSelectedCrewId ? pairedRevision : restoredPairedRevision;
  const effectivePairedCrewId = effectivePairedRevision ? effectiveSelectedCrewId : "";
  const compatibility = !changed && selectedDeck && selectedCrew ? packageState.compatibility.find((item) => item.deckId === selectedDeck.id && item.crewId === selectedCrew.crewId) : null;
  const activePackage = packageState.activePackage;
  const activePackageDeck = activePackage ? decks.find((deck) => deck.id === activePackage.deckId) || null : null;
  const activePackageDeckName = activePackageDeck?.name || "DECK RECORD UNAVAILABLE";
  const activePackageMatchesSelectedRevision = Boolean(!changed && activePackage && selectedDeck && activePackage.deckId === selectedDeck.id && String(activePackage.deckRevision || "") === String(selectedDeck.updatedAt || ""));
  const activePackageCurrent = Boolean(activePackageMatchesSelectedRevision && (!effectiveSelectedCrewId || String(activePackage.crewId || "") === String(effectiveSelectedCrewId)));
  const activePackageCrew = activePackage && activePackage.deckId === selectedDeck?.id
    ? packageState.eligibleCrews.find((crew) => crew.crewId === activePackage.crewId) || activePackage.crewSnapshot || null
    : null;
  const tutorialStorageKey = "supermekabots.deckBayTutorial.v2:" + String(deckState.identity || "anonymous");
  const tutorialDismissedStorageKey = tutorialStorageKey + ":dismissed";
  const tutorialDeckStorageKey = tutorialStorageKey + ":deck-id";
  const tutorialDraftStorageKey = tutorialStorageKey + ":draft";
  const tutorialRunStorageKey = tutorialStorageKey + ":run";
  const tutorialRunIdentity = String(postFounding?.arsenal?.rewardReviewedAt || postFounding?.debrief?.completedAt || postFounding?.reward?.receiptId || "pending");
  const tutorialDeckRecordsRevision = decks.map((deck) => [deck.id, deck.deckType, deck.updatedAt || ""].join(":" )).join("|");
  const briefingComplete = packageState.directives.some((directive) => String(directive.directiveId || directive.id || "") === "post_founding.deck_bay_briefing_reviewed" && (directive.status === "complete" || directive.completedAt));
  if (postFounding?.phase === "deck_bay_orientation") restrictedTutorialStartedRef.current = true;
  const deckTutorialComplete = hasCompletedFeatureTutorial(postFounding, "deck_bay");
  const restrictedTutorial = !deckTutorialComplete && postFounding?.phase === "deck_bay_orientation";
  const deckTutorialEntry = useCompletedTutorialEntry(deckState.identity, deckTutorialComplete, Boolean(postFounding?.phase));
  const tutorialCrew = packageState.eligibleCrews.find((crew) => {
    const code = String(crew?.signatureMeka?.code || "").toUpperCase();
    return code && collection.cards.some((card) => String(card?.code || "").toUpperCase() === code && Number(card?.quantity || 0) > 0);
  }) || packageState.eligibleCrews[0] || null;
  const tutorialSignatureCode = String(tutorialCrew?.signatureMeka?.code || "").toUpperCase();
  const tutorialSignaturePresent = Boolean(tutorialSignatureCode && draft?.entries?.some((entry) => String(entry?.code || "").toUpperCase() === tutorialSignatureCode && Number(entry?.quantity || 0) > 0));
  const tutorialDeckTotal = (Array.isArray(draft?.entries) ? draft.entries : []).reduce((sum, entry) => sum + Number(entry.quantity || 0), 0);
  const tutorialPairingConfirmed = Boolean(activePackageCurrent || effectivePairedRevision === selectedDeck?.updatedAt && effectivePairedCrewId);
  const durableTutorialSteps = new Set([
    effectivePreparedRevision && effectivePreparedRevision === selectedDeck?.updatedAt ? "save" : "",
    activePackageCurrent ? "crew" : ""
  ].filter(Boolean));
  const reconstructedTutorialSteps = [
    tutorialDeckId && selectedDeck?.id === tutorialDeckId ? "create" : "",
    tutorialSignaturePresent ? "signature" : "",
    tutorialDeckTotal === 40 ? "build" : "",
    selectedDeck?.legality?.legal === true && !changed ? "save" : "",
    activePackageCurrent ? "crew" : ""
  ].filter(Boolean);
  const completedTutorialSteps = new Set([...(tutorialStepsKey === tutorialStorageKey ? tutorialSteps : []), ...durableTutorialSteps, ...reconstructedTutorialSteps]);
  if (!tutorialSignaturePresent) completedTutorialSteps.delete("signature");
  if (tutorialDeckTotal !== 40) completedTutorialSteps.delete("build");
  if (changed || selectedDeck?.legality?.legal !== true) completedTutorialSteps.delete("save");
  if (!activePackageCurrent) completedTutorialSteps.delete("crew");
  const restrictedGuidanceStep = getDeckBayGuidanceStep({ completedSteps: [...completedTutorialSteps] }, { activePackageCurrent, tutorialSignatureCode, deckTotal: tutorialDeckTotal, pilotPickerOpen, pairingCinematic: Boolean(pairingCinematic), pairingConfirmed: tutorialPairingConfirmed });
  const restrictedSelectors = [
    "[data-tutorial-assistant-control]",
    ".deck-bay-tutorial-cta",
    ".deck-bay-tutorial-trigger",
    ".deck-library-feedback button",
    ".deck-library-collection-feedback button",
    ".deck-bay-collection-pane [role=alert] button",
    ...(restrictedGuidanceStep.selectors || [])
  ];
  function observeTutorial(step) {
    if (tutorialStepsKey !== tutorialStorageKey) return;
    setTutorialSteps((current) => {
      if (current.has(step)) return current;
      return new Set([...current, step]);
    });
  }
  function beginDeckDrag(source) { if (!workflowBusyRef.current && !deckBayBusy) activeDragSourceRef.current = source; }
  function endDeckDrag() {
    activeDragSourceRef.current = "";
    document.querySelectorAll(".deck-bay-collection-pane[data-drop-ready], .deck-bay-manifest-pane[data-drop-ready]").forEach((node) => delete node.dataset.dropReady);
  }
  function openDeckInspector(code, trigger) { setSelectedCard({ code, trigger }); }
  function closeDeckInspector() { const current = selectedCard; setSelectedCard({ code: "", trigger: "" }); window.requestAnimationFrame(() => document.querySelector(`[data-deck-inspect-trigger="${current.trigger}"][data-card-code="${current.code}"]`)?.focus()); }
  useEffect(() => { if (selectedBuilderCard) inspectorRef.current?.focus(); }, [selectedBuilderCard && selectedBuilderCard.code]);
  useEffect(() => {
    const previousIdentity = deckBayIdentityRef.current;
    deckBayIdentityRef.current = deckState.identity;
    if (!previousIdentity || previousIdentity === deckState.identity) return;
    setDeckBayMode("library");
    setSelectedId("");
    setDraft(null);
    setTutorialDeckId("");
    setTutorialReplayRequested(false);
    setPilotPickerOpen(false);
    setPairingCinematic(null);
  }, [deckState.identity]);
  useEffect(() => {
    if (!requestedDeckId) { requestedDeckRouteRef.current = ""; return; }
    if (deckState.status !== "ready") return;
    const requestedDeck = decks.find((deck) => String(deck?.id || "") === String(requestedDeckId));
    if (!requestedDeck) return;
    const routeToken = [deckState.identity, requestedDeck.id, requestedDeck.updatedAt || ""].join(":");
    if (requestedDeckRouteRef.current === routeToken) return;
    requestedDeckRouteRef.current = routeToken;
    chooseDeck(requestedDeck);
  }, [requestedDeckId, deckState.status, deckState.identity, decks.map((deck) => [deck.id, deck.updatedAt].join(":" )).join("|")]);
  useEffect(() => { restrictedTutorialStartedRef.current = postFounding?.phase === "deck_bay_orientation"; }, [deckState.identity]);
  useEffect(() => {
    if (deckState.status !== "ready") return;
    setTutorialHydratedKey("");
    setTutorialStepsKey("");
    try {
      const persistedRunIdentity = String(localStorage.getItem(tutorialRunStorageKey) || "");
      const resetStaleRun = restrictedTutorial && persistedRunIdentity !== tutorialRunIdentity;
      if (resetStaleRun) {
        localStorage.removeItem(tutorialStorageKey);
        localStorage.removeItem(tutorialDismissedStorageKey);
        localStorage.removeItem(tutorialDeckStorageKey);
      }
      if (restrictedTutorial) localStorage.setItem(tutorialRunStorageKey, tutorialRunIdentity);
      const persisted = resetStaleRun ? [] : JSON.parse(localStorage.getItem(tutorialStorageKey) || "[]");
      setTutorialSteps(new Set(Array.isArray(persisted) ? persisted : []));
      if (restrictedTutorial) localStorage.removeItem(tutorialDismissedStorageKey);
      setTutorialDismissed(restrictedTutorial ? false : localStorage.getItem(tutorialDismissedStorageKey) === "1");
      setTutorialDeckId(resetStaleRun ? "" : String(localStorage.getItem(tutorialDeckStorageKey) || ""));
    } catch {
      setTutorialSteps(new Set());
      setTutorialDismissed(false);
      setTutorialDeckId("");
    } finally {
      setTutorialStepsKey(tutorialStorageKey);
      setTutorialHydratedKey(tutorialStorageKey);
    }
  }, [deckState.status, restrictedTutorial, tutorialRunIdentity, tutorialDeckRecordsRevision, tutorialStorageKey, tutorialDismissedStorageKey, tutorialDeckStorageKey, tutorialDraftStorageKey, tutorialRunStorageKey]);
  useEffect(() => { if (tutorialHydratedKey !== tutorialStorageKey || tutorialStepsKey !== tutorialStorageKey) return; try { localStorage.setItem(tutorialStorageKey, JSON.stringify([...tutorialSteps])); } catch {} }, [tutorialHydratedKey, tutorialStepsKey, tutorialSteps, tutorialStorageKey]);
  useEffect(() => {
    if (!deckTutorialComplete) return;
    try { localStorage.removeItem(tutorialDraftStorageKey); } catch {}
    if (deckTutorialEntry.completedAtEntry && !tutorialReplayRequested) setTutorialDismissed(true);
  }, [deckTutorialComplete, deckTutorialEntry.completedAtEntry, tutorialReplayRequested, tutorialDraftStorageKey]);
  useEffect(() => {
    if (!restrictedTutorial || tutorialHydratedKey !== tutorialStorageKey || !tutorialDeckId || !decks.length) return;
    const resumeDeck = decks.find((deck) => deck.id === tutorialDeckId && deck.deckType === "constructed");
    if (!resumeDeck) {
      setTutorialDeckId("");
      try { localStorage.removeItem(tutorialDeckStorageKey); localStorage.removeItem(tutorialDraftStorageKey); } catch {}
      setDeckBayMode("library");
      return;
    }
    if (selectedId !== resumeDeck.id) setSelectedId(resumeDeck.id);
    if (deckBayMode !== "editor") setDeckBayMode("editor");
  }, [restrictedTutorial, tutorialHydratedKey, tutorialStorageKey, tutorialDeckId, tutorialDeckStorageKey, tutorialDraftStorageKey, decks, selectedId, deckBayMode]);
  useEffect(() => { if (!requestedDeckId && !selectedId && decks.length) setSelectedId(getDeckBayDefaultDeckId(decks)); }, [decks, selectedId, requestedDeckId]);
  useEffect(() => { if (selectedId && !decks.some((deck) => deck.id === selectedId)) setSelectedId(getDeckBayDefaultDeckId(decks)); }, [decks, selectedId]);
  useEffect(() => {
    if (!selectedCrewId && activePackage?.deckId === selectedId && packageState.eligibleCrews.some((crew) => crew.crewId === activePackage.crewId)) setSelectedCrewId(activePackage.crewId);
  }, [selectedId, selectedCrewId, activePackage?.deckId, activePackage?.crewId, packageState.eligibleCrews]);
  useEffect(() => {
    if (!selectedDeckRecord) return;
    const serverDraft = createDeckBayDraft(deckState.identity, selectedDeckRecord);
    if (restrictedTutorial && selectedDeckRecord.id === tutorialDeckId) {
      try {
        const persistedDraft = JSON.parse(localStorage.getItem(tutorialDraftStorageKey) || "null");
        if (persistedDraft && persistedDraft.deckId === serverDraft.deckId && persistedDraft.identity === serverDraft.identity && persistedDraft.baseline === serverDraft.baseline) {
          setDraft({ ...serverDraft, name: String(persistedDraft.name || serverDraft.name), entries: cloneDeckEntries(persistedDraft.entries) });
          return;
        }
      } catch {}
    }
    setDraft(serverDraft);
  }, [deckState.identity, selectedId, selectedDeckRecord && selectedDeckRecord.updatedAt, restrictedTutorial, tutorialDeckId, tutorialDraftStorageKey]);
  useEffect(() => {
    if (!restrictedTutorial || !draft || draft.deckId !== tutorialDeckId || tutorialHydratedKey !== tutorialStorageKey) return;
    try {
      if (changed) localStorage.setItem(tutorialDraftStorageKey, JSON.stringify(draft));
      else localStorage.removeItem(tutorialDraftStorageKey);
    } catch {}
  }, [restrictedTutorial, draft, changed, tutorialDeckId, tutorialHydratedKey, tutorialStorageKey, tutorialDraftStorageKey]);
  useEffect(() => {
    if (!changed) return undefined;
    const warnBeforeUnload = (event) => { event.preventDefault(); event.returnValue = ""; };
    window.addEventListener("beforeunload", warnBeforeUnload);
    return () => window.removeEventListener("beforeunload", warnBeforeUnload);
  }, [changed]);
  function discardUnsavedDraft() {
    setDraft(createDeckBayDraft(deckState.identity, selectedDeckRecord));
    setPreparedRevision("");
    setPairedRevision("");
    setPairedCrewId("");
    setReviewedRevision("");
  }
  function confirmDiscardUnsavedDraft() {
    if (!window.confirm("DISCARD UNSAVED DECK CHANGES?")) {
      setActionNotice("UNSAVED CHANGES PRESERVED / Save this Deck or confirm discard before leaving the Editor.");
      return false;
    }
    discardUnsavedDraft();
    setActionNotice("UNSAVED CHANGES DISCARDED / The saved Deck revision is unchanged.");
    return true;
  }
  function guardDeckBayRoute(nextHash, source = "hashchange") {
    if (source === "hashchange" && allowedRouteHashRef.current === nextHash) {
      allowedRouteHashRef.current = "";
      return true;
    }
    if (workflowBusyRef.current || deckBayBusy) {
      allowedRouteHashRef.current = "";
      setActionNotice("ACTION IN PROGRESS / Wait for the current Deck Bay operation to finish before navigating.");
      return false;
    }
    if (deckBayMode === "editor" && changed && !confirmDiscardUnsavedDraft()) {
      allowedRouteHashRef.current = "";
      return false;
    }
    if (source === "anchor") allowedRouteHashRef.current = nextHash;
    return true;
  }
  useEffect(() => {
    if (!onRegisterRouteGuard) return undefined;
    return onRegisterRouteGuard(guardDeckBayRoute);
  }, [onRegisterRouteGuard, deckBayMode, changed, deckBayBusy, deckState.identity, selectedDeckRecord && selectedDeckRecord.updatedAt]);
  useEffect(() => {
    const guardHashAnchor = (event) => {
      if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
      const anchor = event.target && event.target.closest ? event.target.closest("a[href]") : null;
      if (!anchor || anchor.target && anchor.target !== "_self" || anchor.hasAttribute("download")) return;
      const destination = new URL(anchor.href, window.location.href);
      if (destination.origin !== window.location.origin || destination.pathname !== window.location.pathname || destination.search !== window.location.search || destination.hash === window.location.hash) return;
      if (!guardDeckBayRoute(destination.hash, "anchor")) event.preventDefault();
    };
    document.addEventListener("click", guardHashAnchor, true);
    return () => document.removeEventListener("click", guardHashAnchor, true);
  }, [deckBayMode, changed, deckBayBusy, deckState.identity, selectedDeckRecord && selectedDeckRecord.updatedAt]);
  async function runDeckBayWorkflow(operation) {
    if (workflowBusyRef.current) return null;
    workflowBusyRef.current = true;
    setWorkflowBusy(true);
    try {
      return await operation();
    } finally {
      workflowBusyRef.current = false;
      setWorkflowBusy(false);
    }
  }
  async function refreshProjections() { await Promise.all([deckState.load(), packageState.load(), onActivated?.()]); }
  async function acceptDirective(result, tutorialStep) { const directive = result && result.receipt && result.receipt.directive; if (!directive) return false; onDirectiveNotice?.(directive); if (tutorialStep) observeTutorial(tutorialStep); await refreshProjections(); return true; }
  function persistTutorialDraft(nextDraft) {
    if (!restrictedTutorial || !nextDraft || nextDraft.deckId !== tutorialDeckId) return;
    try {
      localStorage.setItem(tutorialDraftStorageKey, JSON.stringify(nextDraft));
    } catch {}
  }
  function markDraftEntries(entries) {
    if (workflowBusyRef.current || deckBayBusy || !draft || !deckEntriesChanged(draft.entries, entries)) return;
    const signatureQuantity = Number(entries.find((entry) => String(entry.code || "").toUpperCase() === tutorialSignatureCode)?.quantity || 0);
    const nextTotal = entries.reduce((sum, entry) => sum + Number(entry.quantity || 0), 0);
    if (signatureQuantity > 0) observeTutorial("signature");
    if (nextTotal === 40) observeTutorial("build");
    const nextDraft = { ...draft, entries };
    persistTutorialDraft(nextDraft);
    setPreparedRevision(""); setPairedRevision(""); setPairedCrewId(""); setReviewedRevision(""); setDraft(nextDraft);
  }
  function markDraftName(name) {
    if (workflowBusyRef.current || deckBayBusy || !draft || draft.name === name) return;
    if (String(name || "").trim()) observeTutorial("rename");
    const nextDraft = { ...draft, name };
    persistTutorialDraft(nextDraft);
    setPreparedRevision(""); setPairedRevision(""); setPairedCrewId(""); setReviewedRevision(""); setDraft(nextDraft);
  }
  function requestDeckBayMode(nextMode) {
    if (!["library", "editor"].includes(nextMode) || nextMode === deckBayMode) return;
    if (workflowBusyRef.current || deckBayBusy) {
      setActionNotice("ACTION IN PROGRESS / Wait for the current Deck Bay operation to finish before navigating.");
      return;
    }
    if (deckBayMode === "editor" && nextMode !== "editor" && changed && !confirmDiscardUnsavedDraft()) return;
    if (nextMode === "library" && requestedDeckId && typeof window !== "undefined") window.location.hash = "#deckbay";
    setDeckBayMode(nextMode);
  }
  function focusDeckBayGuidanceTarget(step) {
    if (!step || !Array.isArray(step.selectors)) return;
    const focusTarget = () => {
      for (const selector of step.selectors) {
        const node = document.querySelector(selector);
        if (!node || typeof node.focus !== "function") continue;
        const focusNode = node.disabled ? node.closest(".deck-legality-summary") : node;
        if (!focusNode || typeof focusNode.focus !== "function") continue;
        focusNode.scrollIntoView({ behavior: "smooth", block: "center" });
        focusNode.focus();
        return;
      }
    };
    if (step.mode && step.mode !== deckBayMode) {
      requestDeckBayMode(step.mode);
      window.requestAnimationFrame(() => window.requestAnimationFrame(focusTarget));
    } else focusTarget();
  }
  function chooseDeck(deck) { setSelectedId(deck.id); setDraft(createDeckBayDraft(deckState.identity, deck)); setSelectedCrewId(""); setDeleteConfirmId(""); setPreparedRevision(""); setPairedRevision(""); setPairedCrewId(""); setReviewedRevision(""); setPilotPickerOpen(false); setPairingCinematic(null); setDeckBayMode("editor"); }
  function nextDraftName(prefix = "CONSTRUCTED DECK") { const taken = new Set(decks.map((deck) => String(deck.name || "").toLowerCase())); let sequence = 1; let name = prefix + " " + String(sequence).padStart(2, "0"); while (taken.has(name.toLowerCase())) name = prefix + " " + String(++sequence).padStart(2, "0"); return name; }
  async function create(entries = []) {
    const deck = await deckState.createDeck(nextDraftName(restrictedTutorial ? "TUTORIAL DECK" : "CONSTRUCTED DECK"), entries);
    if (!deck) return;
    setSelectedId(deck.id);
    setDraft(createDeckBayDraft(deckState.identity, deck));
    setDeckBayMode("editor");
    if (restrictedTutorial) {
      setTutorialDeckId(deck.id);
      try { localStorage.setItem(tutorialDeckStorageKey, deck.id); localStorage.removeItem(tutorialDraftStorageKey); } catch {}
    }
    observeTutorial("create");
    await refreshProjections();
    setActionNotice("NEW CONSTRUCTED DRAFT CREATED / Add your Pilot's Signature Meka, then build the manifest to 40 cards.");
  }
  async function duplicate(deck) { if (!deck) return; const copy = await deckState.createDeck(nextDraftName("COPY"), deck.entries); if (copy) { setSelectedId(copy.id); setDraft(createDeckBayDraft(deckState.identity, copy)); setDeckBayMode("editor"); await refreshProjections(); setActionNotice("DECK DUPLICATED / Constructed copy ready for rename or edits."); } }
  async function remove(deck) {
    if (!deck || deck.deckType === "sealed" || packageState.status !== "ready") return;
    if (activePackage && activePackage.deckId === deck.id) { setActionNotice("DELETE BLOCKED / Activate another Deployment Package before deleting this Deck."); return; }
    if (deleteConfirmId !== deck.id) { setDeleteConfirmId(deck.id); setActionNotice("DELETE ARMED / Press CONFIRM DELETE to permanently remove this draft."); return; }
    if (await deckState.deleteDeck(deck.id)) { setDeleteConfirmId(""); await refreshProjections(); setActionNotice("DECK DELETED / The constructed draft was removed."); }
  }
  async function prepareSavedRevision() {
    if (!selectedDeck || changed || !selectedDeck.legality?.legal) return;
    return runDeckBayWorkflow(async () => {
      const result = await packageState.prepareDeck(selectedDeck.id, selectedDeck.updatedAt);
      if (await acceptDirective(result, "save")) {
        setPreparedRevision(selectedDeck.updatedAt);
        setActionNotice("BATTLE-READY DECK PREPARED / Choose compatible Crew.");
      }
    });
  }
  async function save() {
    if (!draft || !selectedDeck || selectedDeck.deckType === "sealed") return;
    return runDeckBayWorkflow(async () => {
      const wasActive = activePackage && activePackage.deckId === selectedDeck.id;
      const deck = await deckState.saveDeck(selectedDeck.id, draft);
      if (deck) {
        setDraft({ identity: deckState.identity, deckId: deck.id, name: deck.name, entries: cloneDeckEntries(deck.entries), baseline: JSON.stringify({ name: deck.name, entries: cloneDeckEntries(deck.entries) }) });
        setPreparedRevision("");
        setPairedRevision("");
        setPairedCrewId("");
        setReviewedRevision("");
        await refreshProjections();
        if (deck.legality && deck.legality.legal) {
          const result = await packageState.prepareDeck(deck.id, deck.updatedAt);
          if (!await acceptDirective(result, "save")) return null;
          setPreparedRevision(deck.updatedAt);
        }
        setActionNotice(wasActive ? "ACTIVE PACKAGE INVALIDATED / Saved Deck revision must be prepared, paired, and activated again." : (deck.legality && deck.legality.legal ? "DECK SAVED / BATTLE-READY REVISION PREPARED." : "DRAFT SAVED / Continue building to 40 / 40."));
        return deck;
      }
    });
  }
  async function openPilotPicker() {
    if (workflowBusyRef.current || deckBayBusy || !selectedDeck) return;
    if (changed) {
      const savedDeck = await save();
      if (!savedDeck) return;
    } else {
      const projection = await runDeckBayWorkflow(() => packageState.load());
      if (!projection) return;
    }
    setPilotPickerOpen(true);
  }
  async function pairSelectedCrew() {
    if (!selectedDeck || !selectedCrew || changed || effectivePreparedRevision !== selectedDeck.updatedAt) return;
    return runDeckBayWorkflow(async () => {
      const result = await packageState.pairCrew(selectedDeck.id, selectedCrew.crewId, selectedDeck.updatedAt);
      if (await acceptDirective(result, "crew")) {
        setPairedRevision(selectedDeck.updatedAt);
        setPairedCrewId(selectedCrew.crewId);
        setReviewedRevision("");
        setActionNotice("");
      }
    });
  }
  async function pairCrewFromPicker(crewId) {
    const crew = packageState.eligibleCrews.find((candidate) => String(candidate?.crewId || "") === String(crewId || ""));
    const pairCompatibility = selectedDeck && crew ? packageState.compatibility.find((item) => item.deckId === selectedDeck.id && item.crewId === crew.crewId) : null;
    const pairDisplay = selectedDeck && crew ? getDeckCrewPairingDisplay(selectedDeck, draft?.entries || selectedDeck.entries, crew, pairCompatibility) : null;
    setPilotPickerOpen(false);
    setSelectedCrewId(String(crewId || ""));
    if (!selectedDeck || !crew || changed || selectedDeck.legality?.legal !== true || !pairDisplay?.ready) {
      setActionNotice(changed ? "SAVE REQUIRED / Save this Deck revision before pairing a Pilot." : "PAIRING BLOCKED / " + (pairDisplay?.reasons?.[0] || "A saved legal Deck containing the Pilot's Signature Meka is required."));
      return;
    }
    return runDeckBayWorkflow(async () => {
      if (effectivePreparedRevision !== selectedDeck.updatedAt) {
        const prepared = await packageState.prepareDeck(selectedDeck.id, selectedDeck.updatedAt);
        if (!prepared || !await acceptDirective(prepared, "save")) return;
        setPreparedRevision(selectedDeck.updatedAt);
      }
      const result = await packageState.pairCrew(selectedDeck.id, crew.crewId, selectedDeck.updatedAt);
      if (await acceptDirective(result)) {
        setPairedRevision(selectedDeck.updatedAt);
        setPairedCrewId(crew.crewId);
        setReviewedRevision("");
        setPairingCinematic(crew);
        setActionNotice("");
      }
    });
  }
  async function activateDeploymentPackage() {
    if (!briefingComplete || !selectedDeck || !selectedCrew || changed || effectivePairedRevision !== selectedDeck.updatedAt || effectivePairedCrewId !== selectedCrew.crewId || reviewedRevision !== selectedDeck.updatedAt) return;
    return runDeckBayWorkflow(async () => {
      const result = await packageState.activate(selectedDeck.id, selectedCrew.crewId, selectedDeck.updatedAt);
      if (await acceptDirective(result, "activate")) setActionNotice("ACTIVE DEPLOYMENT PACKAGE UPDATED.");
    });
  }
  async function registerDeckForBattle() {
    if (!selectedDeck || changed || selectedDeck.legality?.legal !== true) return;
    if (!editorPairedCrew || effectivePairedRevision !== selectedDeck.updatedAt || !effectivePairedCrewId) {
      setPilotPickerOpen(true);
      return;
    }
    if (activePackageCurrent) {
      setActionNotice("DECK REGISTERED / This Deck and Pilot pairing is already battle ready.");
      return;
    }
    if (!briefingComplete) {
      setTutorialDismissed(false);
      setActionNotice("BRIEFING REQUIRED / Complete the visible Deck Bay briefing before registration.");
      return;
    }
    return runDeckBayWorkflow(async () => {
      const result = await packageState.activate(selectedDeck.id, effectivePairedCrewId, selectedDeck.updatedAt);
      if (await acceptDirective(result, "crew")) setActionNotice("DECK REGISTERED / BATTLE READY.");
    });
  }
  const deckTotal = (Array.isArray(draft && draft.entries) ? draft.entries : []).reduce((sum, entry) => sum + Number(entry.quantity || 0), 0);
  const editorPrecheck = getDeckEditorLocalPrecheck(draft?.entries || [], collection.cards);
  const deckStatus = selectedDeck?.deckType === "sealed" ? "SEALED" : changed ? editorPrecheck.ready ? "BATTLE READY" : "DRAFT" : selectedDeck?.legality?.legal ? "BATTLE READY" : "DRAFT";
  const selectedBuilderQuantity = draft?.entries.find((entry) => entry.code === selectedBuilderCard?.code)?.quantity || 0;
  const selectedBuilderAddState = selectedBuilderCard ? getDeckSourceAddState({ code: selectedBuilderCard.code, kind: selectedBuilderCard.kind, ownedQuantity: selectedBuilderCard.quantity, currentQuantity: selectedBuilderQuantity, readOnly: selectedDeck?.deckType === "sealed" }) : { disabled: true };
  const editorHasPersistedActivePairing = Boolean(activePackageCurrent && activePackageCrew);
  const editorPairingConfirmed = Boolean(editorHasPersistedActivePairing || effectivePairedRevision === selectedDeck?.updatedAt && effectivePairedCrewId && effectivePairedCrewId === selectedCrew?.crewId);
  const editorPairedCrew = editorHasPersistedActivePairing ? activePackageCrew : editorPairingConfirmed ? selectedCrew : null;
  const editorPairingCompatibility = activePackageCurrent ? { ready: true, reasons: [] } : editorPairedCrew ? compatibility : null;
  return (
    <RestrictedTutorialGuard active={restrictedTutorial} highlightActive={deckTutorialEntry.resolved && (!deckTutorialComplete || tutorialReplayRequested) && (restrictedTutorial || !tutorialDismissed)} allowedSelectors={restrictedSelectors} highlightSelectors={[".deck-bay-tutorial-cta:not([disabled])", ...(restrictedGuidanceStep.highlightSelectors || [])]} onBlockedChange={setTutorialBlocked}>
    <section className="deck-bay-workbench" aria-label="Deck Bay workbench" data-selected-deck-id={selectedId || undefined}>
      <DeckBayShell mode={deckBayMode} onModeChange={requestDeckBayMode} deckCount={deckTotal} deckStatus={deckStatus} busy={deckBayBusy}>
        {deckState.error && deckBayMode !== "library" && <p className="post-founding-error" role="alert">{deckState.error}</p>}
        {packageState.error && deckBayMode !== "library" && deckBayMode !== "package" && <p className="post-founding-error" role="alert">{packageState.error}</p>}
        {deckBayMode === "library" && <DeckBayLibraryView deckState={deckState} packageState={packageState} decks={decks} cards={collection.cards} collectionStatus={collection.status} collectionError={collection.error} activePackage={activePackage} pairedEvidence={pairedEvidence} selectedId={selectedId} deleteConfirmId={deleteConfirmId} onOpen={chooseDeck} onCreate={() => create()} onDuplicate={duplicate} onDelete={remove} onRetry={refreshProjections} onRetryCollection={collection.refresh} />}
        {deckBayMode === "editor" && <DeckBayEditorView selectedDeck={selectedDeck} draft={draft} collection={collection} filters={filters} onFiltersChange={setFilters} onChangeEntries={markDraftEntries} onNameChange={markDraftName} onInspect={openDeckInspector} onDragStart={beginDeckDrag} onDragEnd={endDeckDrag} activeDragSourceRef={activeDragSourceRef} onSave={save} onRegister={registerDeckForBattle} busy={deckBayBusy} pairedCrew={editorPairedCrew} pairingCompatibility={editorPairingCompatibility} pairingConfirmed={editorPairingConfirmed} activePackageCurrent={activePackageCurrent} onOpenPilotPicker={openPilotPicker} />}
        {(!deckTutorialEntry.completedAtEntry || tutorialReplayRequested) && <DeckBayGuidancePanel mode={deckBayMode} tutorialState={{ completedSteps: [...completedTutorialSteps], dismissed: tutorialDismissed }} observableState={{ activePackageCurrent, deckTotal, tutorialSignatureCode, pilotPickerOpen, pairingCinematic: Boolean(pairingCinematic), pairingConfirmed: tutorialPairingConfirmed, assistantName: organization?.assistantName || "MIRA", assistantAvatar: getAssistantAvatarSource(organization || {}), briefingComplete, busy: deckBayBusy, onFocusTarget: focusDeckBayGuidanceTarget }} onDismiss={() => { setTutorialDismissed(true); try { localStorage.setItem(tutorialDismissedStorageKey, "1"); } catch {} }} onReopen={() => { setTutorialDismissed(false); try { localStorage.removeItem(tutorialDismissedStorageKey); } catch {} }} onAcknowledgeBriefing={async () => { const result = await packageState.completeBriefing(); await acceptDirective(result); }} restricted={restrictedTutorial} showRestrictedNudge={restrictedTutorial && tutorialBlocked} />}
      </DeckBayShell>
      {pilotPickerOpen && selectedDeck && draft && <DeckPilotPickerDialog deck={selectedDeck} entries={draft.entries} cards={collection.cards} crews={packageState.eligibleCrews} compatibility={packageState.compatibility} pairedCrewId={editorPairedCrew?.crewId || ""} busy={deckBayBusy || changed} onChoose={pairCrewFromPicker} onClose={() => setPilotPickerOpen(false)} />}
      {pairingCinematic && <DeckPairingCinematic crew={pairingCinematic} cards={collection.cards} onClose={() => setPairingCinematic(null)} />}
      {selectedBuilderCard && <div className="deck-card-inspector" role="dialog" aria-modal="true" aria-label={"Card inspector / " + selectedBuilderCard.code} tabIndex="-1" ref={inspectorRef} onMouseDown={(event) => { if (event.target === event.currentTarget) closeDeckInspector(); }} onKeyDown={(event) => { if (event.key === "Escape") { event.preventDefault(); closeDeckInspector(); return; } trapModalTabFocus(event, inspectorRef.current); }}><div className="deck-inspector-composition"><div className="deck-inspector-card-frame"><DeckBuilderCardInspector card={selectedBuilderCard} onClose={closeDeckInspector} /></div><aside className="deck-inspector-controls" aria-label="Deck copy controls"><div className="deck-inspector-quantity-readback"><span data-inspector-quantity="in-deck">IN DECK: <b>{selectedBuilderQuantity} / {String(selectedBuilderCard.kind || "").toLowerCase() === "mk" ? 1 : 4}</b></span><span className="sr-only" data-inspector-quantity="owned">OWNED {Number(selectedBuilderCard.quantity || 0)}</span></div>{selectedBuilderAddState.reason && <p id={selectedBuilderAddState.reasonId} className="deck-inspector-add-reason">{selectedBuilderAddState.reason.replace("ADD CONTROL LOCKED / ", "")}</p>}<button type="button" className="btn primary" aria-describedby={selectedBuilderAddState.reason ? selectedBuilderAddState.reasonId : undefined} onClick={() => markDraftEntries(mutateDeckEntries(draft?.entries || [], selectedBuilderCard, 1, selectedDeck?.deckType === "sealed"))} disabled={deckBayBusy || selectedBuilderAddState.disabled}>ADD COPY</button><button type="button" className="btn" onClick={() => markDraftEntries(mutateDeckEntries(draft?.entries || [], selectedBuilderCard, -1, selectedDeck?.deckType === "sealed"))} disabled={deckBayBusy || selectedDeck?.deckType === "sealed" || !selectedBuilderQuantity}>REMOVE COPY</button></aside></div></div>}
    </section>
    </RestrictedTutorialGuard>
  );
}

function DeckBayShell({ mode, onModeChange, deckCount, deckStatus, busy, children }) {
  return <div className={"deck-bay-shell deck-bay-" + mode + "-shell is-" + mode} data-deck-bay-mode={mode}>
    <header className="deck-bay-head"><a className="deck-bay-back-control" href="#hangar" aria-label="Back to My Hangar">◂ MY HANGAR</a><div className="deck-bay-head-title"><span>SUPER MEKABOTS TCG · BOND//BREACH</span><h2>DECK BAY</h2></div><div className="deck-bay-shell-status">{mode === "editor" && <div className="deck-bay-head-count" data-count-state={deckCount === 40 ? "ready" : deckCount > 40 ? "over" : "building"}><span>DECK SIZE</span><b>{deckCount} / 40</b><small className="sr-only">{deckStatus}</small></div>}{mode === "editor" && <button type="button" onClick={() => onModeChange("library")} disabled={busy}>BACK TO DECKS</button>}</div></header>
    <div className="deck-bay-mode-stage">{children}</div>
  </div>;
}

function groupDecksByPilotAuthority(decks, eligibleCrews, activePackage, pairedEvidence, crewTemplates) {
  const records = Array.isArray(decks) ? decks : [];
  const crewById = new Map((Array.isArray(eligibleCrews) ? eligibleCrews : []).map((crew) => [String(crew?.crewId || ""), crew]));
  const pairingByDeckId = new Map();
  const authorityRank = { saved: 0, active: 1, paired: 2, founding: 3, unassigned: 4 };
  const assign = (deck, crew, authority) => {
    if (!deck || !crew) return;
    const current = pairingByDeckId.get(String(deck.id));
    if (current && (authorityRank[current.authority] ?? 4) <= (authorityRank[authority] ?? 4)) return;
    pairingByDeckId.set(String(deck.id), { crew, authority });
  };
  const register = (deckId, deckRevision, crewId, authority) => {
    const deck = records.find((candidate) => String(candidate?.id || "") === String(deckId || ""));
    const crew = crewById.get(String(crewId || ""));
    if (!deck || !crew || String(deck?.updatedAt || "") !== String(deckRevision || "")) return;
    assign(deck, crew, authority);
  };
  register(activePackage?.deckId, activePackage?.deckRevision, activePackage?.crewId, "active");
  register(pairedEvidence?.deckId, pairedEvidence?.deckRevision, pairedEvidence?.crewId, "paired");
  records.forEach((deck) => assign(deck, crewById.get(String(deck?.pairedCrewId || "")), "saved"));
  const foundingByDeckId = new Map();
  (Array.isArray(crewTemplates) ? crewTemplates : []).forEach((template) => {
    const deck = records.find((candidate) => String(candidate?.id || "") === String(template?.savedDeckId || ""));
    const crew = crewById.get(String(template?.crewId || ""));
    if (!deck || !crew || String(deck?.deckType || "") !== "sealed" || String(template?.savedDeckType || "") !== "sealed" || Number(deck?.sourceJourneyVersion || 0) < 1) return;
    const candidates = foundingByDeckId.get(String(deck.id)) || [];
    candidates.push(crew);
    foundingByDeckId.set(String(deck.id), candidates);
  });
  foundingByDeckId.forEach((crews, deckId) => {
    if (crews.length === 1) assign(records.find((deck) => String(deck?.id || "") === deckId), crews[0], "founding");
  });
  const grouped = new Map();
  records.forEach((deck) => {
    const pairing = pairingByDeckId.get(String(deck.id)) || null;
    const key = pairing ? String(pairing.crew.crewId) : "__unassigned__";
    if (!grouped.has(key)) grouped.set(key, { key, crew: pairing?.crew || null, authority: pairing?.authority || "unassigned", decks: [] });
    const group = grouped.get(key);
    if ((authorityRank[pairing?.authority] ?? 4) < (authorityRank[group.authority] ?? 4)) group.authority = pairing.authority;
    group.decks.push(deck);
  });
  return [...grouped.values()].sort((left, right) => {
    return (authorityRank[left.authority] ?? 4) - (authorityRank[right.authority] ?? 4);
  });
}

function DeckLibraryArtwork({ entries, authorityUnavailable }) {
  const [failedArt, setFailedArt] = useState(() => new Set());
  const candidates = entries.map((entry) => ({ entry, art: resolveFoundingDeckCardArt(entry) })).filter((item) => item.art && !failedArt.has(item.art)).slice(0, 4);
  if (authorityUnavailable) return <div className="deck-library-card-art is-authority-unavailable" data-art-state="authority-unavailable" aria-label="Deck card art data unavailable"><span>CARD DATA OFFLINE</span><b>ART AUTHORITY UNAVAILABLE</b><i aria-hidden="true"></i></div>;
  if (!entries.length) return <div className="deck-library-card-art is-empty" data-art-state="empty" aria-label="Empty Deck art state"><span>EMPTY MANIFEST</span><b>PUBLICATION COLLAGE PENDING</b></div>;
  if (!candidates.length) return <div className="deck-library-card-art is-technical" data-art-state="technical" aria-label="Deck technical silhouette"><span>DECK VISUAL</span><b>TECHNICAL SILHOUETTE</b><i aria-hidden="true"></i></div>;
  return <div className="deck-library-card-art" data-art-state="ready" aria-label="Deck publication art collage">{candidates.map(({ entry, art }, index) => <figure key={entry.code + ":" + index}><img src={art} alt={entry.code + " " + entry.name + " gameplay publication card"} loading="lazy" decoding="async" onError={() => setFailedArt((current) => new Set([...current, art]))} /></figure>)}</div>;
}

function DeckLibraryCard({ deck, cards, authorityUnavailable, pairedCrew, selected, deleteConfirmId, busy, packageReady, onOpen, onDuplicate, onDelete }) {
  const total = (deck.entries || []).reduce((sum, entry) => sum + Number(entry.quantity || 0), 0);
  const legal = Boolean(deck.legality && deck.legality.legal);
  const stateLabel = legal ? "BATTLE READY" : "DRAFT";
  const cardByCode = new Map(cards.map((card) => [String(card.code || "").toUpperCase(), card]));
  const publicationEntries = (deck.entries || []).map((entry) => {
    const card = cardByCode.get(String(entry.code || "").toUpperCase());
    return card ? collectionCardGameplayEntry(card) : { code: entry.code, kind: entry.kind, name: entry.code, doctrine: "" };
  });
  const doctrines = [...new Set(publicationEntries.map((entry) => entry.doctrine).filter(Boolean))].slice(0, 2);
  const pairedPilot = pairedCrew?.pilot?.callsign || pairedCrew?.pilot?.name || "";
  return <article className={"deck-library-card" + (selected ? " is-selected" : "")}>
    <button type="button" className="deck-library-card-open" data-deck-id={deck.id} aria-current={selected ? "true" : undefined} aria-pressed={selected} aria-label={"Edit Deck / " + deck.name} onClick={() => onOpen(deck)}>
      <div className="deck-library-card-art-wrap"><DeckLibraryArtwork entries={publicationEntries} authorityUnavailable={authorityUnavailable} />{pairedPilot && <span className="deck-library-sync">SYNC 100%</span>}</div>
      <div className="deck-library-card-record"><div className="deck-library-card-doctrines" aria-label={authorityUnavailable ? "Deck doctrine data unavailable" : doctrines.length ? "Deck doctrines / " + doctrines.join(" and ") : "Deck doctrines unavailable"}>{authorityUnavailable ? <span><i aria-hidden="true" /></span> : doctrines.map((doctrine) => <span key={doctrine}>{FOUNDING_DOCTRINE_ICON_URLS[doctrine] && <img src={FOUNDING_DOCTRINE_ICON_URLS[doctrine]} alt="" aria-hidden="true" />}</span>)}</div><div className="deck-library-card-name"><h4>{deck.name}</h4><span>{total} CARDS · {doctrines.length} DOCTRINE{doctrines.length === 1 ? "" : "S"}{deck.deckType === "sealed" ? " · STARTER" : ""}</span></div><b className="deck-library-card-state">{stateLabel}</b></div>
    </button>
    <div className="deck-library-card-actions"><button type="button" onClick={() => onOpen(deck)} disabled={busy}>EDIT</button><button type="button" onClick={() => onDuplicate(deck)} disabled={busy}>DUPLICATE</button>{deck.deckType === "constructed" && <button type="button" className="is-danger" onClick={() => onDelete(deck)} disabled={busy || !packageReady}>{deleteConfirmId === deck.id ? "CONFIRM" : "DELETE"}</button>}</div>
  </article>;
}

function DeckPilotGroup({ group, cards, collectionStatus, selectedId, deleteConfirmId, busy, packageReady, onOpen, onDuplicate, onDelete }) {
  const crew = group.crew;
  const pilotName = crew?.pilot?.callsign || crew?.pilot?.name || "UNASSIGNED FRAMES";
  const pilotPerson = crew?.pilot?.person || crew?.pilot?.name || "";
  const pilotFace = getCrewPilotFaceSource(crew);
  const unassigned = !crew;
  return <section className={"deck-pilot-group" + (unassigned ? " is-unassigned" : "")} aria-label={unassigned ? "Unassigned Decks" : pilotName + " paired Decks"}>
    <header className="deck-pilot-group-header">
      <figure>{unassigned ? <span aria-hidden="true">?</span> : <PackageIdentityImage src={pilotFace} alt={pilotName + " Pilot portrait"} pending="PILOT PORTRAIT PENDING" />}</figure>
      <div><span>{unassigned ? "PAIR A PILOT TO DEPLOY THESE" : "PILOT"}</span><h4>{pilotName}</h4>{!unassigned && <small>{pilotPerson}</small>}</div>
      <b>{String(group.decks.length).padStart(2, "0")} DECK{group.decks.length === 1 ? "" : "S"}</b>
    </header>
    <div className="deck-library-card-grid" aria-label={pilotName + " Decks"}>{group.decks.map((deck) => <DeckLibraryCard key={deck.id} deck={deck} cards={cards} authorityUnavailable={collectionStatus === "error"} pairedCrew={crew} selected={deck.id === selectedId} deleteConfirmId={deleteConfirmId} busy={busy} packageReady={packageReady} onOpen={onOpen} onDuplicate={onDuplicate} onDelete={onDelete} />)}</div>
  </section>;
}

function DeckBayLibraryView({ deckState, packageState, decks, cards, collectionStatus, collectionError, activePackage, pairedEvidence, selectedId, deleteConfirmId, onOpen, onCreate, onDuplicate, onDelete, onRetry, onRetryCollection }) {
  const pilotGroups = groupDecksByPilotAuthority(decks, packageState.eligibleCrews, activePackage, pairedEvidence, packageState.crewTemplates);
  const libraryBusy = Boolean(deckState.actionBusy) || Boolean(packageState.actionBusy);
  return <section className="deck-bay-library-view" data-deck-bay-region="library" aria-label="Deck Library">
    <header className="deck-library-heading"><div><span aria-hidden="true">YOUR DECKS · {decks.length}</span><h3 className="sr-only">YOUR DECKS · {decks.length}</h3><p className="sr-only">Open a saved Deck to inspect or edit it, or create a new Deck.</p></div><button type="button" className="btn primary deck-library-create" onClick={onCreate} disabled={Boolean(deckState.actionBusy) || Boolean(packageState.actionBusy)}>+ NEW DECK</button></header>
    {deckState.status === "loading" && !decks.length && <div className="arsenal-state-panel" role="status">SYNCING DECK LIBRARY...</div>}
    {deckState.status === "loading" && decks.length > 0 && <div className="arsenal-state-panel deck-library-refreshing" role="status">REFRESHING SAVED DECK RECORDS...</div>}
    {deckState.status === "error" && !decks.length && <div className="arsenal-state-panel is-error" role="alert"><b>DECK LIBRARY UNAVAILABLE</b><span>{deckState.error || "Deck library unavailable"}</span><button type="button" className="btn" onClick={onRetry}>RETRY DECK BAY</button></div>}
    {Boolean(deckState.error && decks.length) && <div className="arsenal-state-panel is-error deck-library-feedback" role="alert"><b>DECK LIBRARY UPDATE FAILED</b><span>{deckState.error}</span><button type="button" className="btn" onClick={onRetry} disabled={Boolean(deckState.actionBusy)}>RETRY DECK LIBRARY</button></div>}
    {collectionStatus === "loading" && decks.length > 0 && <div className="arsenal-state-panel deck-library-collection-feedback" role="status">SYNCING CARD ART / DOCTRINE DATA...</div>}
    {collectionStatus === "error" && decks.length > 0 && <div className="arsenal-state-panel is-error deck-library-collection-feedback" role="alert"><b>CARD ART / DOCTRINE DATA UNAVAILABLE</b><span>{collectionError || "Card Collection unavailable"} Saved Deck records remain available.</span><button type="button" className="btn" onClick={onRetryCollection} disabled={Boolean(deckState.actionBusy) || Boolean(packageState.actionBusy)}>RETRY CARD DATA</button></div>}
    {!["loading", "error"].includes(deckState.status) && !decks.length && <div className="arsenal-state-panel deck-library-empty"><b>NO SAVED DECKS YET</b><span>Choose + NEW DECK to start a blank frame.</span></div>}
    {pilotGroups.length > 0 && <div className="deck-pilot-groups" aria-label="Saved Decks grouped by Pilot authority">{pilotGroups.map((group) => <DeckPilotGroup key={group.key} group={group} cards={cards} collectionStatus={collectionStatus} selectedId={selectedId} deleteConfirmId={deleteConfirmId} busy={libraryBusy} packageReady={packageState.status === "ready"} onOpen={onOpen} onDuplicate={onDuplicate} onDelete={onDelete} />)}</div>}
    <p className="deck-library-rule-copy">A legal Deck holds exactly 40 cards, max 4 copies per print. Pilots ride outside the Deck. Pilot pairing requires that Pilot's Signature Meka/True-Bond Meka in the Deck. Reactor payments must match your Doctrines — fewer Doctrines, smoother payments.</p>
  </section>;
}

function getDeckCrewPairingDisplay(deck, entries, crew, compatibility) {
  const signatureCode = String(crew?.signatureMeka?.code || "").toUpperCase();
  const signatureQuantity = Number((Array.isArray(entries) ? entries : []).find((entry) => String(entry?.code || "").toUpperCase() === signatureCode)?.quantity || 0);
  const signaturePresent = Boolean(signatureCode) && signatureQuantity > 0;
  const ready = compatibility?.ready === true && signaturePresent;
  const hasCompatibility = compatibility !== null && compatibility !== undefined;
  const state = ready ? "compatible" : !signaturePresent || hasCompatibility ? "blocked" : "pending";
  const pilotName = crew?.pilot?.callsign || crew?.pilot?.name || "this Pilot";
  const reasons = Array.isArray(compatibility?.reasons) ? compatibility.reasons.map((reason) => reason?.message).filter(Boolean) : [];
  if (!signaturePresent && signatureCode && !reasons.some((reason) => String(reason).toUpperCase().includes(signatureCode))) {
    reasons.unshift(signatureCode + " is required in this Deck before " + pilotName + " can be paired for True Bond.");
  }
  return {
    ready,
    state,
    status: state === "compatible" ? "COMPATIBLE" : state === "blocked" ? "PAIRING BLOCKED" : "VERIFYING AUTHORITY",
    verificationLabel: state === "compatible" ? "SERVER VERIFIED" : state === "blocked" ? "REVIEW REQUIRED" : "AUTHORITY PENDING",
    bondMessage: state === "compatible"
      ? crew?.trueBond?.name ? "True Bond link verified: " + crew.trueBond.name + "." : "True Bond authority unavailable."
      : state === "blocked"
        ? signaturePresent ? "True Bond compatibility is blocked by current authority." : "Add " + signatureCode + " to this Deck before pairing this Pilot."
        : "True Bond compatibility requires revalidation after Deck changes.",
    signatureQuantity,
    signatureCode,
    reasons,
  };
}

function getDeckPilotSyncDisplay(entries, cards, crew, pairingDisplay) {
  const code = (value) => String(value || "").trim().toUpperCase();
  const cardByCode = new Map((Array.isArray(cards) ? cards : []).map((card) => [code(card?.code), card]));
  const mekaEntries = (Array.isArray(entries) ? entries : []).flatMap((entry) => {
    const card = cardByCode.get(code(entry?.code));
    const definition = card?.definition || {};
    const kind = String(card?.kind || entry?.kind || definition?.kind || "").toLowerCase();
    if (!["mk", "md", "meka"].includes(kind)) return [];
    return [{
      ...entry,
      name: definition.name || entry?.name || code(entry?.code),
      traits: Array.isArray(definition.traits) ? definition.traits : Array.isArray(entry?.traits) ? entry.traits : []
    }];
  });
  const trueBondPossible = Boolean(
    pairingDisplay?.signatureQuantity > 0
    && crew?.trueBond?.name
    && crew?.trueBond?.reciprocal !== false
  );
  const sync = getFoundingPilotDeckSync(crew, mekaEntries, trueBondPossible);
  const signatureCard = cardByCode.get(code(pairingDisplay?.signatureCode));
  return {
    ...sync,
    signatureName: signatureCard?.definition?.name || crew?.signatureMeka?.codename || crew?.signatureMeka?.name || pairingDisplay?.signatureCode || "SIGNATURE MEKA"
  };
}

function DeckPilotPairingPanel({ deck, entries, crew, compatibility, paired, active, busy, onOpen }) {
  const pilotName = crew?.pilot?.callsign || crew?.pilot?.name || "";
  const pilotPerson = crew?.pilot?.person || crew?.pilot?.name || "";
  const pilotArt = crew?.pilot?.selectImage || crew?.pilot?.cinematicImage || getCrewPilotFaceSource(crew);
  const display = getDeckCrewPairingDisplay(deck, entries, crew, compatibility);
  if (!crew || !paired) return <section className="deck-pilot-pairing-panel is-empty" aria-label="Pilot Pairing">
    <button type="button" className="deck-pilot-pairing-empty" onClick={onOpen} disabled={busy}>
      <span>NO PILOT PAIRED · CANNOT DEPLOY</span><b>PAIR A PILOT</b><small>REVIEW SERVER COMPATIBILITY AND TRUE BOND AUTHORITY</small>
    </button>
  </section>;
  return <section className={"deck-pilot-pairing-panel is-paired" + (active ? " is-active" : "")} aria-label={"Pilot Pairing / " + pilotName}>
    <button type="button" className="deck-pilot-pairing-card" onClick={onOpen} disabled={busy} aria-label={"Change paired Pilot / " + pilotName}>
      <span className="deck-pilot-pairing-art"><PackageIdentityImage src={pilotArt} alt={pilotName + " Pilot pairing portrait"} pending="PILOT PORTRAIT PENDING" /></span>
      <span className="deck-pilot-pairing-scrim" aria-hidden="true" />
      <span className="deck-pilot-pairing-copy"><span>PILOT PAIRING · {display.status}</span><b>{pilotName}</b><small>{pilotPerson}</small><span className="deck-pilot-pairing-meter"><i aria-hidden="true"><em style={{ width: display.ready ? "100%" : display.state === "blocked" ? "0%" : "35%" }} /></i><strong>{display.ready ? "100%" : display.state === "blocked" ? "0%" : "SYNCING"}</strong></span></span>
      <span className="deck-pilot-pairing-change">CHANGE</span>
    </button>
    <p>{display.signatureQuantity} COPY{display.signatureQuantity === 1 ? "" : "IES"} OF {display.signatureCode || "SIGNATURE MEKA"} IN DECK · {display.bondMessage}</p>
  </section>;
}

function DeckPilotPickerDialog({ deck, entries, cards, crews, compatibility, pairedCrewId, busy, onChoose, onClose }) {
  const dialogRef = useRef(null);
  useLayoutEffect(() => {
    const previous = document.activeElement;
    const priorOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    dialogRef.current?.focus();
    return () => { document.body.style.overflow = priorOverflow; if (previous && previous.isConnected && typeof previous.focus === "function") previous.focus(); };
  }, []);
  return <div className="deck-pilot-picker" role="dialog" aria-modal="true" aria-label="Pair a Pilot" tabIndex="-1" ref={dialogRef} onClick={(event) => { if (event.target === event.currentTarget) onClose(); }} onKeyDown={(event) => { if (event.key === "Escape") { event.preventDefault(); onClose(); return; } trapModalTabFocus(event, dialogRef.current); }}>
    <section className="deck-pilot-picker-window">
      <header><div><span>CREW ROSTER</span><h3>PAIR A PILOT TO THIS DECK</h3></div><button type="button" aria-label="Close Pilot picker" onClick={onClose}>×</button></header>
      <div className="deck-pilot-picker-list">{crews.map((crew) => {
        const pilotName = crew?.pilot?.callsign || crew?.pilot?.name || "PILOT RECORD UNAVAILABLE";
        const pilotPerson = crew?.pilot?.person || crew?.pilot?.name || "";
        const pilotFace = getCrewPilotFaceSource(crew);
        const pairAuthority = compatibility.find((item) => item.deckId === deck.id && item.crewId === crew.crewId) || null;
        const display = getDeckCrewPairingDisplay(deck, entries, crew, pairAuthority);
        const sync = getDeckPilotSyncDisplay(entries, cards, crew, display);
        const selected = String(pairedCrewId || "") === String(crew.crewId || "");
        const traits = (crew?.pilot?.bondTraits || crew?.bondTraits || []).join(" · ");
        const rawAbility = crew?.pilot?.ability;
        const ability = typeof rawAbility === "string" ? rawAbility : rawAbility?.text || rawAbility?.description || "";
        const reasonId = "pilot-pair-reason-" + String(crew.crewId || "").replace(/[^a-z0-9_-]/gi, "-");
        return <button type="button" className={"deck-pilot-picker-row" + (selected ? " is-paired" : "") + (display.state === "pending" ? " is-pending" : display.state === "compatible" ? " is-ready" : " is-blocked")} key={crew.crewId} aria-pressed={selected} aria-describedby={!display.ready && display.reasons.length ? reasonId : undefined} onClick={() => onChoose(crew.crewId)} disabled={busy || !display.ready}>
          <span className="deck-pilot-picker-face"><PackageIdentityImage src={pilotFace} alt={pilotName + " Pilot portrait"} pending="PILOT PORTRAIT PENDING" /></span>
          <span className="deck-pilot-picker-record"><span><b>{pilotName}</b><small>{pilotPerson}</small></span>{traits && <em>BOND TRAITS · {traits}</em>}{ability && <p>{ability}</p>}{!display.ready && display.reasons.length > 0 && <i id={reasonId}>{display.reasons.join(" ")}</i>}</span>
          <span className="deck-pilot-picker-score"><b>{sync.percentageLabel}</b><i aria-label={"Deck sync " + sync.percentageLabel}><em style={{ width: sync.percentage + "%" }} /></i><small>{sync.grade}</small>{display.signatureQuantity > 0 && <strong>⚡ {sync.signatureName} ×{display.signatureQuantity}</strong>}<span>{display.state === "pending" ? "PENDING" : selected ? "PAIRED" : display.ready ? "PAIR" : "BLOCKED"}</span></span>
        </button>;
      })}{!crews.length && <div className="arsenal-state-panel"><b>NO ELIGIBLE CREW</b><span>Complete Crew licensing before creating a Deployment Package.</span></div>}</div>
    </section>
  </div>;
}

function DeckPairingCinematic({ crew, cards, onClose }) {
  const dialogRef = useRef(null);
  const closeRef = useRef(onClose);
  closeRef.current = onClose;
  const signatureCode = String(crew?.signatureMeka?.code || "").toUpperCase();
  const pilotName = crew?.pilot?.callsign || crew?.pilot?.name || "PILOT";
  const pilotArt = getCrewPilotSceneSource(crew);
  const signatureCard = (Array.isArray(cards) ? cards : []).find((card) => String(card?.code || "").toUpperCase() === signatureCode);
  const mekaName = signatureCard?.definition?.name || crew?.signatureMeka?.codename || crew?.signatureMeka?.name || signatureCode || "SIGNATURE MEKA";
  const mekaArt = signatureCard ? resolveFoundingDeckCardArt(collectionCardGameplayEntry(signatureCard)) : crew?.signatureMeka?.publicationArt || crew?.signatureMeka?.image || "";
  useLayoutEffect(() => {
    const previous = document.activeElement;
    const priorOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    dialogRef.current?.focus();
    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const timeout = reduced ? null : window.setTimeout(() => closeRef.current?.(), 4200);
    return () => {
      if (timeout !== null) window.clearTimeout(timeout);
      document.body.style.overflow = priorOverflow;
      if (previous && previous.isConnected && typeof previous.focus === "function") previous.focus();
    };
  }, [crew?.crewId]);
  return <div className="deck-pairing-cinematic" role="dialog" aria-modal="true" aria-label="Pairing established" tabIndex="-1" ref={dialogRef} onClick={onClose} onKeyDown={(event) => { if (event.key === "Escape" || event.key === "Enter" || event.key === " ") { event.preventDefault(); onClose(); } }}>
    <span className="deck-pairing-flash" aria-hidden="true" /><span className="deck-pairing-scanlines" aria-hidden="true" />
    <span className="deck-pairing-pilot"><PackageIdentityImage src={pilotArt} alt={pilotName + " Pilot cinematic"} pending="PILOT VISUAL PENDING" /></span>
    <span className="deck-pairing-meka"><PackageIdentityImage src={mekaArt} alt={signatureCode + " / " + mekaName + " gameplay publication art"} pending="MEKA PUBLICATION ART PENDING" /></span>
    <span className="deck-pairing-slash" aria-hidden="true" />
    <div className="deck-pairing-caption"><h2>PAIRING ESTABLISHED</h2><p>{pilotName} × {mekaName}</p><div><span>SERVER COMPATIBILITY</span><b>CONFIRMED</b></div><i data-authority-state="confirmed" aria-hidden="true"><em /></i><strong>TRUE BOND LINK</strong><small>PRESS ENTER OR TAP TO CONTINUE</small></div>
  </div>;
}

function DeckBayEditorView({ selectedDeck, draft, collection, filters, onFiltersChange, onChangeEntries, onNameChange, onInspect, onDragStart, onDragEnd, activeDragSourceRef, onSave, onRegister, busy, pairedCrew, pairingCompatibility, pairingConfirmed, activePackageCurrent, onOpenPilotPicker }) {
  if (!selectedDeck || !draft) return <section className="deck-bay-editor-view" data-deck-bay-region="editor" aria-label="Deck Editor"><div className="arsenal-state-panel" role="status">SYNCING SELECTED DECK...</div></section>;
  const readOnly = selectedDeck.deckType === "sealed";
  const changed = draft.baseline !== JSON.stringify({ name: draft.name, entries: draft.entries });
  return <section className="deck-bay-editor-view" data-deck-bay-region="editor" aria-label="Deck Editor">
    {busy && <p className="deck-editor-workflow-lock" id="deck-editor-workflow-lock" role="status">DECK UPDATE IN PROGRESS / Editor controls are locked until the saved revision is synchronized.</p>}
    <div className="deck-editor-stage deck-editor-two-pane" aria-busy={busy ? "true" : undefined}>
      <div className="deck-bay-collection-pane" onDragEnter={(event) => { if (!busy && !readOnly && activeDragSourceRef.current === "manifest") { event.preventDefault(); event.currentTarget.dataset.dropReady = "true"; } }} onDragOver={(event) => { if (!busy && !readOnly && activeDragSourceRef.current === "manifest") { event.preventDefault(); event.currentTarget.dataset.dropReady = "true"; } }} onDragLeave={(event) => { delete event.currentTarget.dataset.dropReady; }} onDrop={(event) => { event.preventDefault(); onDragEnd(); if (busy) return; const transfer = decodeDeckTransfer(event); const entry = transfer?.source === "manifest" && draft.entries.find((item) => item.code === transfer.cardCode); const card = entry && (collection.cards.find((item) => item.code === transfer.cardCode) || entry); if (card) onChangeEntries(mutateDeckEntries(draft.entries, card, -1, readOnly)); }}><div className="deck-drop-overlay" aria-hidden="true">RELEASE TO REMOVE PRINT</div><DeckCollectionSource cards={collection.cards} status={collection.status} error={collection.error} onRetry={collection.refresh} filters={filters} onFiltersChange={onFiltersChange} entries={draft.entries} onChangeEntries={onChangeEntries} readOnly={readOnly} busy={busy} onInspect={onInspect} onDragStart={onDragStart} onDragEnd={onDragEnd} /></div>
      <div className="deck-bay-manifest-pane" onDragEnter={(event) => { if (!busy && !readOnly && activeDragSourceRef.current === "collection") { event.preventDefault(); event.currentTarget.dataset.dropReady = "true"; } }} onDragOver={(event) => { if (!busy && !readOnly && activeDragSourceRef.current === "collection") { event.preventDefault(); event.currentTarget.dataset.dropReady = "true"; } }} onDragLeave={(event) => { delete event.currentTarget.dataset.dropReady; }} onDrop={(event) => { event.preventDefault(); onDragEnd(); if (busy) return; const transfer = decodeDeckTransfer(event); const card = transfer?.source === "collection" && collection.cards.find((item) => item.code === transfer.cardCode && isDeckPlayableCollectionCard(item)); if (card) onChangeEntries(mutateDeckEntries(draft.entries, card, 1, readOnly)); }}><div className="deck-drop-overlay" aria-hidden="true">RELEASE TO ADD TO DECK</div><DeckManifestEditor deck={{ ...selectedDeck, name: draft.name }} entries={draft.entries} cards={collection.cards} changed={changed} busy={busy} onChangeEntries={onChangeEntries} onNameChange={onNameChange} onInspect={onInspect} onDragStart={onDragStart} onDragEnd={onDragEnd} onSave={onSave} onRegister={onRegister} paired={pairingConfirmed} active={activePackageCurrent} pairingPanel={<DeckPilotPairingPanel deck={selectedDeck} entries={draft.entries} crew={pairedCrew} compatibility={pairingCompatibility} paired={pairingConfirmed} active={activePackageCurrent} busy={busy} onOpen={onOpenPilotPicker} />} /></div>
    </div>
  </section>;
}

function PackageCrewChoiceCard({ crew, compatibility, selected, locked, onChoose }) {
  const pilotCallsign = crew?.pilot?.callsign || crew?.pilot?.name || "PILOT RECORD UNAVAILABLE";
  const signatureCode = String(crew?.signatureMeka?.code || "SIGNATURE MEKA").toUpperCase();
  const signatureName = crew?.signatureMeka?.codename || crew?.signatureMeka?.name || "PUBLICATION RECORD PENDING";
  const pilotImage = getCrewPilotFaceSource(crew);
  const mekaPublicationArt = crew?.signatureMeka?.publicationArt || resolveFoundingDeckCardArt({ code: signatureCode }) || crew?.signatureMeka?.image || "";
  const trueBond = crew?.trueBond || null;
  const trueBondTiming = formatTrueBondTiming(trueBond);
  const doctrines = (crew?.doctrines || []).join(" + ") || "DOCTRINE GUIDANCE PENDING";
  const compatibilityLabel = compatibility?.ready ? "COMPATIBLE" : compatibility ? "BLOCKED" : "VERIFYING";
  return <article className={"package-dock-crew-card" + (selected ? " is-selected" : "") + (compatibility?.ready ? " is-compatible" : compatibility ? " is-blocked" : "")}>
    <button type="button" className="package-dock-crew-choice" aria-label={"Inspect Crew compatibility / " + pilotCallsign + " + " + signatureCode} aria-pressed={selected} onClick={() => onChoose(crew.crewId)} disabled={locked}>
      <span className="package-dock-crew-visuals"><figure><PackageIdentityImage src={pilotImage} alt={pilotCallsign + " Pilot portrait"} pending="PILOT PORTRAIT PENDING" /></figure><figure><PackageIdentityImage src={mekaPublicationArt} alt={signatureCode + " Signature Meka publication art"} pending="MEKA PUBLICATION ART PENDING" /></figure></span>
      <span className="package-dock-crew-copy"><span>PILOT + SIGNATURE MEKA</span><b>{pilotCallsign} + {signatureCode}</b><small>{signatureName}</small><strong>TRUE BOND · {trueBond?.name || "VERIFYING"}</strong><em>TIMING · {trueBondTiming}</em><em>DOCTRINE GUIDANCE · {doctrines}</em></span>
      <span className="package-dock-crew-state">{selected ? "SELECTED · " : ""}{compatibilityLabel}</span>
    </button>
  </article>;
}

function DeckBayPackageView({ selectedDeck, draft, changed, selectedCrew, selectedCrewId, displayedPackageCrew, compatibility, activePackage, activePackageCurrent, activePackageCrew, activePackageDeckName, packageState, briefingComplete, preparedRevision, pairedRevision, pairedCrewId, reviewedRevision, busy, onModeChange, onChooseCrew, onPrepare, onPair, onReview, onActivate, onRetry }) {
  if (!selectedDeck || !draft) return <section className="deck-bay-package-view" data-deck-bay-region="package" aria-label="Deployment Package Dock"><div className="arsenal-state-panel">SELECT A SAVED BATTLE-READY DECK FIRST.</div></section>;
  const prepared = preparedRevision === selectedDeck.updatedAt;
  const paired = pairedRevision === selectedDeck.updatedAt && pairedCrewId === selectedCrew?.crewId;
  const reviewed = paired && reviewedRevision === selectedDeck.updatedAt;
  const presentationState = activePackageCurrent ? "PACKAGE ACTIVE" : paired ? "CREW PAIRED" : "DECK SELECTED";
  const presentationKey = presentationState.toLowerCase().replace(" ", "-");
  const packageCrew = activePackageCurrent ? activePackageCrew : displayedPackageCrew;
  const assemblyCompatibility = activePackageCurrent ? { ready: true } : selectedCrew ? compatibility : null;
  const selectedTrueBondTiming = formatTrueBondTiming(selectedCrew?.trueBond);
  const activeTrueBondTiming = formatTrueBondTiming(activePackageCrew?.trueBond);
  const deckTotal = draft.entries.reduce((sum, entry) => sum + Number(entry.quantity || 0), 0);
  const crewChoices = activePackageCurrent ? (activePackageCrew ? [activePackageCrew] : []) : packageState.eligibleCrews;
  const exactBlockers = changed
    ? ["LOCAL DRAFT CHANGED / Save this revision before preparation, pairing, or activation."]
    : selectedCrew && compatibility && !compatibility.ready
      ? (compatibility.reasons || []).map((reason) => reason.message).filter(Boolean)
      : [];
  let dominantAction = null;
  if (activePackageCurrent) {
    dominantAction = <a className="btn primary package-dock-primary-action package-dock-next-objective" href="#operations">OPEN OPERATIONS</a>;
  } else if (!prepared) {
    dominantAction = <button type="button" className="btn primary package-dock-primary-action" onClick={onPrepare} disabled={busy || changed || selectedDeck.legality?.legal !== true}>ASSEMBLE DEPLOYMENT PACKAGE</button>;
  } else if (selectedCrew && !paired) {
    dominantAction = <button type="button" className="btn primary package-dock-primary-action" onClick={onPair} disabled={busy || changed || compatibility?.ready !== true}>PAIR THIS CREW</button>;
  } else if (paired && !reviewed) {
    dominantAction = <button type="button" className="btn primary package-dock-primary-action" onClick={onReview} disabled={busy}>REVIEW PACKAGE</button>;
  } else if (reviewed) {
    dominantAction = <button type="button" className="btn primary package-dock-primary-action deployment-package-primary-action" data-deployment-package-action="activate" aria-label="Activate Deployment Package" onClick={onActivate} disabled={busy || !briefingComplete || compatibility?.ready !== true}>ACTIVATE DEPLOYMENT PACKAGE</button>;
  }
  return <section className="deck-bay-package-view" data-deck-bay-region="package" aria-label="Deployment Package Dock">
    <section className="deployment-package-panel package-dock" aria-label="Deployment Package" aria-busy={busy ? "true" : undefined} data-package-presentation-state={presentationKey}>
      <header className="package-dock-header"><div><span>DECK BAY / PACKAGE DOCK</span><h2>{activePackageCurrent ? "ACTIVE DEPLOYMENT PACKAGE" : "ASSEMBLE DEPLOYMENT PACKAGE"}</h2><p>{activePackageCurrent ? "Activation receipt reconstructed from the current server-authorized Deck revision and Crew pairing." : "Link one saved Battle-Ready Deck with one compatible Pilot and Signature Meka, then review the complete package before activation."}</p></div><nav className="package-dock-nav" aria-label="Package Dock navigation"><button type="button" onClick={() => onModeChange("editor")} disabled={busy}>BACK TO EDITOR</button><button type="button" onClick={() => onModeChange("library")} disabled={busy}>CHANGE DECK</button></nav></header>
      <ol className="package-dock-state-rail" aria-label="Deployment Package progress">{["DECK SELECTED", "CREW PAIRED", "PACKAGE ACTIVE"].map((state) => <li key={state} aria-current={state === presentationState ? "step" : undefined} className={state === presentationState ? "is-current" : ""}>{state}</li>)}</ol>
      {packageState.status === "loading" && <p className="package-dock-sync" role="status">SYNCING DEPLOYMENT PACKAGE AUTHORITY...</p>}
      {packageState.error && <div className="package-dock-error" role="alert"><b>PACKAGE DOCK ACTION FAILED</b><span>{packageState.error}</span><button type="button" onClick={onRetry} disabled={busy}>RETRY PACKAGE STATUS</button></div>}
      <footer className="package-dock-action-bar"><div><span>NEXT AUTHORIZED ACTION</span><p>{activePackageCurrent ? "This package is active. Continue to the next available Operations objective." : !prepared ? "Prepare the saved revision without pairing Crew yet." : !selectedCrew ? "Inspect a Crew choice. Compatibility inspection completes nothing." : !paired ? "Pair the selected Crew after server compatibility is ready." : !reviewed ? "Review Pilot, Signature Meka, True Bond, and doctrine guidance." : "Activate the complete reviewed Deployment Package."}</p></div>{dominantAction}</footer>
      <div className="package-dock-layout">
        <article className="package-dock-deck-card" aria-label={"Selected Deck / " + selectedDeck.name}><span>SELECTED DECK</span><h3>{activePackageCurrent ? activePackageDeckName : draft.name}</h3><strong>{deckTotal} / 40</strong><small>{changed ? "UNSAVED REVISION" : selectedDeck.legality?.legal ? "SAVED / BATTLE READY" : "SERVER LEGALITY REQUIRED"}</small><p>{selectedDeck.deckType === "sealed" ? "SEALED FOUNDING DECK" : "CONSTRUCTED DECK"} · Exact manifest remains in the Editor.</p></article>
        <DeploymentPackageAssembly deck={selectedDeck} entries={draft.entries} changed={changed} crew={packageCrew} compatibility={assemblyCompatibility} activePackage={activePackageCurrent ? activePackage : null} />
      </div>
      {!prepared && !activePackageCurrent ? <section className="package-dock-guidance"><span>01 / ASSEMBLE DEPLOYMENT PACKAGE</span><p>Assembly authorizes only the current saved legal Deck revision. Crew pairing remains a separate action.</p></section> : <section className="package-dock-crew-section" aria-label="Eligible Crew choices"><header><div><span>{activePackageCurrent ? "ACTIVATION RECEIPT / CREW" : "02 / CHOOSE CREW"}</span><h3>{activePackageCurrent ? "SERVER-AUTHORIZED CREW" : "COMPATIBLE CREW"}</h3></div><b>{crewChoices.length} AVAILABLE</b></header>{crewChoices.length ? <div className="package-dock-crew-grid">{crewChoices.map((crew) => { const crewCompatibility = packageState.compatibility.find((item) => item.deckId === selectedDeck.id && item.crewId === crew.crewId) || (activePackageCurrent ? { ready: true } : null); const selected = activePackageCurrent ? activePackage?.crewId === crew.crewId : selectedCrewId === crew.crewId; return <PackageCrewChoiceCard key={crew.crewId} crew={crew} compatibility={crewCompatibility} selected={selected} locked={busy || activePackageCurrent} onChoose={onChooseCrew} />; })}</div> : <div className="arsenal-state-panel"><b>NO ELIGIBLE CREW AVAILABLE</b><span>Refresh Crew authority or complete the required Crew training before pairing.</span></div>}</section>}
      {selectedCrew && !activePackageCurrent && <section className="package-dock-compatibility" aria-live="polite"><span>SERVER COMPATIBILITY</span><h3>{compatibility?.ready ? "DECK + CREW COMPATIBLE" : "PAIRING BLOCKED"}</h3><p>TRUE BOND · {selectedCrew.trueBond?.name || "VERIFYING"}</p><small>TIMING · {selectedTrueBondTiming}</small><small>DOCTRINE GUIDANCE · {(selectedCrew.doctrines || []).join(" + ") || "No doctrine advice is available. Server compatibility remains authoritative."}</small>{exactBlockers.length > 0 && <ul className="package-dock-blocker">{exactBlockers.map((message) => <li key={message}>{message}</li>)}</ul>}</section>}
      {activePackageCurrent && <section className="package-dock-receipt" aria-label="Active Deployment Package receipt"><span>SERVER RECEIPT / CURRENT REVISION</span><h3>ACTIVE DEPLOYMENT PACKAGE</h3><p>{activePackageDeckName} + {activePackageCrew?.pilot?.callsign || "PILOT RECORD UNAVAILABLE"} + {activePackageCrew?.signatureMeka?.code || "SIGNATURE MEKA"}</p><strong>TRUE BOND · {activePackageCrew?.trueBond?.name || "AUTHORITY UNAVAILABLE"}</strong><small>TIMING · {activeTrueBondTiming}</small><small>Activation remains valid only while this exact Deck revision and Crew authority remain current.</small></section>}
      {!briefingComplete && reviewed && <p className="package-dock-blocker" role="alert">DECK BAY BRIEFING REQUIRED / Review the briefing before activation.</p>}
    </section>
  </section>;
}

function getArsenalTutorialRedirect(phase, view) {
  if (phase === "combat_imprints_orientation" && view !== "imprints") return "#arsenal/imprints";
  if (phase === "deck_bay_orientation" && view !== "decks") return "#deckbay";
  return "";
}

function ArsenalPage({ account, journeyStatus, routeHash, onDirectiveNotice, onRegisterDeckBayRouteGuard }) {
  const journey = journeyStatus && journeyStatus.data;
  const postFounding = journey && journey.postFounding;
  const enabled = Boolean(postFounding && postFounding.arsenal && postFounding.arsenal.status !== "locked");
  const reviewedAt = postFounding && postFounding.arsenal && postFounding.arsenal.rewardReviewedAt;
  const collection = useTcgCollection(account, enabled, postFounding && postFounding.collection, reviewedAt || "");
  const deckMembership = useTcgDeckMembership(account, enabled);
  const tcgDecks = useTcgDecks(account, enabled);
  const deploymentPackage = useDeploymentPackage(account, enabled);
  const requestedDeckId = parseDeckBayRouteDeckId(routeHash);
  const view = routeHash === "#deckbay" || routeHash === "#arsenal/decks" || requestedDeckId ? "decks" : routeHash === "#arsenal/imprints" ? "imprints" : "collection";
  const combatImprints = useCombatImprints(account, enabled && view === "imprints");
  const reward = postFounding && postFounding.reward;
  const restrictedImprintsTutorial = postFounding?.phase === "combat_imprints_orientation";
  const imprintsTutorialComplete = hasCompletedFeatureTutorial(postFounding, "combat_imprints");
  const collectionTutorialComplete = hasCompletedFeatureTutorial(postFounding, "card_collection");
  const restrictedCollectionTutorial = !collectionTutorialComplete && postFounding?.phase === "card_collection_orientation";
  const organizationId = String(account && account.organization && account.organization.id || "").trim();
  const rewardCode = reward && reward.targetMeka && reward.targetMeka.cardCode;
  const rewardInspectionKey = buildCardInspectionStorageKey(organizationId, reward && reward.receiptId, rewardCode);
  const inspectionIdentity = [organizationId || "memory", reward && reward.receiptId || "", rewardCode || ""].join(":");
  const [filters, setFilters] = useState(() => ({ search: "", kind: "all", doctrine: "all", sort: "cost" }));
  const [selectedCode, setSelectedCode] = useState("");
  const [inspectionState, setInspectionState] = useState(() => ({ identity: "", codes: new Set() }));
  const collectionTutorialKey = buildCollectionTutorialStorageKey(organizationId);
  const collectionTutorialEntry = useCompletedTutorialEntry(collectionTutorialKey, collectionTutorialComplete, Boolean(postFounding?.phase), view === "collection");
  const [collectionTutorial, setCollectionTutorial] = useState(() => ({ identity: "", step: null }));
  const [collectionTutorialMinimized, setCollectionTutorialMinimized] = useState(false);
  const [collectionTutorialCompletedThisVisit, setCollectionTutorialCompletedThisVisit] = useState(false);
  const [collectionTutorialSaving, setCollectionTutorialSaving] = useState(false);
  const [collectionTutorialError, setCollectionTutorialError] = useState("");
  const [collectionTutorialBlocked, setCollectionTutorialBlocked] = useState(false);
  const cardButtonRefs = useRef(new Map());
  const imprintLedgerRef = useRef(null);
  const inspectedNewCodes = inspectionState.identity === inspectionIdentity ? inspectionState.codes : new Set();
  const telemetry = useMemo(() => collectionTelemetry(collection.cards), [collection.cards]);
  const visibleCards = useMemo(() => filterAndSortCollectionCards(collection.cards, filters), [collection.cards, filters]);
  const visibleCardGroups = useMemo(() => {
    const order = ["mk", "md", "command"];
    const labels = { mk: "FOUNDING MEKA · MK", md: "MEKA FRAMES · MD", command: "BATTLE COMMANDS · CMD" };
    return order.map((kind) => ({ kind, label: labels[kind], cards: visibleCards.filter((card) => String(card.kind || "").toLowerCase() === kind) })).filter((group) => group.cards.length);
  }, [visibleCards]);
  const selectedCard = collection.cards.find((card) => card.code === selectedCode) || null;
  const selectedVisibleIndex = visibleCards.findIndex((card) => card.code === selectedCode);

  useEffect(() => {
    if (view !== "collection") return;
    if (collectionTutorialComplete) writeCollectionTutorialCompletion(getCollectionTutorialStorage(), collectionTutorialKey);
    setCollectionTutorial({ identity: collectionTutorialKey, step: collectionTutorialEntry.completedAtEntry ? null : 0 });
    setCollectionTutorialMinimized(collectionTutorialEntry.completedAtEntry);
    setCollectionTutorialCompletedThisVisit(false);
  }, [collectionTutorialKey, collectionTutorialEntry.completedAtEntry, view]);

  useLayoutEffect(() => {
    const tutorialRedirect = getArsenalTutorialRedirect(postFounding?.phase, view);
    if (tutorialRedirect) activateDirectiveTarget(tutorialRedirect);
  }, [postFounding?.phase, view]);

  useEffect(() => {
    if (!selectedCode) return;
    if (!visibleCards.some((card) => card.code === selectedCode)) setSelectedCode("");
  }, [selectedCode, visibleCards]);

  useEffect(() => {
    const inspected = readCardInspectionMarker(getCardInspectionStorage(), rewardInspectionKey);
    setInspectionState({ identity: inspectionIdentity, codes: new Set(inspected && rewardCode ? [rewardCode] : []) });
  }, [inspectionIdentity, rewardInspectionKey, rewardCode]);

  function inspectCard(code) {
    setSelectedCode(code);
    setCollectionTutorial((current) => current.identity === collectionTutorialKey && current.step === 2 ? { ...current, step: 3 } : current);
    if (code === rewardCode) setInspectionState((current) => {
      const currentCodes = current.identity === inspectionIdentity ? current.codes : new Set();
      if (currentCodes.has(code)) return current;
      const next = new Set(currentCodes);
      next.add(code);
      writeCardInspectionMarker(getCardInspectionStorage(), rewardInspectionKey);
      return { identity: inspectionIdentity, codes: next };
    });
  }

  async function finishCollectionTutorial() {
    if (collectionTutorialSaving) return;
    setCollectionTutorialSaving(true);
    setCollectionTutorialError("");
    try {
      if (!collectionTutorialComplete) {
        const next = await journeyStatus.completeArsenalOrientation();
        const directive = next && next.directiveReceipt;
        if (!next) { setCollectionTutorialError("Completion could not be saved. Select FINISH to retry."); return; }
        if (directive) onDirectiveNotice?.(directive);
      }
      writeCollectionTutorialCompletion(getCollectionTutorialStorage(), collectionTutorialKey);
      setCollectionTutorial((current) => ({ identity: collectionTutorialKey, step: current.step == null ? 3 : current.step }));
      setCollectionTutorialMinimized(false);
      setCollectionTutorialCompletedThisVisit(true);
    } catch {
      setCollectionTutorialError("Completion could not be saved. Select FINISH to retry.");
    } finally { setCollectionTutorialSaving(false); }
  }

  function minimizeCollectionTutorial() {
    setCollectionTutorialMinimized(true);
  }

  function reopenCollectionTutorial() {
    setCollectionTutorialMinimized(false);
    setCollectionTutorial((current) => current.identity === collectionTutorialKey && current.step != null
      ? current
      : { identity: collectionTutorialKey, step: 0 });
  }

  function advanceCollectionTutorial() {
    if (collectionTutorial.identity === collectionTutorialKey && collectionTutorial.step >= 3) {
      void finishCollectionTutorial();
      return;
    }
    setCollectionTutorial((current) => {
      if (current.identity !== collectionTutorialKey || current.step == null) return current;
      return { ...current, step: current.step + 1 };
    });
  }

  function closeInspector() {
    const code = selectedCode;
    setSelectedCode("");
    window.requestAnimationFrame(() => cardButtonRefs.current.get(code)?.focus());
  }

  function navigateInspector(delta) {
    if (!visibleCards.length) return;
    const currentIndex = selectedVisibleIndex >= 0 ? selectedVisibleIndex : 0;
    const nextIndex = (currentIndex + delta + visibleCards.length) % visibleCards.length;
    inspectCard(visibleCards[nextIndex].code);
  }

  if (!enabled) return <main className="post-founding-page"><div className="post-founding-page-locked"><span>ARSENAL ACCESS LOCKED</span><h1>Complete your first deployment debrief.</h1></div></main>;
  const tabs = [
    { href: "#cardcollection", label: "CARD COLLECTION", active: view === "collection" },
    { href: "#arsenal/imprints", label: "COMBAT IMPRINTS", active: view === "imprints" },
    { href: "#deckbay", label: "DECK BAY", active: view === "decks" }
  ];
  return (
    <CommandPageShell className={"arsenal-page" + (view === "collection" ? " is-card-collection-v2" : "") + (view === "decks" ? " is-deck-bay-v2" : "") + (view === "imprints" ? " is-combat-imprints-v2" : "")} eyebrow="ARSENAL / ORGANIZATION ASSET CONTROL" title="Arsenal" summary="Owned cards, recorded Combat Imprints, and legal deployment decks.">
      {view === "collection" && (
        <RestrictedTutorialGuard active={restrictedCollectionTutorial && !collectionTutorialCompletedThisVisit} highlightActive={collectionTutorialEntry.resolved && !collectionTutorialComplete && !collectionTutorialCompletedThisVisit && !collectionTutorialMinimized && collectionTutorial.step != null} allowedSelectors={["[data-tutorial-assistant-control]", ...(collectionTutorial.step === 2 ? [".arsenal-card-print"] : [".collection-assistant-next"])]} highlightSelectors={collectionTutorial.step === 2 ? [".arsenal-card-print"] : [".collection-assistant-next:not([disabled])"]} onBlockedChange={setCollectionTutorialBlocked}>
        <section className="arsenal-collection" aria-label="Card Collection">
          <CardCollectionHeader telemetry={telemetry} />
          <p className="sr-only">Playable card prints registered to your organization. Meka Licenses, Pilot records, and partial Combat Imprints are tracked separately.</p>
          <CollectionToolbar filters={filters} onChange={setFilters} />
          {collection.status === "loading" && <div className="arsenal-state-panel">SYNCING CARD COLLECTION...</div>}
          {collection.notice && <div className="arsenal-state-panel" role="status">{collection.notice}</div>}
          {collection.error && <div className="arsenal-state-panel is-error">{collection.error}</div>}
          {collectionTutorialError && <p className="post-founding-error" role="alert">{collectionTutorialError}</p>}
          <div className="arsenal-collection-layout">
            <div className="arsenal-card-groups" aria-label="Registered card prints">
              {visibleCardGroups.map((group) => <section className={"arsenal-card-group is-" + group.kind} key={group.kind}><header><span>{group.label}</span><i aria-hidden="true" /><b>{String(group.cards.length).padStart(2, "0")} PRINTS</b></header><div className="arsenal-card-grid">{group.cards.map((card) => <ArsenalCardPrint key={card.code} card={card} selected={selectedCode === card.code} isNew={Boolean(reward && reward.combatPrintGranted === true && card.code === rewardCode && !inspectedNewCodes.has(card.code))} deckMembershipCount={deckMembership.counts.get(String(card.code).toUpperCase()) || 0} onSelect={inspectCard} buttonRef={(node) => node ? cardButtonRefs.current.set(card.code, node) : cardButtonRefs.current.delete(card.code)} />)}</div></section>)}
              {collection.status === "ready" && !visibleCards.length && <div className="arsenal-state-panel"><b>{collection.cards.length ? "NO CARDS MATCH THESE FILTERS" : "NO REGISTERED PRINTS FOUND"}</b><span>{collection.cards.length ? "Clear or change the controls above." : "The collection service returned no owned cards. Refresh after the catalog synchronizes."}</span></div>}
            </div>
          </div>
          {view === "collection" && !collectionTutorialEntry.completedAtEntry && !selectedCard && collectionTutorial.identity === collectionTutorialKey && <CardCollectionAssistant account={account} telemetry={telemetry} tutorialStep={collectionTutorial.step == null ? 0 : collectionTutorial.step} minimized={collectionTutorialMinimized || collectionTutorial.step == null} completedThisVisit={collectionTutorialCompletedThisVisit} onAdvance={advanceCollectionTutorial} onDismiss={minimizeCollectionTutorial} onReopen={reopenCollectionTutorial} restricted={restrictedCollectionTutorial} showRestrictedNudge={restrictedCollectionTutorial && collectionTutorialBlocked} />}
          <CardInspector card={selectedCard} deckMembershipCount={deckMembership.counts.get(String(selectedCode).toUpperCase()) || 0} membershipStatus={deckMembership.status} onClose={closeInspector} onPrevious={() => navigateInspector(-1)} onNext={() => navigateInspector(1)} />
          {collection.pendingMeka.map((item) => <div key={item.sourceMekaId} className="arsenal-state-panel">{item.sourceMekaId} · CANONICAL CARD RECORD PENDING</div>)}
        </section>
        </RestrictedTutorialGuard>
      )}
      {view === "imprints" && <CombatImprintLedger account={account} ledger={combatImprints} ledgerRef={imprintLedgerRef} restrictedTutorial={restrictedImprintsTutorial} tutorialComplete={imprintsTutorialComplete} tutorialCompletionResolved={Boolean(postFounding?.phase)} reward={reward} onReviewReward={journeyStatus.reviewArsenalReward} />}
      {view === "decks" && <DeckBayWorkbench deckState={tcgDecks} packageState={deploymentPackage} collection={collection} postFounding={postFounding} organization={account?.organization} requestedDeckId={requestedDeckId} onActivated={journeyStatus.refresh} onDirectiveNotice={onDirectiveNotice} onRegisterRouteGuard={onRegisterDeckBayRouteGuard} />}
    </CommandPageShell>
  );
}

function OperationsPage({ journeyStatus }) {
  const postFounding = journeyStatus && journeyStatus.data && journeyStatus.data.postFounding;
  const unlocked = Boolean(postFounding && postFounding.operations && postFounding.operations.status === "unlocked");
  if (!unlocked) {
    const collectionPending = postFounding?.phase === "card_collection_orientation";
    return <main className="post-founding-page"><div className="post-founding-page-locked"><span>OPERATIONS ACCESS LOCKED</span><h1>{collectionPending ? "Complete the Card Collection briefing first." : "Activate a complete Deployment Package first."}</h1><p>{collectionPending ? "Review the playable card library, then return to My Hangar to receive the next mission." : "Save and prepare a legal 40-card Deck, pair compatible Crew, then activate the package."}</p><a className="btn primary" href={collectionPending ? "#cardcollection" : "#deckbay"}>{collectionPending ? "OPEN CARD COLLECTION" : "OPEN DECK BAY"}</a></div></main>;
  }
  return (
    <CommandPageShell className="operations-page" eyebrow="OPERATIONS / FIELD COMMAND" title="Operations" summary="Deployment routes for training, challenges, and campaigns.">
      <section className="operations-route-grid"><a href="/battle/bond-breach/?mode=deployment"><span>ACTIVE DEPLOYMENT PACKAGE</span><h2>BOND // BREACH</h2><p>Deploy with your active Deck + Crew against the current AI opponent.</p><b>ENTER BATTLE</b></a><a href="#hangar"><span>CHALLENGE CHANNEL</span><h2>Incoming signals</h2><p>Review and answer organization challenges from My Hangar.</p><b>OPEN CHANNEL</b></a><article aria-disabled="true"><span>NUSANTARA CAMPAIGN</span><h2>Campaign route</h2><p>Regional campaign sectors are still being prepared.</p><b>COMING SOON</b></article></section>
    </CommandPageShell>
  );
}

function HangarBay({ engagement, onOpen, onOpenOrganization, onOpenCertificate, onOpenCertificateVault, account, registry, onboardingStatus, foundingJourneyStatus, suppressFoundingDeckBriefing, archiveDispatchStatus, battleArenaStatus, creatorBattleQueueStatus, onSignupStarterIntent, onDirectiveCompleted, onDispatchDirectiveCompleted }) {
  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 showFoundingDeckBriefing = Boolean(isSignedInDashboard && shouldShowFoundingDeckBriefing(foundingJourneyStatus, suppressFoundingDeckBriefing, onboardingStatus));
  const postFounding = foundingJourneyStatus && foundingJourneyStatus.data
    ? foundingJourneyStatus.data.postFounding
    : null;
  const showPostDeploymentDebrief = Boolean(
    isSignedInDashboard
    && postFounding
    && postFounding.phase === "post_deployment_debrief"
    && postFounding.debrief
    && postFounding.debrief.status !== "complete"
  );
  const showChallengeChannel = Boolean(isSignedInDashboard);
  const crewLoadoutsEnabled = Boolean(isSignedInDashboard && postFounding?.arsenal && postFounding.arsenal.status !== "locked");
  const crewLoadoutDecks = useTcgDecks(account, crewLoadoutsEnabled);
  const crewLoadoutPackage = useDeploymentPackage(account, crewLoadoutsEnabled);
  const crewLoadoutCollection = useTcgCollection(account, crewLoadoutsEnabled, postFounding?.collection);
  const [activeId, setActiveId] = useState(displayMechs[0] ? displayMechs[0].id : null);
  const [manualStarterSelection, setManualStarterSelection] = useState(false);
  const [journeyExperienceOpen, setJourneyExperienceOpen] = useState("");
  const closeJourneyExperience = useCallback(() => setJourneyExperienceOpen(""), []);
  const openFoundingJourney = useCallback(async (requestedView, returnedProjection = null) => {
    const journey = returnedProjection || foundingJourneyStatus && foundingJourneyStatus.data;
    if (
      requestedView === "challenge"
      && ["starter_deck_ready", "starter_deck_acquired"].includes(journey?.stage)
    ) {
      const next = await foundingJourneyStatus.completeDeckBriefing();
      if (next?.stage === "challenge_received") setJourneyExperienceOpen("challenge");
      return next;
    }
    setJourneyExperienceOpen(requestedView);
    return journey;
  }, [foundingJourneyStatus]);
  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="#founding-starter-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 ? (
          <>
            {showPostDeploymentDebrief && <PostDeploymentDebrief account={account} journeyStatus={foundingJourneyStatus} />}
            {showFoundingDeckBriefing && (
              <FoundingDeckBriefingSequence
                account={account}
                foundingMech={organizationStarterMech}
                journeyStatus={foundingJourneyStatus}
              />
            )}
            <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">
                <CertificateVaultPanel account={account} archiveDispatchStatus={archiveDispatchStatus} onOpenVault={onOpenCertificateVault} />
                {!showPostDeploymentDebrief && (
                  <VirtualAssistantAvatarDialogue account={account} organization={accountOrganization} starterMech={organizationStarterMech} onboardingStatus={onboardingStatus} archiveDispatchStatus={archiveDispatchStatus} foundingJourneyStatus={foundingJourneyStatus} onDirectiveCompleted={onDirectiveCompleted} onDispatchDirectiveCompleted={onDispatchDirectiveCompleted} onFoundingJourneyDirective={openFoundingJourney} />
                )}
                <ObjectiveCommandPanel
                  onboardingStatus={onboardingStatus}
                  starterMech={organizationStarterMech}
                  archiveDispatchStatus={archiveDispatchStatus}
                  foundingJourneyStatus={foundingJourneyStatus}
                />
                <OrganizationConsole starterMech={organizationStarterMech} account={account} registry={registry} compact onSelectStarter={selectActiveStarter} />
              </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>
      {showChallengeChannel && (
        <section className="section battle-arena-home-section" aria-label="Challenge Channel" data-screen-label="Challenge Channel">
          <div className="section-inner">
            <ChallengeChannelCard
              battleArenaStatus={battleArenaStatus}
              foundingJourneyStatus={foundingJourneyStatus}
              onOpenFoundingJourney={openFoundingJourney}
              onAcceptBattle={battleArenaStatus.acceptBattle}
              onRetry={() => Promise.all([foundingJourneyStatus.refresh(), battleArenaStatus.refresh()])}
            />
          </div>
        </section>
      )}
      {crewLoadoutsEnabled && <CrewLoadoutsSection deckState={crewLoadoutDecks} packageState={crewLoadoutPackage} collectionState={crewLoadoutCollection} />}
      <ArsenalHangarSection postFounding={postFounding} />
      <OperationsHangarSection postFounding={postFounding} />
      {journeyExperienceOpen && (
        <FoundingJourneyOverlay onClose={closeJourneyExperience} canDismiss={!foundingJourneyStatus.actionBusy}>
          <FoundingJourneyExperience
            account={account}
            journeyStatus={foundingJourneyStatus}
            view={journeyExperienceOpen}
            onViewChange={setJourneyExperienceOpen}
            onClose={closeJourneyExperience}
          />
        </FoundingJourneyOverlay>
      )}
      <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", "#founding-starter-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 normalizeApplicationRouteHash(rawHash) {
  if (rawHash === "#arsenal" || rawHash === "#arsenal/collection") return "#cardcollection";
  if (rawHash === "#arsenal/decks") return "#deckbay";
  return rawHash;
}

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" ? normalizeApplicationRouteHash(window.location.hash || "") : ""));
  const currentRouteHashRef = useRef(routeHash);
  const deckBayRouteGuardRef = useRef(null);
  const registerDeckBayRouteGuard = useCallback((guard) => {
    deckBayRouteGuardRef.current = guard;
    return () => {
      if (deckBayRouteGuardRef.current === guard) deckBayRouteGuardRef.current = null;
    };
  }, []);
  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 foundingJourneyStatus = useFoundingJourneyStatus(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 routeIsArsenal = routeHash === "#cardcollection" || routeHash === "#deckbay" || routeHash === "#arsenal" || routeHash === "#arsenal/collection" || routeHash === "#arsenal/imprints" || routeHash === "#arsenal/decks" || Boolean(parseDeckBayRouteDeckId(routeHash));
  const routeIsOperations = routeHash === "#operations";
  const routeIsObjectives = routeHash === "#objectives";
  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 || routeIsArsenal || routeIsOperations || routeIsObjectives;
  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 queueArsenalDirectiveReceipt(receipt) {
    const directiveId = receipt && (receipt.id || receipt.directiveId);
    if (typeof window === "undefined" || !directiveId || !receipt.completedAt || (receipt.status && receipt.status !== "complete")) return;
    const labels = {
      "post_founding.deck_bay_briefing_reviewed": ["DECK BAY BRIEFING REVIEWED", "Deck Bay briefing acknowledged. Continue the Deployment Package checklist."],
      "post_founding.battle_ready_deck_prepared": ["BATTLE-READY DECK PREPARED", "Saved legal Deck revision is ready for Crew pairing."],
      "post_founding.compatible_crew_paired": ["COMPATIBLE CREW PAIRED", "Signature Meka and True Bond compatibility have been recorded."],
      "post_founding.deployment_package_activated": ["DEPLOYMENT PACKAGE ACTIVATED", "Deployment authority is active for Operations."],
      "post_founding.card_collection_reviewed": ["CARD COLLECTION REVIEWED", "Card Collection briefing complete. Arsenal Orientation is complete and Operations access is now unlocked."],
    };
    const acquisitionReceipt = directiveId === "post_founding.battle_acquisition_reviewed" ? receipt : null;
    const copy = labels[directiveId];
    if (!acquisitionReceipt && !copy) return;
    if (acquisitionReceipt && (!acquisitionReceipt.title || !acquisitionReceipt.line)) return;
    const completionIdentity = [accountOrganization && accountOrganization.id ? accountOrganization.id : "organization", "arsenal", directiveId, receipt.completedAt].join(":");
    const persistedKey = DIRECTIVE_COMPLETION_REPLAY_STORAGE_PREFIX + completionIdentity;
    try { if (window.localStorage.getItem(persistedKey) === "1") return; window.localStorage.setItem(persistedKey, "1"); } catch {}
    enqueueDirectiveReceipt({
      ...buildReceiptShell([completionIdentity]),
      id: directiveId,
      title: acquisitionReceipt ? acquisitionReceipt.title : "Directive achieved: " + copy[0],
      line: acquisitionReceipt ? acquisitionReceipt.line : copy[1],
      nextTitle: acquisitionReceipt ? acquisitionReceipt.nextTitle || "" : directiveId === "post_founding.card_collection_reviewed" ? "OPERATIONS UNLOCKED" : ""
    }, 180);
  }

  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
  ]);

  useEffect(() => { currentRouteHashRef.current = routeHash || ""; }, [routeHash]);

  // open detail when hash matches
  useEffect(() => {
    const checkHash = () => {
      const rawHash = window.location.hash || "";
      const h = normalizeApplicationRouteHash(rawHash);
      if (h !== rawHash) history.replaceState(history.state, "", window.location.pathname + window.location.search + h);
      const acceptedHash = currentRouteHashRef.current || "";
      if (h !== acceptedHash && deckBayRouteGuardRef.current && deckBayRouteGuardRef.current(h, "hashchange") === false) {
        history.replaceState(history.state, "", window.location.pathname + window.location.search + acceptedHash);
        return;
      }
      currentRouteHashRef.current = h;
      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 && !routeIsArsenal && !routeIsOperations && !routeIsObjectives) 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, routeIsArsenal, routeIsOperations, routeIsObjectives]);

  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();
    foundingJourneyStatus.refresh();
    registry.refresh();
  };
  const skipCeremony = () => {
    setCeremonySkipRequested(true);
    setRegistryClaimCeremony(null);
    foundingJourneyStatus.refresh();
    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} foundingJourneyStatus={foundingJourneyStatus} />
        {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} />}
        {routeIsArsenal && <ArsenalPage account={account} journeyStatus={foundingJourneyStatus} routeHash={routeHash} onDirectiveNotice={queueArsenalDirectiveReceipt} onRegisterDeckBayRouteGuard={registerDeckBayRouteGuard} />}
        {routeIsOperations && <OperationsPage journeyStatus={foundingJourneyStatus} />}
        {routeIsObjectives && <ObjectiveCenterPage account={account} onboardingStatus={onboardingStatus} archiveDispatchStatus={archiveDispatchStatus} foundingJourneyStatus={foundingJourneyStatus} />}
        {!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} foundingJourneyStatus={foundingJourneyStatus} suppressFoundingDeckBriefing={Boolean(registryClaimCeremony && !ceremonySkipRequested)} archiveDispatchStatus={archiveDispatchStatus} battleArenaStatus={battleArenaStatus} creatorBattleQueueStatus={creatorBattleQueueStatus} onSignupStarterIntent={rememberSignupStarter} onDirectiveCompleted={queueDirectiveCompletionReceipt} onDispatchDirectiveCompleted={queueDispatchDirectiveCompletionReceipt} />}
            {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} archiveDispatchStatus={archiveDispatchStatus} onClaimComplete={openRegistryClaimCeremony} onDispatchDirectiveCompleted={queueDispatchDirectiveCompletionReceipt} />
            <CommsSection engagement={engagement} engagementDispatch={engagementApi.dispatch} />
            <AboutLog />
            <Footer />
          </>
        )}
        {!routeIsDedicatedAuth && <MobileUtilityNav engagement={engagement} account={account} registry={registry} foundingJourneyStatus={foundingJourneyStatus} />}
        {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}
            archiveDispatchStatus={archiveDispatchStatus}
            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} elevated={routeHash === "#deckbay" || routeHash === "#arsenal/decks"} onDismiss={() => setDirectiveReceipt(null)} />
      {registryClaimCeremony && !ceremonySkipRequested && (
        <RegistryClaimCeremonyGate
          claim={registryClaimCeremony}
          account={account}
          assistantIntro={onboardingStatus && onboardingStatus.data && onboardingStatus.data.assistantIntro}
          assistantIntroStatus={onboardingStatus && onboardingStatus.status}
          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 />);
