@nswds/app 1.107.1 → 1.108.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ import * as PopoverPrimitive from '@radix-ui/react-popover';
37
37
  import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
38
38
  import * as SelectPrimitive from '@radix-ui/react-select';
39
39
  import { useCopyToClipboard } from '@uidotdev/usehooks';
40
- import { Toaster as Toaster$1, toast } from 'sonner';
40
+ import { toast, Toaster as Toaster$1 } from 'sonner';
41
41
  import * as LabelPrimitive from '@radix-ui/react-label';
42
42
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
43
43
  import * as TabsPrimitives from '@radix-ui/react-tabs';
@@ -14918,6 +14918,1129 @@ function ColorCard({ name, token, hex: hex2, rgb: rgb2, hsl, oklch: oklch2, form
14918
14918
  ] })
14919
14919
  ] }) });
14920
14920
  }
14921
+ var APPROVED_TONES = [200, 400, 600, 800];
14922
+ var DEFAULT_VISIBLE_FORMATS = ["hex", "rgb", "hsl", "oklch"];
14923
+ var DEFAULT_PRIMARY_FAMILY_BY_THEME = {
14924
+ brand: "blue",
14925
+ aboriginal: "blue"
14926
+ };
14927
+ var DEFAULT_ACCENT_FAMILY_BY_THEME = {
14928
+ brand: "red",
14929
+ aboriginal: "red"
14930
+ };
14931
+ var DEFAULT_BACKGROUND_TONE = 800;
14932
+ function ColorPairingToolLoading() {
14933
+ return /* @__PURE__ */ jsx(
14934
+ "section",
14935
+ {
14936
+ "aria-busy": "true",
14937
+ "aria-label": "Loading colour pairing tool",
14938
+ className: "overflow-hidden rounded-sm bg-white p-6",
14939
+ children: /* @__PURE__ */ jsx("div", { className: "animate-pulse space-y-6", children: /* @__PURE__ */ jsxs("div", { className: "grid gap-6 xl:grid-cols-[260px_minmax(0,1fr)] xl:gap-x-6", children: [
14940
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
14941
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-20 rounded bg-grey-200" }),
14942
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-2", children: [1, 2, 3, 4].map((item) => /* @__PURE__ */ jsx("div", { className: "h-12 rounded bg-grey-200" }, item)) }),
14943
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: [1, 2, 3].map((item) => /* @__PURE__ */ jsx("div", { className: "h-14 rounded bg-grey-200" }, item)) })
14944
+ ] }),
14945
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
14946
+ /* @__PURE__ */ jsx("div", { className: "h-64 rounded bg-grey-200" }),
14947
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-3", children: [1, 2, 3].map((item) => /* @__PURE__ */ jsx("div", { className: "h-8 w-28 rounded bg-grey-200" }, item)) }),
14948
+ /* @__PURE__ */ jsx("div", { className: "flex gap-3 overflow-hidden", children: [1, 2, 3].map((item) => /* @__PURE__ */ jsx("div", { className: "h-32 w-40 rounded bg-grey-200" }, item)) })
14949
+ ] })
14950
+ ] }) })
14951
+ }
14952
+ );
14953
+ }
14954
+ function extractTone(token) {
14955
+ const match = token.match(/-(\d+)$/);
14956
+ return match ? Number.parseInt(match[1], 10) : null;
14957
+ }
14958
+ function formatFamilyLabel(name, key) {
14959
+ if (key === "grey") return "Grey";
14960
+ return name.replace(/^NSW Aboriginal\s+/i, "").replace(/^NSW\s+/i, "").trim();
14961
+ }
14962
+ function buildPaletteFamilies(themeCategory) {
14963
+ return Object.entries(colors[themeCategory]).flatMap(([familyKey, palette]) => {
14964
+ const familyLabel = formatFamilyLabel(palette.name, familyKey);
14965
+ const shades2 = APPROVED_TONES.flatMap((tone) => {
14966
+ const color2 = palette.colors.find((entry) => extractTone(entry.token) === tone);
14967
+ if (!color2) {
14968
+ return [];
14969
+ }
14970
+ return [
14971
+ {
14972
+ familyKey,
14973
+ familyLabel,
14974
+ hex: color2.hex,
14975
+ hsl: color2.hsl,
14976
+ name: color2.name ?? `${familyLabel} ${tone}`,
14977
+ oklch: color2.oklch,
14978
+ rgb: color2.rgb,
14979
+ token: color2.token,
14980
+ tone
14981
+ }
14982
+ ];
14983
+ });
14984
+ if (shades2.length !== APPROVED_TONES.length) {
14985
+ return [];
14986
+ }
14987
+ return [
14988
+ {
14989
+ key: familyKey,
14990
+ label: familyLabel,
14991
+ shades: shades2,
14992
+ swatch: shades2.find((shade) => shade.tone === 600)?.hex ?? shades2[0]?.hex ?? "transparent"
14993
+ }
14994
+ ];
14995
+ });
14996
+ }
14997
+ var paletteFamiliesByTheme = {
14998
+ brand: buildPaletteFamilies("brand"),
14999
+ aboriginal: buildPaletteFamilies("aboriginal")
15000
+ };
15001
+ function getPaletteFamilies(themeCategory) {
15002
+ return paletteFamiliesByTheme[themeCategory];
15003
+ }
15004
+ function getSelectableFamilies(themeCategory) {
15005
+ return getPaletteFamilies(themeCategory).filter((family) => family.key !== "grey");
15006
+ }
15007
+ function getDefaultPrimaryKey(themeCategory) {
15008
+ const families = getSelectableFamilies(themeCategory);
15009
+ const defaultPrimary = DEFAULT_PRIMARY_FAMILY_BY_THEME[themeCategory];
15010
+ return families.find((family) => family.key === defaultPrimary)?.key ?? families[0]?.key ?? defaultPrimary;
15011
+ }
15012
+ function getFamilyByKey(themeCategory, key) {
15013
+ const families = getPaletteFamilies(themeCategory);
15014
+ return families.find((family) => family.key === key) ?? families[0];
15015
+ }
15016
+ function getDefaultAccentKey(themeCategory, primaryKey) {
15017
+ const families = getSelectableFamilies(themeCategory);
15018
+ const preferredAccent = families.find(
15019
+ (family) => family.key !== primaryKey && family.key === DEFAULT_ACCENT_FAMILY_BY_THEME[themeCategory]
15020
+ );
15021
+ if (preferredAccent) {
15022
+ return preferredAccent.key;
15023
+ }
15024
+ return families.find((family) => family.key !== primaryKey)?.key ?? DEFAULT_ACCENT_FAMILY_BY_THEME[themeCategory];
15025
+ }
15026
+ function getShadeForTone(family, tone) {
15027
+ return family.shades.find((shade) => shade.tone === tone) ?? family.shades[0];
15028
+ }
15029
+ function getBackgroundRole(themeCategory, token, primaryKey, accentKey) {
15030
+ if (!token) {
15031
+ return "primary";
15032
+ }
15033
+ const primaryFamily = getFamilyByKey(themeCategory, primaryKey);
15034
+ const accentFamily = getFamilyByKey(themeCategory, accentKey);
15035
+ const greyFamily = getFamilyByKey(themeCategory, "grey");
15036
+ if (greyFamily.shades.some((shade) => shade.token === token)) {
15037
+ return "grey";
15038
+ }
15039
+ if (accentFamily.shades.some((shade) => shade.token === token)) {
15040
+ return "accent";
15041
+ }
15042
+ if (primaryFamily.shades.some((shade) => shade.token === token)) {
15043
+ return "primary";
15044
+ }
15045
+ return "primary";
15046
+ }
15047
+ function resolveBackgroundToken(themeCategory, primaryKey, accentKey, preferredToken, previousPrimaryKey = primaryKey, previousAccentKey = accentKey) {
15048
+ const primaryFamily = getFamilyByKey(themeCategory, primaryKey);
15049
+ const accentFamily = getFamilyByKey(themeCategory, accentKey);
15050
+ const greyFamily = getFamilyByKey(themeCategory, "grey");
15051
+ const backgroundOptions = [...primaryFamily.shades, ...accentFamily.shades, ...greyFamily.shades];
15052
+ if (preferredToken && backgroundOptions.some((shade) => shade.token === preferredToken)) {
15053
+ return preferredToken;
15054
+ }
15055
+ const preferredTone = extractTone(preferredToken ?? "");
15056
+ if (preferredTone !== null && APPROVED_TONES.includes(preferredTone)) {
15057
+ const backgroundRole = getBackgroundRole(
15058
+ themeCategory,
15059
+ preferredToken,
15060
+ previousPrimaryKey,
15061
+ previousAccentKey
15062
+ );
15063
+ if (backgroundRole === "grey") {
15064
+ return getShadeForTone(greyFamily, preferredTone).token;
15065
+ }
15066
+ if (backgroundRole === "accent") {
15067
+ return getShadeForTone(accentFamily, preferredTone).token;
15068
+ }
15069
+ return getShadeForTone(primaryFamily, preferredTone).token;
15070
+ }
15071
+ return getShadeForTone(primaryFamily, DEFAULT_BACKGROUND_TONE).token;
15072
+ }
15073
+ function getContrastRatio(backgroundHex, foregroundHex) {
15074
+ return culori.wcagContrast(backgroundHex, foregroundHex) ?? 0;
15075
+ }
15076
+ function getContrastLevel(contrastRatio) {
15077
+ if (contrastRatio >= 7) return "AAA";
15078
+ if (contrastRatio >= 4.5) return "AAA large";
15079
+ return "Fail";
15080
+ }
15081
+ function getContrastTone(contrastRatio) {
15082
+ if (contrastRatio >= 7) return "success";
15083
+ if (contrastRatio >= 4.5) return "warning";
15084
+ return "danger";
15085
+ }
15086
+ function getPreviewHeroRatingLabel(contrastRatio) {
15087
+ if (contrastRatio >= 7) return "AAA";
15088
+ if (contrastRatio >= 4.5) return "AAA large";
15089
+ return "Fail";
15090
+ }
15091
+ function getPreviewHeroStatusLabel(contrastRatio) {
15092
+ if (contrastRatio >= 7) return "Pass";
15093
+ if (contrastRatio >= 4.5) return "Large text only";
15094
+ return "Fail";
15095
+ }
15096
+ function getCompliancePills(contrastRatio) {
15097
+ const aaaNormalPass = contrastRatio >= 7;
15098
+ const aaaLargePass = contrastRatio >= 4.5;
15099
+ return [
15100
+ {
15101
+ label: aaaNormalPass ? "AAA normal" : "AAA normal fail",
15102
+ tone: aaaNormalPass ? "success" : "danger"
15103
+ },
15104
+ {
15105
+ label: aaaLargePass ? "AAA large" : "AAA large fail",
15106
+ tone: aaaLargePass ? "success" : "danger"
15107
+ }
15108
+ ];
15109
+ }
15110
+ function getShadeReadability(shade) {
15111
+ return Math.max(getContrastRatio(shade.hex, "#ffffff"), getContrastRatio(shade.hex, "#000000"));
15112
+ }
15113
+ function buildForegroundCandidates(themeCategory, primaryFamily, accentFamily) {
15114
+ const seen = /* @__PURE__ */ new Set();
15115
+ const candidates = [];
15116
+ const pushCandidate = (candidate) => {
15117
+ if (seen.has(candidate.hex)) {
15118
+ return;
15119
+ }
15120
+ seen.add(candidate.hex);
15121
+ candidates.push(candidate);
15122
+ };
15123
+ for (const shade of primaryFamily.shades) {
15124
+ pushCandidate({
15125
+ familyKey: primaryFamily.key,
15126
+ familyLabel: primaryFamily.label,
15127
+ hex: shade.hex,
15128
+ hsl: shade.hsl,
15129
+ id: shade.token,
15130
+ name: shade.name,
15131
+ oklch: shade.oklch,
15132
+ rgb: shade.rgb,
15133
+ token: shade.token,
15134
+ tone: shade.tone
15135
+ });
15136
+ }
15137
+ for (const shade of accentFamily.shades) {
15138
+ pushCandidate({
15139
+ familyKey: accentFamily.key,
15140
+ familyLabel: accentFamily.label,
15141
+ hex: shade.hex,
15142
+ hsl: shade.hsl,
15143
+ id: shade.token,
15144
+ name: shade.name,
15145
+ oklch: shade.oklch,
15146
+ rgb: shade.rgb,
15147
+ token: shade.token,
15148
+ tone: shade.tone
15149
+ });
15150
+ }
15151
+ for (const shade of getFamilyByKey(themeCategory, "grey").shades) {
15152
+ pushCandidate({
15153
+ familyKey: "grey",
15154
+ familyLabel: "Grey",
15155
+ hex: shade.hex,
15156
+ hsl: shade.hsl,
15157
+ id: shade.token,
15158
+ name: shade.name,
15159
+ oklch: shade.oklch,
15160
+ rgb: shade.rgb,
15161
+ token: shade.token,
15162
+ tone: shade.tone
15163
+ });
15164
+ }
15165
+ pushCandidate({
15166
+ familyKey: "white",
15167
+ familyLabel: "White",
15168
+ hex: "#ffffff",
15169
+ hsl: "hsl(0, 0%, 100%)",
15170
+ id: "white",
15171
+ name: "White",
15172
+ oklch: "oklch(1 0 0)",
15173
+ rgb: "rgb(255, 255, 255)",
15174
+ token: "white",
15175
+ tone: 0
15176
+ });
15177
+ return candidates;
15178
+ }
15179
+ function scoreForegroundCandidates(themeCategory, background, primaryFamily, accentFamily) {
15180
+ return buildForegroundCandidates(themeCategory, primaryFamily, accentFamily).filter((candidate) => candidate.hex !== background.hex).map((candidate) => ({
15181
+ ...candidate,
15182
+ contrastRatio: getContrastRatio(background.hex, candidate.hex)
15183
+ }));
15184
+ }
15185
+ function getRecommendedCandidate(themeCategory, background, primaryFamily, accentFamily) {
15186
+ const scored = scoreForegroundCandidates(themeCategory, background, primaryFamily, accentFamily);
15187
+ const aaaCandidates = scored.filter((candidate) => candidate.contrastRatio >= 7).sort((left, right) => {
15188
+ const leftScore = left.contrastRatio + (left.familyKey === primaryFamily.key ? 2 : 0);
15189
+ const rightScore = right.contrastRatio + (right.familyKey === primaryFamily.key ? 2 : 0);
15190
+ return rightScore - leftScore;
15191
+ });
15192
+ if (aaaCandidates[0]) {
15193
+ return aaaCandidates[0];
15194
+ }
15195
+ return null;
15196
+ }
15197
+ function getAccessibleForegroundOptions(themeCategory, background, primaryFamily, accentFamily) {
15198
+ return scoreForegroundCandidates(themeCategory, background, primaryFamily, accentFamily).filter((candidate) => candidate.contrastRatio >= 4.5).sort((left, right) => right.contrastRatio - left.contrastRatio);
15199
+ }
15200
+ function getPreviewAnnouncement(background, foreground) {
15201
+ if (!foreground) {
15202
+ return `${background.token} selected. No accessible foreground options meeting 4.5 to 1 are available.`;
15203
+ }
15204
+ return `${background.token} paired with ${foreground.token}. Contrast ratio ${foreground.contrastRatio.toFixed(2)} to 1.`;
15205
+ }
15206
+ function getWhiteFallbackForeground(background) {
15207
+ return {
15208
+ familyKey: "white",
15209
+ familyLabel: "White",
15210
+ hex: "#ffffff",
15211
+ hsl: "hsl(0, 0%, 100%)",
15212
+ id: "white",
15213
+ name: "White",
15214
+ oklch: "oklch(1 0 0)",
15215
+ rgb: "rgb(255, 255, 255)",
15216
+ token: "white",
15217
+ tone: 0,
15218
+ contrastRatio: getContrastRatio(background.hex, "#ffffff")
15219
+ };
15220
+ }
15221
+ function getColorFormatLabel(format) {
15222
+ return format === "oklch" ? "OKLCH" : format.toUpperCase();
15223
+ }
15224
+ function parseSharedPairParam(value) {
15225
+ if (!value) {
15226
+ return { backgroundToken: null, foregroundId: null };
15227
+ }
15228
+ const separatorIndex = value.indexOf(":");
15229
+ if (separatorIndex === -1) {
15230
+ return { backgroundToken: null, foregroundId: value };
15231
+ }
15232
+ return {
15233
+ backgroundToken: value.slice(0, separatorIndex),
15234
+ foregroundId: value.slice(separatorIndex + 1)
15235
+ };
15236
+ }
15237
+ function getInitialPairingState(searchParams) {
15238
+ const paletteParam = searchParams.get("palette");
15239
+ const primaryParam = searchParams.get("primary");
15240
+ const accentParam = searchParams.get("accent");
15241
+ const backgroundParam = searchParams.get("background");
15242
+ const foregroundParam = searchParams.get("foreground");
15243
+ const pairParam = parseSharedPairParam(searchParams.get("pair"));
15244
+ const themeCategory = paletteParam === "brand" || paletteParam === "aboriginal" ? paletteParam : "brand";
15245
+ const selectableFamilies = getSelectableFamilies(themeCategory);
15246
+ const primaryKey = selectableFamilies.some((family) => family.key === primaryParam) ? primaryParam : getDefaultPrimaryKey(themeCategory);
15247
+ const accentKey = accentParam && accentParam !== primaryKey && selectableFamilies.some((family) => family.key === accentParam) ? accentParam : getDefaultAccentKey(themeCategory, primaryKey);
15248
+ const selectedBackgroundToken = resolveBackgroundToken(
15249
+ themeCategory,
15250
+ primaryKey,
15251
+ accentKey,
15252
+ backgroundParam ?? pairParam.backgroundToken
15253
+ );
15254
+ const primaryFamily = getFamilyByKey(themeCategory, primaryKey);
15255
+ const accentFamily = getFamilyByKey(themeCategory, accentKey);
15256
+ const greyFamily = getFamilyByKey(themeCategory, "grey");
15257
+ const backgroundShade = [...primaryFamily.shades, ...accentFamily.shades, ...greyFamily.shades].find(
15258
+ (shade) => shade.token === selectedBackgroundToken
15259
+ ) ?? getShadeForTone(primaryFamily, DEFAULT_BACKGROUND_TONE);
15260
+ const selectedForegroundId = getAccessibleForegroundOptions(
15261
+ themeCategory,
15262
+ backgroundShade,
15263
+ primaryFamily,
15264
+ accentFamily
15265
+ ).find((candidate) => candidate.id === (foregroundParam ?? pairParam.foregroundId))?.id ?? null;
15266
+ return {
15267
+ accentKey,
15268
+ primaryKey,
15269
+ selectedBackgroundToken,
15270
+ selectedForegroundId,
15271
+ themeCategory
15272
+ };
15273
+ }
15274
+ function SectionLabel({ children }) {
15275
+ return /* @__PURE__ */ jsx("p", { className: "text-[0.8rem] font-semibold tracking-[0.10em] text-grey-800 uppercase", children });
15276
+ }
15277
+ function HeaderPaletteButton({
15278
+ children,
15279
+ disabled = false,
15280
+ isSelected = false,
15281
+ onClick
15282
+ }) {
15283
+ return /* @__PURE__ */ jsx(
15284
+ "button",
15285
+ {
15286
+ type: "button",
15287
+ "aria-pressed": isSelected,
15288
+ disabled,
15289
+ onClick,
15290
+ className: cn(
15291
+ "rounded-md border border-transparent px-3 py-1.5 text-sm font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600",
15292
+ isSelected && "border-grey-400 bg-grey-200 text-grey-800",
15293
+ !isSelected && !disabled && "text-grey-600 hover:text-grey-800",
15294
+ disabled && "cursor-not-allowed text-grey-600/50"
15295
+ ),
15296
+ children
15297
+ }
15298
+ );
15299
+ }
15300
+ function FamilyButton({
15301
+ family,
15302
+ isSelected,
15303
+ onClick
15304
+ }) {
15305
+ return /* @__PURE__ */ jsxs(
15306
+ "button",
15307
+ {
15308
+ type: "button",
15309
+ "aria-pressed": isSelected,
15310
+ onClick,
15311
+ className: cn(
15312
+ "flex flex-col items-center gap-1 rounded-sm border px-1 py-2 transition-all focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600",
15313
+ isSelected ? "border-grey-400 bg-grey-200" : "border-transparent bg-transparent hover:border-grey-400 hover:bg-white"
15314
+ ),
15315
+ children: [
15316
+ /* @__PURE__ */ jsx(
15317
+ "span",
15318
+ {
15319
+ "aria-hidden": "true",
15320
+ className: cn(
15321
+ "size-[1.35rem] rounded-full transition-transform",
15322
+ isSelected && "scale-110"
15323
+ ),
15324
+ style: { backgroundColor: family.swatch }
15325
+ }
15326
+ ),
15327
+ /* @__PURE__ */ jsx(
15328
+ "span",
15329
+ {
15330
+ className: cn(
15331
+ "text-xs leading-none font-medium text-grey-600",
15332
+ isSelected && "text-grey-800"
15333
+ ),
15334
+ children: family.label
15335
+ }
15336
+ )
15337
+ ]
15338
+ }
15339
+ );
15340
+ }
15341
+ function ShadeButton({
15342
+ contrastRatio,
15343
+ isSelected,
15344
+ shade,
15345
+ onClick
15346
+ }) {
15347
+ const contrastTone = getContrastTone(contrastRatio);
15348
+ return /* @__PURE__ */ jsxs(
15349
+ "button",
15350
+ {
15351
+ type: "button",
15352
+ "aria-pressed": isSelected,
15353
+ onClick,
15354
+ className: cn(
15355
+ "flex w-full items-center gap-3 rounded-[0.4rem] border px-3 py-2.5 text-left transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600",
15356
+ isSelected ? "border-primary-600 bg-[#f3f8ff]" : "border-grey-400 bg-white hover:border-primary-600 hover:bg-[#f6f6f6]"
15357
+ ),
15358
+ children: [
15359
+ /* @__PURE__ */ jsx(
15360
+ "span",
15361
+ {
15362
+ "aria-hidden": "true",
15363
+ className: cn(
15364
+ "size-[1.9rem] shrink-0 rounded-sm border border-black/10 transition-transform",
15365
+ isSelected && "scale-105"
15366
+ ),
15367
+ style: { backgroundColor: shade.hex }
15368
+ }
15369
+ ),
15370
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
15371
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-sm font-medium text-grey-800", children: shade.name }),
15372
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-[0.62rem] tracking-normal text-grey-600 normal-case", children: shade.token })
15373
+ ] }),
15374
+ /* @__PURE__ */ jsx(
15375
+ CompliancePill,
15376
+ {
15377
+ className: "shrink-0 font-mono text-[0.62rem] tracking-normal normal-case",
15378
+ label: `${contrastRatio.toFixed(2)}:1`,
15379
+ tone: contrastTone
15380
+ }
15381
+ )
15382
+ ]
15383
+ }
15384
+ );
15385
+ }
15386
+ function CompliancePill({
15387
+ className,
15388
+ label,
15389
+ tone
15390
+ }) {
15391
+ return /* @__PURE__ */ jsx(
15392
+ "span",
15393
+ {
15394
+ className: cn(
15395
+ "rounded-sm border px-2 py-1 text-[0.58rem] font-semibold tracking-[0.08em] uppercase",
15396
+ tone === "success" && "border-success-600/25 bg-success-600/10 text-success-800",
15397
+ tone === "warning" && "border-warning-600/25 bg-warning-600/10 text-warning-800",
15398
+ tone === "danger" && "border-danger-600/25 bg-danger-600/10 text-danger-800",
15399
+ className
15400
+ ),
15401
+ children: label
15402
+ }
15403
+ );
15404
+ }
15405
+ function getForegroundOptionBadge(candidate) {
15406
+ if (candidate.contrastRatio >= 7) {
15407
+ return { label: "AAA", tone: "success" };
15408
+ }
15409
+ return { label: "AAA large", tone: "warning" };
15410
+ }
15411
+ function TokenRow({ color: color2, token, value }) {
15412
+ return /* @__PURE__ */ jsxs("div", { className: "flex max-w-[15rem] items-center gap-2", children: [
15413
+ /* @__PURE__ */ jsx(
15414
+ "span",
15415
+ {
15416
+ "aria-hidden": "true",
15417
+ className: "size-4 shrink-0 rounded-[0.25rem] border border-black/10",
15418
+ style: { backgroundColor: color2 }
15419
+ }
15420
+ ),
15421
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[0.66rem] font-medium text-grey-800", children: token }),
15422
+ /* @__PURE__ */ jsx("span", { className: "flex-1 overflow-x-auto text-[0.6rem] tracking-[0.08em] whitespace-nowrap text-grey-600 [scrollbar-width:thin]", children: value })
15423
+ ] });
15424
+ }
15425
+ function ForegroundOption({
15426
+ backgroundHex,
15427
+ candidate,
15428
+ isSelected,
15429
+ onClick
15430
+ }) {
15431
+ const badge = getForegroundOptionBadge(candidate);
15432
+ return /* @__PURE__ */ jsxs(
15433
+ "button",
15434
+ {
15435
+ type: "button",
15436
+ "aria-pressed": isSelected,
15437
+ onClick,
15438
+ className: cn(
15439
+ "w-[10rem] shrink-0 rounded-[0.4rem] border p-3 text-left transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600",
15440
+ isSelected ? "border-primary-600 bg-[#f3f8ff]" : "border-grey-400 bg-white hover:border-primary-600 hover:bg-[#f6f6f6]"
15441
+ ),
15442
+ children: [
15443
+ /* @__PURE__ */ jsxs(
15444
+ "div",
15445
+ {
15446
+ className: "overflow-hidden rounded-sm border border-black/10",
15447
+ style: {
15448
+ boxShadow: `0 0 0 1px ${candidate.hex === "#ffffff" ? "rgba(255,255,255,0.08)" : "transparent"}`
15449
+ },
15450
+ children: [
15451
+ /* @__PURE__ */ jsx("div", { className: "h-9 w-full", style: { backgroundColor: backgroundHex } }),
15452
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-full", style: { backgroundColor: candidate.hex } })
15453
+ ]
15454
+ }
15455
+ ),
15456
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-sm font-semibold text-grey-800", children: candidate.name }),
15457
+ /* @__PURE__ */ jsx("p", { className: "mt-1 font-mono text-[0.72rem] break-all text-grey-600", children: candidate.token }),
15458
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center justify-between gap-2", children: [
15459
+ /* @__PURE__ */ jsxs("span", { className: "font-mono text-[0.72rem] text-grey-800", children: [
15460
+ candidate.contrastRatio.toFixed(2),
15461
+ ":1"
15462
+ ] }),
15463
+ /* @__PURE__ */ jsx(CompliancePill, { label: badge.label, tone: badge.tone })
15464
+ ] }),
15465
+ /* @__PURE__ */ jsxs("div", { className: "sr-only", children: [
15466
+ "Background ",
15467
+ backgroundHex,
15468
+ ", foreground ",
15469
+ candidate.token,
15470
+ ", contrast",
15471
+ " ",
15472
+ candidate.contrastRatio.toFixed(2),
15473
+ " to 1"
15474
+ ] })
15475
+ ]
15476
+ }
15477
+ );
15478
+ }
15479
+ function ColorPairingToolContent({ visibleFormats }) {
15480
+ const searchParams = useSearchParams();
15481
+ const [initialState] = useState(() => getInitialPairingState(searchParams));
15482
+ const [themeCategory, setThemeCategory] = useState(initialState.themeCategory);
15483
+ const [primaryFamilyKey, setPrimaryFamilyKey] = useState(initialState.primaryKey);
15484
+ const [accentFamilyKey, setAccentFamilyKey] = useState(initialState.accentKey);
15485
+ const [selectedBackgroundToken, setSelectedBackgroundToken] = useState(
15486
+ initialState.selectedBackgroundToken
15487
+ );
15488
+ const [selectedForegroundId, setSelectedForegroundId] = useState(
15489
+ initialState.selectedForegroundId
15490
+ );
15491
+ const [copyFormat, setCopyFormat] = useState(
15492
+ visibleFormats[0] ?? DEFAULT_VISIBLE_FORMATS[0]
15493
+ );
15494
+ const [copiedKey, setCopiedKey] = useState(null);
15495
+ const [, copyToClipboardRaw] = useCopyToClipboard();
15496
+ const copiedKeyTimeoutRef = useRef(null);
15497
+ const selectableFamilies = useMemo(() => getSelectableFamilies(themeCategory), [themeCategory]);
15498
+ const primaryFamily = useMemo(
15499
+ () => getFamilyByKey(themeCategory, primaryFamilyKey),
15500
+ [themeCategory, primaryFamilyKey]
15501
+ );
15502
+ const greyFamily = useMemo(() => getFamilyByKey(themeCategory, "grey"), [themeCategory]);
15503
+ const accentFamily = useMemo(
15504
+ () => getFamilyByKey(themeCategory, accentFamilyKey),
15505
+ [themeCategory, accentFamilyKey]
15506
+ );
15507
+ const backgroundShadeOptions = useMemo(
15508
+ () => [...primaryFamily.shades, ...accentFamily.shades, ...greyFamily.shades],
15509
+ [accentFamily.shades, greyFamily.shades, primaryFamily.shades]
15510
+ );
15511
+ const backgroundShade = useMemo(
15512
+ () => backgroundShadeOptions.find((shade) => shade.token === selectedBackgroundToken) ?? backgroundShadeOptions[0],
15513
+ [backgroundShadeOptions, selectedBackgroundToken]
15514
+ );
15515
+ const accessibleForegroundOptions = useMemo(
15516
+ () => getAccessibleForegroundOptions(themeCategory, backgroundShade, primaryFamily, accentFamily),
15517
+ [accentFamily, backgroundShade, primaryFamily, themeCategory]
15518
+ );
15519
+ const recommendedForeground = useMemo(
15520
+ () => getRecommendedCandidate(themeCategory, backgroundShade, primaryFamily, accentFamily),
15521
+ [accentFamily, backgroundShade, primaryFamily, themeCategory]
15522
+ );
15523
+ const selectedForeground = useMemo(
15524
+ () => accessibleForegroundOptions.find((candidate) => candidate.id === selectedForegroundId) ?? recommendedForeground ?? accessibleForegroundOptions[0] ?? null,
15525
+ [accessibleForegroundOptions, recommendedForeground, selectedForegroundId]
15526
+ );
15527
+ const previewForeground = useMemo(
15528
+ () => selectedForeground ?? getWhiteFallbackForeground(backgroundShade),
15529
+ [backgroundShade, selectedForeground]
15530
+ );
15531
+ const fauxButtonStyle = {
15532
+ "--btn-bg": previewForeground.hex,
15533
+ "--btn-border": previewForeground.hex,
15534
+ "--btn-text": backgroundShade.hex,
15535
+ "--btn-icon": backgroundShade.hex,
15536
+ "--btn-hover-overlay": backgroundShade.hex
15537
+ };
15538
+ const optionCount = useMemo(
15539
+ () => accessibleForegroundOptions.length,
15540
+ [accessibleForegroundOptions]
15541
+ );
15542
+ const familySummary = useMemo(
15543
+ () => [primaryFamily.label, accentFamily.label, greyFamily.label].join(" + ").toLocaleUpperCase("en-AU"),
15544
+ [accentFamily.label, greyFamily.label, primaryFamily.label]
15545
+ );
15546
+ useEffect(() => {
15547
+ return () => {
15548
+ if (copiedKeyTimeoutRef.current) {
15549
+ clearTimeout(copiedKeyTimeoutRef.current);
15550
+ }
15551
+ };
15552
+ }, []);
15553
+ const previewAnnouncement = useMemo(
15554
+ () => selectedForeground ? getPreviewAnnouncement(backgroundShade, selectedForeground) : accessibleForegroundOptions.length > 0 ? `${backgroundShade.token} selected. No AAA normal foreground options are available. White preview contrast ${previewForeground.contrastRatio.toFixed(2)} to 1.` : `${backgroundShade.token} selected. No AAA foreground options are available. White preview contrast ${previewForeground.contrastRatio.toFixed(2)} to 1.`,
15555
+ [
15556
+ accessibleForegroundOptions.length,
15557
+ backgroundShade,
15558
+ previewForeground.contrastRatio,
15559
+ selectedForeground
15560
+ ]
15561
+ );
15562
+ const updateUrlParams = (nextThemeCategory, nextPrimaryKey, nextAccentKey, nextSelectedBackgroundToken, nextSelectedForegroundId) => {
15563
+ const params = new URLSearchParams(window.location.search);
15564
+ params.delete("family");
15565
+ params.delete("pair");
15566
+ params.set("palette", nextThemeCategory);
15567
+ params.set("primary", nextPrimaryKey);
15568
+ params.set("accent", nextAccentKey);
15569
+ params.set("background", nextSelectedBackgroundToken);
15570
+ if (nextSelectedForegroundId) {
15571
+ params.set("foreground", nextSelectedForegroundId);
15572
+ } else {
15573
+ params.delete("foreground");
15574
+ }
15575
+ window.history.replaceState(
15576
+ null,
15577
+ "",
15578
+ `${window.location.pathname}?${params.toString()}${window.location.hash}`
15579
+ );
15580
+ };
15581
+ const handlePrimaryFamilyChange = (nextPrimaryKey) => {
15582
+ const nextAccentKey = accentFamilyKey === nextPrimaryKey ? getDefaultAccentKey(themeCategory, nextPrimaryKey) : accentFamilyKey;
15583
+ const nextBackgroundToken = resolveBackgroundToken(
15584
+ themeCategory,
15585
+ nextPrimaryKey,
15586
+ nextAccentKey,
15587
+ selectedBackgroundToken,
15588
+ primaryFamilyKey,
15589
+ accentFamilyKey
15590
+ );
15591
+ setPrimaryFamilyKey(nextPrimaryKey);
15592
+ setAccentFamilyKey(nextAccentKey);
15593
+ setSelectedBackgroundToken(nextBackgroundToken);
15594
+ setSelectedForegroundId(null);
15595
+ updateUrlParams(themeCategory, nextPrimaryKey, nextAccentKey, nextBackgroundToken, null);
15596
+ };
15597
+ const handleThemeCategoryChange = (nextThemeCategory) => {
15598
+ const nextFamilies = getSelectableFamilies(nextThemeCategory);
15599
+ const nextPrimaryKey = nextFamilies.some((family) => family.key === primaryFamilyKey) ? primaryFamilyKey : getDefaultPrimaryKey(nextThemeCategory);
15600
+ const canKeepAccent = accentFamilyKey !== nextPrimaryKey && nextFamilies.some((family) => family.key === accentFamilyKey);
15601
+ const nextAccentKey = canKeepAccent ? accentFamilyKey : getDefaultAccentKey(nextThemeCategory, nextPrimaryKey);
15602
+ const resolvedAccentKey = nextAccentKey === nextPrimaryKey ? getDefaultAccentKey(nextThemeCategory, nextPrimaryKey) : nextAccentKey;
15603
+ const nextBackgroundToken = resolveBackgroundToken(
15604
+ nextThemeCategory,
15605
+ nextPrimaryKey,
15606
+ resolvedAccentKey,
15607
+ selectedBackgroundToken,
15608
+ primaryFamilyKey,
15609
+ accentFamilyKey
15610
+ );
15611
+ setThemeCategory(nextThemeCategory);
15612
+ setPrimaryFamilyKey(nextPrimaryKey);
15613
+ setAccentFamilyKey(resolvedAccentKey);
15614
+ setSelectedBackgroundToken(nextBackgroundToken);
15615
+ setSelectedForegroundId(null);
15616
+ updateUrlParams(nextThemeCategory, nextPrimaryKey, resolvedAccentKey, nextBackgroundToken, null);
15617
+ };
15618
+ const handleAccentFamilyChange = (nextAccentKey) => {
15619
+ const nextBackgroundToken = resolveBackgroundToken(
15620
+ themeCategory,
15621
+ primaryFamilyKey,
15622
+ nextAccentKey,
15623
+ selectedBackgroundToken,
15624
+ primaryFamilyKey,
15625
+ accentFamilyKey
15626
+ );
15627
+ setSelectedBackgroundToken(nextBackgroundToken);
15628
+ setAccentFamilyKey(nextAccentKey);
15629
+ setSelectedForegroundId(null);
15630
+ updateUrlParams(themeCategory, primaryFamilyKey, nextAccentKey, nextBackgroundToken, null);
15631
+ };
15632
+ const handleBackgroundChange = (nextBackgroundToken) => {
15633
+ setSelectedBackgroundToken(nextBackgroundToken);
15634
+ setSelectedForegroundId(null);
15635
+ updateUrlParams(themeCategory, primaryFamilyKey, accentFamilyKey, nextBackgroundToken, null);
15636
+ };
15637
+ const handleForegroundChange = (nextForegroundId) => {
15638
+ setSelectedForegroundId(nextForegroundId);
15639
+ updateUrlParams(
15640
+ themeCategory,
15641
+ primaryFamilyKey,
15642
+ accentFamilyKey,
15643
+ backgroundShade.token,
15644
+ nextForegroundId
15645
+ );
15646
+ };
15647
+ const handleCopyPairing = () => {
15648
+ copyToClipboardRaw(
15649
+ [
15650
+ `format: ${getColorFormatLabel(resolvedCopyFormat)}`,
15651
+ `foreground: ${previewForeground.token} (${getColorValue(previewForeground, resolvedCopyFormat)})`,
15652
+ `background: ${backgroundShade.token} (${getColorValue(backgroundShade, resolvedCopyFormat)})`,
15653
+ `contrast: ${previewForeground.contrastRatio.toFixed(2)}:1 ${getContrastLevel(previewForeground.contrastRatio)}`
15654
+ ].join("\n")
15655
+ );
15656
+ setCopiedKey("pairing");
15657
+ toast("Colour pairing copied to clipboard", { duration: 2e3 });
15658
+ if (copiedKeyTimeoutRef.current) {
15659
+ clearTimeout(copiedKeyTimeoutRef.current);
15660
+ }
15661
+ copiedKeyTimeoutRef.current = setTimeout(() => {
15662
+ setCopiedKey(null);
15663
+ copiedKeyTimeoutRef.current = null;
15664
+ }, 2e3);
15665
+ };
15666
+ const handleCopyUrl = () => {
15667
+ copyToClipboardRaw(window.location.href);
15668
+ setCopiedKey("share-url");
15669
+ toast("URL copied to clipboard", { duration: 2e3 });
15670
+ if (copiedKeyTimeoutRef.current) {
15671
+ clearTimeout(copiedKeyTimeoutRef.current);
15672
+ }
15673
+ copiedKeyTimeoutRef.current = setTimeout(() => {
15674
+ setCopiedKey(null);
15675
+ copiedKeyTimeoutRef.current = null;
15676
+ }, 2e3);
15677
+ };
15678
+ const selectableAccentFamilies = selectableFamilies.filter(
15679
+ (family) => family.key !== primaryFamily.key
15680
+ );
15681
+ const contrastRatio = previewForeground.contrastRatio;
15682
+ const previewHeroRatingLabel = getPreviewHeroRatingLabel(contrastRatio);
15683
+ const previewHeroStatusLabel = getPreviewHeroStatusLabel(contrastRatio);
15684
+ const contrastTone = getContrastTone(contrastRatio);
15685
+ const resolvedCopyFormat = visibleFormats.includes(copyFormat) ? copyFormat : visibleFormats[0] ?? DEFAULT_VISIBLE_FORMATS[0];
15686
+ return /* @__PURE__ */ jsx("section", { className: "overflow-hidden rounded-sm bg-white text-grey-800", children: /* @__PURE__ */ jsxs("div", { className: "grid min-h-[46rem] xl:grid-cols-[260px_minmax(0,1fr)] xl:gap-x-6", children: [
15687
+ /* @__PURE__ */ jsx("aside", { className: "border-b border-grey-200 py-5 xl:border-b-0", children: /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
15688
+ /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
15689
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Palette" }),
15690
+ /* @__PURE__ */ jsxs("div", { className: "inline-flex rounded-sm border border-grey-200 bg-white p-1", children: [
15691
+ /* @__PURE__ */ jsx(
15692
+ HeaderPaletteButton,
15693
+ {
15694
+ isSelected: themeCategory === "brand",
15695
+ onClick: () => handleThemeCategoryChange("brand"),
15696
+ children: "Brand"
15697
+ }
15698
+ ),
15699
+ /* @__PURE__ */ jsx(
15700
+ HeaderPaletteButton,
15701
+ {
15702
+ isSelected: themeCategory === "aboriginal",
15703
+ onClick: () => handleThemeCategoryChange("aboriginal"),
15704
+ children: "Aboriginal"
15705
+ }
15706
+ )
15707
+ ] })
15708
+ ] }),
15709
+ /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
15710
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Background family" }),
15711
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1", children: selectableFamilies.map((family) => /* @__PURE__ */ jsx(
15712
+ FamilyButton,
15713
+ {
15714
+ family,
15715
+ isSelected: family.key === primaryFamily.key,
15716
+ onClick: () => handlePrimaryFamilyChange(family.key)
15717
+ },
15718
+ family.key
15719
+ )) })
15720
+ ] }),
15721
+ /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
15722
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Background shade" }),
15723
+ /* @__PURE__ */ jsx("div", { className: "h-[20.5rem] space-y-1 overflow-y-auto pr-1", children: backgroundShadeOptions.map((shade) => /* @__PURE__ */ jsx(
15724
+ ShadeButton,
15725
+ {
15726
+ shade,
15727
+ contrastRatio: getShadeReadability(shade),
15728
+ isSelected: shade.token === backgroundShade.token,
15729
+ onClick: () => handleBackgroundChange(shade.token)
15730
+ },
15731
+ shade.token
15732
+ )) })
15733
+ ] }),
15734
+ /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
15735
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Accent family" }),
15736
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1", children: selectableAccentFamilies.map((family) => /* @__PURE__ */ jsx(
15737
+ FamilyButton,
15738
+ {
15739
+ family,
15740
+ isSelected: family.key === accentFamily.key,
15741
+ onClick: () => handleAccentFamilyChange(family.key)
15742
+ },
15743
+ family.key
15744
+ )) })
15745
+ ] })
15746
+ ] }) }),
15747
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-col", children: [
15748
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-5 overflow-y-auto py-5 sm:py-6", children: [
15749
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(Button2, { variant: "soft", color: "primary", onClick: handleCopyUrl, className: "mr-1", children: copiedKey === "share-url" ? /* @__PURE__ */ jsxs(Fragment, { children: [
15750
+ /* @__PURE__ */ jsx(Icons.check, { "data-slot": "icon", className: "size-4" }),
15751
+ "Copied URL!"
15752
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
15753
+ /* @__PURE__ */ jsx(Icons.content_copy, { "data-slot": "icon", className: "size-4" }),
15754
+ "Copy URL"
15755
+ ] }) }) }),
15756
+ /* @__PURE__ */ jsx(
15757
+ "article",
15758
+ {
15759
+ className: "overflow-hidden rounded-sm border border-grey-200",
15760
+ style: { backgroundColor: backgroundShade.hex },
15761
+ children: /* @__PURE__ */ jsxs(
15762
+ "div",
15763
+ {
15764
+ className: "flex min-h-[25rem] flex-col justify-between gap-8 px-6 py-6 sm:min-h-[27rem] sm:px-8 sm:py-8",
15765
+ style: { color: previewForeground.hex },
15766
+ children: [
15767
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
15768
+ /* @__PURE__ */ jsxs(
15769
+ "span",
15770
+ {
15771
+ className: "inline-flex items-center gap-2 rounded-full border px-3 py-1 text-[0.72rem] font-semibold tracking-[0.16em] uppercase",
15772
+ style: {
15773
+ backgroundColor: previewForeground.hex,
15774
+ borderColor: previewForeground.hex,
15775
+ color: backgroundShade.hex
15776
+ },
15777
+ children: [
15778
+ /* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: [
15779
+ /* @__PURE__ */ jsx(
15780
+ "path",
15781
+ {
15782
+ d: "M8 1.5a6.5 6.5 0 1 0 0 13h.32a1.68 1.68 0 0 0 1.18-2.87l-.17-.16a1.23 1.23 0 0 1 .87-2.1h1.05A3.75 3.75 0 0 0 15 5.62 4.12 4.12 0 0 0 11.02 1.5H8Z",
15783
+ stroke: "currentColor",
15784
+ strokeWidth: "1.4",
15785
+ strokeLinejoin: "round"
15786
+ }
15787
+ ),
15788
+ /* @__PURE__ */ jsx("circle", { cx: "4.75", cy: "7", r: "0.8", fill: "currentColor" }),
15789
+ /* @__PURE__ */ jsx("circle", { cx: "7.4", cy: "4.8", r: "0.8", fill: "currentColor" }),
15790
+ /* @__PURE__ */ jsx("circle", { cx: "10.1", cy: "4.95", r: "0.8", fill: "currentColor" })
15791
+ ] }),
15792
+ familySummary
15793
+ ]
15794
+ }
15795
+ ),
15796
+ /* @__PURE__ */ jsxs(
15797
+ "span",
15798
+ {
15799
+ className: "inline-flex rounded-full border px-3 py-1 text-[0.72rem] font-semibold tracking-[0.16em] uppercase",
15800
+ style: { borderColor: previewForeground.hex },
15801
+ children: [
15802
+ previewHeroRatingLabel,
15803
+ " ",
15804
+ contrastRatio.toFixed(2),
15805
+ ":1"
15806
+ ]
15807
+ }
15808
+ )
15809
+ ] }),
15810
+ /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-center", children: /* @__PURE__ */ jsxs("div", { className: "max-w-[42rem] space-y-5 pb-12 sm:pb-8", children: [
15811
+ /* @__PURE__ */ jsx("p", { className: "text-[0.82rem] font-semibold tracking-[0.12em] uppercase", children: "NSW Government Digital" }),
15812
+ /* @__PURE__ */ jsx("h3", { className: "text-4xl leading-none font-bold sm:text-5xl", children: "Connecting communities to services that matter." }),
15813
+ /* @__PURE__ */ jsx("p", { className: "max-w-[38rem] text-base leading-7 sm:text-lg sm:leading-8", children: "Use only AAA-recommended combinations across your selected primary, accent, and grey families." }),
15814
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 pt-1", children: [
15815
+ /* @__PURE__ */ jsx(
15816
+ "span",
15817
+ {
15818
+ "aria-hidden": "true",
15819
+ "data-variant": "solid",
15820
+ className: cn(
15821
+ buttonVariants({ variant: "solid", size: "default" }),
15822
+ "pointer-events-none cursor-default px-6 text-[16px] font-[700] select-none sm:px-6 sm:text-[16px] sm:font-[700]"
15823
+ ),
15824
+ style: fauxButtonStyle,
15825
+ children: "Get started"
15826
+ }
15827
+ ),
15828
+ /* @__PURE__ */ jsx(
15829
+ "span",
15830
+ {
15831
+ "data-variant": "outline",
15832
+ className: cn(
15833
+ buttonVariants({ variant: "outline", size: "default" }),
15834
+ "pointer-events-none cursor-default px-6 text-[16px] font-[700] select-none sm:px-6 sm:text-[16px] sm:font-[700]"
15835
+ ),
15836
+ style: fauxButtonStyle,
15837
+ children: "Learn more"
15838
+ }
15839
+ )
15840
+ ] })
15841
+ ] }) }),
15842
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
15843
+ /* @__PURE__ */ jsxs(
15844
+ "span",
15845
+ {
15846
+ className: "inline-flex items-center gap-2 rounded-full border px-4 py-2 text-sm font-semibold",
15847
+ style: previewHeroStatusLabel === "Fail" ? {
15848
+ borderColor: previewForeground.hex,
15849
+ color: previewForeground.hex
15850
+ } : {
15851
+ backgroundColor: previewForeground.hex,
15852
+ borderColor: previewForeground.hex,
15853
+ color: backgroundShade.hex
15854
+ },
15855
+ children: [
15856
+ previewHeroStatusLabel === "Pass" ? /* @__PURE__ */ jsx(
15857
+ "svg",
15858
+ {
15859
+ "aria-hidden": "true",
15860
+ width: "16",
15861
+ height: "16",
15862
+ viewBox: "0 0 16 16",
15863
+ fill: "none",
15864
+ children: /* @__PURE__ */ jsx(
15865
+ "path",
15866
+ {
15867
+ d: "M3.5 8.25 6.5 11.25 12.5 5.25",
15868
+ stroke: "currentColor",
15869
+ strokeWidth: "1.8",
15870
+ strokeLinecap: "round",
15871
+ strokeLinejoin: "round"
15872
+ }
15873
+ )
15874
+ }
15875
+ ) : null,
15876
+ previewHeroStatusLabel === "Fail" ? /* @__PURE__ */ jsx(
15877
+ "svg",
15878
+ {
15879
+ "aria-hidden": "true",
15880
+ width: "16",
15881
+ height: "16",
15882
+ viewBox: "0 0 16 16",
15883
+ fill: "none",
15884
+ children: /* @__PURE__ */ jsx(
15885
+ "path",
15886
+ {
15887
+ d: "M4.5 4.5 11.5 11.5M11.5 4.5 4.5 11.5",
15888
+ stroke: "currentColor",
15889
+ strokeWidth: "1.8",
15890
+ strokeLinecap: "round",
15891
+ strokeLinejoin: "round"
15892
+ }
15893
+ )
15894
+ }
15895
+ ) : null,
15896
+ previewHeroStatusLabel === "Large text only" ? /* @__PURE__ */ jsxs(
15897
+ "svg",
15898
+ {
15899
+ "aria-hidden": "true",
15900
+ width: "16",
15901
+ height: "16",
15902
+ viewBox: "0 0 16 16",
15903
+ fill: "none",
15904
+ children: [
15905
+ /* @__PURE__ */ jsx(
15906
+ "path",
15907
+ {
15908
+ d: "M8 4.25v4.75",
15909
+ stroke: "currentColor",
15910
+ strokeWidth: "1.8",
15911
+ strokeLinecap: "round"
15912
+ }
15913
+ ),
15914
+ /* @__PURE__ */ jsx("circle", { cx: "8", cy: "11.75", r: "1", fill: "currentColor" })
15915
+ ]
15916
+ }
15917
+ ) : null,
15918
+ previewHeroStatusLabel
15919
+ ]
15920
+ }
15921
+ ),
15922
+ /* @__PURE__ */ jsxs(
15923
+ "span",
15924
+ {
15925
+ className: "inline-flex max-w-full rounded-full border px-4 py-2 text-[0.82rem] break-all sm:text-sm",
15926
+ style: { borderColor: previewForeground.hex },
15927
+ children: [
15928
+ backgroundShade.token,
15929
+ " / ",
15930
+ previewForeground.token
15931
+ ]
15932
+ }
15933
+ )
15934
+ ] })
15935
+ ]
15936
+ }
15937
+ )
15938
+ }
15939
+ ),
15940
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5 lg:flex-row lg:items-start lg:justify-between", children: [
15941
+ /* @__PURE__ */ jsxs("div", { children: [
15942
+ /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-2", children: [
15943
+ /* @__PURE__ */ jsx(
15944
+ "span",
15945
+ {
15946
+ className: cn(
15947
+ "text-[2.6rem] leading-none font-extrabold tracking-[-0.06em] tabular-nums",
15948
+ contrastTone === "success" && "text-success-800",
15949
+ contrastTone === "warning" && "text-warning-800",
15950
+ contrastTone === "danger" && "text-danger-800"
15951
+ ),
15952
+ children: contrastRatio.toFixed(2)
15953
+ }
15954
+ ),
15955
+ /* @__PURE__ */ jsx("span", { className: "pb-1 text-sm tracking-[0.08em] text-grey-600 uppercase", children: ":1" })
15956
+ ] }),
15957
+ /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-2", children: getCompliancePills(contrastRatio).map((pill) => /* @__PURE__ */ jsx(CompliancePill, { label: pill.label, tone: pill.tone }, pill.label)) })
15958
+ ] }),
15959
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 lg:items-end", children: [
15960
+ /* @__PURE__ */ jsx(
15961
+ TokenRow,
15962
+ {
15963
+ color: previewForeground.hex,
15964
+ token: previewForeground.token,
15965
+ value: getColorValue(previewForeground, resolvedCopyFormat)
15966
+ }
15967
+ ),
15968
+ /* @__PURE__ */ jsx(
15969
+ TokenRow,
15970
+ {
15971
+ color: backgroundShade.hex,
15972
+ token: backgroundShade.token,
15973
+ value: getColorValue(backgroundShade, resolvedCopyFormat)
15974
+ }
15975
+ ),
15976
+ /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-1 lg:justify-end", children: visibleFormats.map((format) => /* @__PURE__ */ jsx(
15977
+ "button",
15978
+ {
15979
+ type: "button",
15980
+ "aria-pressed": resolvedCopyFormat === format,
15981
+ onClick: () => setCopyFormat(format),
15982
+ className: cn(
15983
+ "rounded-sm border px-2.5 py-1 text-[0.62rem] font-semibold tracking-[0.06em] uppercase transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600",
15984
+ resolvedCopyFormat === format ? "border-grey-400 bg-grey-200 text-grey-800" : "border-grey-200 bg-white text-grey-600 hover:border-grey-400 hover:text-grey-800"
15985
+ ),
15986
+ children: getColorFormatLabel(format)
15987
+ },
15988
+ format
15989
+ )) }),
15990
+ /* @__PURE__ */ jsx(
15991
+ "button",
15992
+ {
15993
+ type: "button",
15994
+ onClick: handleCopyPairing,
15995
+ className: cn(
15996
+ "mt-2 inline-flex items-center gap-2 rounded-sm border px-3 py-1.5 text-[0.68rem] font-semibold tracking-[0.04em] transition-colors",
15997
+ copiedKey === "pairing" ? "border-success-600/35 bg-success-600/10 text-success-800" : "border-grey-200 bg-grey-100 text-grey-600 hover:bg-grey-200 hover:text-grey-800"
15998
+ ),
15999
+ children: copiedKey === "pairing" ? /* @__PURE__ */ jsxs(Fragment, { children: [
16000
+ /* @__PURE__ */ jsx(Icons.check, { "data-slot": "icon", className: "size-4" }),
16001
+ "Copied!"
16002
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
16003
+ /* @__PURE__ */ jsx(Icons.content_copy, { "data-slot": "icon", className: "size-4" }),
16004
+ "Copy pairing"
16005
+ ] })
16006
+ }
16007
+ )
16008
+ ] })
16009
+ ] }),
16010
+ /* @__PURE__ */ jsx("p", { className: "sr-only", role: "status", "aria-live": "polite", children: previewAnnouncement })
16011
+ ] }),
16012
+ /* @__PURE__ */ jsxs("div", { className: "border-t border-grey-200 py-4", children: [
16013
+ /* @__PURE__ */ jsxs("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-2", children: [
16014
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Foreground options" }),
16015
+ /* @__PURE__ */ jsxs("span", { className: "text-[0.6rem] font-semibold tracking-[0.18em] text-grey-600 uppercase", children: [
16016
+ optionCount,
16017
+ " accessible option",
16018
+ optionCount === 1 ? "" : "s"
16019
+ ] })
16020
+ ] }),
16021
+ /* @__PURE__ */ jsx("div", { className: "flex gap-2 overflow-x-auto pb-1", children: accessibleForegroundOptions.length > 0 ? accessibleForegroundOptions.map((candidate) => /* @__PURE__ */ jsx(
16022
+ ForegroundOption,
16023
+ {
16024
+ backgroundHex: backgroundShade.hex,
16025
+ candidate,
16026
+ isSelected: candidate.id === selectedForeground?.id,
16027
+ onClick: () => handleForegroundChange(candidate.id)
16028
+ },
16029
+ candidate.id
16030
+ )) : /* @__PURE__ */ jsx("p", { className: "py-3 text-sm text-grey-600", children: "No accessible foreground options meeting 4.5:1 are available for this background." }) })
16031
+ ] })
16032
+ ] })
16033
+ ] }) });
16034
+ }
16035
+ function ColorPairingTool({
16036
+ visibleFormats = DEFAULT_VISIBLE_FORMATS
16037
+ } = {}) {
16038
+ const normalizedVisibleFormats = [...new Set(visibleFormats)].filter(
16039
+ (format) => DEFAULT_VISIBLE_FORMATS.includes(format)
16040
+ );
16041
+ const resolvedVisibleFormats = normalizedVisibleFormats.length > 0 ? normalizedVisibleFormats : DEFAULT_VISIBLE_FORMATS;
16042
+ return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ColorPairingToolLoading, {}), children: /* @__PURE__ */ jsx(ColorPairingToolContent, { visibleFormats: resolvedVisibleFormats }) });
16043
+ }
14921
16044
  var recommendedBackgroundTones = [50, 100, 200, 400, 600, 800];
14922
16045
  var recommendedForegroundTones = [50, 200, 400, 600, 800];
14923
16046
  var AAA_NORMAL_TEXT_RATIO = 7;
@@ -14935,11 +16058,11 @@ var WHITE_FOREGROUND = {
14935
16058
  familyLabel: "White",
14936
16059
  tone: 0
14937
16060
  };
14938
- function extractTone(token) {
16061
+ function extractTone2(token) {
14939
16062
  const match = token.match(/-(\d+)$/);
14940
16063
  return match ? Number.parseInt(match[1], 10) : 0;
14941
16064
  }
14942
- function formatFamilyLabel(name, key) {
16065
+ function formatFamilyLabel2(name, key) {
14943
16066
  if (key === "grey") return "Grey";
14944
16067
  return name.replace(/^NSW Aboriginal\s+/i, "").replace(/^NSW\s+/i, "").trim();
14945
16068
  }
@@ -14948,13 +16071,13 @@ function toPairingColor(color2, familyKey, familyLabel) {
14948
16071
  ...color2,
14949
16072
  familyKey,
14950
16073
  familyLabel,
14951
- tone: extractTone(color2.token)
16074
+ tone: extractTone2(color2.token)
14952
16075
  };
14953
16076
  }
14954
16077
  function buildPairingCollections() {
14955
16078
  return {
14956
16079
  brand: Object.entries(colors.brand).map(([key, palette]) => {
14957
- const familyLabel = formatFamilyLabel(palette.name, key);
16080
+ const familyLabel = formatFamilyLabel2(palette.name, key);
14958
16081
  return {
14959
16082
  key,
14960
16083
  label: familyLabel,
@@ -14963,7 +16086,7 @@ function buildPairingCollections() {
14963
16086
  };
14964
16087
  }),
14965
16088
  aboriginal: Object.entries(colors.aboriginal).map(([key, palette]) => {
14966
- const familyLabel = formatFamilyLabel(palette.name, key);
16089
+ const familyLabel = formatFamilyLabel2(palette.name, key);
14967
16090
  return {
14968
16091
  key,
14969
16092
  label: familyLabel,
@@ -15239,7 +16362,7 @@ function Heading({
15239
16362
  var AAA_NORMAL_TEXT_THRESHOLD = "7.0:1 for text below the WCAG large-text threshold. Sentence-case body copy should generally stay at 16px+ unless it is microcopy.";
15240
16363
  var AAA_LARGE_TEXT_THRESHOLD = "4.5:1 for WCAG large text: 24px+, or 18.5px+ bold";
15241
16364
  var PREFERRED_BACKGROUND_TONES = [400, 600, 200, 800, 100, 50];
15242
- var DEFAULT_VISIBLE_FORMATS = ["hex", "rgb", "hsl", "oklch"];
16365
+ var DEFAULT_VISIBLE_FORMATS2 = ["hex", "rgb", "hsl", "oklch"];
15243
16366
  var DEFAULT_INITIAL_BACKGROUND_TOKEN = "nsw-blue-800";
15244
16367
  var DEFAULT_INITIAL_PAIR_ID = "nsw-blue-800:nsw-blue-200";
15245
16368
  function getToneFromToken(token) {
@@ -15368,7 +16491,7 @@ function getDefaultBackgroundToken(context) {
15368
16491
  }
15369
16492
  return context.backgrounds[0]?.token ?? "";
15370
16493
  }
15371
- function resolveBackgroundToken(context, preferredToken, preferredTone) {
16494
+ function resolveBackgroundToken2(context, preferredToken, preferredTone) {
15372
16495
  if (preferredToken && context.backgrounds.some((background) => background.token === preferredToken)) {
15373
16496
  return preferredToken;
15374
16497
  }
@@ -15382,7 +16505,7 @@ function resolveBackgroundToken(context, preferredToken, preferredTone) {
15382
16505
  }
15383
16506
  return getDefaultBackgroundToken(context);
15384
16507
  }
15385
- function ColorPairingToolLoading() {
16508
+ function ColorPairingToolLoading2() {
15386
16509
  return /* @__PURE__ */ jsxs("div", { className: "animate-pulse space-y-6", children: [
15387
16510
  /* @__PURE__ */ jsx("div", { className: "h-32 rounded-sm border border-grey-200 bg-grey-50 dark:border-grey-700 dark:bg-grey-900" }),
15388
16511
  /* @__PURE__ */ jsxs("div", { className: "grid gap-6 lg:grid-cols-2", children: [
@@ -15395,7 +16518,7 @@ function ColorPairingToolLoading() {
15395
16518
  ] })
15396
16519
  ] });
15397
16520
  }
15398
- function getInitialPairingState(searchParams) {
16521
+ function getInitialPairingState2(searchParams) {
15399
16522
  const paletteParam = searchParams.get("palette");
15400
16523
  const primaryParam = searchParams.get("primary");
15401
16524
  const accentParam = searchParams.get("accent");
@@ -15411,7 +16534,7 @@ function getInitialPairingState(searchParams) {
15411
16534
  (pair) => pair.id === DEFAULT_INITIAL_PAIR_ID
15412
16535
  ) ? DEFAULT_INITIAL_PAIR_ID : null;
15413
16536
  const pairBackgroundToken = context.recommendedPairs.find((pair) => pair.id === pairParam)?.background.token ?? null;
15414
- const selectedBackgroundToken = resolveBackgroundToken(
16537
+ const selectedBackgroundToken = resolveBackgroundToken2(
15415
16538
  context,
15416
16539
  backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken,
15417
16540
  getToneFromToken(backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken)
@@ -15785,9 +16908,9 @@ function ColorFamilySelector({
15785
16908
  }) })
15786
16909
  ] });
15787
16910
  }
15788
- function ColorPairingToolContent({ visibleFormats }) {
16911
+ function ColorPairingToolContent2({ visibleFormats }) {
15789
16912
  const searchParams = useSearchParams();
15790
- const [initialState] = useState(() => getInitialPairingState(searchParams));
16913
+ const [initialState] = useState(() => getInitialPairingState2(searchParams));
15791
16914
  const [themeCategory, setThemeCategory] = useState(initialState.themeCategory);
15792
16915
  const [primaryFamilyKey, setPrimaryFamilyKey] = useState(initialState.primaryKey);
15793
16916
  const [accentFamilyKey, setAccentFamilyKey] = useState(initialState.accentKey);
@@ -15860,7 +16983,7 @@ function ColorPairingToolContent({ visibleFormats }) {
15860
16983
  };
15861
16984
  const syncSelection = (nextThemeCategory, nextPrimaryKey, nextAccentKey, preferredBackgroundToken, preferredPairId) => {
15862
16985
  const nextContext = getPairingContext(nextThemeCategory, nextPrimaryKey, nextAccentKey);
15863
- const nextSelectedBackgroundToken = resolveBackgroundToken(
16986
+ const nextSelectedBackgroundToken = resolveBackgroundToken2(
15864
16987
  nextContext,
15865
16988
  preferredBackgroundToken,
15866
16989
  getToneFromToken(preferredBackgroundToken)
@@ -16297,11 +17420,11 @@ function ColorPairingToolContent({ visibleFormats }) {
16297
17420
  ] }) })
16298
17421
  ] });
16299
17422
  }
16300
- function ColorPairingTool({
16301
- visibleFormats = DEFAULT_VISIBLE_FORMATS
17423
+ function ColorPairingToolV1({
17424
+ visibleFormats = DEFAULT_VISIBLE_FORMATS2
16302
17425
  } = {}) {
16303
17426
  const normalizedVisibleFormats = [...new Set(visibleFormats)];
16304
- return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ColorPairingToolLoading, {}), children: /* @__PURE__ */ jsx(ColorPairingToolContent, { visibleFormats: normalizedVisibleFormats }) });
17427
+ return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ColorPairingToolLoading2, {}), children: /* @__PURE__ */ jsx(ColorPairingToolContent2, { visibleFormats: normalizedVisibleFormats }) });
16305
17428
  }
16306
17429
  function Text({ className, trim = "normal", size = 2, label = false, ...props }) {
16307
17430
  const textSizeClasses = {
@@ -16372,7 +17495,7 @@ function Code({ className, ...props }) {
16372
17495
  );
16373
17496
  }
16374
17497
  var PREFERRED_BACKGROUND_TONES2 = [400, 600, 200, 800, 100, 50];
16375
- var DEFAULT_VISIBLE_FORMATS2 = ["hex", "rgb", "hsl", "oklch"];
17498
+ var DEFAULT_VISIBLE_FORMATS3 = ["hex", "rgb", "hsl", "oklch"];
16376
17499
  var DEFAULT_INITIAL_BACKGROUND_TOKEN2 = "nsw-blue-800";
16377
17500
  var DEFAULT_INITIAL_PAIR_ID2 = "nsw-blue-800:nsw-blue-200";
16378
17501
  function getToneFromToken2(token) {
@@ -16454,7 +17577,7 @@ function getDefaultBackgroundToken2(context) {
16454
17577
  }
16455
17578
  return context.backgrounds[0]?.token ?? "";
16456
17579
  }
16457
- function resolveBackgroundToken2(context, preferredToken, preferredTone) {
17580
+ function resolveBackgroundToken3(context, preferredToken, preferredTone) {
16458
17581
  if (preferredToken && context.backgrounds.some((background) => background.token === preferredToken)) {
16459
17582
  return preferredToken;
16460
17583
  }
@@ -16468,7 +17591,7 @@ function resolveBackgroundToken2(context, preferredToken, preferredTone) {
16468
17591
  }
16469
17592
  return getDefaultBackgroundToken2(context);
16470
17593
  }
16471
- function getInitialPairingState2(searchParams) {
17594
+ function getInitialPairingState3(searchParams) {
16472
17595
  const paletteParam = searchParams.get("palette");
16473
17596
  const primaryParam = searchParams.get("primary");
16474
17597
  const accentParam = searchParams.get("accent");
@@ -16484,7 +17607,7 @@ function getInitialPairingState2(searchParams) {
16484
17607
  (pair) => pair.id === DEFAULT_INITIAL_PAIR_ID2
16485
17608
  ) ? DEFAULT_INITIAL_PAIR_ID2 : null;
16486
17609
  const pairBackgroundToken = context.recommendedPairs.find((pair) => pair.id === pairParam)?.background.token ?? null;
16487
- const selectedBackgroundToken = resolveBackgroundToken2(
17610
+ const selectedBackgroundToken = resolveBackgroundToken3(
16488
17611
  context,
16489
17612
  backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken,
16490
17613
  getToneFromToken2(backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken)
@@ -16852,7 +17975,7 @@ function RecommendedPairCard({
16852
17975
  }
16853
17976
  function ColorPairingToolV2Content({ visibleFormats }) {
16854
17977
  const searchParams = useSearchParams();
16855
- const [initialState] = useState(() => getInitialPairingState2(searchParams));
17978
+ const [initialState] = useState(() => getInitialPairingState3(searchParams));
16856
17979
  const [themeCategory, setThemeCategory] = useState(initialState.themeCategory);
16857
17980
  const [primaryFamilyKey, setPrimaryFamilyKey] = useState(initialState.primaryKey);
16858
17981
  const [accentFamilyKey, setAccentFamilyKey] = useState(initialState.accentKey);
@@ -16910,7 +18033,7 @@ function ColorPairingToolV2Content({ visibleFormats }) {
16910
18033
  };
16911
18034
  const syncSelection = (nextThemeCategory, nextPrimaryKey, nextAccentKey, preferredBackgroundToken, preferredPairId) => {
16912
18035
  const nextContext = getPairingContext(nextThemeCategory, nextPrimaryKey, nextAccentKey);
16913
- const nextSelectedBackgroundToken = resolveBackgroundToken2(
18036
+ const nextSelectedBackgroundToken = resolveBackgroundToken3(
16914
18037
  nextContext,
16915
18038
  preferredBackgroundToken,
16916
18039
  getToneFromToken2(preferredBackgroundToken)
@@ -17186,7 +18309,7 @@ function ColorPairingToolV2Content({ visibleFormats }) {
17186
18309
  ] });
17187
18310
  }
17188
18311
  function ColorPairingToolV2({
17189
- visibleFormats = DEFAULT_VISIBLE_FORMATS2
18312
+ visibleFormats = DEFAULT_VISIBLE_FORMATS3
17190
18313
  } = {}) {
17191
18314
  const normalizedVisibleFormats = [...new Set(visibleFormats)];
17192
18315
  return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ColorPairingToolV2Loading, {}), children: /* @__PURE__ */ jsx(ColorPairingToolV2Content, { visibleFormats: normalizedVisibleFormats }) });
@@ -17328,10 +18451,9 @@ function useStickyOffset(extraPadding = 0) {
17328
18451
  }, [extraPadding, headerHeight, navigationHeight]);
17329
18452
  }
17330
18453
  var PREFERRED_BACKGROUND_TONES3 = [400, 600, 200, 800, 100, 50];
17331
- var DEFAULT_VISIBLE_FORMATS3 = ["hex", "rgb", "hsl", "oklch"];
18454
+ var DEFAULT_VISIBLE_FORMATS4 = ["hex", "rgb", "hsl", "oklch"];
17332
18455
  var DEFAULT_INITIAL_BACKGROUND_TOKEN3 = "nsw-blue-800";
17333
18456
  var DEFAULT_INITIAL_PAIR_ID3 = "nsw-blue-800:nsw-blue-200";
17334
- var COLOR_PAIRING_TOOL_V3_PATH = "/core/colour/colour-pairing-tool-3";
17335
18457
  var AAA_NORMAL_TEXT_THRESHOLD2 = "7.0:1 for text below the WCAG large-text threshold. Sentence-case body copy should generally stay at 16px+ unless it is microcopy.";
17336
18458
  var AAA_LARGE_TEXT_THRESHOLD2 = "4.5:1 for WCAG large text: 24px+, or 18.5px+ bold";
17337
18459
  var MOBILE_RESULT_SCROLL_QUERY = "(max-width: 1023px)";
@@ -17436,7 +18558,7 @@ function getDefaultBackgroundToken3(context) {
17436
18558
  }
17437
18559
  return context.backgrounds[0]?.token ?? "";
17438
18560
  }
17439
- function resolveBackgroundToken3(context, preferredToken, preferredTone) {
18561
+ function resolveBackgroundToken4(context, preferredToken, preferredTone) {
17440
18562
  if (preferredToken && context.backgrounds.some((background) => background.token === preferredToken)) {
17441
18563
  return preferredToken;
17442
18564
  }
@@ -17450,7 +18572,7 @@ function resolveBackgroundToken3(context, preferredToken, preferredTone) {
17450
18572
  }
17451
18573
  return getDefaultBackgroundToken3(context);
17452
18574
  }
17453
- function getInitialPairingState3(searchParams) {
18575
+ function getInitialPairingState4(searchParams) {
17454
18576
  const paletteParam = searchParams.get("palette");
17455
18577
  const primaryParam = searchParams.get("primary");
17456
18578
  const accentParam = searchParams.get("accent");
@@ -17466,7 +18588,7 @@ function getInitialPairingState3(searchParams) {
17466
18588
  (pair) => pair.id === DEFAULT_INITIAL_PAIR_ID3
17467
18589
  ) ? DEFAULT_INITIAL_PAIR_ID3 : null;
17468
18590
  const pairBackgroundToken = context.recommendedPairs.find((pair) => pair.id === pairParam)?.background.token ?? null;
17469
- const selectedBackgroundToken = resolveBackgroundToken3(
18591
+ const selectedBackgroundToken = resolveBackgroundToken4(
17470
18592
  context,
17471
18593
  backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken,
17472
18594
  getToneFromToken3(backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken)
@@ -18164,7 +19286,7 @@ function TechnicalDetailsPanel({
18164
19286
  }
18165
19287
  function resolveSelectionState(nextThemeCategory, nextPrimaryKey, nextAccentKey, preferredBackgroundToken, preferredPairId) {
18166
19288
  const context = getPairingContext(nextThemeCategory, nextPrimaryKey, nextAccentKey);
18167
- const selectedBackgroundToken = resolveBackgroundToken3(
19289
+ const selectedBackgroundToken = resolveBackgroundToken4(
18168
19290
  context,
18169
19291
  preferredBackgroundToken,
18170
19292
  getToneFromToken3(preferredBackgroundToken)
@@ -18199,9 +19321,10 @@ function ColorPairingToolV3Content({
18199
19321
  onAnalyticsEvent,
18200
19322
  visibleFormats
18201
19323
  }) {
19324
+ const pathname = usePathname();
18202
19325
  const searchParams = useSearchParams();
18203
19326
  const stickyOffset = useStickyOffset(24);
18204
- const [initialState] = useState(() => getInitialPairingState3(searchParams));
19327
+ const [initialState] = useState(() => getInitialPairingState4(searchParams));
18205
19328
  const [themeCategory, setThemeCategory] = useState(initialState.themeCategory);
18206
19329
  const [primaryFamilyKey, setPrimaryFamilyKey] = useState(initialState.primaryKey);
18207
19330
  const [accentFamilyKey, setAccentFamilyKey] = useState(initialState.accentKey);
@@ -18322,8 +19445,16 @@ function ColorPairingToolV3Content({
18322
19445
  params.set("pair", selectedPairId);
18323
19446
  }
18324
19447
  const query = params.toString();
18325
- return `${COLOR_PAIRING_TOOL_V3_PATH}${query ? `?${query}` : ""}`;
18326
- }, [context.accent.key, context.primary.key, shareBackgroundToken, selectedPairId, themeCategory]);
19448
+ const currentPathname = pathname ?? (typeof window !== "undefined" ? window.location.pathname : "/tests/colour/colour-pairing-tool-3");
19449
+ return `${currentPathname}${query ? `?${query}` : ""}`;
19450
+ }, [
19451
+ context.accent.key,
19452
+ context.primary.key,
19453
+ pathname,
19454
+ shareBackgroundToken,
19455
+ selectedPairId,
19456
+ themeCategory
19457
+ ]);
18327
19458
  const activeDrawerStep = COLOR_PAIRING_TOOL_DRAWER_STEPS[drawerStepIndex];
18328
19459
  const isFirstDrawerStep = drawerStepIndex === 0;
18329
19460
  const isLastDrawerStep = drawerStepIndex === COLOR_PAIRING_TOOL_DRAWER_STEPS.length - 1;
@@ -18931,7 +20062,7 @@ function ColorPairingToolV3Content({
18931
20062
  function ColorPairingToolV3({
18932
20063
  onAnalyticsEvent = () => {
18933
20064
  },
18934
- visibleFormats = DEFAULT_VISIBLE_FORMATS3
20065
+ visibleFormats = DEFAULT_VISIBLE_FORMATS4
18935
20066
  } = {}) {
18936
20067
  const normalizedVisibleFormats = [...new Set(visibleFormats)];
18937
20068
  return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ColorPairingToolV3Loading, {}), children: /* @__PURE__ */ jsx(
@@ -18943,10 +20074,9 @@ function ColorPairingToolV3({
18943
20074
  ) });
18944
20075
  }
18945
20076
  var PREFERRED_BACKGROUND_TONES4 = [400, 600, 200, 800, 100, 50];
18946
- var DEFAULT_VISIBLE_FORMATS4 = ["hex", "rgb", "hsl", "oklch"];
20077
+ var DEFAULT_VISIBLE_FORMATS5 = ["hex", "rgb", "hsl", "oklch"];
18947
20078
  var DEFAULT_INITIAL_BACKGROUND_TOKEN4 = "nsw-blue-800";
18948
20079
  var DEFAULT_INITIAL_PAIR_ID4 = "nsw-blue-800:nsw-blue-200";
18949
- var COLOR_PAIRING_TOOL_V4_PATH = "/core/colour/colour-pairing-tool-4";
18950
20080
  var MOBILE_RESULT_SCROLL_QUERY2 = "(max-width: 1023px)";
18951
20081
  var PERSISTENT_DRAWER_MIN_WIDTH_QUERY2 = "(min-width: 1280px)";
18952
20082
  var INITIAL_VISIBLE_ALTERNATIVES = 6;
@@ -19050,7 +20180,7 @@ function getDefaultBackgroundToken4(context) {
19050
20180
  }
19051
20181
  return context.backgrounds[0]?.token ?? "";
19052
20182
  }
19053
- function resolveBackgroundToken4(context, preferredToken, preferredTone) {
20183
+ function resolveBackgroundToken5(context, preferredToken, preferredTone) {
19054
20184
  if (preferredToken && context.backgrounds.some((background) => background.token === preferredToken)) {
19055
20185
  return preferredToken;
19056
20186
  }
@@ -19064,7 +20194,7 @@ function resolveBackgroundToken4(context, preferredToken, preferredTone) {
19064
20194
  }
19065
20195
  return getDefaultBackgroundToken4(context);
19066
20196
  }
19067
- function getInitialPairingState4(searchParams) {
20197
+ function getInitialPairingState5(searchParams) {
19068
20198
  const paletteParam = searchParams.get("palette");
19069
20199
  const primaryParam = searchParams.get("primary");
19070
20200
  const accentParam = searchParams.get("accent");
@@ -19080,7 +20210,7 @@ function getInitialPairingState4(searchParams) {
19080
20210
  (pair) => pair.id === DEFAULT_INITIAL_PAIR_ID4
19081
20211
  ) ? DEFAULT_INITIAL_PAIR_ID4 : null;
19082
20212
  const pairBackgroundToken = context.recommendedPairs.find((pair) => pair.id === pairParam)?.background.token ?? null;
19083
- const selectedBackgroundToken = resolveBackgroundToken4(
20213
+ const selectedBackgroundToken = resolveBackgroundToken5(
19084
20214
  context,
19085
20215
  backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken,
19086
20216
  getToneFromToken4(backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken)
@@ -19637,7 +20767,7 @@ function TechnicalDetailsPanel2({
19637
20767
  }
19638
20768
  function resolveSelectionState2(nextThemeCategory, nextPrimaryKey, nextAccentKey, preferredBackgroundToken, preferredPairId) {
19639
20769
  const context = getPairingContext(nextThemeCategory, nextPrimaryKey, nextAccentKey);
19640
- const selectedBackgroundToken = resolveBackgroundToken4(
20770
+ const selectedBackgroundToken = resolveBackgroundToken5(
19641
20771
  context,
19642
20772
  preferredBackgroundToken,
19643
20773
  getToneFromToken4(preferredBackgroundToken)
@@ -19672,9 +20802,10 @@ function ColorPairingToolV4Content({
19672
20802
  onAnalyticsEvent,
19673
20803
  visibleFormats
19674
20804
  }) {
20805
+ const pathname = usePathname();
19675
20806
  const searchParams = useSearchParams();
19676
20807
  const stickyOffset = useStickyOffset(24);
19677
- const [initialState] = useState(() => getInitialPairingState4(searchParams));
20808
+ const [initialState] = useState(() => getInitialPairingState5(searchParams));
19678
20809
  const [themeCategory, setThemeCategory] = useState(initialState.themeCategory);
19679
20810
  const [primaryFamilyKey, setPrimaryFamilyKey] = useState(initialState.primaryKey);
19680
20811
  const [accentFamilyKey, setAccentFamilyKey] = useState(initialState.accentKey);
@@ -19832,8 +20963,16 @@ function ColorPairingToolV4Content({
19832
20963
  params.set("pair", selectedPairId);
19833
20964
  }
19834
20965
  const query = params.toString();
19835
- return `${COLOR_PAIRING_TOOL_V4_PATH}${query ? `?${query}` : ""}`;
19836
- }, [context.accent.key, context.primary.key, shareBackgroundToken, selectedPairId, themeCategory]);
20966
+ const currentPathname = pathname ?? (typeof window !== "undefined" ? window.location.pathname : "/tests/colour/colour-pairing-tool-4");
20967
+ return `${currentPathname}${query ? `?${query}` : ""}`;
20968
+ }, [
20969
+ context.accent.key,
20970
+ context.primary.key,
20971
+ pathname,
20972
+ shareBackgroundToken,
20973
+ selectedPairId,
20974
+ themeCategory
20975
+ ]);
19837
20976
  const activeDrawerStep = COLOR_PAIRING_TOOL_DRAWER_STEPS2[drawerStepIndex];
19838
20977
  const isFirstDrawerStep = drawerStepIndex === 0;
19839
20978
  const isLastDrawerStep = drawerStepIndex === COLOR_PAIRING_TOOL_DRAWER_STEPS2.length - 1;
@@ -20462,7 +21601,7 @@ function ColorPairingToolV4Content({
20462
21601
  function ColorPairingToolV4({
20463
21602
  onAnalyticsEvent = () => {
20464
21603
  },
20465
- visibleFormats = DEFAULT_VISIBLE_FORMATS4
21604
+ visibleFormats = DEFAULT_VISIBLE_FORMATS5
20466
21605
  } = {}) {
20467
21606
  const normalizedVisibleFormats = [...new Set(visibleFormats)];
20468
21607
  return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ColorPairingToolV4Loading, {}), children: /* @__PURE__ */ jsx(
@@ -20474,10 +21613,9 @@ function ColorPairingToolV4({
20474
21613
  ) });
20475
21614
  }
20476
21615
  var PREFERRED_BACKGROUND_TONES5 = [400, 600, 200, 800, 100, 50];
20477
- var DEFAULT_VISIBLE_FORMATS5 = ["hex", "rgb", "hsl", "oklch"];
21616
+ var DEFAULT_VISIBLE_FORMATS6 = ["hex", "rgb", "hsl", "oklch"];
20478
21617
  var DEFAULT_INITIAL_BACKGROUND_TOKEN5 = "nsw-blue-800";
20479
21618
  var DEFAULT_INITIAL_PAIR_ID5 = "nsw-blue-800:nsw-blue-200";
20480
- var COLOR_PAIRING_TOOL_V5_PATH = "/core/colour/colour-pairing-tool-5";
20481
21619
  var MOBILE_RESULT_SCROLL_QUERY3 = "(max-width: 1023px)";
20482
21620
  var PERSISTENT_DRAWER_MIN_WIDTH_QUERY3 = "(min-width: 1280px)";
20483
21621
  var INITIAL_VISIBLE_ALTERNATIVES2 = 6;
@@ -20512,9 +21650,15 @@ function getFamilySwatchColor5(family, preferredTone = 600) {
20512
21650
  if (exactMatch) {
20513
21651
  return exactMatch.hex;
20514
21652
  }
20515
- const closestMatch = [...family.colors].sort(
20516
- (left, right) => Math.abs(left.tone - preferredTone) - Math.abs(right.tone - preferredTone)
20517
- )[0];
21653
+ let closestMatch = null;
21654
+ let smallestDiff = Number.POSITIVE_INFINITY;
21655
+ for (const color2 of family.colors) {
21656
+ const diff = Math.abs(color2.tone - preferredTone);
21657
+ if (diff < smallestDiff) {
21658
+ smallestDiff = diff;
21659
+ closestMatch = color2;
21660
+ }
21661
+ }
20518
21662
  return closestMatch?.hex ?? "transparent";
20519
21663
  }
20520
21664
  function getFamilySelectorLabel5(family, themeCategory, selectionRole) {
@@ -20581,7 +21725,7 @@ function getDefaultBackgroundToken5(context) {
20581
21725
  }
20582
21726
  return context.backgrounds[0]?.token ?? "";
20583
21727
  }
20584
- function resolveBackgroundToken5(context, preferredToken, preferredTone) {
21728
+ function resolveBackgroundToken6(context, preferredToken, preferredTone) {
20585
21729
  if (preferredToken && context.backgrounds.some((background) => background.token === preferredToken)) {
20586
21730
  return preferredToken;
20587
21731
  }
@@ -20595,7 +21739,7 @@ function resolveBackgroundToken5(context, preferredToken, preferredTone) {
20595
21739
  }
20596
21740
  return getDefaultBackgroundToken5(context);
20597
21741
  }
20598
- function getInitialPairingState5(searchParams) {
21742
+ function getInitialPairingState6(searchParams) {
20599
21743
  const paletteParam = searchParams.get("palette");
20600
21744
  const primaryParam = searchParams.get("primary");
20601
21745
  const accentParam = searchParams.get("accent");
@@ -20611,7 +21755,7 @@ function getInitialPairingState5(searchParams) {
20611
21755
  (pair) => pair.id === DEFAULT_INITIAL_PAIR_ID5
20612
21756
  ) ? DEFAULT_INITIAL_PAIR_ID5 : null;
20613
21757
  const pairBackgroundToken = context.recommendedPairs.find((pair) => pair.id === pairParam)?.background.token ?? null;
20614
- const selectedBackgroundToken = resolveBackgroundToken5(
21758
+ const selectedBackgroundToken = resolveBackgroundToken6(
20615
21759
  context,
20616
21760
  backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken,
20617
21761
  getToneFromToken5(backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken)
@@ -21249,7 +22393,7 @@ function TechnicalDetailsPanel3({
21249
22393
  }
21250
22394
  function resolveSelectionState3(nextThemeCategory, nextPrimaryKey, nextAccentKey, preferredBackgroundToken, preferredPairId) {
21251
22395
  const context = getPairingContext(nextThemeCategory, nextPrimaryKey, nextAccentKey);
21252
- const selectedBackgroundToken = resolveBackgroundToken5(
22396
+ const selectedBackgroundToken = resolveBackgroundToken6(
21253
22397
  context,
21254
22398
  preferredBackgroundToken,
21255
22399
  getToneFromToken5(preferredBackgroundToken)
@@ -21284,9 +22428,10 @@ function ColorPairingToolV5Content({
21284
22428
  onAnalyticsEvent,
21285
22429
  visibleFormats
21286
22430
  }) {
22431
+ const pathname = usePathname();
21287
22432
  const searchParams = useSearchParams();
21288
22433
  const stickyOffset = useStickyOffset(24);
21289
- const [initialState] = useState(() => getInitialPairingState5(searchParams));
22434
+ const [initialState] = useState(() => getInitialPairingState6(searchParams));
21290
22435
  const [themeCategory, setThemeCategory] = useState(initialState.themeCategory);
21291
22436
  const [primaryFamilyKey, setPrimaryFamilyKey] = useState(initialState.primaryKey);
21292
22437
  const [accentFamilyKey, setAccentFamilyKey] = useState(initialState.accentKey);
@@ -21448,8 +22593,16 @@ function ColorPairingToolV5Content({
21448
22593
  params.set("pair", selectedPairId);
21449
22594
  }
21450
22595
  const query = params.toString();
21451
- return `${COLOR_PAIRING_TOOL_V5_PATH}${query ? `?${query}` : ""}`;
21452
- }, [context.accent.key, context.primary.key, shareBackgroundToken, selectedPairId, themeCategory]);
22596
+ const currentPathname = pathname || "/core/colour/colour-pairing-tool-5";
22597
+ return `${currentPathname}${query ? `?${query}` : ""}`;
22598
+ }, [
22599
+ context.accent.key,
22600
+ context.primary.key,
22601
+ pathname,
22602
+ shareBackgroundToken,
22603
+ selectedPairId,
22604
+ themeCategory
22605
+ ]);
21453
22606
  const activeDrawerStep = COLOR_PAIRING_TOOL_DRAWER_STEPS3[drawerStepIndex];
21454
22607
  const isFirstDrawerStep = drawerStepIndex === 0;
21455
22608
  const isLastDrawerStep = drawerStepIndex === COLOR_PAIRING_TOOL_DRAWER_STEPS3.length - 1;
@@ -22079,7 +23232,7 @@ function ColorPairingToolV5Content({
22079
23232
  function ColorPairingToolV5({
22080
23233
  onAnalyticsEvent = () => {
22081
23234
  },
22082
- visibleFormats = DEFAULT_VISIBLE_FORMATS5
23235
+ visibleFormats = DEFAULT_VISIBLE_FORMATS6
22083
23236
  } = {}) {
22084
23237
  const normalizedVisibleFormats = [...new Set(visibleFormats)];
22085
23238
  return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ColorPairingToolV5Loading, {}), children: /* @__PURE__ */ jsx(
@@ -22090,6 +23243,691 @@ function ColorPairingToolV5({
22090
23243
  }
22091
23244
  ) });
22092
23245
  }
23246
+ var DEFAULT_THEME_CATEGORY = "brand";
23247
+ var DEFAULT_PRIMARY_KEY = "blue";
23248
+ var DEFAULT_BACKGROUND_TOKEN = "nsw-blue-800";
23249
+ var PREFERRED_BACKGROUND_TONES6 = [400, 600, 200, 800, 100, 50];
23250
+ function getToneFromToken6(token) {
23251
+ if (!token) return null;
23252
+ const match = token.match(/-(\d+)$/);
23253
+ return match ? Number.parseInt(match[1], 10) : null;
23254
+ }
23255
+ function getFamilySwatchColor6(family, preferredTone = 600) {
23256
+ const exactMatch = family.colors.find((color2) => color2.tone === preferredTone);
23257
+ if (exactMatch) {
23258
+ return exactMatch.hex;
23259
+ }
23260
+ let closestMatch = null;
23261
+ let smallestDiff = Number.POSITIVE_INFINITY;
23262
+ for (const color2 of family.colors) {
23263
+ const diff = Math.abs(color2.tone - preferredTone);
23264
+ if (diff < smallestDiff) {
23265
+ smallestDiff = diff;
23266
+ closestMatch = color2;
23267
+ }
23268
+ }
23269
+ return closestMatch?.hex ?? "transparent";
23270
+ }
23271
+ function getFamilySelectorLabel6(family, themeCategory, selectionRole) {
23272
+ if (themeCategory !== "aboriginal") {
23273
+ return family.label;
23274
+ }
23275
+ const preferredTone = selectionRole === "primary colour" ? 800 : 600;
23276
+ return family.colors.find((color2) => color2.tone === preferredTone)?.name ?? family.label;
23277
+ }
23278
+ function getPairingColorDisplayName6(color2) {
23279
+ return color2.name ?? `${color2.familyLabel} ${color2.tone}`;
23280
+ }
23281
+ function isWhiteForegroundPair6(pair) {
23282
+ return pair.foreground.token === "white";
23283
+ }
23284
+ function getPreferredPairForBackground6(pairs, preferredPairId) {
23285
+ if (preferredPairId) {
23286
+ const preferredPair = pairs.find((pair) => pair.id === preferredPairId);
23287
+ if (preferredPair) {
23288
+ return preferredPair;
23289
+ }
23290
+ }
23291
+ return pairs.find((pair) => !isWhiteForegroundPair6(pair)) ?? pairs[0] ?? null;
23292
+ }
23293
+ function getDefaultBackgroundToken6(context) {
23294
+ for (const tone of PREFERRED_BACKGROUND_TONES6) {
23295
+ for (const group of context.backgroundGroups) {
23296
+ const match = group.backgrounds.find(
23297
+ (background) => background.tone === tone && (context.pairsByBackground[background.token]?.length ?? 0) > 0
23298
+ );
23299
+ if (match) {
23300
+ return match.token;
23301
+ }
23302
+ }
23303
+ }
23304
+ for (const tone of PREFERRED_BACKGROUND_TONES6) {
23305
+ for (const group of context.backgroundGroups) {
23306
+ const match = group.backgrounds.find((background) => background.tone === tone);
23307
+ if (match) {
23308
+ return match.token;
23309
+ }
23310
+ }
23311
+ }
23312
+ return context.backgrounds[0]?.token ?? "";
23313
+ }
23314
+ function resolveBackgroundToken7(context, preferredToken, preferredTone) {
23315
+ if (preferredToken && context.backgrounds.some((background) => background.token === preferredToken)) {
23316
+ return preferredToken;
23317
+ }
23318
+ if (preferredTone !== null && preferredTone !== void 0) {
23319
+ for (const group of context.backgroundGroups) {
23320
+ const match = group.backgrounds.find((background) => background.tone === preferredTone);
23321
+ if (match) {
23322
+ return match.token;
23323
+ }
23324
+ }
23325
+ }
23326
+ return getDefaultBackgroundToken6(context);
23327
+ }
23328
+ function getReadableTextColor5(tone) {
23329
+ return tone >= 600 ? "#ffffff" : "#002664";
23330
+ }
23331
+ function buildForegroundOptions(background, context) {
23332
+ const approvedPairs = context.pairsByBackground[background.token] ?? [];
23333
+ const whiteExample = supportsWhiteForegroundPreview(background) ? getWhiteForegroundPair(background) : null;
23334
+ if (whiteExample && whiteExample.passes.aaaLarge && !approvedPairs.some((pair) => pair.id === whiteExample.id)) {
23335
+ return [...approvedPairs, whiteExample];
23336
+ }
23337
+ return approvedPairs;
23338
+ }
23339
+ function getDefaultPairIdForBackground(context, backgroundToken) {
23340
+ const background = context.backgrounds.find((item) => item.token === backgroundToken);
23341
+ if (!background) {
23342
+ return "";
23343
+ }
23344
+ return getPreferredPairForBackground6(buildForegroundOptions(background, context))?.id ?? "";
23345
+ }
23346
+ function getInitialSelectionState() {
23347
+ const defaultAccentKey = getDefaultAccentFamilyKey(DEFAULT_THEME_CATEGORY, DEFAULT_PRIMARY_KEY);
23348
+ const context = getPairingContext(DEFAULT_THEME_CATEGORY, DEFAULT_PRIMARY_KEY, defaultAccentKey);
23349
+ const backgroundToken = resolveBackgroundToken7(
23350
+ context,
23351
+ DEFAULT_BACKGROUND_TOKEN,
23352
+ getToneFromToken6(DEFAULT_BACKGROUND_TOKEN)
23353
+ );
23354
+ return {
23355
+ accentKey: context.accent.key,
23356
+ backgroundToken,
23357
+ pairId: getDefaultPairIdForBackground(context, backgroundToken),
23358
+ primaryKey: context.primary.key,
23359
+ themeCategory: DEFAULT_THEME_CATEGORY
23360
+ };
23361
+ }
23362
+ function resolveSelectionState4(themeCategory, primaryKey, accentKey, backgroundToken) {
23363
+ const context = getPairingContext(themeCategory, primaryKey, accentKey);
23364
+ const resolvedBackgroundToken = resolveBackgroundToken7(
23365
+ context,
23366
+ backgroundToken,
23367
+ getToneFromToken6(backgroundToken)
23368
+ );
23369
+ return {
23370
+ accentKey: context.accent.key,
23371
+ backgroundToken: resolvedBackgroundToken,
23372
+ pairId: getDefaultPairIdForBackground(context, resolvedBackgroundToken),
23373
+ primaryKey: context.primary.key,
23374
+ themeCategory
23375
+ };
23376
+ }
23377
+ function getResultLabel(pair, bestPair) {
23378
+ if (!pair) {
23379
+ return "No AAA pairing available";
23380
+ }
23381
+ if (pair.id === bestPair?.id) {
23382
+ return "NSW recommended pairing";
23383
+ }
23384
+ if (isWhiteForegroundPair6(pair) && !pair.passes.aaaText && pair.passes.aaaLarge) {
23385
+ return "Large-text example";
23386
+ }
23387
+ return "Approved alternative";
23388
+ }
23389
+ function getSupportText(pair, bestPair) {
23390
+ if (!pair) {
23391
+ return "No AAA-compliant foreground is available for this background. Select another background tone to continue.";
23392
+ }
23393
+ if (pair.id === bestPair?.id) {
23394
+ return "Use this pairing for headings, body copy, and calls to action on the selected background.";
23395
+ }
23396
+ if (isWhiteForegroundPair6(pair) && !pair.passes.aaaText && pair.passes.aaaLarge) {
23397
+ return "Use white only for large text on this background. Keep regular body copy and small interface text on a darker recommended foreground.";
23398
+ }
23399
+ return "Use this approved alternative when you need a different tone or stronger emphasis.";
23400
+ }
23401
+ function getComplianceBadges(pair) {
23402
+ if (!pair) {
23403
+ return [];
23404
+ }
23405
+ return [
23406
+ {
23407
+ label: pair.passes.aaaText ? "AAA normal" : pair.passes.aaText ? "AA normal" : "Normal fail",
23408
+ tone: pair.passes.aaaText ? "success" : pair.passes.aaText ? "warning" : "neutral"
23409
+ },
23410
+ {
23411
+ label: pair.passes.aaaLarge ? "AAA large" : pair.passes.aaLarge ? "AA large" : "Large fail",
23412
+ tone: pair.passes.aaaLarge ? "success" : pair.passes.aaLarge ? "warning" : "neutral"
23413
+ }
23414
+ ];
23415
+ }
23416
+ function getShadeMeta(context, background) {
23417
+ const bestPair = getPreferredPairForBackground6(context.pairsByBackground[background.token] ?? []);
23418
+ if (!bestPair) {
23419
+ return {
23420
+ description: "No approved AAA foreground",
23421
+ label: "No AAA",
23422
+ ratio: null,
23423
+ tone: "neutral"
23424
+ };
23425
+ }
23426
+ return {
23427
+ description: `Recommends ${bestPair.foreground.token}`,
23428
+ label: "AAA ready",
23429
+ ratio: bestPair.contrastRatio,
23430
+ tone: "success"
23431
+ };
23432
+ }
23433
+ function getPairingCopyText4(pair) {
23434
+ const accessibilityLine = pair.passes.aaaText ? "Accessibility: Meets AAA for normal and large text" : pair.passes.aaaLarge ? "Accessibility: Meets AAA for large text only" : "Accessibility: Does not meet AAA";
23435
+ return [
23436
+ `Background: ${pair.background.token} (${pair.background.hex})`,
23437
+ `Foreground: ${pair.foreground.token} (${pair.foreground.hex})`,
23438
+ `Contrast ratio: ${pair.contrastRatio.toFixed(2)}:1`,
23439
+ accessibilityLine
23440
+ ].join("\n");
23441
+ }
23442
+ function getLiveAnnouncement4(pair, background) {
23443
+ if (!background) {
23444
+ return "No approved background tones available.";
23445
+ }
23446
+ if (!pair) {
23447
+ return `${background.token} selected. No AAA-compliant foreground is available for this background.`;
23448
+ }
23449
+ if (isWhiteForegroundPair6(pair) && !pair.passes.aaaText && pair.passes.aaaLarge) {
23450
+ return `${background.token} with white. Contrast ratio ${pair.contrastRatio.toFixed(2)} to 1. Meets AAA for large text only.`;
23451
+ }
23452
+ return `${background.token} with ${pair.foreground.token}. Contrast ratio ${pair.contrastRatio.toFixed(2)} to 1.`;
23453
+ }
23454
+ function ThemeButton({
23455
+ isSelected,
23456
+ label,
23457
+ onClick
23458
+ }) {
23459
+ return /* @__PURE__ */ jsx(
23460
+ "button",
23461
+ {
23462
+ type: "button",
23463
+ "aria-pressed": isSelected,
23464
+ onClick,
23465
+ className: cn(
23466
+ "rounded-sm border px-4 py-2.5 text-sm font-semibold transition-colors focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
23467
+ isSelected ? "border-primary-800 bg-primary-50 text-primary-900" : "border-grey-300 bg-white text-foreground hover:border-primary-500 hover:bg-grey-50"
23468
+ ),
23469
+ children: label
23470
+ }
23471
+ );
23472
+ }
23473
+ function FamilyButton2({
23474
+ isSelected,
23475
+ label,
23476
+ onClick,
23477
+ swatch
23478
+ }) {
23479
+ return /* @__PURE__ */ jsx(
23480
+ "button",
23481
+ {
23482
+ type: "button",
23483
+ "aria-pressed": isSelected,
23484
+ onClick,
23485
+ className: cn(
23486
+ "rounded-sm border p-3 text-left transition-colors focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
23487
+ isSelected ? "border-primary-800 bg-primary-50" : "border-grey-300 bg-white hover:border-primary-500 hover:bg-grey-50"
23488
+ ),
23489
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
23490
+ /* @__PURE__ */ jsx(
23491
+ "span",
23492
+ {
23493
+ "aria-hidden": "true",
23494
+ className: "mt-0.5 size-8 shrink-0 rounded-sm border border-black/10",
23495
+ style: { backgroundColor: swatch }
23496
+ }
23497
+ ),
23498
+ /* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: label }) })
23499
+ ] })
23500
+ }
23501
+ );
23502
+ }
23503
+ function StatusBadge({ label, tone }) {
23504
+ return /* @__PURE__ */ jsx(
23505
+ "span",
23506
+ {
23507
+ className: cn(
23508
+ "inline-flex rounded-sm border px-2 py-1 text-[0.68rem] font-semibold tracking-[0.12em] uppercase",
23509
+ tone === "success" && "border-primary-200 bg-primary-50 text-primary-900",
23510
+ tone === "warning" && "border-accent-200 bg-accent-50 text-accent-900",
23511
+ tone === "neutral" && "border-grey-300 bg-grey-50 text-foreground"
23512
+ ),
23513
+ children: label
23514
+ }
23515
+ );
23516
+ }
23517
+ function BackgroundShadeButton({
23518
+ background,
23519
+ context,
23520
+ isSelected,
23521
+ onClick
23522
+ }) {
23523
+ const meta = getShadeMeta(context, background);
23524
+ return /* @__PURE__ */ jsx(
23525
+ "button",
23526
+ {
23527
+ type: "button",
23528
+ "aria-pressed": isSelected,
23529
+ onClick,
23530
+ className: cn(
23531
+ "w-full rounded-sm border p-3 text-left transition-colors focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
23532
+ isSelected ? "border-primary-800 bg-primary-50" : "border-grey-300 bg-white hover:border-primary-500 hover:bg-grey-50"
23533
+ ),
23534
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
23535
+ /* @__PURE__ */ jsx(
23536
+ "span",
23537
+ {
23538
+ "aria-hidden": "true",
23539
+ className: "mt-0.5 size-10 shrink-0 rounded-sm border border-black/10",
23540
+ style: { backgroundColor: background.hex }
23541
+ }
23542
+ ),
23543
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
23544
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [
23545
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
23546
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: getPairingColorDisplayName6(background) }),
23547
+ /* @__PURE__ */ jsx("p", { className: "mt-1 font-mono text-[0.72rem] break-all text-muted-foreground", children: background.token })
23548
+ ] }),
23549
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end gap-1", children: [
23550
+ /* @__PURE__ */ jsx(StatusBadge, { label: meta.label, tone: meta.tone }),
23551
+ meta.ratio ? /* @__PURE__ */ jsxs("span", { className: "font-mono text-[0.72rem] text-muted-foreground", children: [
23552
+ meta.ratio.toFixed(2),
23553
+ ":1"
23554
+ ] }) : null
23555
+ ] })
23556
+ ] }),
23557
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-xs/5 text-muted-foreground", children: meta.description })
23558
+ ] })
23559
+ ] })
23560
+ }
23561
+ );
23562
+ }
23563
+ function PairTokenRow({ color: color2, label }) {
23564
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded-sm border border-grey-200 bg-white px-3 py-3", children: [
23565
+ /* @__PURE__ */ jsx(
23566
+ "span",
23567
+ {
23568
+ "aria-hidden": "true",
23569
+ className: "mt-0.5 size-8 shrink-0 rounded-sm border border-black/10",
23570
+ style: { backgroundColor: color2.hex }
23571
+ }
23572
+ ),
23573
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
23574
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.12em] text-muted-foreground uppercase", children: label }),
23575
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm font-semibold text-foreground", children: color2.token }),
23576
+ /* @__PURE__ */ jsx("p", { className: "mt-1 font-mono text-[0.72rem] break-all text-muted-foreground", children: color2.hex })
23577
+ ] })
23578
+ ] });
23579
+ }
23580
+ function ForegroundOptionButton({
23581
+ background,
23582
+ isSelected,
23583
+ onClick,
23584
+ pair
23585
+ }) {
23586
+ return /* @__PURE__ */ jsxs(
23587
+ "button",
23588
+ {
23589
+ type: "button",
23590
+ "aria-pressed": isSelected,
23591
+ onClick,
23592
+ className: cn(
23593
+ "w-[10rem] shrink-0 rounded-sm border p-3 text-left transition-colors focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
23594
+ isSelected ? "border-primary-800 bg-primary-50" : "border-grey-300 bg-white hover:border-primary-500 hover:bg-grey-50"
23595
+ ),
23596
+ children: [
23597
+ /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-sm border border-black/10", children: [
23598
+ /* @__PURE__ */ jsx("div", { className: "h-9 w-full", style: { backgroundColor: background.hex } }),
23599
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-full", style: { backgroundColor: pair.foreground.hex } })
23600
+ ] }),
23601
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-sm font-semibold text-foreground", children: getPairingColorDisplayName6(pair.foreground) }),
23602
+ /* @__PURE__ */ jsx("p", { className: "mt-1 font-mono text-[0.72rem] break-all text-muted-foreground", children: pair.foreground.token }),
23603
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center justify-between gap-2", children: [
23604
+ /* @__PURE__ */ jsxs("span", { className: "font-mono text-[0.72rem] text-foreground", children: [
23605
+ pair.contrastRatio.toFixed(2),
23606
+ ":1"
23607
+ ] }),
23608
+ isWhiteForegroundPair6(pair) && !pair.passes.aaaText ? /* @__PURE__ */ jsx(StatusBadge, { label: "Large text", tone: "warning" }) : pair.passes.aaaText ? /* @__PURE__ */ jsx(StatusBadge, { label: "AAA", tone: "success" }) : null
23609
+ ] })
23610
+ ]
23611
+ }
23612
+ );
23613
+ }
23614
+ function ColorPairingToolV6() {
23615
+ const [initialState] = useState(getInitialSelectionState);
23616
+ const [themeCategory, setThemeCategory] = useState(initialState.themeCategory);
23617
+ const [primaryFamilyKey, setPrimaryFamilyKey] = useState(initialState.primaryKey);
23618
+ const [accentFamilyKey, setAccentFamilyKey] = useState(initialState.accentKey);
23619
+ const [selectedBackgroundToken, setSelectedBackgroundToken] = useState(
23620
+ initialState.backgroundToken
23621
+ );
23622
+ const [selectedPairId, setSelectedPairId] = useState(initialState.pairId);
23623
+ const [, copyToClipboardRaw] = useCopyToClipboard();
23624
+ const [copiedKey, setCopiedKey] = useState(null);
23625
+ const copiedKeyTimeoutRef = useRef(null);
23626
+ const themeFamilies = useMemo(() => getPairingFamilies(themeCategory), [themeCategory]);
23627
+ const context = useMemo(
23628
+ () => getPairingContext(themeCategory, primaryFamilyKey, accentFamilyKey),
23629
+ [themeCategory, primaryFamilyKey, accentFamilyKey]
23630
+ );
23631
+ const selectableFamilies = useMemo(
23632
+ () => themeFamilies.filter((family) => family.key !== context.grey.key),
23633
+ [context.grey.key, themeFamilies]
23634
+ );
23635
+ const selectableAccentFamilies = useMemo(
23636
+ () => selectableFamilies.filter((family) => family.key !== context.primary.key),
23637
+ [context.primary.key, selectableFamilies]
23638
+ );
23639
+ const selectedBackground = useMemo(
23640
+ () => context.backgrounds.find((background) => background.token === selectedBackgroundToken) ?? context.backgrounds[0] ?? null,
23641
+ [context.backgrounds, selectedBackgroundToken]
23642
+ );
23643
+ const availableForegroundOptions = useMemo(
23644
+ () => selectedBackground ? buildForegroundOptions(selectedBackground, context) : [],
23645
+ [context, selectedBackground]
23646
+ );
23647
+ const bestRecommendedPair = useMemo(
23648
+ () => selectedBackground ? getPreferredPairForBackground6(context.pairsByBackground[selectedBackground.token] ?? []) : null,
23649
+ [context.pairsByBackground, selectedBackground]
23650
+ );
23651
+ const selectedPair = useMemo(
23652
+ () => getPreferredPairForBackground6(availableForegroundOptions, selectedPairId),
23653
+ [availableForegroundOptions, selectedPairId]
23654
+ );
23655
+ useEffect(() => {
23656
+ return () => {
23657
+ if (copiedKeyTimeoutRef.current) {
23658
+ clearTimeout(copiedKeyTimeoutRef.current);
23659
+ }
23660
+ };
23661
+ }, []);
23662
+ const copyValue = useCallback(
23663
+ (copyKey, value, toastLabel) => {
23664
+ copyToClipboardRaw(value);
23665
+ setCopiedKey(copyKey);
23666
+ toast(toastLabel, { duration: 2e3 });
23667
+ if (copiedKeyTimeoutRef.current) {
23668
+ clearTimeout(copiedKeyTimeoutRef.current);
23669
+ }
23670
+ copiedKeyTimeoutRef.current = setTimeout(() => {
23671
+ setCopiedKey(null);
23672
+ copiedKeyTimeoutRef.current = null;
23673
+ }, 2e3);
23674
+ },
23675
+ [copyToClipboardRaw]
23676
+ );
23677
+ const handleThemeCategoryChange = (nextThemeCategory) => {
23678
+ const nextState = resolveSelectionState4(
23679
+ nextThemeCategory,
23680
+ primaryFamilyKey,
23681
+ accentFamilyKey,
23682
+ selectedBackgroundToken
23683
+ );
23684
+ setThemeCategory(nextState.themeCategory);
23685
+ setPrimaryFamilyKey(nextState.primaryKey);
23686
+ setAccentFamilyKey(nextState.accentKey);
23687
+ setSelectedBackgroundToken(nextState.backgroundToken);
23688
+ setSelectedPairId(nextState.pairId);
23689
+ };
23690
+ const handlePrimaryColorChange = (nextPrimaryKey) => {
23691
+ const nextAccentKey = nextPrimaryKey === accentFamilyKey ? getDefaultAccentFamilyKey(themeCategory, nextPrimaryKey) : accentFamilyKey;
23692
+ const nextState = resolveSelectionState4(
23693
+ themeCategory,
23694
+ nextPrimaryKey,
23695
+ nextAccentKey,
23696
+ selectedBackgroundToken
23697
+ );
23698
+ setPrimaryFamilyKey(nextState.primaryKey);
23699
+ setAccentFamilyKey(nextState.accentKey);
23700
+ setSelectedBackgroundToken(nextState.backgroundToken);
23701
+ setSelectedPairId(nextState.pairId);
23702
+ };
23703
+ const handleAccentColorChange = (nextAccentKey) => {
23704
+ if (nextAccentKey === primaryFamilyKey) {
23705
+ return;
23706
+ }
23707
+ const nextState = resolveSelectionState4(
23708
+ themeCategory,
23709
+ primaryFamilyKey,
23710
+ nextAccentKey,
23711
+ selectedBackgroundToken
23712
+ );
23713
+ setAccentFamilyKey(nextState.accentKey);
23714
+ setSelectedBackgroundToken(nextState.backgroundToken);
23715
+ setSelectedPairId(nextState.pairId);
23716
+ };
23717
+ const handleBackgroundChange = (nextBackgroundToken) => {
23718
+ setSelectedBackgroundToken(nextBackgroundToken);
23719
+ setSelectedPairId(getDefaultPairIdForBackground(context, nextBackgroundToken));
23720
+ };
23721
+ const previewForeground = selectedPair?.foreground.hex ?? (selectedBackground && getReadableTextColor5(selectedBackground.tone));
23722
+ const resultLabel = getResultLabel(selectedPair, bestRecommendedPair);
23723
+ const supportText = getSupportText(selectedPair, bestRecommendedPair);
23724
+ const complianceBadges = getComplianceBadges(selectedPair);
23725
+ const liveAnnouncement = getLiveAnnouncement4(selectedPair, selectedBackground);
23726
+ if (!selectedBackground || !previewForeground) {
23727
+ return /* @__PURE__ */ jsxs(Card, { className: "px-6 py-6", children: [
23728
+ /* @__PURE__ */ jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "No approved background tones available" }),
23729
+ /* @__PURE__ */ jsx(Text, { size: 2, className: "mt-3", children: "No approved tones are available for the current palette and family selection." })
23730
+ ] });
23731
+ }
23732
+ return /* @__PURE__ */ jsxs("section", { className: "overflow-hidden rounded-sm border border-grey-200 bg-grey-50", children: [
23733
+ /* @__PURE__ */ jsx("div", { className: "border-b border-grey-200 bg-white px-5 py-5 sm:px-6 sm:py-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5 xl:flex-row xl:items-start xl:justify-between", children: [
23734
+ /* @__PURE__ */ jsxs("div", { className: "max-w-3xl space-y-3", children: [
23735
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.14em] text-primary-800 uppercase", children: "Experimental V6" }),
23736
+ /* @__PURE__ */ jsx(Heading, { level: 2, size: 4, className: "text-foreground", trim: "normal", children: "NSW colour pairing" }),
23737
+ /* @__PURE__ */ jsx(Text, { size: 2, className: "text-grey-700", children: "This version keeps the attached picker structure but moves it into a lighter NSW documentation treatment. Choose a palette, set the main background family and tone, then review approved foreground options on the right." })
23738
+ ] }),
23739
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
23740
+ /* @__PURE__ */ jsx(
23741
+ ThemeButton,
23742
+ {
23743
+ label: "Brand palette",
23744
+ isSelected: themeCategory === "brand",
23745
+ onClick: () => handleThemeCategoryChange("brand")
23746
+ }
23747
+ ),
23748
+ /* @__PURE__ */ jsx(
23749
+ ThemeButton,
23750
+ {
23751
+ label: "Aboriginal palette",
23752
+ isSelected: themeCategory === "aboriginal",
23753
+ onClick: () => handleThemeCategoryChange("aboriginal")
23754
+ }
23755
+ )
23756
+ ] })
23757
+ ] }) }),
23758
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-px bg-grey-200 xl:grid-cols-[20rem_minmax(0,1fr)]", children: [
23759
+ /* @__PURE__ */ jsx("aside", { className: "bg-white px-5 py-5 sm:px-6 sm:py-6", children: /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
23760
+ /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
23761
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
23762
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.14em] text-primary-800 uppercase", children: "Background family" }),
23763
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 6, className: "text-foreground", trim: "normal", children: "Primary colour family" })
23764
+ ] }),
23765
+ /* @__PURE__ */ jsx("div", { className: "grid gap-2 sm:grid-cols-2 xl:grid-cols-1", children: selectableFamilies.map((family) => /* @__PURE__ */ jsx(
23766
+ FamilyButton2,
23767
+ {
23768
+ label: getFamilySelectorLabel6(family, themeCategory, "primary colour"),
23769
+ isSelected: family.key === context.primary.key,
23770
+ onClick: () => handlePrimaryColorChange(family.key),
23771
+ swatch: getFamilySwatchColor6(family, 800)
23772
+ },
23773
+ family.key
23774
+ )) })
23775
+ ] }),
23776
+ /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
23777
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
23778
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.14em] text-primary-800 uppercase", children: "Background shade" }),
23779
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 6, className: "text-foreground", trim: "normal", children: "Approved tones" })
23780
+ ] }),
23781
+ /* @__PURE__ */ jsx("div", { className: "space-y-2", children: context.primary.colors.filter(
23782
+ (color2) => context.backgrounds.some((background) => background.token === color2.token)
23783
+ ).map((background) => /* @__PURE__ */ jsx(
23784
+ BackgroundShadeButton,
23785
+ {
23786
+ background,
23787
+ context,
23788
+ isSelected: background.token === selectedBackground.token,
23789
+ onClick: () => handleBackgroundChange(background.token)
23790
+ },
23791
+ background.token
23792
+ )) })
23793
+ ] }),
23794
+ /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
23795
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
23796
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.14em] text-primary-800 uppercase", children: "Accent family" }),
23797
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 6, className: "text-foreground", trim: "normal", children: "Supporting colour family" })
23798
+ ] }),
23799
+ /* @__PURE__ */ jsx("div", { className: "grid gap-2 sm:grid-cols-2 xl:grid-cols-1", children: selectableAccentFamilies.map((family) => /* @__PURE__ */ jsx(
23800
+ FamilyButton2,
23801
+ {
23802
+ label: getFamilySelectorLabel6(family, themeCategory, "accent colour"),
23803
+ isSelected: family.key === context.accent.key,
23804
+ onClick: () => handleAccentColorChange(family.key),
23805
+ swatch: getFamilySwatchColor6(family, 600)
23806
+ },
23807
+ family.key
23808
+ )) })
23809
+ ] }),
23810
+ /* @__PURE__ */ jsxs("div", { className: "border-t border-grey-200 pt-5", children: [
23811
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: "Grey stays available" }),
23812
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "Neutral grey foreground options are added automatically so each pairing keeps a practical NSW fallback." })
23813
+ ] })
23814
+ ] }) }),
23815
+ /* @__PURE__ */ jsx("div", { className: "bg-grey-50 px-4 py-4 sm:px-6 sm:py-6", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
23816
+ /* @__PURE__ */ jsx("div", { className: "sr-only", "aria-live": "polite", children: liveAnnouncement }),
23817
+ /* @__PURE__ */ jsxs(Card, { className: "gap-0 overflow-hidden border-grey-200 bg-white py-0", children: [
23818
+ /* @__PURE__ */ jsx("div", { className: "border-b border-grey-200 px-4 py-4 sm:px-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between", children: [
23819
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
23820
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.14em] text-primary-800 uppercase", children: "Current result" }),
23821
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 5, className: "text-foreground", trim: "normal", children: resultLabel })
23822
+ ] }),
23823
+ selectedPair ? /* @__PURE__ */ jsx(
23824
+ Button2,
23825
+ {
23826
+ variant: "outline",
23827
+ color: "grey",
23828
+ size: "sm",
23829
+ className: "self-start",
23830
+ onClick: () => copyValue("pairing", getPairingCopyText4(selectedPair), "Pairing copied"),
23831
+ children: copiedKey === "pairing" ? /* @__PURE__ */ jsxs(Fragment, { children: [
23832
+ /* @__PURE__ */ jsx(Icons.check, { "data-slot": "icon", className: "size-5" }),
23833
+ "Copied"
23834
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
23835
+ /* @__PURE__ */ jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
23836
+ "Copy pairing"
23837
+ ] })
23838
+ }
23839
+ ) : null
23840
+ ] }) }),
23841
+ /* @__PURE__ */ jsxs("div", { className: "space-y-5 px-4 py-4 sm:px-6 sm:py-6", children: [
23842
+ /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-sm border border-black/10", children: /* @__PURE__ */ jsx(
23843
+ "div",
23844
+ {
23845
+ className: "p-6 sm:p-8",
23846
+ style: {
23847
+ backgroundColor: selectedBackground.hex,
23848
+ color: previewForeground
23849
+ },
23850
+ children: /* @__PURE__ */ jsxs("div", { className: "max-w-3xl space-y-5", children: [
23851
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
23852
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.18em] uppercase", children: "NSW Government Digital" }),
23853
+ /* @__PURE__ */ jsx("h3", { className: "max-w-2xl text-[2rem] leading-tight font-bold sm:text-[2.75rem]", children: "Connecting communities to services that matter." }),
23854
+ /* @__PURE__ */ jsx("p", { className: "max-w-xl text-sm/7 sm:text-base/7", children: "This pairing demonstrates legibility across headings, body copy, and key actions. Surrounding chrome stays light so the selected colour treatment reads as the content focus rather than the whole interface shell." })
23855
+ ] }),
23856
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-3", children: [
23857
+ /* @__PURE__ */ jsx(
23858
+ "span",
23859
+ {
23860
+ className: "inline-flex items-center rounded-sm border px-4 py-2 text-sm font-semibold",
23861
+ style: {
23862
+ backgroundColor: previewForeground,
23863
+ borderColor: previewForeground,
23864
+ color: selectedBackground.hex
23865
+ },
23866
+ children: "Get started"
23867
+ }
23868
+ ),
23869
+ /* @__PURE__ */ jsx(
23870
+ "span",
23871
+ {
23872
+ className: "inline-flex items-center rounded-sm border px-4 py-2 text-sm font-semibold",
23873
+ style: {
23874
+ borderColor: previewForeground,
23875
+ color: previewForeground
23876
+ },
23877
+ children: "Learn more"
23878
+ }
23879
+ )
23880
+ ] })
23881
+ ] })
23882
+ }
23883
+ ) }),
23884
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 lg:grid-cols-[minmax(0,1fr)_18rem]", children: [
23885
+ /* @__PURE__ */ jsx("div", { className: "rounded-sm border border-grey-200 bg-grey-50 px-4 py-4 sm:px-5", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
23886
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
23887
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.14em] text-primary-800 uppercase", children: "Contrast summary" }),
23888
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-end gap-3", children: [
23889
+ /* @__PURE__ */ jsx("span", { className: "text-[2.5rem] leading-none font-bold text-foreground sm:text-[3.25rem]", children: selectedPair ? selectedPair.contrastRatio.toFixed(2) : "0.00" }),
23890
+ /* @__PURE__ */ jsx("span", { className: "pb-1 font-mono text-sm text-muted-foreground", children: ":1" })
23891
+ ] }),
23892
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: complianceBadges.map((badge) => /* @__PURE__ */ jsx(StatusBadge, { label: badge.label, tone: badge.tone }, badge.label)) })
23893
+ ] }),
23894
+ /* @__PURE__ */ jsx(Text, { size: 2, className: "text-grey-700", children: supportText })
23895
+ ] }) }),
23896
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: selectedPair ? /* @__PURE__ */ jsxs(Fragment, { children: [
23897
+ /* @__PURE__ */ jsx(PairTokenRow, { color: selectedPair.foreground, label: "Foreground" }),
23898
+ /* @__PURE__ */ jsx(PairTokenRow, { color: selectedPair.background, label: "Background" })
23899
+ ] }) : /* @__PURE__ */ jsx("div", { className: "rounded-sm border border-grey-200 bg-white px-4 py-4", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No foreground token is available for the current background." }) }) })
23900
+ ] })
23901
+ ] })
23902
+ ] }),
23903
+ /* @__PURE__ */ jsxs(Card, { className: "gap-0 overflow-hidden border-grey-200 bg-white py-0", children: [
23904
+ /* @__PURE__ */ jsx("div", { className: "border-b border-grey-200 px-4 py-4 sm:px-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between", children: [
23905
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
23906
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.14em] text-primary-800 uppercase", children: "Foreground options" }),
23907
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 5, className: "text-foreground", trim: "normal", children: "Approved alternatives for this background" })
23908
+ ] }),
23909
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
23910
+ availableForegroundOptions.length,
23911
+ " ",
23912
+ availableForegroundOptions.length === 1 ? "option" : "options",
23913
+ " available"
23914
+ ] })
23915
+ ] }) }),
23916
+ /* @__PURE__ */ jsx("div", { className: "px-4 py-4 sm:px-6 sm:py-5", children: availableForegroundOptions.length > 0 ? /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsx("div", { className: "flex gap-3 pb-1", children: availableForegroundOptions.map((pair) => /* @__PURE__ */ jsx(
23917
+ ForegroundOptionButton,
23918
+ {
23919
+ background: selectedBackground,
23920
+ isSelected: pair.id === selectedPair?.id,
23921
+ onClick: () => setSelectedPairId(pair.id),
23922
+ pair
23923
+ },
23924
+ pair.id
23925
+ )) }) }) : /* @__PURE__ */ jsx("div", { className: "rounded-sm border border-grey-200 bg-grey-50 px-4 py-4", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No approved foreground options are available for this background. Select a different background tone to continue." }) }) })
23926
+ ] })
23927
+ ] }) })
23928
+ ] })
23929
+ ] });
23930
+ }
22093
23931
  function ColorSwatches({ theme: theme2, format, viewMode }) {
22094
23932
  return /* @__PURE__ */ jsx(
22095
23933
  "div",
@@ -24714,7 +26552,7 @@ function FormatToggle({ format, setFormat }) {
24714
26552
 
24715
26553
  // package.json
24716
26554
  var package_default = {
24717
- version: "1.105.0"};
26555
+ version: "1.107.0"};
24718
26556
  function Logo(props) {
24719
26557
  return /* @__PURE__ */ jsxs(Fragment, { children: [
24720
26558
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "NSW Government" }),
@@ -40601,6 +42439,6 @@ var languages = [
40601
42439
  "html"
40602
42440
  ];
40603
42441
 
40604
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Action2 as Action, Actions, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AreaChart, Artifact, ArtifactAction, ArtifactActions, ArtifactContent, ArtifactDescription, ArtifactHeader, ArtifactTitle, AspectRatio, AuthLayout, AvailableChartColors, Avatar, AvatarFallback, AvatarImage, Badge, BadgeButton, BarChart, BarList, BaseColorSwatches, Branch, BranchMessages, BranchNext, BranchPage, BranchPrevious, BranchSelector, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Breadcrumbs, Button2 as Button, Calendar, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, CategoryBar, ChainOfThought, ChainOfThoughtContent, ChainOfThoughtHeader, ChainOfThoughtImage, ChainOfThoughtSearchResult, ChainOfThoughtSearchResults, ChainOfThoughtStep, ChartContainer, ChartLegend3 as ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip3 as ChartTooltip, ChartTooltipContent, Checkbox, CheckboxSmall, Code, CodeBlock, CodeBlockCopyButton, CodeDemo, CodeHighlight, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, ColorCard, ColorPairingTool, ColorPairingToolV2, ColorPairingToolV3, ColorPairingToolV4, ColorPairingToolV5, ColorSwatches, ColourScale, ComboChart, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Context, ContextCacheUsage, ContextContent, ContextContentBody, ContextContentFooter, ContextContentHeader, ContextInputUsage, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ContextOutputUsage, ContextReasoningUsage, ContextTrigger, Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton, DataTable, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableToolbar, DataTableViewOptions, Description5 as Description, DescriptionDetails, DescriptionList, DescriptionTerm, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DonutChart, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, DynamicFavicon, ErrorMessage, ExpandableSearch, ExpandableSearchField, Field2 as Field, FieldGroup, FieldLabel, Fieldset2 as Fieldset, Footer, FooterAcknowledgement, FooterLegalLinks, FooterSmallPrint, FooterSocialLink, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, FormatToggle, GenerateInterpolatedColors, Header2 as Header, Heading, HeroBannerSupportingImage, HoverCard, HoverCardContent, HoverCardTrigger, Icons, Image4 as Image, InlineCitation, InlineCitationCard, InlineCitationCardBody, InlineCitationCardTrigger, InlineCitationCarousel, InlineCitationCarouselContent, InlineCitationCarouselHeader, InlineCitationCarouselIndex, InlineCitationCarouselItem, InlineCitationSource, InlineCitationText, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Label5 as Label, Legend6 as Legend, LineChart, Link, _List as List, Listbox2 as Listbox, ListboxDescription, ListboxLabel, ListboxOption2 as ListboxOption, Loader, Loading, Logo, MainNavigation, Masthead, MegaMenu, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, Message, MessageContent, MobileHeader, MobileSearch, MultiLevelPushMenu, NSWCard, NSWCardArrow, NSWCardDescription, NSWCardIcon, NSWCardImg, NSWCardTitle, Navbar, NavbarDivider, NavbarItem, NavbarLabel, NavbarSection, NavbarSpacer, Navigation, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NotFound, OpenIn, OpenInChatGPT, OpenInClaude, OpenInContent, OpenInScira, OpenInT3, OpenInTrigger, OpenInv0, PageHeading, Pagination, PaginationGap, PaginationList, PaginationNext, PaginationPage, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PreWithCopy, PrevNextLinks, PrevNextLinksPageLink, Progress, ProgressBar, ProgressCircle, PromptInput, PromptInputActionAddAttachments, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuItem, PromptInputActionMenuTrigger, PromptInputAttachment, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputSubmit, PromptInputTextarea, PromptInputToolbar, PromptInputTools, Prose, RadioGroup2 as RadioGroup, RadioGroupItem, Reasoning, ReasoningContent, ReasoningTrigger, ResizableHandle, ResizablePanel, ResizablePanelGroup, Response, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator4 as Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarLink, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarNavigation, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SiteSearch, Skeleton, Slider, Social, Source, Sources, SourcesContent, SourcesTrigger, SparkAreaChart, SparkBarChart, SparkLineChart, Spinner, StepIndicator, StepNavigation, Strong, SubmitButton, Suggestion, Suggestions, Switch2 as Switch, SwitchField, SwitchGroup, TabNavigation, TabNavigationLink, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableOfContents, TableRow, Tabs2 as Tabs, TabsContent, TabsList, TabsTrigger, Task, TaskContent, TaskItem, TaskItemFile, TaskTrigger, Text, TextLink, Textarea, ThemeColorPalette, ThemeProvider, ThemeSelector, ThemeSwitcher, Toaster, TocContext, TocProvider, Toggle, ToggleGroup, ToggleGroupItem, Tool, ToolContent, ToolHeader, ToolInput, ToolOutput, Tooltip5 as Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopLevel, TouchTarget, Tracker, Tooltip3 as TremorTooltip, ViewToggle, WebPreview, WebPreviewBody, WebPreviewNavigation, WebPreviewUrl, Wrapper, aboriginal, addStartStopToColorArray, allPalettes, badgeVariants, brand, buttonVariants, camelCase, chartColors, cn, colorDataArray, colorThemes, colors, constructCategoryColors, createColorArray, createColorData, createFormStore, darkenColor, diverging, domToSimple, focusInput, focusRing, generateColorThemes, generateDataVisColors, getColorClassName, getColorValue, getHeadings, getNodeText, getSurroundingColors, getYAxisDomain, hasErrorInput, hasOnlyOneValueForKey, humaniseVariant, interpolateColors, isLightColor, kebabCase, languages, lightenColor, navigationMenuTriggerStyle, oklchConverter, progressBarVariants, renderColorOutput, renderColorOutputToDTFM, semantic, sequential, shades, themeIndices, themeTokens, toggleVariants, truncate, useActiveSectionObserver, useDisableToc, useFormField, useIsMobile, useOnWindowResize, usePageHeadings, usePromptInputAttachments, useSelectorHeight, useSidebar, useStickyOffset, useToc };
42442
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Action2 as Action, Actions, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AreaChart, Artifact, ArtifactAction, ArtifactActions, ArtifactContent, ArtifactDescription, ArtifactHeader, ArtifactTitle, AspectRatio, AuthLayout, AvailableChartColors, Avatar, AvatarFallback, AvatarImage, Badge, BadgeButton, BarChart, BarList, BaseColorSwatches, Branch, BranchMessages, BranchNext, BranchPage, BranchPrevious, BranchSelector, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Breadcrumbs, Button2 as Button, Calendar, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, CategoryBar, ChainOfThought, ChainOfThoughtContent, ChainOfThoughtHeader, ChainOfThoughtImage, ChainOfThoughtSearchResult, ChainOfThoughtSearchResults, ChainOfThoughtStep, ChartContainer, ChartLegend3 as ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip3 as ChartTooltip, ChartTooltipContent, Checkbox, CheckboxSmall, Code, CodeBlock, CodeBlockCopyButton, CodeDemo, CodeHighlight, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, ColorCard, ColorPairingTool, ColorPairingToolV1, ColorPairingToolV2, ColorPairingToolV3, ColorPairingToolV4, ColorPairingToolV5, ColorPairingToolV6, ColorSwatches, ColourScale, ComboChart, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Context, ContextCacheUsage, ContextContent, ContextContentBody, ContextContentFooter, ContextContentHeader, ContextInputUsage, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ContextOutputUsage, ContextReasoningUsage, ContextTrigger, Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton, DataTable, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableToolbar, DataTableViewOptions, Description5 as Description, DescriptionDetails, DescriptionList, DescriptionTerm, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DonutChart, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, DynamicFavicon, ErrorMessage, ExpandableSearch, ExpandableSearchField, Field2 as Field, FieldGroup, FieldLabel, Fieldset2 as Fieldset, Footer, FooterAcknowledgement, FooterLegalLinks, FooterSmallPrint, FooterSocialLink, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, FormatToggle, GenerateInterpolatedColors, Header2 as Header, Heading, HeroBannerSupportingImage, HoverCard, HoverCardContent, HoverCardTrigger, Icons, Image4 as Image, InlineCitation, InlineCitationCard, InlineCitationCardBody, InlineCitationCardTrigger, InlineCitationCarousel, InlineCitationCarouselContent, InlineCitationCarouselHeader, InlineCitationCarouselIndex, InlineCitationCarouselItem, InlineCitationSource, InlineCitationText, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Label5 as Label, Legend6 as Legend, LineChart, Link, _List as List, Listbox2 as Listbox, ListboxDescription, ListboxLabel, ListboxOption2 as ListboxOption, Loader, Loading, Logo, MainNavigation, Masthead, MegaMenu, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, Message, MessageContent, MobileHeader, MobileSearch, MultiLevelPushMenu, NSWCard, NSWCardArrow, NSWCardDescription, NSWCardIcon, NSWCardImg, NSWCardTitle, Navbar, NavbarDivider, NavbarItem, NavbarLabel, NavbarSection, NavbarSpacer, Navigation, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NotFound, OpenIn, OpenInChatGPT, OpenInClaude, OpenInContent, OpenInScira, OpenInT3, OpenInTrigger, OpenInv0, PageHeading, Pagination, PaginationGap, PaginationList, PaginationNext, PaginationPage, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PreWithCopy, PrevNextLinks, PrevNextLinksPageLink, Progress, ProgressBar, ProgressCircle, PromptInput, PromptInputActionAddAttachments, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuItem, PromptInputActionMenuTrigger, PromptInputAttachment, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputSubmit, PromptInputTextarea, PromptInputToolbar, PromptInputTools, Prose, RadioGroup2 as RadioGroup, RadioGroupItem, Reasoning, ReasoningContent, ReasoningTrigger, ResizableHandle, ResizablePanel, ResizablePanelGroup, Response, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator4 as Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarLink, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarNavigation, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SiteSearch, Skeleton, Slider, Social, Source, Sources, SourcesContent, SourcesTrigger, SparkAreaChart, SparkBarChart, SparkLineChart, Spinner, StepIndicator, StepNavigation, Strong, SubmitButton, Suggestion, Suggestions, Switch2 as Switch, SwitchField, SwitchGroup, TabNavigation, TabNavigationLink, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableOfContents, TableRow, Tabs2 as Tabs, TabsContent, TabsList, TabsTrigger, Task, TaskContent, TaskItem, TaskItemFile, TaskTrigger, Text, TextLink, Textarea, ThemeColorPalette, ThemeProvider, ThemeSelector, ThemeSwitcher, Toaster, TocContext, TocProvider, Toggle, ToggleGroup, ToggleGroupItem, Tool, ToolContent, ToolHeader, ToolInput, ToolOutput, Tooltip5 as Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopLevel, TouchTarget, Tracker, Tooltip3 as TremorTooltip, ViewToggle, WebPreview, WebPreviewBody, WebPreviewNavigation, WebPreviewUrl, Wrapper, aboriginal, addStartStopToColorArray, allPalettes, badgeVariants, brand, buttonVariants, camelCase, chartColors, cn, colorDataArray, colorThemes, colors, constructCategoryColors, createColorArray, createColorData, createFormStore, darkenColor, diverging, domToSimple, focusInput, focusRing, generateColorThemes, generateDataVisColors, getColorClassName, getColorValue, getHeadings, getNodeText, getSurroundingColors, getYAxisDomain, hasErrorInput, hasOnlyOneValueForKey, humaniseVariant, interpolateColors, isLightColor, kebabCase, languages, lightenColor, navigationMenuTriggerStyle, oklchConverter, progressBarVariants, renderColorOutput, renderColorOutputToDTFM, semantic, sequential, shades, themeIndices, themeTokens, toggleVariants, truncate, useActiveSectionObserver, useDisableToc, useFormField, useIsMobile, useOnWindowResize, usePageHeadings, usePromptInputAttachments, useSelectorHeight, useSidebar, useStickyOffset, useToc };
40605
42443
  //# sourceMappingURL=index.js.map
40606
42444
  //# sourceMappingURL=index.js.map