"use client";

// src/components/shell/product-root-gate.tsx
import { Navigate, Outlet, useParams } from "react-router-dom";

// src/product-framework/app-store.ts
import { create } from "zustand";
import { persist } from "zustand/middleware";

// src/product-framework/exxat-palette.json
var exxat_palette_default = {
  exxatPink: {
    "50": {
      hex: "#FFF3F7",
      oklch: "oklch(97.46% 0.0139 355.00)",
      oklchValues: {
        l: 0.97463,
        c: 0.01388,
        h: 355
      }
    },
    "100": {
      hex: "#FDE9F1",
      oklch: "oklch(95.22% 0.0241 351.33)",
      oklchValues: {
        l: 0.95224,
        c: 0.02406,
        h: 351.33
      }
    },
    "150": {
      hex: "#FCE1ED",
      oklch: "oklch(93.51% 0.0334 349.08)",
      oklchValues: {
        l: 0.93514,
        c: 0.03342,
        h: 349.08
      }
    },
    "200": {
      hex: "#FBD9E8",
      oklch: "oklch(91.78% 0.0423 349.53)",
      oklchValues: {
        l: 0.91784,
        c: 0.04232,
        h: 349.53
      }
    },
    "250": {
      hex: "#F9C6DD",
      oklch: "oklch(87.79% 0.0648 349.68)",
      oklchValues: {
        l: 0.87787,
        c: 0.06482,
        h: 349.68
      }
    },
    "300": {
      hex: "#F4A0C7",
      oklch: "oklch(79.99% 0.1103 350.51)",
      oklchValues: {
        l: 0.79994,
        c: 0.11026,
        h: 350.51
      }
    },
    "400": {
      hex: "#EC65A5",
      oklch: "oklch(69.18% 0.1789 353.21)",
      oklchValues: {
        l: 0.69181,
        c: 0.1789,
        h: 353.21
      }
    },
    "450": {
      hex: "#E8418F",
      oklch: "oklch(64.00% 0.2124 356.53)",
      oklchValues: {
        l: 0.63995,
        c: 0.2124,
        h: 356.53
      }
    },
    "500": {
      hex: "#E31C79",
      oklch: "oklch(60.07% 0.2312 0.68)",
      oklchValues: {
        l: 0.60069,
        c: 0.23124,
        h: 0.68
      }
    },
    "550": {
      hex: "#CF0E72",
      oklch: "oklch(55.82% 0.2218 358.57)",
      oklchValues: {
        l: 0.55823,
        c: 0.22178,
        h: 358.57
      }
    },
    "600": {
      hex: "#C00B6C",
      oklch: "oklch(52.83% 0.2110 357.44)",
      oklchValues: {
        l: 0.52833,
        c: 0.21099,
        h: 357.44
      }
    },
    "650": {
      hex: "#B00766",
      oklch: "oklch(49.59% 0.1999 355.83)",
      oklchValues: {
        l: 0.49592,
        c: 0.19987,
        h: 355.83
      }
    },
    "700": {
      hex: "#91005A",
      oklch: "oklch(43.11% 0.1786 352.06)",
      oklchValues: {
        l: 0.43114,
        c: 0.17862,
        h: 352.06
      }
    },
    "750": {
      hex: "#600042",
      oklch: "oklch(32.49% 0.1374 346.39)",
      oklchValues: {
        l: 0.32494,
        c: 0.13741,
        h: 346.39
      }
    },
    "850": {
      hex: "#410823",
      oklch: "oklch(25.39% 0.0894 357.13)",
      oklchValues: {
        l: 0.25387,
        c: 0.08935,
        h: 357.13
      }
    },
    "900": {
      hex: "#2C0517",
      oklch: "oklch(20.08% 0.0678 356.26)",
      oklchValues: {
        l: 0.20076,
        c: 0.06778,
        h: 356.26
      }
    }
  },
  exxatBlue: {
    "50": {
      hex: "#EBF6FF",
      oklch: "oklch(96.75% 0.0168 242.42)",
      oklchValues: {
        l: 0.96755,
        c: 0.01682,
        h: 242.42
      }
    },
    "100": {
      hex: "#E2F2FF",
      oklch: "oklch(95.31% 0.0244 242.34)",
      oklchValues: {
        l: 0.95314,
        c: 0.02443,
        h: 242.34
      }
    },
    "150": {
      hex: "#D2EBFF",
      oklch: "oklch(92.79% 0.0380 242.12)",
      oklchValues: {
        l: 0.92795,
        c: 0.038,
        h: 242.12
      }
    },
    "200": {
      hex: "#C2E4FF",
      oklch: "oklch(90.30% 0.0516 242.16)",
      oklchValues: {
        l: 0.90303,
        c: 0.05161,
        h: 242.16
      }
    },
    "250": {
      hex: "#AEDBFF",
      oklch: "oklch(87.18% 0.0687 242.71)",
      oklchValues: {
        l: 0.87183,
        c: 0.06871,
        h: 242.71
      }
    },
    "300": {
      hex: "#9DD2FF",
      oklch: "oklch(84.29% 0.0839 244.64)",
      oklchValues: {
        l: 0.84294,
        c: 0.08386,
        h: 244.64
      }
    },
    "400": {
      hex: "#7EBBEE",
      oklch: "oklch(76.99% 0.0968 244.75)",
      oklchValues: {
        l: 0.76991,
        c: 0.09678,
        h: 244.75
      }
    },
    "450": {
      hex: "#64A3DD",
      oklch: "oklch(69.67% 0.1078 247.70)",
      oklchValues: {
        l: 0.6967,
        c: 0.10775,
        h: 247.7
      }
    },
    "500": {
      hex: "#2E74BB",
      oklch: "oklch(55.03% 0.1309 251.73)",
      oklchValues: {
        l: 0.5503,
        c: 0.13085,
        h: 251.73
      }
    },
    "550": {
      hex: "#005BA3",
      oklch: "oklch(46.70% 0.1369 251.29)",
      oklchValues: {
        l: 0.46702,
        c: 0.13691,
        h: 251.29
      }
    },
    "600": {
      hex: "#004B87",
      oklch: "oklch(40.84% 0.1186 250.94)",
      oklchValues: {
        l: 0.40843,
        c: 0.11856,
        h: 250.94
      }
    },
    "650": {
      hex: "#004379",
      oklch: "oklch(37.83% 0.1091 250.70)",
      oklchValues: {
        l: 0.37835,
        c: 0.10913,
        h: 250.7
      }
    },
    "700": {
      hex: "#003B6A",
      oklch: "oklch(34.69% 0.0981 249.96)",
      oklchValues: {
        l: 0.34691,
        c: 0.09809,
        h: 249.96
      }
    },
    "750": {
      hex: "#00375E",
      oklch: "oklch(32.77% 0.0862 247.02)",
      oklchValues: {
        l: 0.32766,
        c: 0.08621,
        h: 247.02
      }
    },
    "850": {
      hex: "#003352",
      oklch: "oklch(30.83% 0.0743 242.85)",
      oklchValues: {
        l: 0.30833,
        c: 0.07435,
        h: 242.85
      }
    },
    "900": {
      hex: "#002A3A",
      oklch: "oklch(26.66% 0.0527 229.30)",
      oklchValues: {
        l: 0.26663,
        c: 0.05272,
        h: 229.3
      }
    }
  },
  exxatIndigo: {
    "50": {
      hex: "#F3F3FF",
      oklch: "oklch(96.76% 0.0160 286.10)",
      oklchValues: {
        l: 0.96762,
        c: 0.01597,
        h: 286.1
      }
    },
    "100": {
      hex: "#EBEBFF",
      oklch: "oklch(94.60% 0.0268 285.88)",
      oklchValues: {
        l: 0.946,
        c: 0.02683,
        h: 285.88
      }
    },
    "150": {
      hex: "#E3E3FC",
      oklch: "oklch(92.34% 0.0338 285.72)",
      oklchValues: {
        l: 0.9234,
        c: 0.03379,
        h: 285.72
      }
    },
    "200": {
      hex: "#CFCFFD",
      oklch: "oklch(86.96% 0.0634 285.01)",
      oklchValues: {
        l: 0.86955,
        c: 0.06338,
        h: 285.01
      }
    },
    "250": {
      hex: "#BBB8FE",
      oklch: "oklch(81.01% 0.0981 285.95)",
      oklchValues: {
        l: 0.81015,
        c: 0.09813,
        h: 285.95
      }
    },
    "300": {
      hex: "#A7A7FE",
      oklch: "oklch(76.23% 0.1237 283.07)",
      oklchValues: {
        l: 0.76234,
        c: 0.12375,
        h: 283.07
      }
    },
    "400": {
      hex: "#8C8CF2",
      oklch: "oklch(68.46% 0.1481 281.76)",
      oklchValues: {
        l: 0.68459,
        c: 0.14805,
        h: 281.76
      }
    },
    "450": {
      hex: "#7777E2",
      oklch: "oklch(62.01% 0.1581 280.76)",
      oklchValues: {
        l: 0.62007,
        c: 0.15809,
        h: 280.76
      }
    },
    "500": {
      hex: "#6A6BD3",
      oklch: "oklch(57.84% 0.1560 279.93)",
      oklchValues: {
        l: 0.5784,
        c: 0.15602,
        h: 279.93
      }
    },
    "550": {
      hex: "#5C59C9",
      oklch: "oklch(52.78% 0.1691 280.09)",
      oklchValues: {
        l: 0.52782,
        c: 0.16912,
        h: 280.09
      }
    },
    "600": {
      hex: "#4D49BE",
      oklch: "oklch(47.99% 0.1779 278.83)",
      oklchValues: {
        l: 0.47989,
        c: 0.17795,
        h: 278.83
      }
    },
    "650": {
      hex: "#373490",
      oklch: "oklch(38.75% 0.1472 278.46)",
      oklchValues: {
        l: 0.38755,
        c: 0.14718,
        h: 278.46
      }
    },
    "700": {
      hex: "#2E2B78",
      oklch: "oklch(34.28% 0.1273 279.03)",
      oklchValues: {
        l: 0.3428,
        c: 0.12729,
        h: 279.03
      }
    },
    "750": {
      hex: "#232964",
      oklch: "oklch(31.29% 0.1030 274.42)",
      oklchValues: {
        l: 0.31289,
        c: 0.10301,
        h: 274.42
      }
    },
    "850": {
      hex: "#1B1A48",
      oklch: "oklch(24.98% 0.0835 279.45)",
      oklchValues: {
        l: 0.24981,
        c: 0.08346,
        h: 279.45
      }
    },
    "900": {
      hex: "#121130",
      oklch: "oklch(19.97% 0.0600 280.93)",
      oklchValues: {
        l: 0.19968,
        c: 0.05998,
        h: 280.93
      }
    }
  },
  sapphireGrayBlack: {
    "50": {
      hex: "#F5F7F8",
      oklch: "oklch(97.49% 0.0025 228.78)",
      oklchValues: {
        l: 0.9749,
        c: 252e-5,
        h: 228.78
      }
    },
    "100": {
      hex: "#ECEFF1",
      oklch: "oklch(95.04% 0.0042 236.50)",
      oklchValues: {
        l: 0.95041,
        c: 42e-4,
        h: 236.5
      }
    },
    "150": {
      hex: "#E4E7EA",
      oklch: "oklch(92.65% 0.0052 247.88)",
      oklchValues: {
        l: 0.92653,
        c: 52e-4,
        h: 247.88
      }
    },
    "200": {
      hex: "#DCE0E3",
      oklch: "oklch(90.45% 0.0060 239.83)",
      oklchValues: {
        l: 0.90449,
        c: 597e-5,
        h: 239.83
      }
    },
    "250": {
      hex: "#D5D9DD",
      oklch: "oklch(88.34% 0.0070 247.90)",
      oklchValues: {
        l: 0.88338,
        c: 701e-5,
        h: 247.9
      }
    },
    "300": {
      hex: "#CED2D6",
      oklch: "oklch(86.18% 0.0071 247.91)",
      oklchValues: {
        l: 0.86184,
        c: 706e-5,
        h: 247.91
      }
    },
    "400": {
      hex: "#BBC0C6",
      oklch: "oklch(80.57% 0.0101 252.83)",
      oklchValues: {
        l: 0.80566,
        c: 0.0101,
        h: 252.83
      }
    },
    "450": {
      hex: "#A8AFB6",
      oklch: "oklch(75.06% 0.0128 248.00)",
      oklchValues: {
        l: 0.7506,
        c: 0.01278,
        h: 248
      }
    },
    "500": {
      hex: "#959DA6",
      oklch: "oklch(69.24% 0.0161 251.22)",
      oklchValues: {
        l: 0.69241,
        c: 0.01608,
        h: 251.22
      }
    },
    "550": {
      hex: "#818C95",
      oklch: "oklch(63.41% 0.0187 242.58)",
      oklchValues: {
        l: 0.63408,
        c: 0.01866,
        h: 242.58
      }
    },
    "600": {
      hex: "#6E7A85",
      oklch: "oklch(57.33% 0.0222 245.85)",
      oklchValues: {
        l: 0.57335,
        c: 0.02221,
        h: 245.85
      }
    },
    "650": {
      hex: "#5F6975",
      oklch: "oklch(51.66% 0.0226 253.02)",
      oklchValues: {
        l: 0.51657,
        c: 0.02262,
        h: 253.02
      }
    },
    "700": {
      hex: "#455663",
      oklch: "oklch(44.39% 0.0301 241.29)",
      oklchValues: {
        l: 0.44386,
        c: 0.0301,
        h: 241.29
      }
    },
    "750": {
      hex: "#304251",
      oklch: "oklch(37.01% 0.0347 244.05)",
      oklchValues: {
        l: 0.3701,
        c: 0.03467,
        h: 244.05
      }
    },
    "850": {
      hex: "#1A2F3E",
      oklch: "oklch(29.48% 0.0385 240.87)",
      oklchValues: {
        l: 0.29481,
        c: 0.03848,
        h: 240.87
      }
    },
    "900": {
      hex: "#041C2C",
      oklch: "oklch(21.68% 0.0436 240.97)",
      oklchValues: {
        l: 0.21683,
        c: 0.04363,
        h: 240.97
      }
    }
  },
  orange: {
    "50": {
      hex: "#FEF9F5",
      oklch: "oklch(98.49% 0.0075 61.46)",
      oklchValues: {
        l: 0.98486,
        c: 755e-5,
        h: 61.46
      }
    },
    "100": {
      hex: "#FDF4ED",
      oklch: "oklch(97.22% 0.0135 60.57)",
      oklchValues: {
        l: 0.97223,
        c: 0.01346,
        h: 60.57
      }
    },
    "150": {
      hex: "#FEEBE3",
      oklch: "oklch(95.30% 0.0234 44.34)",
      oklchValues: {
        l: 0.95305,
        c: 0.0234,
        h: 44.34
      }
    },
    "200": {
      hex: "#FEDACD",
      oklch: "oklch(91.51% 0.0440 40.87)",
      oklchValues: {
        l: 0.91505,
        c: 0.04402,
        h: 40.87
      }
    },
    "250": {
      hex: "#FFCAB7",
      oklch: "oklch(88.08% 0.0660 40.64)",
      oklchValues: {
        l: 0.88079,
        c: 0.06599,
        h: 40.64
      }
    },
    "300": {
      hex: "#FFB9A2",
      oklch: "oklch(84.51% 0.0878 38.95)",
      oklchValues: {
        l: 0.84514,
        c: 0.08775,
        h: 38.95
      }
    },
    "400": {
      hex: "#FFA98C",
      oklch: "oklch(81.24% 0.1098 39.40)",
      oklchValues: {
        l: 0.81244,
        c: 0.1098,
        h: 39.4
      }
    },
    "450": {
      hex: "#FF9876",
      oklch: "oklch(77.97% 0.1328 38.99)",
      oklchValues: {
        l: 0.77975,
        c: 0.13281,
        h: 38.99
      }
    },
    "500": {
      hex: "#FF8A64",
      oklch: "oklch(75.45% 0.1516 38.65)",
      oklchValues: {
        l: 0.75448,
        c: 0.1516,
        h: 38.65
      }
    },
    "550": {
      hex: "#FF7C52",
      oklch: "oklch(73.10% 0.1699 38.28)",
      oklchValues: {
        l: 0.73097,
        c: 0.1699,
        h: 38.28
      }
    },
    "600": {
      hex: "#EE6F51",
      oklch: "oklch(68.83% 0.1636 34.58)",
      oklchValues: {
        l: 0.68826,
        c: 0.16365,
        h: 34.58
      }
    },
    "650": {
      hex: "#E56248",
      oklch: "oklch(65.59% 0.1687 32.97)",
      oklchValues: {
        l: 0.65587,
        c: 0.16866,
        h: 32.97
      }
    },
    "700": {
      hex: "#A5353F",
      oklch: "oklch(49.58% 0.1468 19.27)",
      oklchValues: {
        l: 0.49585,
        c: 0.14677,
        h: 19.27
      }
    },
    "750": {
      hex: "#76483F",
      oklch: "oklch(45.26% 0.0653 31.73)",
      oklchValues: {
        l: 0.45258,
        c: 0.06532,
        h: 31.73
      }
    },
    "850": {
      hex: "#483C3F",
      oklch: "oklch(36.98% 0.0174 1.16)",
      oklchValues: {
        l: 0.36984,
        c: 0.01741,
        h: 1.16
      }
    },
    "900": {
      hex: "#352A23",
      oklch: "oklch(29.52% 0.0205 54.20)",
      oklchValues: {
        l: 0.29516,
        c: 0.02052,
        h: 54.2
      }
    }
  },
  teal: {
    "50": {
      hex: "#F6FAFB",
      oklch: "oklch(98.24% 0.0045 214.33)",
      oklchValues: {
        l: 0.98237,
        c: 446e-5,
        h: 214.33
      }
    },
    "100": {
      hex: "#EFF9F7",
      oklch: "oklch(97.41% 0.0109 182.88)",
      oklchValues: {
        l: 0.97409,
        c: 0.01087,
        h: 182.88
      }
    },
    "150": {
      hex: "#DCF5F5",
      oklch: "oklch(95.20% 0.0262 196.72)",
      oklchValues: {
        l: 0.95198,
        c: 0.02615,
        h: 196.72
      }
    },
    "200": {
      hex: "#C7ECEB",
      oklch: "oklch(91.64% 0.0385 194.49)",
      oklchValues: {
        l: 0.91645,
        c: 0.03847,
        h: 194.49
      }
    },
    "250": {
      hex: "#A0DAD9",
      oklch: "oklch(84.86% 0.0592 194.75)",
      oklchValues: {
        l: 0.84855,
        c: 0.05922,
        h: 194.75
      }
    },
    "300": {
      hex: "#7DC9C7",
      oklch: "oklch(78.61% 0.0756 193.58)",
      oklchValues: {
        l: 0.78607,
        c: 0.07556,
        h: 193.58
      }
    },
    "400": {
      hex: "#6CBCC0",
      oklch: "oklch(74.57% 0.0789 199.77)",
      oklchValues: {
        l: 0.74566,
        c: 0.07886,
        h: 199.77
      }
    },
    "450": {
      hex: "#51B0B5",
      oklch: "oklch(70.23% 0.0895 199.99)",
      oklchValues: {
        l: 0.70225,
        c: 0.08948,
        h: 199.99
      }
    },
    "500": {
      hex: "#36AAAA",
      oklch: "oklch(67.53% 0.1006 195.03)",
      oklchValues: {
        l: 0.67534,
        c: 0.1006,
        h: 195.03
      }
    },
    "550": {
      hex: "#1B98A0",
      oklch: "oklch(62.09% 0.1004 201.80)",
      oklchValues: {
        l: 0.62092,
        c: 0.10045,
        h: 201.8
      }
    },
    "600": {
      hex: "#2E858D",
      oklch: "oklch(56.90% 0.0817 203.81)",
      oklchValues: {
        l: 0.56896,
        c: 0.08167,
        h: 203.81
      }
    },
    "650": {
      hex: "#2A767E",
      oklch: "oklch(52.30% 0.0739 204.97)",
      oklchValues: {
        l: 0.52301,
        c: 0.07392,
        h: 204.97
      }
    },
    "700": {
      hex: "#26676F",
      oklch: "oklch(47.61% 0.0659 206.48)",
      oklchValues: {
        l: 0.47607,
        c: 0.06595,
        h: 206.48
      }
    },
    "750": {
      hex: "#225761",
      oklch: "oklch(42.57% 0.0578 211.97)",
      oklchValues: {
        l: 0.42573,
        c: 0.05777,
        h: 211.97
      }
    },
    "850": {
      hex: "#1E4B52",
      oklch: "oklch(38.47% 0.0502 209.02)",
      oklchValues: {
        l: 0.38465,
        c: 0.05025,
        h: 209.02
      }
    },
    "900": {
      hex: "#143034",
      oklch: "oklch(28.93% 0.0345 207.65)",
      oklchValues: {
        l: 0.28928,
        c: 0.03453,
        h: 207.65
      }
    }
  },
  red: {
    "50": {
      hex: "#FFF5F5",
      oklch: "oklch(97.79% 0.0107 17.34)",
      oklchValues: {
        l: 0.97792,
        c: 0.01075,
        h: 17.34
      }
    },
    "100": {
      hex: "#FFEBEC",
      oklch: "oklch(95.63% 0.0218 14.06)",
      oklchValues: {
        l: 0.95629,
        c: 0.02182,
        h: 14.06
      }
    },
    "150": {
      hex: "#FEE2E2",
      oklch: "oklch(93.56% 0.0309 17.72)",
      oklchValues: {
        l: 0.93564,
        c: 0.0309,
        h: 17.72
      }
    },
    "200": {
      hex: "#FEDBD9",
      oklch: "oklch(92.00% 0.0392 21.77)",
      oklchValues: {
        l: 0.92003,
        c: 0.03915,
        h: 21.77
      }
    },
    "250": {
      hex: "#FFCDD2",
      oklch: "oklch(89.31% 0.0569 11.54)",
      oklchValues: {
        l: 0.89311,
        c: 0.05693,
        h: 11.54
      }
    },
    "300": {
      hex: "#FCB2B7",
      oklch: "oklch(83.46% 0.0867 14.63)",
      oklchValues: {
        l: 0.8346,
        c: 0.08674,
        h: 14.63
      }
    },
    "400": {
      hex: "#F9969C",
      oklch: "oklch(77.71% 0.1192 16.30)",
      oklchValues: {
        l: 0.77713,
        c: 0.11922,
        h: 16.3
      }
    },
    "450": {
      hex: "#F57B81",
      oklch: "oklch(72.40% 0.1496 18.47)",
      oklchValues: {
        l: 0.724,
        c: 0.14961,
        h: 18.47
      }
    },
    "500": {
      hex: "#F25F66",
      oklch: "oklch(67.64% 0.1809 20.54)",
      oklchValues: {
        l: 0.6764,
        c: 0.18093,
        h: 20.54
      }
    },
    "550": {
      hex: "#D85158",
      oklch: "oklch(61.68% 0.1695 20.57)",
      oklchValues: {
        l: 0.61683,
        c: 0.16952,
        h: 20.57
      }
    },
    "600": {
      hex: "#BE444A",
      oklch: "oklch(55.71% 0.1567 20.97)",
      oklchValues: {
        l: 0.55714,
        c: 0.15673,
        h: 20.97
      }
    },
    "650": {
      hex: "#AA363C",
      oklch: "oklch(50.49% 0.1513 21.56)",
      oklchValues: {
        l: 0.5049,
        c: 0.15131,
        h: 21.56
      }
    },
    "700": {
      hex: "#8A292F",
      oklch: "oklch(43.20% 0.1312 21.17)",
      oklchValues: {
        l: 0.43196,
        c: 0.13116,
        h: 21.17
      }
    },
    "750": {
      hex: "#701B20",
      oklch: "oklch(36.57% 0.1182 22.23)",
      oklchValues: {
        l: 0.36569,
        c: 0.11824,
        h: 22.23
      }
    },
    "850": {
      hex: "#5B141B",
      oklch: "oklch(31.64% 0.1022 20.03)",
      oklchValues: {
        l: 0.31641,
        c: 0.10216,
        h: 20.03
      }
    },
    "900": {
      hex: "#3F0E15",
      oklch: "oklch(25.19% 0.0758 16.30)",
      oklchValues: {
        l: 0.25192,
        c: 0.07579,
        h: 16.3
      }
    }
  },
  neutral: {
    "50": {
      hex: "#F9F5F4",
      oklch: "oklch(97.29% 0.0045 34.31)",
      oklchValues: {
        l: 0.97295,
        c: 45e-4,
        h: 34.31
      }
    },
    "100": {
      hex: "#F6F0ED",
      oklch: "oklch(95.90% 0.0076 48.65)",
      oklchValues: {
        l: 0.95896,
        c: 763e-5,
        h: 48.65
      }
    },
    "150": {
      hex: "#F3EAE6",
      oklch: "oklch(94.30% 0.0112 45.72)",
      oklchValues: {
        l: 0.94299,
        c: 0.01118,
        h: 45.72
      }
    },
    "200": {
      hex: "#F0E5DE",
      oklch: "oklch(92.87% 0.0153 54.92)",
      oklchValues: {
        l: 0.92867,
        c: 0.01529,
        h: 54.92
      }
    },
    "250": {
      hex: "#E9DCD3",
      oklch: "oklch(90.24% 0.0188 57.20)",
      oklchValues: {
        l: 0.90242,
        c: 0.01883,
        h: 57.2
      }
    },
    "300": {
      hex: "#E3D3C7",
      oklch: "oklch(87.66% 0.0242 59.35)",
      oklchValues: {
        l: 0.87658,
        c: 0.02417,
        h: 59.35
      }
    },
    "400": {
      hex: "#DBC7B5",
      oklch: "oklch(84.15% 0.0334 64.36)",
      oklchValues: {
        l: 0.84145,
        c: 0.03335,
        h: 64.36
      }
    },
    "450": {
      hex: "#D0B9A1",
      oklch: "oklch(79.90% 0.0421 68.36)",
      oklchValues: {
        l: 0.79899,
        c: 0.04212,
        h: 68.36
      }
    },
    "500": {
      hex: "#C6AB8E",
      oklch: "oklch(75.73% 0.0508 68.95)",
      oklchValues: {
        l: 0.75734,
        c: 0.05077,
        h: 68.95
      }
    },
    "550": {
      hex: "#BEA080",
      oklch: "oklch(72.45% 0.0566 68.56)",
      oklchValues: {
        l: 0.72448,
        c: 0.05659,
        h: 68.56
      }
    },
    "600": {
      hex: "#A3886C",
      oklch: "oklch(64.44% 0.0516 67.73)",
      oklchValues: {
        l: 0.64443,
        c: 0.05157,
        h: 67.73
      }
    },
    "650": {
      hex: "#887058",
      oklch: "oklch(56.18% 0.0464 66.64)",
      oklchValues: {
        l: 0.56181,
        c: 0.04644,
        h: 66.64
      }
    },
    "700": {
      hex: "#6C5944",
      oklch: "oklch(47.72% 0.0405 69.42)",
      oklchValues: {
        l: 0.47717,
        c: 0.04052,
        h: 69.42
      }
    },
    "750": {
      hex: "#514130",
      oklch: "oklch(38.74% 0.0350 68.20)",
      oklchValues: {
        l: 0.38738,
        c: 0.03504,
        h: 68.2
      }
    },
    "850": {
      hex: "#36291C",
      oklch: "oklch(29.21% 0.0294 66.25)",
      oklchValues: {
        l: 0.29205,
        c: 0.02942,
        h: 66.25
      }
    },
    "900": {
      hex: "#201911",
      oklch: "oklch(21.92% 0.0185 70.36)",
      oklchValues: {
        l: 0.2192,
        c: 0.01851,
        h: 70.36
      }
    }
  },
  purple: {
    "50": {
      hex: "#F6F3FF",
      oklch: "oklch(96.99% 0.0162 297.53)",
      oklchValues: {
        l: 0.96991,
        c: 0.01621,
        h: 297.53
      }
    },
    "100": {
      hex: "#F2ECFE",
      oklch: "oklch(95.30% 0.0248 301.07)",
      oklchValues: {
        l: 0.95301,
        c: 0.02477,
        h: 301.07
      }
    },
    "150": {
      hex: "#EFE6FE",
      oklch: "oklch(93.91% 0.0334 302.75)",
      oklchValues: {
        l: 0.93913,
        c: 0.03343,
        h: 302.75
      }
    },
    "200": {
      hex: "#E7D9FC",
      oklch: "oklch(90.73% 0.0494 303.56)",
      oklchValues: {
        l: 0.90728,
        c: 0.04943,
        h: 303.56
      }
    },
    "250": {
      hex: "#D2C0F1",
      oklch: "oklch(83.87% 0.0700 301.68)",
      oklchValues: {
        l: 0.83872,
        c: 0.07003,
        h: 301.68
      }
    },
    "300": {
      hex: "#BEA7E5",
      oklch: "oklch(76.99% 0.0903 301.31)",
      oklchValues: {
        l: 0.7699,
        c: 0.09029,
        h: 301.31
      }
    },
    "400": {
      hex: "#A98DDA",
      oklch: "oklch(69.82% 0.1139 300.20)",
      oklchValues: {
        l: 0.69818,
        c: 0.1139,
        h: 300.2
      }
    },
    "450": {
      hex: "#9474CE",
      oklch: "oklch(62.75% 0.1349 298.86)",
      oklchValues: {
        l: 0.62754,
        c: 0.13488,
        h: 298.86
      }
    },
    "500": {
      hex: "#8580C6",
      oklch: "oklch(63.27% 0.1040 286.29)",
      oklchValues: {
        l: 0.63273,
        c: 0.10398,
        h: 286.29
      }
    },
    "550": {
      hex: "#754CBF",
      oklch: "oklch(52.09% 0.1729 296.32)",
      oklchValues: {
        l: 0.52094,
        c: 0.17287,
        h: 296.32
      }
    },
    "600": {
      hex: "#633BB6",
      oklch: "oklch(47.07% 0.1835 292.92)",
      oklchValues: {
        l: 0.47068,
        c: 0.18353,
        h: 292.92
      }
    },
    "650": {
      hex: "#59319E",
      oklch: "oklch(42.66% 0.1669 295.21)",
      oklchValues: {
        l: 0.42658,
        c: 0.1669,
        h: 295.21
      }
    },
    "700": {
      hex: "#4D2A89",
      oklch: "oklch(38.60% 0.1495 295.42)",
      oklchValues: {
        l: 0.38602,
        c: 0.14952,
        h: 295.42
      }
    },
    "750": {
      hex: "#422477",
      oklch: "oklch(34.96% 0.1341 295.14)",
      oklchValues: {
        l: 0.34959,
        c: 0.13414,
        h: 295.14
      }
    },
    "850": {
      hex: "#341D5E",
      oklch: "oklch(30.10% 0.1101 295.25)",
      oklchValues: {
        l: 0.30103,
        c: 0.11011,
        h: 295.25
      }
    },
    "900": {
      hex: "#23133E",
      oklch: "oklch(23.54% 0.0788 297.08)",
      oklchValues: {
        l: 0.23545,
        c: 0.07884,
        h: 297.08
      }
    }
  },
  green: {
    "50": {
      hex: "#F5FCF5",
      oklch: "oklch(98.39% 0.0118 145.49)",
      oklchValues: {
        l: 0.98389,
        c: 0.01178,
        h: 145.49
      }
    },
    "100": {
      hex: "#F1F9F1",
      oklch: "oklch(97.39% 0.0135 145.47)",
      oklchValues: {
        l: 0.97391,
        c: 0.0135,
        h: 145.47
      }
    },
    "150": {
      hex: "#E8F7E7",
      oklch: "oklch(96.06% 0.0264 143.61)",
      oklchValues: {
        l: 0.96064,
        c: 0.02641,
        h: 143.61
      }
    },
    "200": {
      hex: "#DAEFDB",
      oklch: "oklch(93.12% 0.0347 146.62)",
      oklchValues: {
        l: 0.93117,
        c: 0.03471,
        h: 146.62
      }
    },
    "250": {
      hex: "#CDEACD",
      oklch: "oklch(90.81% 0.0495 145.15)",
      oklchValues: {
        l: 0.90809,
        c: 0.04955,
        h: 145.15
      }
    },
    "300": {
      hex: "#BFE3C0",
      oklch: "oklch(88.05% 0.0608 145.77)",
      oklchValues: {
        l: 0.88049,
        c: 0.06077,
        h: 145.77
      }
    },
    "400": {
      hex: "#B1DCB3",
      oklch: "oklch(85.29% 0.0721 146.12)",
      oklchValues: {
        l: 0.85294,
        c: 0.07205,
        h: 146.12
      }
    },
    "450": {
      hex: "#A5D6A7",
      oklch: "oklch(82.92% 0.0827 145.82)",
      oklchValues: {
        l: 0.82921,
        c: 0.08266,
        h: 145.82
      }
    },
    "500": {
      hex: "#93C095",
      oklch: "oklch(76.40% 0.0773 145.90)",
      oklchValues: {
        l: 0.76397,
        c: 0.07727,
        h: 145.9
      }
    },
    "550": {
      hex: "#80AB82",
      oklch: "oklch(69.88% 0.0753 145.88)",
      oklchValues: {
        l: 0.69878,
        c: 0.07526,
        h: 145.88
      }
    },
    "600": {
      hex: "#6E9570",
      oklch: "oklch(63.05% 0.0698 145.97)",
      oklchValues: {
        l: 0.63054,
        c: 0.06976,
        h: 145.97
      }
    },
    "650": {
      hex: "#5C7F5E",
      oklch: "oklch(56.04% 0.0642 146.08)",
      oklchValues: {
        l: 0.56041,
        c: 0.06415,
        h: 146.08
      }
    },
    "700": {
      hex: "#49694B",
      oklch: "oklch(48.71% 0.0603 146.11)",
      oklchValues: {
        l: 0.48712,
        c: 0.06034,
        h: 146.11
      }
    },
    "750": {
      hex: "#375439",
      oklch: "oklch(41.47% 0.0564 146.13)",
      oklchValues: {
        l: 0.41469,
        c: 0.05643,
        h: 146.13
      }
    },
    "850": {
      hex: "#243E26",
      oklch: "oklch(33.53% 0.0526 146.07)",
      oklchValues: {
        l: 0.33526,
        c: 0.05259,
        h: 146.07
      }
    },
    "900": {
      hex: "#122814",
      oklch: "oklch(25.20% 0.0466 146.02)",
      oklchValues: {
        l: 0.25205,
        c: 0.04662,
        h: 146.02
      }
    }
  }
};

// src/product-framework/exxat-palette.ts
var PALETTE = exxat_palette_default;
var EXXAT_PALETTE_FAMILIES = [
  { id: "exxatPink", label: "Pink" },
  { id: "exxatBlue", label: "Blue" },
  { id: "exxatIndigo", label: "Indigo" },
  { id: "purple", label: "Purple" },
  { id: "teal", label: "Teal" },
  { id: "green", label: "Green" },
  { id: "orange", label: "Orange" },
  { id: "red", label: "Red" },
  { id: "neutral", label: "Neutral" },
  { id: "sapphireGrayBlack", label: "Sapphire" }
];
var EXXAT_PALETTE_SHADES = [
  "50",
  "100",
  "150",
  "200",
  "250",
  "300",
  "400",
  "450",
  "500",
  "550",
  "600",
  "650",
  "700",
  "750",
  "850",
  "900"
];
function buildSwatch(family, familyLabel, shade) {
  const data = PALETTE[family]?.[shade];
  if (!data) return null;
  return {
    family,
    familyLabel,
    shade,
    label: `${familyLabel} ${shade}`,
    hex: data.hex,
    oklch: data.oklch,
    oklchValues: data.oklchValues
  };
}
var EXXAT_PALETTE_BY_FAMILY = EXXAT_PALETTE_FAMILIES.map(({ id, label }) => ({
  id,
  label,
  swatches: EXXAT_PALETTE_SHADES.map((shade) => buildSwatch(id, label, shade)).filter(
    (swatch) => swatch !== null
  )
}));
var EXXAT_PALETTE_SWATCHES = EXXAT_PALETTE_BY_FAMILY.flatMap(
  (family) => family.swatches
);
function findExxatPaletteSwatch(value) {
  if (!value) return void 0;
  const normalized = value.trim().toLowerCase();
  if (!normalized) return void 0;
  return EXXAT_PALETTE_SWATCHES.find(
    (swatch) => swatch.oklch.toLowerCase() === normalized || swatch.hex.toLowerCase() === normalized
  );
}

// src/product-framework/brand-color-match.ts
function brandColorsEquivalent(a, b) {
  const left = a?.trim();
  const right = b?.trim();
  if (!left || !right) return false;
  if (left.toLowerCase() === right.toLowerCase()) return true;
  const swatchA = findExxatPaletteSwatch(left);
  const swatchB = findExxatPaletteSwatch(right);
  if (swatchA && swatchB) {
    return swatchA.family === swatchB.family && swatchA.shade === swatchB.shade;
  }
  return false;
}

// src/product-framework/brand-accent-color.ts
var BRAND_ACCENT_LIGHTNESS = 0.5784;
var BRAND_ACCENT_CHROMA = 0.156;
function brandAccentOklchFromHue(hue) {
  const h = (hue % 360 + 360) % 360;
  return `oklch(${BRAND_ACCENT_LIGHTNESS} ${BRAND_ACCENT_CHROMA} ${h})`;
}
function parseOklchHue(value) {
  const trimmed = value?.trim();
  if (!trimmed) return null;
  const match = trimmed.match(/oklch\(\s*[\d.]+%?\s+[\d.]+\s+([\d.]+)/i);
  if (!match) return null;
  const hue = Number.parseFloat(match[1]);
  return Number.isFinite(hue) ? hue : null;
}
function normalizeBrandAccentColor(value) {
  const trimmed = value?.trim();
  if (!trimmed) return brandAccentOklchFromHue(280);
  const swatch = findExxatPaletteSwatch(trimmed);
  if (swatch) return swatch.oklch;
  const hue = parseOklchHue(trimmed);
  if (hue !== null) return brandAccentOklchFromHue(hue);
  return trimmed;
}

// src/product-framework/product-routing.ts
var BUILTIN_SLUGS = {
  prism: "exxat-prism",
  "one-schools": "exxat-one-schools",
  "one-sites": "exxat-one-sites",
  custom: "exxat-custom"
};
function customProductSlugFromSuffix(suffix) {
  const slug = suffix.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
  return slug || "custom-product";
}
function resolveProductFromPath(pathname, customProducts = []) {
  const segment = pathname.replace(/^\/+/, "").split("/", 1)[0] ?? "";
  if (!segment) return null;
  const builtIn = BUILTIN_SLUGS[segment];
  if (builtIn) {
    return { product: builtIn };
  }
  for (let i = 0; i < customProducts.length; i++) {
    const brand = customProducts[i];
    if (!brand?.suffix?.trim()) continue;
    if (customProductSlugFromSuffix(brand.suffix) === segment) {
      return { product: "exxat-custom", customIndex: i };
    }
  }
  return null;
}

// src/product-framework/product-ref.ts
function productRefsEqual(a, b) {
  return a.product === b.product && (a.customIndex ?? -1) === (b.customIndex ?? -1);
}
function adjustProductRefAfterCustomRemoval(ref, removedIndex) {
  if (!ref || ref.product !== "exxat-custom") return ref;
  const idx = ref.customIndex ?? 0;
  if (idx === removedIndex) return null;
  if (idx > removedIndex) return { ...ref, customIndex: idx - 1 };
  return ref;
}
function adjustHiddenProductsAfterCustomRemoval(hidden, removedIndex) {
  return hidden.filter((entry) => !(entry.product === "exxat-custom" && entry.customIndex === removedIndex)).map((entry) => {
    if (entry.product === "exxat-custom" && entry.customIndex !== void 0 && entry.customIndex > removedIndex) {
      return { ...entry, customIndex: entry.customIndex - 1 };
    }
    return entry;
  });
}

// src/product-framework/custom-product-defaults.ts
var DEFAULT_CUSTOM_PRODUCT_BRAND = {
  suffix: "Custom",
  brandColor: "oklch(0.7 0.0913 159.88)"
};

// src/product-framework/product-brand.ts
function defineProductBrand(input) {
  return {
    ...input,
    prefix: (input.prefix ?? "Exxat").trim(),
    suffix: input.suffix.trim()
  };
}
var EXXAT_LOGO_PINK = "#E31C79";
var EXXAT_LOGO_PINK_GRADIENT_END = "#EF609D";
var EXXAT_LOGO_PINK_SHADOW = "#BE1E6D";
var EXXAT_ONE_ACCENT = "oklch(57.84% 0.1560 279.93)";
var EXXAT_PRISM_ACCENT = "oklch(60.07% 0.2312 0.68)";
var EXXAT_ONE_SHARED = {
  prefix: "Exxat",
  suffix: "One",
  brandColor: EXXAT_ONE_ACCENT,
  wordmarkColor: EXXAT_LOGO_PINK,
  markGradient: [EXXAT_LOGO_PINK, EXXAT_LOGO_PINK_GRADIENT_END],
  markShadow: EXXAT_LOGO_PINK_SHADOW
};
var EXXAT_ONE_SCHOOLS_BRAND = defineProductBrand({
  ...EXXAT_ONE_SHARED,
  id: "exxat-one-schools",
  label: "Exxat One \u2014 Schools"
});
var EXXAT_ONE_SITES_BRAND = defineProductBrand({
  ...EXXAT_ONE_SHARED,
  id: "exxat-one-sites",
  label: "Exxat One \u2014 Sites"
});
var EXXAT_PRISM_BRAND = defineProductBrand({
  id: "exxat-prism",
  prefix: "Exxat",
  suffix: "Prism",
  brandColor: EXXAT_PRISM_ACCENT,
  wordmarkColor: EXXAT_LOGO_PINK,
  markGradient: [EXXAT_LOGO_PINK, EXXAT_LOGO_PINK_GRADIENT_END],
  markShadow: EXXAT_LOGO_PINK_SHADOW
});
function customProductBrandConfig(customBrand = DEFAULT_CUSTOM_PRODUCT_BRAND) {
  const suffix = customBrand?.suffix?.trim() || DEFAULT_CUSTOM_PRODUCT_BRAND.suffix;
  const brandColor = normalizeBrandAccentColor(
    customBrand?.brandColor?.trim() || DEFAULT_CUSTOM_PRODUCT_BRAND.brandColor
  );
  return defineProductBrand({
    id: "exxat-custom",
    prefix: "Exxat",
    suffix,
    brandColor,
    wordmarkColor: EXXAT_LOGO_PINK,
    markGradient: [EXXAT_LOGO_PINK, EXXAT_LOGO_PINK_GRADIENT_END],
    markShadow: EXXAT_LOGO_PINK_SHADOW,
    compactLogo: suffix.length > 8
  });
}
var REGISTRY = /* @__PURE__ */ new Map();
function registerProductBrand(config) {
  REGISTRY.set(config.id, config);
}
registerProductBrand(EXXAT_ONE_SCHOOLS_BRAND);
registerProductBrand(EXXAT_ONE_SITES_BRAND);
registerProductBrand(EXXAT_PRISM_BRAND);
registerProductBrand(customProductBrandConfig());

// src/product-framework/product-registry.ts
var REGISTRY2 = [];
var SLUG_SHAPE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
function assertSlugIsAvailable(slug, id) {
  if (!SLUG_SHAPE.test(slug)) {
    throw new Error(
      `[product-registry] Invalid slug "${slug}" for product "${id}" \u2014 slugs MUST be lowercase kebab-case (a-z, 0-9, hyphen-separated).`
    );
  }
  const SHELL_GLOBAL = /* @__PURE__ */ new Set([
    "settings",
    "help",
    "library",
    "login",
    "logout",
    "oauth",
    "dashboard",
    "columns",
    "tokens",
    "tokens-themes"
  ]);
  if (SHELL_GLOBAL.has(slug)) {
    throw new Error(
      `[product-registry] Slug "${slug}" is reserved by the DS shell. Pick a different slug for product "${id}".`
    );
  }
}
function defineProduct(input) {
  const brandPrefix = (input.brandPrefix ?? "Exxat").trim();
  const brandSuffix = input.brandSuffix.trim();
  const slug = input.slug.trim();
  return {
    ...input,
    brandPrefix,
    brandSuffix,
    slug,
    defaultPath: input.defaultPath ?? `/${slug}/dashboard`
  };
}
function registerProducts(products) {
  for (const product of products) {
    assertSlugIsAvailable(product.slug, product.id);
    const existingIndex = REGISTRY2.findIndex((p) => p.id === product.id);
    if (existingIndex >= 0) {
      REGISTRY2[existingIndex] = product;
    } else {
      REGISTRY2.push(product);
    }
    registerProductBrand(defineProductBrand({
      id: product.id,
      prefix: product.brandPrefix,
      suffix: product.brandSuffix,
      brandColor: product.brandColor,
      ...product.brand
    }));
  }
}

// src/product-framework/tenant-products/serialize.ts
import { createElement } from "react";

// src/product-framework/tenant-products/defaults.ts
function defaultTenantNavForSlug(slug) {
  const root = `/${slug}`;
  return [
    {
      key: "dashboard",
      title: "Dashboard",
      url: `${root}/dashboard`,
      iconClass: "fa-light fa-gauge-high",
      iconActiveClass: "fa-solid fa-gauge-high"
    },
    {
      key: "library",
      title: "Library",
      url: `${root}/library`,
      iconClass: "fa-light fa-books",
      iconActiveClass: "fa-solid fa-books",
      secondaryPanel: "library"
    },
    {
      key: "placements",
      title: "Placements",
      url: `${root}/placements`,
      iconClass: "fa-light fa-location-dot",
      iconActiveClass: "fa-solid fa-location-dot"
    },
    {
      key: "team",
      title: "Team",
      url: `${root}/team`,
      iconClass: "fa-light fa-users",
      iconActiveClass: "fa-solid fa-users"
    },
    {
      key: "compliance",
      title: "Compliance",
      url: `${root}/compliance`,
      iconClass: "fa-light fa-shield-check",
      iconActiveClass: "fa-solid fa-shield-check"
    }
  ];
}
var DEFAULT_TENANT_BRAND_PREFIX = "Exxat";

// src/product-framework/tenant-products/serialize.ts
function serializableNavToRuntime(links) {
  return links.map((link) => ({
    key: link.key,
    title: link.title,
    url: link.url,
    icon: createElement("i", { className: link.iconClass, "aria-hidden": true }),
    iconActive: link.iconActiveClass ? createElement("i", {
      className: link.iconActiveClass,
      "aria-hidden": true
    }) : void 0,
    badge: link.badge,
    secondaryPanel: link.secondaryPanel,
    primaryHubChildKey: link.primaryHubChildKey,
    children: link.children ? serializableNavToRuntime(link.children) : void 0
  }));
}
function tenantRecordToDefinition(record) {
  return defineProduct({
    id: record.id,
    slug: record.slug,
    label: record.label,
    brandPrefix: record.brandPrefix,
    brandSuffix: record.brandSuffix,
    brandColor: record.brandColor,
    scope: record.scope,
    nav: serializableNavToRuntime(record.nav),
    defaultPath: record.defaultPath
  });
}
function brandToTenantRecord(input) {
  const suffix = input.suffix.trim();
  const slug = customProductSlugFromSuffix(suffix);
  const id = input.id ?? `tenant-${slug}`;
  const now = (/* @__PURE__ */ new Date()).toISOString();
  return {
    id,
    slug,
    label: `Exxat ${suffix}`,
    brandPrefix: DEFAULT_TENANT_BRAND_PREFIX,
    brandSuffix: suffix,
    brandColor: normalizeBrandAccentColor(input.brandColor),
    scope: "school-program",
    nav: defaultTenantNavForSlug(slug),
    defaultPath: `/${slug}/dashboard`,
    source: "user",
    createdAt: now,
    updatedAt: now,
    extensions: {}
  };
}

// src/lib/persisted-state.ts
import * as React from "react";
var EXXAT_STORAGE_PREFIX = "exxat-ds:";
var isBrowser = () => typeof window !== "undefined";
function getDriverImpl(driver) {
  if (!isBrowser()) return null;
  try {
    return driver === "session" ? window.sessionStorage : window.localStorage;
  } catch {
    return null;
  }
}
function namespacedKey(key) {
  return key.startsWith(EXXAT_STORAGE_PREFIX) ? key : `${EXXAT_STORAGE_PREFIX}${key}`;
}
function getStorageItem(key, driver = "local") {
  const store = getDriverImpl(driver);
  if (!store) return null;
  try {
    return store.getItem(namespacedKey(key));
  } catch {
    return null;
  }
}
function setStorageItem(key, value, driver = "local") {
  const store = getDriverImpl(driver);
  if (!store) return;
  try {
    store.setItem(namespacedKey(key), value);
  } catch {
  }
}

// src/product-framework/tenant-products/types.ts
var TENANT_STORE_KEY = "tenant-store:v1";
var TENANT_STORE_VERSION = 1;
var TENANT_PRODUCT_DATA_VERSION = 1;
function emptyProductDataBag() {
  return {
    v: TENANT_PRODUCT_DATA_VERSION,
    hubs: {},
    entities: {},
    preferences: {},
    legacy: {},
    extensions: {}
  };
}
function emptyTenantStore() {
  return {
    v: TENANT_STORE_VERSION,
    catalog: [],
    products: {},
    meta: {}
  };
}

// src/product-framework/tenant-products/store.ts
function loadTenantStore() {
  const raw = getStorageItem(TENANT_STORE_KEY);
  if (!raw) return emptyTenantStore();
  try {
    const parsed = JSON.parse(raw);
    if (!parsed || typeof parsed !== "object") return emptyTenantStore();
    return {
      ...emptyTenantStore(),
      ...parsed,
      v: TENANT_STORE_VERSION,
      catalog: Array.isArray(parsed.catalog) ? parsed.catalog : [],
      products: parsed.products && typeof parsed.products === "object" ? parsed.products : {},
      meta: parsed.meta && typeof parsed.meta === "object" ? parsed.meta : {}
    };
  } catch {
    return emptyTenantStore();
  }
}
function saveTenantStore(store) {
  setStorageItem(TENANT_STORE_KEY, JSON.stringify({ ...store, v: TENANT_STORE_VERSION }));
}
function getActiveCatalog(store) {
  return store.catalog.filter((p) => !p.deletedAt);
}
function getTenantProductBySlug(store, slug) {
  return store.catalog.find((p) => p.slug === slug && !p.deletedAt);
}
function ensureProductDataBag(store, productId) {
  if (!store.products[productId]) {
    store.products[productId] = emptyProductDataBag();
  }
  return store.products[productId];
}
function userCatalogToCustomProducts(catalog) {
  return getActiveCatalog({ v: TENANT_STORE_VERSION, catalog, products: {}, meta: {} }).filter((p) => p.source === "user").map((p) => ({
    suffix: p.brandSuffix,
    brandColor: p.brandColor
  }));
}

// src/product-framework/tenant-products/migrate.ts
function deleteTenantProductPermanently(productId) {
  const store = loadTenantStore();
  const record = store.catalog.find((p) => p.id === productId);
  if (!record) return;
  record.deletedAt = (/* @__PURE__ */ new Date()).toISOString();
  delete store.products[productId];
  if (typeof window !== "undefined") {
    const prefix = `${EXXAT_STORAGE_PREFIX}${record.slug}:`;
    const toRemove = [];
    try {
      for (let i = 0; i < window.localStorage.length; i++) {
        const key = window.localStorage.key(i);
        if (key?.startsWith(prefix)) toRemove.push(key);
      }
      for (const key of toRemove) window.localStorage.removeItem(key);
    } catch {
    }
  }
  store.catalog = store.catalog.filter((p) => p.id !== productId);
  store.legacyCustomIndexMap = store.legacyCustomIndexMap?.filter((id) => id !== productId);
  saveTenantStore(store);
}

// src/product-framework/tenant-products/catalog.ts
function listTenantProducts() {
  return getActiveCatalog(loadTenantStore());
}
function upsertUserTenantProductFromBrand(brand) {
  const store = loadTenantStore();
  const slug = customProductSlugFromSuffix(brand.suffix);
  const existing = getTenantProductBySlug(store, slug);
  const record = existing ? {
    ...existing,
    brandSuffix: brand.suffix.trim(),
    brandColor: brand.brandColor,
    updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
    source: "user"
  } : brandToTenantRecord({ suffix: brand.suffix, brandColor: brand.brandColor });
  const idx = existing ? store.catalog.findIndex((p) => p.id === existing.id) : store.catalog.length;
  if (existing) {
    store.catalog[idx] = record;
  } else {
    store.catalog.push(record);
    ensureProductDataBag(store, record.id);
  }
  saveTenantStore(store);
  registerProductsFromTenantStore();
  const mirror = userCatalogToCustomProducts(store.catalog);
  const index = mirror.findIndex(
    (cp) => cp.suffix.trim() === record.brandSuffix.trim()
  );
  return { index: index >= 0 ? index : mirror.length - 1, record };
}
function registerProductsFromTenantStore() {
  const catalog = listTenantProducts();
  if (catalog.length === 0) return;
  registerProducts(catalog.map(tenantRecordToDefinition));
}
function removeTenantProduct(productId) {
  deleteTenantProductPermanently(productId);
  registerProductsFromTenantStore();
  const store = loadTenantStore();
  return userCatalogToCustomProducts(store.catalog);
}
function syncCustomProductsMirror() {
  return userCatalogToCustomProducts(loadTenantStore().catalog);
}

// src/product-framework/app-store.ts
function isCustomProductPlaceholder(brand) {
  if (!brand?.suffix?.trim() || !brand?.brandColor?.trim()) return true;
  return brand.suffix.trim() === DEFAULT_CUSTOM_PRODUCT_BRAND.suffix && brandColorsEquivalent(brand.brandColor, DEFAULT_CUSTOM_PRODUCT_BRAND.brandColor);
}
function isCustomProductConfigured(brand) {
  if (!brand?.suffix?.trim() || !brand?.brandColor?.trim()) return false;
  return !isCustomProductPlaceholder(brand);
}
function isListedCustomProduct(brand) {
  return Boolean(brand?.suffix?.trim() && brand?.brandColor?.trim());
}
function hasConfiguredCustomProducts(products) {
  return (products ?? []).some(isListedCustomProduct);
}
var STORE_VERSION = 10;
var LEGACY_ONE = "exxat-one";
var REMOVED_PRODUCTS = /* @__PURE__ */ new Set(["exxat-assessment"]);
var BUILTIN_DEFAULT_ACCENTS = {
  "exxat-prism": "oklch(60.07% 0.2312 0.68)",
  "exxat-one-schools": "oklch(57.84% 0.1560 279.93)",
  "exxat-one-sites": "oklch(57.84% 0.1560 279.93)"
};
function migrateAppStore(persistedState, version) {
  if (!persistedState || typeof persistedState !== "object") {
    return persistedState;
  }
  const draft = { ...persistedState };
  if (version < 1) {
    if (draft.product === LEGACY_ONE) {
      draft.product = "exxat-one-schools";
    }
    if (draft.productBrandColors && typeof draft.productBrandColors === "object") {
      const colors = { ...draft.productBrandColors };
      if (LEGACY_ONE in colors) {
        colors["exxat-one-schools"] = colors[LEGACY_ONE];
        delete colors[LEGACY_ONE];
      }
      draft.productBrandColors = colors;
    }
    if (Array.isArray(draft.hiddenProductIds)) {
      draft.hiddenProductIds = draft.hiddenProductIds.map(
        (id) => id === LEGACY_ONE ? "exxat-one-schools" : id
      );
    }
  }
  if (version < 2) {
    if (typeof draft.product === "string" && REMOVED_PRODUCTS.has(draft.product)) {
      draft.product = "exxat-prism";
    }
    if (draft.productBrandColors && typeof draft.productBrandColors === "object") {
      const colors = { ...draft.productBrandColors };
      for (const removed of REMOVED_PRODUCTS) {
        delete colors[removed];
      }
      draft.productBrandColors = colors;
    }
    if (Array.isArray(draft.hiddenProductIds)) {
      draft.hiddenProductIds = draft.hiddenProductIds.filter(
        (id) => !REMOVED_PRODUCTS.has(id)
      );
    }
  }
  if (version < 3) {
    if (draft.productBrandColors && typeof draft.productBrandColors === "object") {
      const colors = { ...draft.productBrandColors };
      for (const [id, color] of Object.entries(colors)) {
        const def = BUILTIN_DEFAULT_ACCENTS[id];
        if (def && brandColorsEquivalent(color, def)) {
          delete colors[id];
        }
      }
      draft.productBrandColors = colors;
    }
  }
  if (version < 4) {
    const brand = draft.customProductBrand;
    if (brand && !isCustomProductConfigured(brand)) {
      draft.customProductBrand = null;
    }
    if (draft.product === "exxat-custom" && !isCustomProductConfigured(brand)) {
      draft.product = "exxat-prism";
    }
    if (Array.isArray(draft.hiddenProductIds)) {
      draft.hiddenProductIds = draft.hiddenProductIds.filter((id) => id !== "exxat-custom");
    }
  }
  if (version < 5) {
    const legacy = draft.customProductBrand;
    if (legacy && isCustomProductConfigured(legacy)) {
      draft.customProducts = [legacy];
      draft.activeCustomIndex = 0;
    } else {
      draft.customProducts = [];
      draft.activeCustomIndex = 0;
    }
    delete draft.customProductBrand;
    if (draft.product === "exxat-custom" && !hasConfiguredCustomProducts(draft.customProducts)) {
      draft.product = "exxat-prism";
    }
  }
  if (version < 6) {
    if (Array.isArray(draft.customProducts)) {
      draft.customProducts = draft.customProducts.map((entry) => ({
        suffix: entry.suffix,
        brandColor: normalizeBrandAccentColor(entry.brandColor)
      }));
    }
    if (draft.productBrandColors && typeof draft.productBrandColors === "object") {
      const colors = { ...draft.productBrandColors };
      for (const [id, color] of Object.entries(colors)) {
        colors[id] = normalizeBrandAccentColor(color);
      }
      draft.productBrandColors = colors;
    }
  }
  if (version < 7) {
    if (draft.productBrandColors && typeof draft.productBrandColors === "object") {
      const colors = { ...draft.productBrandColors };
      delete colors["exxat-custom"];
      draft.productBrandColors = colors;
    }
  }
  if (version < 8) {
    if (!Array.isArray(draft.hiddenProducts)) {
      const legacy = Array.isArray(draft.hiddenProductIds) ? draft.hiddenProductIds : [];
      draft.hiddenProducts = legacy.map((product) => ({ product }));
    }
    delete draft.hiddenProductIds;
    if (draft.startupProduct === void 0) {
      draft.startupProduct = null;
    }
  }
  if (version < 9) {
    if (draft.productBrandColors && typeof draft.productBrandColors === "object") {
      const colors = { ...draft.productBrandColors };
      for (const [productId, color] of Object.entries(colors)) {
        if (!color || !BUILTIN_DEFAULT_ACCENTS[productId]) continue;
        let crossMatch = false;
        for (const [otherId, otherDefault] of Object.entries(BUILTIN_DEFAULT_ACCENTS)) {
          if (otherId === productId) continue;
          if (brandColorsEquivalent(color, otherDefault)) {
            crossMatch = true;
            break;
          }
        }
        if (crossMatch) {
          delete colors[productId];
        }
      }
      draft.productBrandColors = colors;
    }
  }
  return draft;
}
var useAppStore = create()(
  persist(
    (set) => ({
      product: "exxat-prism",
      setProduct: (product) => set({ product }),
      customProducts: [],
      activeCustomIndex: 0,
      addCustomProduct: (brand) => {
        const normalized = {
          suffix: brand.suffix.trim(),
          brandColor: normalizeBrandAccentColor(brand.brandColor)
        };
        let nextIndex = 0;
        if (typeof window !== "undefined") {
          const { index } = upsertUserTenantProductFromBrand(normalized);
          const mirror = syncCustomProductsMirror();
          nextIndex = index;
          set((state) => {
            const productBrandColors = { ...state.productBrandColors };
            delete productBrandColors["exxat-custom"];
            const customProducts = mirror.length > 0 ? mirror : [...state.customProducts, normalized];
            const activeCustomIndex = mirror.length > 0 ? index : customProducts.length - 1;
            return {
              customProducts,
              activeCustomIndex,
              productBrandColors
            };
          });
          return nextIndex;
        }
        set((state) => {
          const customProducts = [...state.customProducts, normalized];
          nextIndex = customProducts.length - 1;
          const productBrandColors = { ...state.productBrandColors };
          delete productBrandColors["exxat-custom"];
          return { customProducts, activeCustomIndex: nextIndex, productBrandColors };
        });
        return nextIndex;
      },
      updateCustomProduct: (index, brand) => {
        if (typeof window !== "undefined" && index >= 0) {
          upsertUserTenantProductFromBrand({
            suffix: brand.suffix.trim(),
            brandColor: normalizeBrandAccentColor(brand.brandColor)
          });
          const mirror = syncCustomProductsMirror();
          set((state) => {
            if (index >= state.customProducts.length) return state;
            const productBrandColors = { ...state.productBrandColors };
            delete productBrandColors["exxat-custom"];
            return { customProducts: mirror, productBrandColors };
          });
          return;
        }
        set((state) => {
          if (index < 0 || index >= state.customProducts.length) return state;
          const customProducts = [...state.customProducts];
          customProducts[index] = {
            suffix: brand.suffix.trim(),
            brandColor: normalizeBrandAccentColor(brand.brandColor)
          };
          const productBrandColors = { ...state.productBrandColors };
          delete productBrandColors["exxat-custom"];
          return { customProducts, productBrandColors };
        });
      },
      removeCustomProduct: (index) => set((state) => {
        if (index < 0 || index >= state.customProducts.length) return state;
        let customProducts = state.customProducts.filter((_, i) => i !== index);
        if (typeof window !== "undefined") {
          const brand = state.customProducts[index];
          if (brand?.suffix?.trim()) {
            const tenantStore = loadTenantStore();
            const record = getTenantProductBySlug(
              tenantStore,
              customProductSlugFromSuffix(brand.suffix)
            );
            if (record) {
              customProducts = removeTenantProduct(record.id);
            }
          }
        }
        let activeCustomIndex = state.activeCustomIndex;
        if (customProducts.length === 0) {
          activeCustomIndex = 0;
        } else if (activeCustomIndex >= customProducts.length) {
          activeCustomIndex = customProducts.length - 1;
        } else if (index < activeCustomIndex) {
          activeCustomIndex -= 1;
        }
        return {
          customProducts,
          activeCustomIndex,
          startupProduct: adjustProductRefAfterCustomRemoval(state.startupProduct, index),
          hiddenProducts: adjustHiddenProductsAfterCustomRemoval(
            state.hiddenProducts,
            index
          )
        };
      }),
      setActiveCustomIndex: (activeCustomIndex) => set({ activeCustomIndex }),
      setCustomProducts: (customProducts) => set({ customProducts }),
      productBrandColors: {},
      setProductBrandColor: (product, color) => set((state) => {
        if (product === "exxat-custom") return state;
        const next = { ...state.productBrandColors };
        if (color && color.trim()) {
          next[product] = normalizeBrandAccentColor(color);
        } else {
          delete next[product];
        }
        return { productBrandColors: next };
      }),
      productSwitching: false,
      setProductSwitching: (productSwitching) => set({ productSwitching }),
      hiddenProducts: [],
      hideProduct: (ref) => set((state) => ({
        hiddenProducts: state.hiddenProducts.some((entry) => productRefsEqual(entry, ref)) ? state.hiddenProducts : [...state.hiddenProducts, ref]
      })),
      showProduct: (ref) => set((state) => ({
        hiddenProducts: state.hiddenProducts.filter((entry) => !productRefsEqual(entry, ref))
      })),
      startupProduct: null,
      setStartupProduct: (startupProduct) => set({ startupProduct })
    }),
    {
      name: "exxat-app",
      skipHydration: true,
      version: STORE_VERSION,
      migrate: migrateAppStore
    }
  )
);

// src/hooks/use-persist-hydrated.ts
import * as React2 from "react";
function usePersistHydrated() {
  React2.useEffect(() => {
    if (!useAppStore.persist.hasHydrated()) {
      void useAppStore.persist.rehydrate();
    }
  }, []);
  return React2.useSyncExternalStore(
    useAppStore.persist.onFinishHydration,
    () => useAppStore.persist.hasHydrated(),
    () => false
  );
}

// src/components/shell/product-root-gate.tsx
import { Fragment, jsx } from "react/jsx-runtime";
function ProductRootGate({
  loadingFallback = null,
  fallbackPath = "/prism/dashboard"
} = {}) {
  const { productRootSegment = "" } = useParams();
  const customProducts = useAppStore((s) => s.customProducts);
  const hydrated = usePersistHydrated();
  const resolved = resolveProductFromPath(`/${productRootSegment}`, customProducts);
  if (resolved) {
    return /* @__PURE__ */ jsx(Outlet, {});
  }
  if (!hydrated) {
    return /* @__PURE__ */ jsx(Fragment, { children: loadingFallback });
  }
  return /* @__PURE__ */ jsx(Navigate, { to: fallbackPath, replace: true });
}
export {
  ProductRootGate
};
//# sourceMappingURL=product-root-gate.js.map