/* FORGE — Aetherion (Space tenant) cross-cutting atoms.
   Wave A1 / Space / Agent #8.

   Single file. Babel-standalone in-browser pattern. NO ES imports / exports.
   Globals attach to window at end-of-file.

   Spec source-of-truth:
     forge-web/demo/tenant-spec/space.md
       §10 — CSS variables, mono everywhere, units mandatory, no emoji.
       §11 — Onboarding card slot.
   Architectural reference:
     forge-web/client/pump/cross-cutting.jsx
       Inline-style atoms, React.createElement, window-attach pattern,
       severity → tone helper, monospace digits.

   Atoms exposed at window.AE*:
     AECard            — paper-card surface in cool palette
     AEPill            — tonal pill (pass · fail · warn · qual · trl9)
     AEBtn             — primary · ghost · destructive button
     AEToolbar         — left/right slot toolbar
     AEStatRow         — label/value row with mandatory unit prop
     AESectionTitle    — kicker + title block
     AEFlash           — inline flash banner (info · warn · ok · error)
     AEMassPowerBadge  — mass(g) + power(W) + heritage tag composite

   Plus an injection helper that registers the --space-* CSS variables
   per space.md §10 onto :root and onto [data-tenant="aetherion"]. The
   palette is intentionally cool: deep navy ink, mission-blue accent,
   slate labels, no warm accents, no emoji, no glyph stand-ins.

   Mass and power values always render with units (g / kg / W / mW). The
   badge enforces this by accepting numbers, never raw strings.

   Style is self-contained — no coupling to pump/* or to tokens.css beyond
   the --font-mono / --font-ui face references inherited from the global
   token sheet. The CSS-variable block is idempotent: re-injecting it
   (e.g. on hot reload) updates rather than duplicates.
*/

// ──────────────────────────────────────────────────────────────────────
// Hooks alias (avoid global-name collision with pump/cross-cutting.jsx)
// ──────────────────────────────────────────────────────────────────────
const { useState: uSAE, useEffect: uEAE, useMemo: uMAE, useRef: uRAE } = React;

// ──────────────────────────────────────────────────────────────────────
// CSS variable injection (Wave 12D · w12d-aet-light-rest)
//
// REBOUND TO THE LIGHT THEME (tokens.css `[data-theme="light"]`). The
// Aetherion ECO/dashboard/auditor/traveler screens are siblings of the
// cream dashboard.jsx surface, so the legacy `--space-*` token names now
// resolve to the canonical light tokens rather than the original deep-navy
// hex values. This fixes the global :root leak (cross-cutting.jsx used to
// stamp dark `--space-bg: #0B1220` onto every tenant's :root) without
// breaking the dozen+ files that still consume `var(--space-*)`.
//
// Mapping:
//   --space-bg        → var(--bg-0)   cream page bg
//   --space-bg-2      → var(--bg-1)   elevated card surface
//   --space-fg        → var(--ink)    primary text (dark)
//   --space-accent    → #2D5BEA       blue that reads on cream
//   --space-mono      → var(--ink)    mono digit color (dark)
//   --space-slate     → var(--ink-3)  muted label tone
//   --space-line      → var(--line)   hairline divider
//   --space-pass      → var(--ok)     pass tone (canonical)
//   --space-fail      → var(--err)    fail tone (canonical)
//   --space-warn      → var(--warn)   warning tone (canonical)
//   --space-trl9      → #2D5BEA       deep mission-blue (kept as accent)
// ──────────────────────────────────────────────────────────────────────
const AE_CSS_BLOCK_ID = "ae-space-css-vars";
const AE_CSS_TEXT = [
  ":root {",
  "  --space-bg: var(--bg-0);",
  "  --space-bg-2: var(--bg-1);",
  "  --space-fg: var(--ink);",
  "  --space-accent: #2D5BEA;",
  "  --space-mono: var(--ink);",
  "  --space-slate: var(--ink-3);",
  "  --space-line: var(--line);",
  "  --space-pass: var(--ok);",
  "  --space-fail: var(--err);",
  "  --space-warn: var(--warn);",
  "  --space-trl9: #2D5BEA;",
  "}",
  "[data-tenant=\"aetherion\"] {",
  "  --space-bg: var(--bg-0);",
  "  --space-bg-2: var(--bg-1);",
  "  --space-fg: var(--ink);",
  "  --space-accent: #2D5BEA;",
  "  --space-mono: var(--ink);",
  "  --space-slate: var(--ink-3);",
  "  --space-line: var(--line);",
  "  --space-pass: var(--ok);",
  "  --space-fail: var(--err);",
  "  --space-warn: var(--warn);",
  "  --space-trl9: #2D5BEA;",
  "}",
].join("\n");

function aeInjectCssVars() {
  if (typeof document === "undefined") return;
  let node = document.getElementById(AE_CSS_BLOCK_ID);
  if (!node) {
    node = document.createElement("style");
    node.id = AE_CSS_BLOCK_ID;
    document.head.appendChild(node);
  }
  if (node.textContent !== AE_CSS_TEXT) {
    node.textContent = AE_CSS_TEXT;
  }
}

// Inject immediately on script eval so the variables are available
// before any AE* component renders.
aeInjectCssVars();

// ──────────────────────────────────────────────────────────────────────
// Style atom constants
//
// We resolve through CSS variables so a downstream tenant theme switch
// re-skins all atoms without prop-drilling. Fallback values mirror §10
// in case the CSS block fails to inject (e.g. SSR snapshot, jsdom).
// ──────────────────────────────────────────────────────────────────────
// Rebound to light tokens (Wave 12D). Fallback values use the cream
// `tokens.css` light palette so the atoms still read on a missing CSS
// injection (e.g. SSR / jsdom). Accent stays a saturated blue that
// reads on the cream surface, matching dashboard.jsx.
const AE_BG       = "var(--space-bg, var(--bg-0))";
const AE_BG2      = "var(--space-bg-2, var(--bg-1))";
const AE_FG       = "var(--space-fg, var(--ink))";
const AE_ACCENT   = "var(--space-accent, #2D5BEA)";
const AE_MONO     = "var(--space-mono, var(--ink))";
const AE_SLATE    = "var(--space-slate, var(--ink-3))";
const AE_LINE     = "var(--space-line, var(--line))";
const AE_PASS     = "var(--space-pass, var(--ok))";
const AE_FAIL     = "var(--space-fail, var(--err))";
const AE_WARN     = "var(--space-warn, var(--warn))";
const AE_TRL9     = "var(--space-trl9, #2D5BEA)";

// Dark-on-fill / dark-on-page text for fail-tone content. --err resolves to
// oklch(0.70 ...) — light enough that white text on an AE_FAIL fill, or raw
// AE_FAIL used as small informational text on the cream page bg, both fail
// contrast. Darken toward black in oklch so the red hue survives at
// readable contrast in both roles.
const AE_FAIL_TEXT = "color-mix(in oklch, " + AE_FAIL + " 30%, black)";

const AE_FONT_UI   = "var(--font-ui)";
const AE_FONT_MONO = "var(--font-mono)";

// ──────────────────────────────────────────────────────────────────────
// Helpers — units, formatting, tone
// ──────────────────────────────────────────────────────────────────────

// Format mass: <10 kg renders in grams (no decimals); ≥10 kg in kg with
// three decimals. Per space.md §10 typography rule.
function aeFormatMass(grams) {
  const n = Number(grams);
  if (!isFinite(n)) return { value: "—", unit: "g" };
  if (n >= 10000) {
    const kg = n / 1000;
    return { value: kg.toFixed(3), unit: "kg" };
  }
  // sub-kg: show grams, no decimals
  return { value: Math.round(n).toString(), unit: "g" };
}

// Format power: always W with one decimal if <100 W, else integer W.
// Below 1 W shows mW (no decimals).
function aeFormatPower(watts) {
  const n = Number(watts);
  if (!isFinite(n)) return { value: "—", unit: "W" };
  if (n < 1 && n > 0) {
    return { value: Math.round(n * 1000).toString(), unit: "mW" };
  }
  if (n < 100) return { value: n.toFixed(1), unit: "W" };
  return { value: Math.round(n).toString(), unit: "W" };
}

// Map AEPill tone → fg/bg/border. Cool palette only. No warm accents.
function aePillTone(tone) {
  switch (tone) {
    case "pass":
      return { fg: "#08221E", bg: AE_PASS,            border: AE_PASS };
    case "fail":
      return { fg: AE_FAIL_TEXT, bg: AE_FAIL,          border: AE_FAIL };
    case "warn":
      return { fg: "#1B1408", bg: AE_WARN,            border: AE_WARN };
    case "qual":
      return { fg: AE_FG,     bg: "color-mix(in oklch, #2D5BEA 12%, transparent)", border: AE_ACCENT };
    case "trl9":
      return { fg: "#FFFFFF", bg: AE_TRL9,            border: AE_TRL9 };
    case "info":
    default:
      return { fg: AE_FG,     bg: "rgba(91,107,130,0.18)", border: AE_SLATE };
  }
}

// Map AEFlash kind → palette + label. Avoids emoji per §10.
function aeFlashKind(kind) {
  switch (kind) {
    case "ok":    return { fg: "#08221E", bg: AE_PASS,                  bar: AE_PASS,   label: "ok" };
    case "warn":  return { fg: "#1B1408", bg: AE_WARN,                  bar: AE_WARN,   label: "warn" };
    case "error": return { fg: AE_FAIL_TEXT, bg: AE_FAIL,                bar: AE_FAIL,   label: "error" };
    case "info":
    default:      return { fg: AE_FG,     bg: "color-mix(in oklch, #2D5BEA 10%, transparent)",  bar: AE_ACCENT, label: "info" };
  }
}

// Heritage tag → tone. Honors space.md §3 values: "TRL-9", "TRL-8", etc,
// optionally with an `· ISS-6Y` flight-heritage suffix.
function aeHeritageTone(heritage) {
  const h = String(heritage || "").toUpperCase();
  if (h.indexOf("TRL-9") >= 0) return "trl9";
  if (h.indexOf("TRL-8") >= 0) return "qual";
  if (h.indexOf("TRL-7") >= 0) return "warn";
  if (h.indexOf("TRL-6") >= 0) return "warn";
  return "info";
}

// ──────────────────────────────────────────────────────────────────────
// AECard
//
// Paper-card surface in the cool palette. The default `pad` is 16, which
// matches the pump cards. Pass `pad: 0` for flush-edge content.
// ──────────────────────────────────────────────────────────────────────
function AECard(props) {
  const pad = (props && props.pad !== undefined) ? props.pad : 16;
  const extra = (props && props.style) ? props.style : {};
  const style = Object.assign({}, {
    background: AE_BG2,
    color: AE_FG,
    border: "1px solid " + AE_LINE,
    borderRadius: 6,
    padding: pad,
    fontFamily: AE_FONT_UI,
    boxShadow: "0 1px 0 rgba(0,0,0,0.20), inset 0 1px 0 rgba(255,255,255,0.02)",
  }, extra);
  return React.createElement(
    "div",
    { style: style, className: (props && props.className) || undefined },
    props && props.children
  );
}

// ──────────────────────────────────────────────────────────────────────
// AEPill
//
// Tones: pass · fail · warn · qual · trl9 · info (default).
// Mono. Uppercase 9px. Slim border keeps it crisp on dark surfaces.
// ──────────────────────────────────────────────────────────────────────
function AEPill(props) {
  const tone = (props && props.tone) || "info";
  const t = aePillTone(tone);
  return React.createElement(
    "span",
    {
      style: {
        display: "inline-flex",
        alignItems: "center",
        gap: 4,
        height: 16,
        padding: "0 7px",
        borderRadius: 3,
        fontFamily: AE_FONT_MONO,
        fontSize: 12,
        letterSpacing: "0.06em",
        textTransform: "uppercase",
        color: t.fg,
        background: t.bg,
        border: "1px solid " + t.border,
        whiteSpace: "nowrap",
      },
    },
    props && props.children
  );
}

// ──────────────────────────────────────────────────────────────────────
// AEBtn
//
// Variants:
//   primary      — accent background, dark ink
//   ghost        — transparent, accent border, accent text
//   destructive  — fail background, dark ink
//
// `small: true` → 22px height. Default is 28px. Cool only — no warm
// hover glows.
// ──────────────────────────────────────────────────────────────────────
function AEBtn(props) {
  const variant = (props && props.variant) || "primary";
  const small = !!(props && props.small);
  const [hover, setHover] = uSAE(false);

  let bg, fg, border;
  if (variant === "primary") {
    bg = AE_ACCENT;
    fg = "#06122B";
    border = AE_ACCENT;
  } else if (variant === "destructive") {
    bg = AE_FAIL;
    fg = AE_FAIL_TEXT;
    border = AE_FAIL;
  } else {
    // ghost
    bg = "transparent";
    fg = AE_ACCENT;
    border = AE_ACCENT;
  }

  const hoverBg = hover && variant === "ghost"
    ? "color-mix(in oklch, #2D5BEA 10%, transparent)"
    : bg;

  return React.createElement(
    "button",
    {
      type: "button",
      onMouseEnter: function() { setHover(true); },
      onMouseLeave: function() { setHover(false); },
      onClick: props && props.onClick,
      disabled: !!(props && props.disabled),
      title: props && props.title,
      style: {
        height: small ? 22 : 28,
        padding: small ? "0 10px" : "0 14px",
        background: hoverBg,
        color: fg,
        border: "1px solid " + border,
        borderRadius: 4,
        fontFamily: AE_FONT_MONO,
        fontSize: small ? 10 : 11,
        letterSpacing: "0.06em",
        textTransform: "uppercase",
        cursor: (props && props.disabled) ? "not-allowed" : "pointer",
        opacity: (props && props.disabled) ? 0.5 : 1,
        display: "inline-flex",
        alignItems: "center",
        gap: 6,
        transition: "background .12s ease",
      },
    },
    props && props.children
  );
}

// ──────────────────────────────────────────────────────────────────────
// AEToolbar
//
// Two slots: `left` and `right`. Bottom-bordered, surface-tinted.
// Default height 36. Used as a chrome strip atop screens.
// ──────────────────────────────────────────────────────────────────────
function AEToolbar(props) {
  const h = (props && props.height) || 36;
  return React.createElement(
    "div",
    {
      style: {
        height: h,
        display: "flex",
        alignItems: "center",
        justifyContent: "space-between",
        padding: "0 14px",
        background: AE_BG2,
        color: AE_FG,
        borderBottom: "1px solid " + AE_LINE,
        fontFamily: AE_FONT_UI,
      },
    },
    React.createElement(
      "div",
      { style: { display: "flex", alignItems: "center", gap: 10, minWidth: 0 } },
      props && props.left
    ),
    React.createElement(
      "div",
      { style: { display: "flex", alignItems: "center", gap: 8, flexShrink: 0 } },
      props && props.right
    )
  );
}

// ──────────────────────────────────────────────────────────────────────
// AEStatRow
//
// Single stat line — label on the left in slate, value on the right.
// `unit` is REQUIRED for any quantity row (mass, power, voltage, etc.).
// We render value and unit in monospace with a tight, tabular feel.
// Pass `mono: false` for non-numeric value strings (rare).
//
// Examples:
//   AEStatRow({ label: "Mass margin", value: "1.54", unit: "kg" })
//   AEStatRow({ label: "Power BOL",   value: "70.0", unit: "W" })
//   AEStatRow({ label: "Δv budget",   value: "30.0", unit: "m/s" })
//
// If `unit` is omitted at runtime we render "—" in fail tone — a hard
// reminder that units are mandatory in the Aetherion UI per §10.
// ──────────────────────────────────────────────────────────────────────
function AEStatRow(props) {
  const mono = (props && props.mono === false) ? false : true;
  const hasUnit = !!(props && props.unit !== undefined && props.unit !== "");
  const v = props && props.value;
  const u = props && props.unit;

  return React.createElement(
    "div",
    {
      style: {
        display: "flex",
        alignItems: "baseline",
        justifyContent: "space-between",
        gap: 12,
        padding: "6px 0",
        borderBottom: "1px dashed " + AE_LINE,
        fontFamily: AE_FONT_UI,
      },
    },
    React.createElement(
      "span",
      {
        style: {
          fontFamily: AE_FONT_UI,
          fontSize: 12,
          color: AE_SLATE,
          letterSpacing: "0.02em",
        },
      },
      props && props.label
    ),
    React.createElement(
      "span",
      {
        style: {
          display: "inline-flex",
          alignItems: "baseline",
          gap: 4,
          fontFamily: mono ? AE_FONT_MONO : AE_FONT_UI,
          fontSize: 13,
          fontFeatureSettings: '"tnum" 1',
          color: hasUnit ? AE_MONO : AE_FAIL_TEXT,
        },
      },
      React.createElement("span", null, v !== undefined && v !== null ? String(v) : "—"),
      hasUnit
        ? React.createElement(
            "span",
            {
              style: {
                fontFamily: AE_FONT_MONO,
                fontSize: 12,
                color: AE_SLATE,
                letterSpacing: "0.04em",
                marginLeft: 1,
              },
            },
            u
          )
        : React.createElement(
            "span",
            {
              style: {
                fontFamily: AE_FONT_MONO,
                fontSize: 12,
                color: AE_FAIL_TEXT,
                letterSpacing: "0.06em",
                textTransform: "uppercase",
              },
            },
            "no-unit"
          )
    )
  );
}

// ──────────────────────────────────────────────────────────────────────
// AESectionTitle
//
// Kicker (mono, all caps, slate) above a serif/UI title. Use this for
// the top of cards and screen sections. Keeps the visual rhythm tight
// with the rest of the Aetherion UI.
// ──────────────────────────────────────────────────────────────────────
function AESectionTitle(props) {
  return React.createElement(
    "div",
    { style: { display: "flex", flexDirection: "column", gap: 2, marginBottom: 8 } },
    props && props.kicker
      ? React.createElement(
          "span",
          {
            style: {
              fontFamily: AE_FONT_MONO,
              fontSize: 12,
              letterSpacing: "0.10em",
              textTransform: "uppercase",
              color: AE_SLATE,
            },
          },
          props.kicker
        )
      : null,
    React.createElement(
      "span",
      {
        style: {
          fontFamily: AE_FONT_UI,
          fontSize: 16,
          fontWeight: 600,
          color: AE_FG,
          lineHeight: 1.3,
        },
      },
      props && props.children
    )
  );
}

// ──────────────────────────────────────────────────────────────────────
// AEFlash
//
// Inline flash banner. Kinds: info · ok · warn · error.
// `onClose` shows a close affordance. Mono label tag on the left.
// No emoji, no glyph stand-ins — text labels only per §10.
// ──────────────────────────────────────────────────────────────────────
function AEFlash(props) {
  const kind = (props && props.kind) || "info";
  const meta = aeFlashKind(kind);
  return React.createElement(
    "div",
    {
      style: {
        display: "flex",
        alignItems: "center",
        gap: 10,
        padding: "8px 12px",
        background: meta.bg,
        color: meta.fg,
        borderLeft: "3px solid " + meta.bar,
        borderRadius: 3,
        fontFamily: AE_FONT_UI,
        fontSize: 12,
        lineHeight: 1.4,
      },
    },
    React.createElement(
      "span",
      {
        style: {
          fontFamily: AE_FONT_MONO,
          fontSize: 12,
          letterSpacing: "0.10em",
          textTransform: "uppercase",
          padding: "1px 6px",
          borderRadius: 3,
          background: "rgba(0,0,0,0.18)",
          color: meta.fg,
          flexShrink: 0,
        },
      },
      meta.label
    ),
    React.createElement(
      "span",
      { style: { flex: 1, minWidth: 0 } },
      props && props.msg
    ),
    (props && props.onClose)
      ? React.createElement(
          "button",
          {
            type: "button",
            onClick: props.onClose,
            "aria-label": "close",
            style: {
              background: "transparent",
              border: "1px solid " + meta.fg,
              color: meta.fg,
              fontFamily: AE_FONT_MONO,
              fontSize: 12,
              padding: "1px 6px",
              borderRadius: 3,
              cursor: "pointer",
              flexShrink: 0,
              opacity: 0.7,
            },
          },
          "close"
        )
      : null
  );
}

// ──────────────────────────────────────────────────────────────────────
// AEMassPowerBadge
//
// Composite atom for the Space context. Renders a horizontal triplet:
// MASS / POWER / HERITAGE. Mass and power get unit suffixes per §10.
// Heritage uses the AEPill atom in the matching tone.
//
// Inputs are numeric (massG: number in grams; powerW: number in W).
// Heritage is a string (e.g. "TRL-9 · ISS-6Y"). All three are required;
// missing inputs render "—" with an explicit no-data note. This is a
// compliance gate — the Space tenant must never silently drop a value.
// ──────────────────────────────────────────────────────────────────────
function AEMassPowerBadge(props) {
  const massG = (props && props.massG !== undefined) ? props.massG : null;
  const powerW = (props && props.powerW !== undefined) ? props.powerW : null;
  const heritage = (props && props.heritage) || "";

  const m = massG === null ? null : aeFormatMass(massG);
  const p = powerW === null ? null : aeFormatPower(powerW);
  const heritageTone = aeHeritageTone(heritage);

  const cellStyle = {
    display: "flex",
    flexDirection: "column",
    gap: 2,
    minWidth: 0,
    paddingRight: 12,
    borderRight: "1px solid " + AE_LINE,
  };
  const labelStyle = {
    fontFamily: AE_FONT_MONO,
    fontSize: 12,
    letterSpacing: "0.10em",
    textTransform: "uppercase",
    color: AE_SLATE,
  };
  const valueStyle = {
    fontFamily: AE_FONT_MONO,
    fontSize: 13,
    fontFeatureSettings: '"tnum" 1',
    color: AE_MONO,
    display: "inline-flex",
    alignItems: "baseline",
    gap: 3,
  };
  const unitStyle = {
    fontFamily: AE_FONT_MONO,
    fontSize: 12,
    color: AE_SLATE,
    letterSpacing: "0.04em",
  };

  return React.createElement(
    "div",
    {
      style: {
        display: "inline-flex",
        alignItems: "center",
        gap: 12,
        padding: "8px 12px",
        background: AE_BG,
        border: "1px solid " + AE_LINE,
        borderRadius: 4,
        fontFamily: AE_FONT_UI,
      },
      "data-ae-atom": "mass-power-badge",
    },
    // MASS
    React.createElement(
      "div",
      { style: cellStyle },
      React.createElement("span", { style: labelStyle }, "mass"),
      React.createElement(
        "span",
        { style: valueStyle },
        React.createElement("span", null, m ? m.value : "—"),
        React.createElement("span", { style: unitStyle }, m ? m.unit : "g")
      )
    ),
    // POWER
    React.createElement(
      "div",
      { style: cellStyle },
      React.createElement("span", { style: labelStyle }, "power"),
      React.createElement(
        "span",
        { style: valueStyle },
        React.createElement("span", null, p ? p.value : "—"),
        React.createElement("span", { style: unitStyle }, p ? p.unit : "W")
      )
    ),
    // HERITAGE
    React.createElement(
      "div",
      { style: { display: "flex", flexDirection: "column", gap: 2, minWidth: 0 } },
      React.createElement("span", { style: labelStyle }, "heritage"),
      heritage
        ? React.createElement(AEPill, { tone: heritageTone }, heritage)
        : React.createElement(
            "span",
            {
              style: {
                fontFamily: AE_FONT_MONO,
                fontSize: 12,
                color: AE_FAIL_TEXT,
                letterSpacing: "0.06em",
                textTransform: "uppercase",
              },
            },
            "no-heritage"
          )
    )
  );
}

// ──────────────────────────────────────────────────────────────────────
// Re-export the formatter helpers — the build agents in §12 will need
// them for KPI strips, BOM cells, and dashboard tiles. Attach to a
// single namespace to keep the global surface tight.
// ──────────────────────────────────────────────────────────────────────
const AE_FMT = {
  mass: aeFormatMass,
  power: aeFormatPower,
  heritageTone: aeHeritageTone,
  pillTone: aePillTone,
  flashKind: aeFlashKind,
};

const AE_VARS = {
  bg: AE_BG,
  bg2: AE_BG2,
  fg: AE_FG,
  accent: AE_ACCENT,
  mono: AE_MONO,
  slate: AE_SLATE,
  line: AE_LINE,
  pass: AE_PASS,
  fail: AE_FAIL,
  failText: AE_FAIL_TEXT,
  warn: AE_WARN,
  trl9: AE_TRL9,
  fontUi: AE_FONT_UI,
  fontMono: AE_FONT_MONO,
};

// ──────────────────────────────────────────────────────────────────────
// Globals — atoms are window-attached only. No ES exports.
// ──────────────────────────────────────────────────────────────────────
if (typeof window !== "undefined") {
  window.AECard            = AECard;
  window.AEPill            = AEPill;
  window.AEBtn             = AEBtn;
  window.AEToolbar         = AEToolbar;
  window.AEStatRow         = AEStatRow;
  window.AESectionTitle    = AESectionTitle;
  window.AEFlash           = AEFlash;
  window.AEMassPowerBadge  = AEMassPowerBadge;
  window.AE_FMT            = AE_FMT;
  window.AE_VARS           = AE_VARS;
  window.aeInjectCssVars   = aeInjectCssVars;
}
