@nswds/app 1.102.0 → 1.104.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
@@ -1,6 +1,6 @@
1
1
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import clsx12, { clsx } from 'clsx';
3
+ import clsx13, { clsx } from 'clsx';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import { cva } from 'class-variance-authority';
6
6
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
@@ -42,8 +42,8 @@ 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';
44
44
  import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
45
+ import * as SheetPrimitive from '@radix-ui/react-dialog';
45
46
  import { Command as Command$1 } from 'cmdk';
46
- import * as DialogPrimitive from '@radix-ui/react-dialog';
47
47
  import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
48
48
  import { useReactTable, getFacetedUniqueValues, getFacetedRowModel, getSortedRowModel, getPaginationRowModel, getFilteredRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
49
49
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
@@ -4499,7 +4499,7 @@ var Button2 = forwardRef(function Button3({ className, variant, color: color2, s
4499
4499
  {
4500
4500
  "data-variant": variant,
4501
4501
  ...props,
4502
- className: clsx12(classes, "cursor-pointer"),
4502
+ className: clsx13(classes, "cursor-pointer"),
4503
4503
  ref,
4504
4504
  children: /* @__PURE__ */ jsx(TouchTarget, { children })
4505
4505
  }
@@ -5958,7 +5958,7 @@ var BadgeButton = forwardRef(function BadgeButton2({
5958
5958
  children,
5959
5959
  ...props
5960
5960
  }, ref) {
5961
- const classes = clsx12(className, focusOutline[color2], [
5961
+ const classes = clsx13(className, focusOutline[color2], [
5962
5962
  // Base
5963
5963
  "group relative inline-flex rounded-sm",
5964
5964
  // Focus
@@ -5980,7 +5980,7 @@ var BadgeButton = forwardRef(function BadgeButton2({
5980
5980
  {
5981
5981
  "data-variant": variant,
5982
5982
  ...props,
5983
- className: clsx12(classes, "cursor-pointer"),
5983
+ className: clsx13(classes, "cursor-pointer"),
5984
5984
  ref,
5985
5985
  children: /* @__PURE__ */ jsx(TouchTarget, { children: /* @__PURE__ */ jsx(Badge, { variant, color: color2, size, children }) })
5986
5986
  }
@@ -15223,7 +15223,7 @@ function Heading({
15223
15223
  ...props,
15224
15224
  id: computedId,
15225
15225
  "data-anchor": true,
15226
- className: clsx12(
15226
+ className: clsx13(
15227
15227
  className,
15228
15228
  trimClasses[trim],
15229
15229
  "m-0",
@@ -16303,6 +16303,2611 @@ function ColorPairingTool({
16303
16303
  const normalizedVisibleFormats = [...new Set(visibleFormats)];
16304
16304
  return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ColorPairingToolLoading, {}), children: /* @__PURE__ */ jsx(ColorPairingToolContent, { visibleFormats: normalizedVisibleFormats }) });
16305
16305
  }
16306
+ function Text({ className, trim = "normal", size = 2, label = false, ...props }) {
16307
+ const textSizeClasses = {
16308
+ 1: "text-[length:var(--font-size-1)] leading-[var(--line-height-28)] tracking-[var(--letter-spacing-0)]",
16309
+ 2: "text-[length:var(--font-size-2)] leading-[var(--line-height-24)] tracking-[var(--letter-spacing-0)]",
16310
+ 3: "text-[length:var(--font-size-3)] leading-[var(--line-height-20)] tracking-[var(--letter-spacing-0)]",
16311
+ 4: "text-[length:var(--font-size-4)] leading-[var(--line-height-20)] tracking-[var(--letter-spacing-0)]"
16312
+ };
16313
+ const labelSizeClasses = {
16314
+ 1: "text-[length:var(--font-size-1)] leading-[var(--line-height-24)] tracking-[var(--letter-spacing-0)]",
16315
+ 2: "text-[length:var(--font-size-2)] leading-[var(--line-height-20)] tracking-[var(--letter-spacing-0)]",
16316
+ 3: "text-[length:var(--font-size-3)] leading-[var(--line-height-16)] tracking-[var(--letter-spacing-0)]",
16317
+ 4: "text-[length:var(--font-size-4)] leading-[var(--line-height-16)] tracking-[var(--letter-spacing-0)]"
16318
+ };
16319
+ const sizeClass = label ? labelSizeClasses[size] : textSizeClasses[size];
16320
+ const trimClasses = {
16321
+ normal: ["before:content-none after:content-none"],
16322
+ start: [
16323
+ 'before:content-[""] before:table after:content-none',
16324
+ "before:mb-[calc(var(--leading-trim-start,var(--default-leading-trim-start))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
16325
+ ],
16326
+ end: [
16327
+ 'before:content-none after:content-[""] after:table',
16328
+ "after:mt-[calc(var(--leading-trim-end,var(--default-leading-trim-end))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
16329
+ ],
16330
+ both: [
16331
+ 'before:content-[""] before:table after:content-[""] after:table',
16332
+ "before:mb-[calc(var(--leading-trim-start,var(--default-leading-trim-start))-var(--line-height,calc(1em*var(--default-line-height)))/2)]",
16333
+ "after:mt-[calc(var(--leading-trim-end,var(--default-leading-trim-end))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
16334
+ ]
16335
+ };
16336
+ return /* @__PURE__ */ jsx(
16337
+ "p",
16338
+ {
16339
+ "data-slot": "text",
16340
+ ...props,
16341
+ className: clsx13(className, trimClasses[trim], "text-grey-800 dark:text-grey-400", sizeClass)
16342
+ }
16343
+ );
16344
+ }
16345
+ function TextLink({ className, ...props }) {
16346
+ return /* @__PURE__ */ jsx(
16347
+ Link,
16348
+ {
16349
+ ...props,
16350
+ className: clsx13(
16351
+ className,
16352
+ "text-primary-800 underline decoration-primary-800/50 data-hover:decoration-primary-800 dark:text-white dark:decoration-white/50 dark:data-hover:decoration-white"
16353
+ )
16354
+ }
16355
+ );
16356
+ }
16357
+ function Strong({ className, ...props }) {
16358
+ return /* @__PURE__ */ jsx("strong", { ...props, className: clsx13(className, "font-medium text-grey-950 dark:text-white") });
16359
+ }
16360
+ function Code({ className, ...props }) {
16361
+ const hasLanguageClass = typeof className === "string" && className.includes("language-");
16362
+ return /* @__PURE__ */ jsx(
16363
+ "code",
16364
+ {
16365
+ ...props,
16366
+ className: clsx13(
16367
+ className,
16368
+ !hasLanguageClass && "language-plaintext",
16369
+ "text-sm sm:text-[0.8125rem]"
16370
+ )
16371
+ }
16372
+ );
16373
+ }
16374
+ var PREFERRED_BACKGROUND_TONES2 = [400, 600, 200, 800, 100, 50];
16375
+ var DEFAULT_VISIBLE_FORMATS2 = ["hex", "rgb", "hsl", "oklch"];
16376
+ var DEFAULT_INITIAL_BACKGROUND_TOKEN2 = "nsw-blue-800";
16377
+ var DEFAULT_INITIAL_PAIR_ID2 = "nsw-blue-800:nsw-blue-200";
16378
+ function getToneFromToken2(token) {
16379
+ if (!token) return null;
16380
+ const match = token.match(/-(\d+)$/);
16381
+ return match ? Number.parseInt(match[1], 10) : null;
16382
+ }
16383
+ function getFamilySwatchColor2(family, preferredTone = 600) {
16384
+ const exactMatch = family.colors.find((color2) => color2.tone === preferredTone);
16385
+ if (exactMatch) {
16386
+ return exactMatch.hex;
16387
+ }
16388
+ const closestMatch = [...family.colors].sort(
16389
+ (left, right) => Math.abs(left.tone - preferredTone) - Math.abs(right.tone - preferredTone)
16390
+ )[0];
16391
+ return closestMatch?.hex ?? "transparent";
16392
+ }
16393
+ function getFamilySelectorLabel2(family, themeCategory, selectionRole) {
16394
+ if (themeCategory !== "aboriginal") {
16395
+ return family.label;
16396
+ }
16397
+ const preferredTone = selectionRole === "primary colour" ? 800 : 600;
16398
+ return family.colors.find((color2) => color2.tone === preferredTone)?.name ?? family.label;
16399
+ }
16400
+ function getPairingColorDisplayName2(color2) {
16401
+ return color2.name ?? color2.token;
16402
+ }
16403
+ function isWhiteForegroundPair2(pair) {
16404
+ return pair.foreground.token === "white";
16405
+ }
16406
+ function getWhiteForegroundGuidance2(pair) {
16407
+ if (pair.passes.aaaText) {
16408
+ return "White is approved for headings, body copy, and calls to action on this background.";
16409
+ }
16410
+ if (pair.passes.aaaLarge) {
16411
+ return "Use white only for WCAG large text on this background, such as headings at 24px+ or bold text at 18.5px+. Keep sentence-case body copy at 16px+ and use a darker recommended foreground instead.";
16412
+ }
16413
+ return "Do not use white on this background. Choose one of the recommended foregrounds below instead.";
16414
+ }
16415
+ function getPreviewGuidance2(pair, isRecommended) {
16416
+ if (!isWhiteForegroundPair2(pair)) {
16417
+ return "Use only AAA-recommended combinations across your selected primary, accent, and grey families.";
16418
+ }
16419
+ if (isRecommended) {
16420
+ return "Use white text on dark colour only when it meets AAA for headings, body copy, and calls to action.";
16421
+ }
16422
+ return getWhiteForegroundGuidance2(pair);
16423
+ }
16424
+ function getReadableTextColor(tone) {
16425
+ return tone >= 600 ? "#ffffff" : "#002664";
16426
+ }
16427
+ function getPreferredPairForBackground2(pairs, preferredPairId) {
16428
+ if (preferredPairId) {
16429
+ const preferredPair = pairs.find((pair) => pair.id === preferredPairId);
16430
+ if (preferredPair) {
16431
+ return preferredPair;
16432
+ }
16433
+ }
16434
+ return pairs.find((pair) => !isWhiteForegroundPair2(pair)) ?? pairs[0] ?? null;
16435
+ }
16436
+ function getDefaultBackgroundToken2(context) {
16437
+ for (const tone of PREFERRED_BACKGROUND_TONES2) {
16438
+ for (const group of context.backgroundGroups) {
16439
+ const match = group.backgrounds.find(
16440
+ (background) => background.tone === tone && (context.pairsByBackground[background.token]?.length ?? 0) > 0
16441
+ );
16442
+ if (match) {
16443
+ return match.token;
16444
+ }
16445
+ }
16446
+ }
16447
+ for (const tone of PREFERRED_BACKGROUND_TONES2) {
16448
+ for (const group of context.backgroundGroups) {
16449
+ const match = group.backgrounds.find((background) => background.tone === tone);
16450
+ if (match) {
16451
+ return match.token;
16452
+ }
16453
+ }
16454
+ }
16455
+ return context.backgrounds[0]?.token ?? "";
16456
+ }
16457
+ function resolveBackgroundToken2(context, preferredToken, preferredTone) {
16458
+ if (preferredToken && context.backgrounds.some((background) => background.token === preferredToken)) {
16459
+ return preferredToken;
16460
+ }
16461
+ if (preferredTone !== null && preferredTone !== void 0) {
16462
+ for (const group of context.backgroundGroups) {
16463
+ const match = group.backgrounds.find((background) => background.tone === preferredTone);
16464
+ if (match) {
16465
+ return match.token;
16466
+ }
16467
+ }
16468
+ }
16469
+ return getDefaultBackgroundToken2(context);
16470
+ }
16471
+ function getInitialPairingState2(searchParams) {
16472
+ const paletteParam = searchParams.get("palette");
16473
+ const primaryParam = searchParams.get("primary");
16474
+ const accentParam = searchParams.get("accent");
16475
+ const pairParam = searchParams.get("pair");
16476
+ const backgroundParam = searchParams.get("background");
16477
+ const themeCategory = paletteParam === "brand" || paletteParam === "aboriginal" ? paletteParam : "brand";
16478
+ const context = getPairingContext(themeCategory, primaryParam, accentParam);
16479
+ const shouldUseDefaultBrandExample = !backgroundParam && !pairParam && themeCategory === "brand" && context.primary.key === "blue" && context.accent.key === "red";
16480
+ const defaultBackgroundToken = shouldUseDefaultBrandExample ? context.backgrounds.some(
16481
+ (background) => background.token === DEFAULT_INITIAL_BACKGROUND_TOKEN2
16482
+ ) ? DEFAULT_INITIAL_BACKGROUND_TOKEN2 : null : null;
16483
+ const defaultPairId = shouldUseDefaultBrandExample && defaultBackgroundToken && context.pairsByBackground[defaultBackgroundToken]?.some(
16484
+ (pair) => pair.id === DEFAULT_INITIAL_PAIR_ID2
16485
+ ) ? DEFAULT_INITIAL_PAIR_ID2 : null;
16486
+ const pairBackgroundToken = context.recommendedPairs.find((pair) => pair.id === pairParam)?.background.token ?? null;
16487
+ const selectedBackgroundToken = resolveBackgroundToken2(
16488
+ context,
16489
+ backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken,
16490
+ getToneFromToken2(backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken)
16491
+ );
16492
+ const selectedPairId = getPreferredPairForBackground2(
16493
+ context.pairsByBackground[selectedBackgroundToken] ?? [],
16494
+ pairParam ?? defaultPairId
16495
+ )?.id ?? "";
16496
+ return {
16497
+ accentKey: context.accent.key,
16498
+ primaryKey: context.primary.key,
16499
+ selectedBackgroundToken,
16500
+ selectedPairId,
16501
+ themeCategory
16502
+ };
16503
+ }
16504
+ function ColorPairingToolV2Loading() {
16505
+ return /* @__PURE__ */ jsxs("div", { className: "grid gap-8 lg:grid-cols-[18rem_minmax(0,1fr)]", children: [
16506
+ /* @__PURE__ */ jsxs("div", { className: "space-y-6 bg-grey-50/70 p-6", children: [
16507
+ /* @__PURE__ */ jsx("div", { className: "h-10 rounded-sm bg-grey-100" }),
16508
+ /* @__PURE__ */ jsx("div", { className: "h-40 rounded-sm bg-grey-100" }),
16509
+ /* @__PURE__ */ jsx("div", { className: "h-52 rounded-sm bg-grey-100" })
16510
+ ] }),
16511
+ /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
16512
+ /* @__PURE__ */ jsx("div", { className: "h-12 rounded-sm bg-grey-100" }),
16513
+ /* @__PURE__ */ jsx("div", { className: "h-64 rounded-sm bg-grey-100" }),
16514
+ /* @__PURE__ */ jsx("div", { className: "h-40 rounded-sm bg-grey-100" }),
16515
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2 xl:grid-cols-3", children: [
16516
+ /* @__PURE__ */ jsx("div", { className: "h-44 rounded-sm bg-grey-100" }),
16517
+ /* @__PURE__ */ jsx("div", { className: "h-44 rounded-sm bg-grey-100" }),
16518
+ /* @__PURE__ */ jsx("div", { className: "h-44 rounded-sm bg-grey-100" })
16519
+ ] })
16520
+ ] })
16521
+ ] });
16522
+ }
16523
+ function SidebarStep({
16524
+ children,
16525
+ description,
16526
+ step,
16527
+ title
16528
+ }) {
16529
+ return /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
16530
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
16531
+ /* @__PURE__ */ jsxs("p", { className: "text-[0.72rem] font-semibold tracking-[0.12em] text-muted-foreground uppercase", children: [
16532
+ "Step ",
16533
+ step
16534
+ ] }),
16535
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 6, className: "text-foreground", trim: "normal", children: title }),
16536
+ description ? /* @__PURE__ */ jsx("p", { className: "text-sm/6 text-muted-foreground", children: description }) : null
16537
+ ] }),
16538
+ children
16539
+ ] });
16540
+ }
16541
+ function PreviewHeroCard({
16542
+ familySummary,
16543
+ isRecommended,
16544
+ pair
16545
+ }) {
16546
+ const whiteForeground = isWhiteForegroundPair2(pair);
16547
+ const statusLabel = isRecommended ? "Pass" : pair.passes.aaaLarge ? "Large text only" : "Example only";
16548
+ const StatusIcon = isRecommended ? Icons.check : Icons.info;
16549
+ const fauxButtonStyle = {
16550
+ "--btn-bg": pair.foreground.hex,
16551
+ "--btn-border": pair.foreground.hex,
16552
+ "--btn-text": pair.background.hex,
16553
+ "--btn-icon": pair.background.hex,
16554
+ "--btn-hover-overlay": pair.background.hex
16555
+ };
16556
+ return /* @__PURE__ */ jsx(Card, { className: "gap-0 overflow-hidden py-0", children: /* @__PURE__ */ jsx(
16557
+ "div",
16558
+ {
16559
+ className: "p-6 sm:min-h-[26rem] sm:p-8",
16560
+ style: {
16561
+ backgroundColor: pair.background.hex,
16562
+ color: pair.foreground.hex
16563
+ },
16564
+ children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-[22rem] flex-col justify-between gap-8", children: [
16565
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
16566
+ /* @__PURE__ */ jsxs(
16567
+ "span",
16568
+ {
16569
+ className: "inline-flex items-center gap-2 rounded-full border px-3 py-1 text-[0.72rem] font-semibold tracking-[0.16em] uppercase",
16570
+ style: {
16571
+ borderColor: pair.foreground.hex,
16572
+ backgroundColor: pair.foreground.hex,
16573
+ color: pair.background.hex
16574
+ },
16575
+ children: [
16576
+ /* @__PURE__ */ jsx(Icons.palette, { "data-slot": "icon", className: "size-4" }),
16577
+ familySummary
16578
+ ]
16579
+ }
16580
+ ),
16581
+ /* @__PURE__ */ jsxs(
16582
+ "span",
16583
+ {
16584
+ className: "inline-flex rounded-full border px-3 py-1 text-[0.72rem] font-semibold tracking-[0.16em] uppercase",
16585
+ style: {
16586
+ borderColor: pair.foreground.hex
16587
+ },
16588
+ children: [
16589
+ pair.rating,
16590
+ " ",
16591
+ pair.contrastRatio.toFixed(2),
16592
+ ":1"
16593
+ ]
16594
+ }
16595
+ )
16596
+ ] }),
16597
+ /* @__PURE__ */ jsxs("div", { className: "max-w-xl space-y-4 pb-12 sm:pb-16", children: [
16598
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold tracking-[0.22em] uppercase", children: whiteForeground && !isRecommended ? "White on colour example" : whiteForeground ? "White on colour" : "Colour on colour" }),
16599
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
16600
+ /* @__PURE__ */ jsx("h3", { className: "max-w-lg text-4xl leading-none font-bold text-current sm:text-5xl", children: "Pair colour with confidence." }),
16601
+ /* @__PURE__ */ jsx("p", { className: "max-w-md text-base/6 sm:text-base/7", children: getPreviewGuidance2(pair, isRecommended) }),
16602
+ /* @__PURE__ */ jsx(
16603
+ "span",
16604
+ {
16605
+ "aria-hidden": "true",
16606
+ "data-variant": "solid",
16607
+ className: cn(
16608
+ buttonVariants({ variant: "solid", size: "default" }),
16609
+ "pointer-events-none cursor-default px-6 text-[16px] font-[700] select-none sm:px-6 sm:text-[16px] sm:font-[700]"
16610
+ ),
16611
+ style: fauxButtonStyle,
16612
+ children: "Get started"
16613
+ }
16614
+ )
16615
+ ] })
16616
+ ] }),
16617
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
16618
+ /* @__PURE__ */ jsxs(
16619
+ "span",
16620
+ {
16621
+ className: "inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-semibold",
16622
+ style: {
16623
+ backgroundColor: pair.foreground.hex,
16624
+ color: pair.background.hex
16625
+ },
16626
+ children: [
16627
+ statusLabel,
16628
+ /* @__PURE__ */ jsx(StatusIcon, { "data-slot": "icon", className: "size-4" })
16629
+ ]
16630
+ }
16631
+ ),
16632
+ /* @__PURE__ */ jsxs(
16633
+ "span",
16634
+ {
16635
+ className: "inline-flex rounded-full border px-4 py-2 text-sm",
16636
+ style: {
16637
+ borderColor: pair.foreground.hex
16638
+ },
16639
+ children: [
16640
+ pair.background.token,
16641
+ " / ",
16642
+ pair.foreground.token
16643
+ ]
16644
+ }
16645
+ )
16646
+ ] })
16647
+ ] })
16648
+ }
16649
+ ) });
16650
+ }
16651
+ function PreviewFallbackCard2({ background }) {
16652
+ return /* @__PURE__ */ jsx(Card, { className: "gap-0 overflow-hidden py-0", children: /* @__PURE__ */ jsxs(
16653
+ "div",
16654
+ {
16655
+ className: "space-y-6 px-6 py-7 sm:px-8 sm:py-8",
16656
+ style: {
16657
+ backgroundColor: background.hex,
16658
+ color: getReadableTextColor(background.tone)
16659
+ },
16660
+ children: [
16661
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Hero preview" }),
16662
+ /* @__PURE__ */ jsxs("div", { className: "max-w-xl space-y-4", children: [
16663
+ /* @__PURE__ */ jsx("h3", { className: "max-w-lg text-3xl leading-tight font-bold sm:text-4xl", children: "No AAA combination available." }),
16664
+ /* @__PURE__ */ jsx("p", { className: "max-w-lg text-base/7", children: "This background tone is approved, but there are no recommended AAA foreground pairings available for it in the current tool." })
16665
+ ] })
16666
+ ]
16667
+ }
16668
+ ) });
16669
+ }
16670
+ function PairDetailCard2({
16671
+ color: color2,
16672
+ role,
16673
+ visibleFormats
16674
+ }) {
16675
+ const [, copyToClipboardRaw] = useCopyToClipboard();
16676
+ const [copiedField, setCopiedField] = useState(null);
16677
+ const copiedFieldTimeoutRef = useRef(null);
16678
+ const hasDisplayTone = color2.token !== "white";
16679
+ const formatRows = visibleFormats.map((format) => ({
16680
+ key: format,
16681
+ label: format.toUpperCase(),
16682
+ value: color2[format],
16683
+ mono: true,
16684
+ copyable: true
16685
+ }));
16686
+ const valueRows = [
16687
+ { key: "token", label: "Token", value: color2.token, mono: true, copyable: true },
16688
+ {
16689
+ key: "tone",
16690
+ label: "Tone",
16691
+ value: hasDisplayTone ? String(color2.tone) : "Not applicable",
16692
+ mono: false,
16693
+ copyable: hasDisplayTone
16694
+ },
16695
+ ...formatRows
16696
+ ];
16697
+ useEffect(() => {
16698
+ return () => {
16699
+ if (copiedFieldTimeoutRef.current) {
16700
+ clearTimeout(copiedFieldTimeoutRef.current);
16701
+ }
16702
+ };
16703
+ }, []);
16704
+ const copyField = (field) => {
16705
+ if (field === "tone" && !hasDisplayTone) {
16706
+ return;
16707
+ }
16708
+ const fieldValue = valueRows.find((row) => row.key === field)?.value;
16709
+ if (!fieldValue) return;
16710
+ copyToClipboardRaw(fieldValue);
16711
+ setCopiedField(field);
16712
+ const toastLabel = valueRows.find((row) => row.key === field)?.label ?? "Value";
16713
+ toast(`${toastLabel} copied to clipboard`, {
16714
+ duration: 2e3
16715
+ });
16716
+ if (copiedFieldTimeoutRef.current) {
16717
+ clearTimeout(copiedFieldTimeoutRef.current);
16718
+ }
16719
+ copiedFieldTimeoutRef.current = setTimeout(() => {
16720
+ setCopiedField(null);
16721
+ copiedFieldTimeoutRef.current = null;
16722
+ }, 2e3);
16723
+ };
16724
+ const renderCopyButton = (field, srLabel, className) => /* @__PURE__ */ jsxs(
16725
+ Button2,
16726
+ {
16727
+ variant: "ghost",
16728
+ size: "icon",
16729
+ className: cn("shrink-0", className),
16730
+ onClick: () => copyField(field),
16731
+ children: [
16732
+ copiedField === field ? /* @__PURE__ */ jsx(Icons.check, { "data-slot": "icon", className: "size-5" }) : /* @__PURE__ */ jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
16733
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: srLabel })
16734
+ ]
16735
+ }
16736
+ );
16737
+ return /* @__PURE__ */ jsxs(Card, { className: "gap-0 pb-0", children: [
16738
+ /* @__PURE__ */ jsxs(CardHeader, { className: "gap-4 border-b", children: [
16739
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
16740
+ /* @__PURE__ */ jsx(CardTitle, { children: role }),
16741
+ /* @__PURE__ */ jsx(CardDescription, { children: color2.name ?? color2.token })
16742
+ ] }),
16743
+ /* @__PURE__ */ jsx(
16744
+ "div",
16745
+ {
16746
+ className: "h-14 w-full rounded-sm border border-grey-200 shadow-sm dark:border-grey-700",
16747
+ style: { backgroundColor: color2.hex }
16748
+ }
16749
+ )
16750
+ ] }),
16751
+ /* @__PURE__ */ jsx(CardContent, { className: "px-0 pb-3", children: /* @__PURE__ */ jsx("div", { className: "divide-y divide-grey-100 dark:divide-grey-800", children: valueRows.map((row) => /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4 px-6 py-3", children: [
16752
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
16753
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold tracking-[0.16em] text-muted-foreground uppercase", children: row.label }),
16754
+ /* @__PURE__ */ jsx(
16755
+ "p",
16756
+ {
16757
+ className: cn(
16758
+ "mt-2 min-w-0 text-base text-foreground",
16759
+ row.mono && "font-mono text-sm break-all sm:text-base"
16760
+ ),
16761
+ children: row.value
16762
+ }
16763
+ )
16764
+ ] }),
16765
+ row.copyable ? renderCopyButton(
16766
+ row.key,
16767
+ `Copy ${role.toLowerCase()} ${row.label.toLowerCase()}`,
16768
+ "mt-0.5"
16769
+ ) : null
16770
+ ] }, row.key)) }) })
16771
+ ] });
16772
+ }
16773
+ function AccessibilityScoreCard({ pair }) {
16774
+ return /* @__PURE__ */ jsxs(Card, { className: "gap-0 py-0", children: [
16775
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5 px-6 py-6 sm:flex-row sm:items-end sm:justify-between", children: [
16776
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
16777
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: "Accessibility score" }),
16778
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
16779
+ /* @__PURE__ */ jsx("p", { className: "text-5xl leading-none font-bold text-foreground", children: pair ? `${pair.contrastRatio.toFixed(2)}:1` : "N/A" }),
16780
+ /* @__PURE__ */ jsx("p", { className: "text-base text-muted-foreground", children: "Contrast ratio" })
16781
+ ] })
16782
+ ] }),
16783
+ /* @__PURE__ */ jsx(
16784
+ "span",
16785
+ {
16786
+ className: cn(
16787
+ "inline-flex items-center gap-2 rounded-full px-4 py-2 text-base font-semibold",
16788
+ pair ? "bg-success-700 text-white" : "border border-grey-300 bg-background text-foreground"
16789
+ ),
16790
+ children: pair ? /* @__PURE__ */ jsxs(Fragment, { children: [
16791
+ "Pass AAA",
16792
+ /* @__PURE__ */ jsx(Icons.check, { "data-slot": "icon", className: "size-5" })
16793
+ ] }) : "No AAA result"
16794
+ }
16795
+ )
16796
+ ] }),
16797
+ /* @__PURE__ */ jsx("div", { className: "border-t border-grey-200 px-6 py-4 dark:border-grey-700", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: pair ? "Meets WCAG 2.1 AAA standards for large and normal text." : "Choose a different approved background tone to review recommended AAA pairings." }) })
16798
+ ] });
16799
+ }
16800
+ function RecommendedPairCard({
16801
+ isSelected,
16802
+ onSelect,
16803
+ pair
16804
+ }) {
16805
+ return /* @__PURE__ */ jsxs(
16806
+ "button",
16807
+ {
16808
+ type: "button",
16809
+ "aria-label": `Use ${getPairingColorDisplayName2(pair.foreground)} on ${getPairingColorDisplayName2(pair.background)}`,
16810
+ "aria-pressed": isSelected,
16811
+ onClick: onSelect,
16812
+ className: cn(
16813
+ "overflow-hidden rounded-sm border bg-background text-left transition-colors",
16814
+ isSelected ? "border-primary-700 ring-2 ring-primary-700 ring-offset-2 ring-offset-background" : "border-grey-200 hover:border-grey-400 dark:border-grey-700 dark:hover:border-grey-500"
16815
+ ),
16816
+ children: [
16817
+ /* @__PURE__ */ jsxs(
16818
+ "div",
16819
+ {
16820
+ className: "min-h-32 space-y-3 px-4 py-4",
16821
+ style: {
16822
+ backgroundColor: pair.background.hex,
16823
+ color: pair.foreground.hex
16824
+ },
16825
+ children: [
16826
+ /* @__PURE__ */ jsxs("p", { className: "text-[0.68rem] font-semibold tracking-[0.12em] uppercase opacity-90", children: [
16827
+ pair.background.token,
16828
+ " / ",
16829
+ pair.foreground.token
16830
+ ] }),
16831
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
16832
+ /* @__PURE__ */ jsx("p", { className: "text-2xl leading-tight font-bold", children: getPairingColorDisplayName2(pair.foreground) }),
16833
+ /* @__PURE__ */ jsxs("p", { className: "text-sm/6 opacity-90", children: [
16834
+ pair.foreground.familyLabel,
16835
+ " on ",
16836
+ pair.background.familyLabel
16837
+ ] })
16838
+ ] })
16839
+ ]
16840
+ }
16841
+ ),
16842
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4 px-4 py-3", children: [
16843
+ /* @__PURE__ */ jsxs("span", { className: "text-sm font-semibold text-foreground", children: [
16844
+ pair.contrastRatio.toFixed(2),
16845
+ ":1"
16846
+ ] }),
16847
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1 rounded-full bg-success-50 px-2.5 py-1 text-xs font-semibold text-success-800 dark:bg-success-950/30 dark:text-success-200", children: "AAA" })
16848
+ ] })
16849
+ ]
16850
+ }
16851
+ );
16852
+ }
16853
+ function ColorPairingToolV2Content({ visibleFormats }) {
16854
+ const searchParams = useSearchParams();
16855
+ const [initialState] = useState(() => getInitialPairingState2(searchParams));
16856
+ const [themeCategory, setThemeCategory] = useState(initialState.themeCategory);
16857
+ const [primaryFamilyKey, setPrimaryFamilyKey] = useState(initialState.primaryKey);
16858
+ const [accentFamilyKey, setAccentFamilyKey] = useState(initialState.accentKey);
16859
+ const [selectedBackgroundToken, setSelectedBackgroundToken] = useState(
16860
+ initialState.selectedBackgroundToken
16861
+ );
16862
+ const [selectedPairId, setSelectedPairId] = useState(initialState.selectedPairId);
16863
+ const themeFamilies = useMemo(() => getPairingFamilies(themeCategory), [themeCategory]);
16864
+ const context = useMemo(
16865
+ () => getPairingContext(themeCategory, primaryFamilyKey, accentFamilyKey),
16866
+ [themeCategory, primaryFamilyKey, accentFamilyKey]
16867
+ );
16868
+ const selectableFamilies = useMemo(
16869
+ () => themeFamilies.filter((family) => family.key !== context.grey.key),
16870
+ [themeFamilies, context.grey.key]
16871
+ );
16872
+ const selectableAccentFamilies = useMemo(
16873
+ () => selectableFamilies.filter((family) => family.key !== context.primary.key),
16874
+ [selectableFamilies, context.primary.key]
16875
+ );
16876
+ const selectedBackground = useMemo(
16877
+ () => context.backgrounds.find((background) => background.token === selectedBackgroundToken) ?? context.backgrounds[0] ?? null,
16878
+ [context.backgrounds, selectedBackgroundToken]
16879
+ );
16880
+ const selectedBackgroundPairs = useMemo(
16881
+ () => selectedBackground ? context.pairsByBackground[selectedBackground.token] ?? [] : [],
16882
+ [context.pairsByBackground, selectedBackground]
16883
+ );
16884
+ const selectedPair = useMemo(
16885
+ () => getPreferredPairForBackground2(selectedBackgroundPairs, selectedPairId),
16886
+ [selectedBackgroundPairs, selectedPairId]
16887
+ );
16888
+ const detailForeground = selectedPair?.foreground ?? null;
16889
+ const familySummary = useMemo(
16890
+ () => [context.primary.label, context.accent.label, context.grey.label].join(" + "),
16891
+ [context.primary.label, context.accent.label, context.grey.label]
16892
+ );
16893
+ const updateUrlParams = (nextThemeCategory, nextPrimaryKey, nextAccentKey, nextSelectedBackgroundToken, nextSelectedPairId) => {
16894
+ const params = new URLSearchParams(window.location.search);
16895
+ params.delete("family");
16896
+ params.set("palette", nextThemeCategory);
16897
+ params.set("primary", nextPrimaryKey);
16898
+ params.set("accent", nextAccentKey);
16899
+ params.set("background", nextSelectedBackgroundToken);
16900
+ if (nextSelectedPairId) {
16901
+ params.set("pair", nextSelectedPairId);
16902
+ } else {
16903
+ params.delete("pair");
16904
+ }
16905
+ window.history.replaceState(
16906
+ null,
16907
+ "",
16908
+ `${window.location.pathname}?${params.toString()}${window.location.hash}`
16909
+ );
16910
+ };
16911
+ const syncSelection = (nextThemeCategory, nextPrimaryKey, nextAccentKey, preferredBackgroundToken, preferredPairId) => {
16912
+ const nextContext = getPairingContext(nextThemeCategory, nextPrimaryKey, nextAccentKey);
16913
+ const nextSelectedBackgroundToken = resolveBackgroundToken2(
16914
+ nextContext,
16915
+ preferredBackgroundToken,
16916
+ getToneFromToken2(preferredBackgroundToken)
16917
+ );
16918
+ const nextSelectedPairId = getPreferredPairForBackground2(
16919
+ nextContext.pairsByBackground[nextSelectedBackgroundToken] ?? [],
16920
+ preferredPairId
16921
+ )?.id ?? "";
16922
+ setThemeCategory(nextThemeCategory);
16923
+ setPrimaryFamilyKey(nextContext.primary.key);
16924
+ setAccentFamilyKey(nextContext.accent.key);
16925
+ setSelectedBackgroundToken(nextSelectedBackgroundToken);
16926
+ setSelectedPairId(nextSelectedPairId);
16927
+ updateUrlParams(
16928
+ nextThemeCategory,
16929
+ nextContext.primary.key,
16930
+ nextContext.accent.key,
16931
+ nextSelectedBackgroundToken,
16932
+ nextSelectedPairId
16933
+ );
16934
+ };
16935
+ const handleThemeCategoryChange = (nextThemeCategory) => {
16936
+ syncSelection(
16937
+ nextThemeCategory,
16938
+ primaryFamilyKey,
16939
+ accentFamilyKey,
16940
+ selectedBackgroundToken,
16941
+ selectedPairId
16942
+ );
16943
+ };
16944
+ const handlePrimaryColorChange = (nextPrimaryKey) => {
16945
+ const nextAccentKey = nextPrimaryKey === accentFamilyKey ? getDefaultAccentFamilyKey(themeCategory, nextPrimaryKey) : accentFamilyKey;
16946
+ syncSelection(
16947
+ themeCategory,
16948
+ nextPrimaryKey,
16949
+ nextAccentKey,
16950
+ selectedBackgroundToken,
16951
+ selectedPairId
16952
+ );
16953
+ };
16954
+ const handleAccentColorChange = (nextAccentKey) => {
16955
+ if (nextAccentKey === primaryFamilyKey) return;
16956
+ syncSelection(
16957
+ themeCategory,
16958
+ primaryFamilyKey,
16959
+ nextAccentKey,
16960
+ selectedBackgroundToken,
16961
+ selectedPairId
16962
+ );
16963
+ };
16964
+ const handleBackgroundChange = (nextSelectedBackgroundToken) => {
16965
+ const nextSelectedPairId = getPreferredPairForBackground2(
16966
+ context.pairsByBackground[nextSelectedBackgroundToken] ?? [],
16967
+ selectedPairId
16968
+ )?.id ?? "";
16969
+ setSelectedBackgroundToken(nextSelectedBackgroundToken);
16970
+ setSelectedPairId(nextSelectedPairId);
16971
+ updateUrlParams(
16972
+ themeCategory,
16973
+ context.primary.key,
16974
+ context.accent.key,
16975
+ nextSelectedBackgroundToken,
16976
+ nextSelectedPairId
16977
+ );
16978
+ };
16979
+ const handlePairChange = (nextSelectedPairId) => {
16980
+ if (!selectedBackground) return;
16981
+ setSelectedPairId(nextSelectedPairId);
16982
+ updateUrlParams(
16983
+ themeCategory,
16984
+ context.primary.key,
16985
+ context.accent.key,
16986
+ selectedBackground.token,
16987
+ nextSelectedPairId
16988
+ );
16989
+ };
16990
+ if (!selectedBackground) {
16991
+ return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs("div", { className: "px-6", children: [
16992
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 5, className: "text-foreground", trim: "normal", children: "No approved background tones available" }),
16993
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-base text-muted-foreground", children: "No approved tones are available for the current palette." })
16994
+ ] }) });
16995
+ }
16996
+ return /* @__PURE__ */ jsxs("div", { className: "grid gap-8 lg:grid-cols-[18rem_minmax(0,1fr)]", children: [
16997
+ /* @__PURE__ */ jsx("aside", { className: "bg-grey-50/60 p-6", children: /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
16998
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
16999
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 5, className: "text-foreground", trim: "normal", children: "Configuration" }),
17000
+ /* @__PURE__ */ jsx(Text, { size: 2, children: "Choose a palette, set your primary and accent families, then select an approved background." })
17001
+ ] }),
17002
+ /* @__PURE__ */ jsx(SidebarStep, { step: 1, title: "Select your palette", children: /* @__PURE__ */ jsx("div", { className: "grid gap-2", children: ["brand", "aboriginal"].map((palette) => {
17003
+ const isSelected = themeCategory === palette;
17004
+ const label = palette === "brand" ? "Brand palette" : "Aboriginal palette";
17005
+ return /* @__PURE__ */ jsx(
17006
+ "button",
17007
+ {
17008
+ type: "button",
17009
+ "aria-label": `Select ${label}`,
17010
+ "aria-pressed": isSelected,
17011
+ onClick: () => handleThemeCategoryChange(palette),
17012
+ className: cn(
17013
+ "rounded-sm border px-3 py-2.5 text-left text-sm font-semibold transition-colors",
17014
+ isSelected ? "border-primary-800 bg-primary-800 text-white" : "border-grey-300 bg-background text-foreground hover:border-primary-800 hover:bg-primary-50"
17015
+ ),
17016
+ children: label
17017
+ },
17018
+ palette
17019
+ );
17020
+ }) }) }),
17021
+ /* @__PURE__ */ jsx(
17022
+ SidebarStep,
17023
+ {
17024
+ step: 2,
17025
+ title: "Choose your colours",
17026
+ description: "Grey is added automatically from the selected palette.",
17027
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
17028
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
17029
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: "Primary colour" }),
17030
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-2", children: selectableFamilies.map((family) => {
17031
+ const swatchTone = 800;
17032
+ const isSelected = family.key === context.primary.key;
17033
+ const label = getFamilySelectorLabel2(family, themeCategory, "primary colour");
17034
+ return /* @__PURE__ */ jsx(
17035
+ "button",
17036
+ {
17037
+ type: "button",
17038
+ "aria-label": `Select ${label} as primary colour`,
17039
+ "aria-pressed": isSelected,
17040
+ onClick: () => handlePrimaryColorChange(family.key),
17041
+ className: cn(
17042
+ "min-h-11 rounded-sm border px-2 py-2 text-center text-[0.8rem] leading-5 font-semibold transition-transform",
17043
+ isSelected ? "ring-2 ring-primary-700 ring-offset-2 ring-offset-grey-50/60" : "hover:-translate-y-px"
17044
+ ),
17045
+ style: {
17046
+ backgroundColor: getFamilySwatchColor2(family, swatchTone),
17047
+ color: getReadableTextColor(swatchTone),
17048
+ borderColor: "rgba(0, 0, 0, 0.12)"
17049
+ },
17050
+ title: label,
17051
+ children: label
17052
+ },
17053
+ family.key
17054
+ );
17055
+ }) })
17056
+ ] }),
17057
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
17058
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: "Accent colour" }),
17059
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-2", children: selectableAccentFamilies.map((family) => {
17060
+ const swatchTone = 600;
17061
+ const isSelected = family.key === context.accent.key;
17062
+ const label = getFamilySelectorLabel2(family, themeCategory, "accent colour");
17063
+ return /* @__PURE__ */ jsx(
17064
+ "button",
17065
+ {
17066
+ type: "button",
17067
+ "aria-label": `Select ${label} as accent colour`,
17068
+ "aria-pressed": isSelected,
17069
+ onClick: () => handleAccentColorChange(family.key),
17070
+ className: cn(
17071
+ "min-h-11 rounded-sm border px-2 py-2 text-center text-[0.8rem] leading-5 font-semibold transition-transform",
17072
+ isSelected ? "ring-2 ring-primary-700 ring-offset-2 ring-offset-grey-50/60" : "hover:-translate-y-px"
17073
+ ),
17074
+ style: {
17075
+ backgroundColor: getFamilySwatchColor2(family, swatchTone),
17076
+ color: getReadableTextColor(swatchTone),
17077
+ borderColor: "rgba(0, 0, 0, 0.12)"
17078
+ },
17079
+ title: label,
17080
+ children: label
17081
+ },
17082
+ family.key
17083
+ );
17084
+ }) })
17085
+ ] })
17086
+ ] })
17087
+ }
17088
+ ),
17089
+ /* @__PURE__ */ jsx(SidebarStep, { step: 3, title: "Pick a background", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
17090
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
17091
+ "Selected:",
17092
+ " ",
17093
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: selectedBackground.token })
17094
+ ] }),
17095
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-4 gap-2", children: context.backgrounds.map((background) => {
17096
+ const hasPairs = (context.pairsByBackground[background.token]?.length ?? 0) > 0;
17097
+ const isSelected = selectedBackground.token === background.token;
17098
+ return /* @__PURE__ */ jsx(
17099
+ "button",
17100
+ {
17101
+ type: "button",
17102
+ "aria-label": hasPairs ? `Select ${background.token} background` : `Select ${background.token} background with no AAA pairings`,
17103
+ "aria-pressed": isSelected,
17104
+ onClick: () => handleBackgroundChange(background.token),
17105
+ className: cn(
17106
+ "relative aspect-square rounded-sm border transition-transform",
17107
+ isSelected ? "ring-2 ring-primary-700 ring-offset-2 ring-offset-grey-50/60" : "hover:-translate-y-px",
17108
+ !hasPairs && "opacity-80"
17109
+ ),
17110
+ style: {
17111
+ backgroundColor: background.hex,
17112
+ borderColor: "rgba(0, 0, 0, 0.14)"
17113
+ },
17114
+ title: background.token,
17115
+ children: !hasPairs ? /* @__PURE__ */ jsx("span", { className: "absolute top-1/2 left-1/2 h-0.5 w-5 -translate-x-1/2 -translate-y-1/2 rotate-45 rounded-full bg-white shadow-[0_0_0_1px_rgba(0,0,0,0.28)]" }) : null
17116
+ },
17117
+ background.token
17118
+ );
17119
+ }) })
17120
+ ] }) })
17121
+ ] }) }),
17122
+ /* @__PURE__ */ jsxs("main", { className: "space-y-8", children: [
17123
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
17124
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 5, className: "text-foreground", trim: "normal", children: "Live Preview & Results" }),
17125
+ /* @__PURE__ */ jsx(Text, { size: 2, children: "Review the selected pairing in context, then compare the available AAA combinations for your chosen background." })
17126
+ ] }),
17127
+ /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
17128
+ selectedPair ? /* @__PURE__ */ jsx(
17129
+ PreviewHeroCard,
17130
+ {
17131
+ familySummary,
17132
+ isRecommended: Boolean(selectedPair),
17133
+ pair: selectedPair
17134
+ }
17135
+ ) : /* @__PURE__ */ jsx(PreviewFallbackCard2, { background: selectedBackground }),
17136
+ /* @__PURE__ */ jsx(AccessibilityScoreCard, { pair: selectedPair })
17137
+ ] }),
17138
+ /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
17139
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
17140
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 5, className: "text-foreground", trim: "normal", children: "Recommended Combinations" }),
17141
+ /* @__PURE__ */ jsxs("p", { className: "text-base text-muted-foreground", children: [
17142
+ "AAA-recommended foregrounds for",
17143
+ " ",
17144
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: selectedBackground.token }),
17145
+ "."
17146
+ ] })
17147
+ ] }),
17148
+ selectedBackgroundPairs.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid gap-4 md:grid-cols-2 xl:grid-cols-3", children: selectedBackgroundPairs.map((pair) => /* @__PURE__ */ jsx(
17149
+ RecommendedPairCard,
17150
+ {
17151
+ pair,
17152
+ isSelected: selectedPair?.id === pair.id,
17153
+ onSelect: () => handlePairChange(pair.id)
17154
+ },
17155
+ pair.id
17156
+ )) }) : /* @__PURE__ */ jsx(Card, { className: "gap-0 py-0", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-6", children: [
17157
+ /* @__PURE__ */ jsx(Heading, { level: 4, size: 6, className: "text-foreground", trim: "normal", children: "No recommended combinations" }),
17158
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-base text-muted-foreground", children: "Choose another approved background tone to review available AAA pairings." })
17159
+ ] }) })
17160
+ ] }),
17161
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [
17162
+ /* @__PURE__ */ jsx(
17163
+ PairDetailCard2,
17164
+ {
17165
+ color: selectedBackground,
17166
+ role: "Background",
17167
+ visibleFormats
17168
+ }
17169
+ ),
17170
+ detailForeground ? /* @__PURE__ */ jsx(
17171
+ PairDetailCard2,
17172
+ {
17173
+ color: detailForeground,
17174
+ role: "Foreground",
17175
+ visibleFormats
17176
+ }
17177
+ ) : /* @__PURE__ */ jsxs(Card, { className: "gap-4", children: [
17178
+ /* @__PURE__ */ jsx(CardHeader, { className: "gap-3 border-b", children: /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
17179
+ /* @__PURE__ */ jsx(CardTitle, { children: "Foreground" }),
17180
+ /* @__PURE__ */ jsx(CardDescription, { children: "No recommended foreground available" })
17181
+ ] }) }),
17182
+ /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Choose another approved tone or review the recommended foregrounds for the same background." }) })
17183
+ ] })
17184
+ ] })
17185
+ ] })
17186
+ ] });
17187
+ }
17188
+ function ColorPairingToolV2({
17189
+ visibleFormats = DEFAULT_VISIBLE_FORMATS2
17190
+ } = {}) {
17191
+ const normalizedVisibleFormats = [...new Set(visibleFormats)];
17192
+ return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ColorPairingToolV2Loading, {}), children: /* @__PURE__ */ jsx(ColorPairingToolV2Content, { visibleFormats: normalizedVisibleFormats }) });
17193
+ }
17194
+ function Sheet({ ...props }) {
17195
+ return /* @__PURE__ */ jsx(SheetPrimitive.Root, { "data-slot": "sheet", ...props });
17196
+ }
17197
+ function SheetTrigger({ ...props }) {
17198
+ return /* @__PURE__ */ jsx(SheetPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
17199
+ }
17200
+ function SheetClose({ ...props }) {
17201
+ return /* @__PURE__ */ jsx(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
17202
+ }
17203
+ function SheetPortal({ ...props }) {
17204
+ return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
17205
+ }
17206
+ function SheetOverlay({
17207
+ className,
17208
+ ...props
17209
+ }) {
17210
+ return /* @__PURE__ */ jsx(
17211
+ SheetPrimitive.Overlay,
17212
+ {
17213
+ "data-slot": "sheet-overlay",
17214
+ className: cn(
17215
+ "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
17216
+ className
17217
+ ),
17218
+ ...props
17219
+ }
17220
+ );
17221
+ }
17222
+ function SheetContent({
17223
+ className,
17224
+ children,
17225
+ side = "right",
17226
+ showClose = true,
17227
+ ...props
17228
+ }) {
17229
+ return /* @__PURE__ */ jsxs(SheetPortal, { children: [
17230
+ /* @__PURE__ */ jsx(SheetOverlay, {}),
17231
+ /* @__PURE__ */ jsxs(
17232
+ SheetPrimitive.Content,
17233
+ {
17234
+ "data-slot": "sheet-content",
17235
+ className: cn(
17236
+ "fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=closed]:animate-out data-[state=open]:duration-500 data-[state=open]:animate-in",
17237
+ side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
17238
+ side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
17239
+ side === "top" && "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
17240
+ side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
17241
+ className
17242
+ ),
17243
+ ...props,
17244
+ children: [
17245
+ children,
17246
+ showClose && /* @__PURE__ */ jsx(SheetPrimitive.Close, { "data-slot": "sheet-close", className: "absolute top-4 right-4", asChild: true, children: /* @__PURE__ */ jsxs(Button2, { variant: "ghost", size: "icon", children: [
17247
+ /* @__PURE__ */ jsx(Icons.close, { className: "size-6", "aria-hidden": "true" }),
17248
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
17249
+ ] }) })
17250
+ ]
17251
+ }
17252
+ )
17253
+ ] });
17254
+ }
17255
+ function SheetHeader({ className, ...props }) {
17256
+ return /* @__PURE__ */ jsx(
17257
+ "div",
17258
+ {
17259
+ "data-slot": "sheet-header",
17260
+ className: cn("flex flex-col gap-1.5 p-4", className),
17261
+ ...props
17262
+ }
17263
+ );
17264
+ }
17265
+ function SheetFooter({ className, ...props }) {
17266
+ return /* @__PURE__ */ jsx(
17267
+ "div",
17268
+ {
17269
+ "data-slot": "sheet-footer",
17270
+ className: cn("mt-auto flex flex-col gap-2 p-4", className),
17271
+ ...props
17272
+ }
17273
+ );
17274
+ }
17275
+ function SheetTitle({ className, ...props }) {
17276
+ return /* @__PURE__ */ jsx(
17277
+ SheetPrimitive.Title,
17278
+ {
17279
+ "data-slot": "sheet-title",
17280
+ className: cn("font-semibold text-foreground", className),
17281
+ ...props
17282
+ }
17283
+ );
17284
+ }
17285
+ function SheetDescription({
17286
+ className,
17287
+ ...props
17288
+ }) {
17289
+ return /* @__PURE__ */ jsx(
17290
+ SheetPrimitive.Description,
17291
+ {
17292
+ "data-slot": "sheet-description",
17293
+ className: cn("text-sm text-muted-foreground", className),
17294
+ ...props
17295
+ }
17296
+ );
17297
+ }
17298
+ function useSelectorHeight(selector = "header") {
17299
+ const [height, setHeight] = useState(0);
17300
+ const elementRef = useRef(null);
17301
+ const resizeObserverRef = useRef(null);
17302
+ useEffect(() => {
17303
+ const element = document.querySelector(selector);
17304
+ if (!element) return;
17305
+ elementRef.current = element;
17306
+ const resizeObserver = new ResizeObserver((entries) => {
17307
+ const entry = entries[0];
17308
+ const target = entry?.target ?? elementRef.current;
17309
+ if (!target) return;
17310
+ setHeight(target.offsetHeight);
17311
+ });
17312
+ resizeObserverRef.current = resizeObserver;
17313
+ resizeObserver.observe(element);
17314
+ return () => {
17315
+ resizeObserverRef.current?.disconnect();
17316
+ };
17317
+ }, [selector]);
17318
+ return height;
17319
+ }
17320
+
17321
+ // src/hooks/useStickyOffset.ts
17322
+ function useStickyOffset(extraPadding = 0) {
17323
+ const headerHeight = useSelectorHeight("#nsw-header");
17324
+ const navigationHeight = useSelectorHeight("#nsw-main-navigation");
17325
+ return useMemo(() => {
17326
+ const total = headerHeight + navigationHeight + extraPadding;
17327
+ return total > 0 ? total : 0;
17328
+ }, [extraPadding, headerHeight, navigationHeight]);
17329
+ }
17330
+ var PREFERRED_BACKGROUND_TONES3 = [400, 600, 200, 800, 100, 50];
17331
+ var DEFAULT_VISIBLE_FORMATS3 = ["hex", "rgb", "hsl", "oklch"];
17332
+ var DEFAULT_INITIAL_BACKGROUND_TOKEN3 = "nsw-blue-800";
17333
+ 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
+ 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
+ var AAA_LARGE_TEXT_THRESHOLD2 = "4.5:1 for WCAG large text: 24px+, or 18.5px+ bold";
17337
+ var MOBILE_RESULT_SCROLL_QUERY = "(max-width: 1023px)";
17338
+ var PERSISTENT_DRAWER_MIN_WIDTH_QUERY = "(min-width: 1280px)";
17339
+ var COLOR_PAIRING_TOOL_DRAWER_STEPS = [
17340
+ {
17341
+ id: "colours",
17342
+ title: "Choose colours",
17343
+ eyebrow: "Step 1 of 3",
17344
+ description: "Select the palette, primary family, and accent family."
17345
+ },
17346
+ {
17347
+ id: "backgrounds",
17348
+ title: "Choose background",
17349
+ eyebrow: "Step 2 of 3",
17350
+ description: "Pick the background tone that you want to pair."
17351
+ },
17352
+ {
17353
+ id: "combinations",
17354
+ title: "Choose recommended combinations",
17355
+ eyebrow: "Step 3 of 3",
17356
+ description: "Select the foreground pairing that should drive the example."
17357
+ }
17358
+ ];
17359
+ var COLOR_PAIRING_TOOL_V3_ANALYTICS_EVENT = "nsw-colour-pairing-tool-v3";
17360
+ function getToneFromToken3(token) {
17361
+ if (!token) return null;
17362
+ const match = token.match(/-(\d+)$/);
17363
+ return match ? Number.parseInt(match[1], 10) : null;
17364
+ }
17365
+ function getFamilySwatchColor3(family, preferredTone = 600) {
17366
+ const exactMatch = family.colors.find((color2) => color2.tone === preferredTone);
17367
+ if (exactMatch) {
17368
+ return exactMatch.hex;
17369
+ }
17370
+ const closestMatch = [...family.colors].sort(
17371
+ (left, right) => Math.abs(left.tone - preferredTone) - Math.abs(right.tone - preferredTone)
17372
+ )[0];
17373
+ return closestMatch?.hex ?? "transparent";
17374
+ }
17375
+ function getFamilySelectorLabel3(family, themeCategory, selectionRole) {
17376
+ if (themeCategory !== "aboriginal") {
17377
+ return family.label;
17378
+ }
17379
+ const preferredTone = selectionRole === "primary colour" ? 800 : 600;
17380
+ return family.colors.find((color2) => color2.tone === preferredTone)?.name ?? family.label;
17381
+ }
17382
+ function getPairingColorDisplayName3(color2) {
17383
+ return color2.name ?? `${color2.familyLabel} ${color2.tone}`;
17384
+ }
17385
+ function isWhiteForegroundPair3(pair) {
17386
+ return pair.foreground.token === "white";
17387
+ }
17388
+ function isLargeTextOnlyPair(pair) {
17389
+ return pair.passes.aaaLarge && !pair.passes.aaaText;
17390
+ }
17391
+ function getWhiteForegroundGuidance3(pair) {
17392
+ if (pair.passes.aaaText) {
17393
+ return "White is approved for headings, body copy, and calls to action on this background.";
17394
+ }
17395
+ if (pair.passes.aaaLarge) {
17396
+ return "Use white only for WCAG large text on this background, such as headings at 24px+ or bold text at 18.5px+. Keep sentence-case body copy at 16px+ and use a darker recommended foreground instead.";
17397
+ }
17398
+ return "Do not use white on this background. Choose one of the recommended foregrounds below instead.";
17399
+ }
17400
+ function getPreviewGuidance3(pair, isRecommended) {
17401
+ if (!isWhiteForegroundPair3(pair)) {
17402
+ return "Use only AAA-recommended combinations across your selected primary, accent, and grey families.";
17403
+ }
17404
+ if (isRecommended) {
17405
+ return "Use white text on dark colour only when it meets AAA for headings, body copy, and calls to action.";
17406
+ }
17407
+ return getWhiteForegroundGuidance3(pair);
17408
+ }
17409
+ function getPreferredPairForBackground3(pairs, preferredPairId) {
17410
+ if (preferredPairId) {
17411
+ const preferredPair = pairs.find((pair) => pair.id === preferredPairId);
17412
+ if (preferredPair) {
17413
+ return preferredPair;
17414
+ }
17415
+ }
17416
+ return pairs.find((pair) => !isWhiteForegroundPair3(pair)) ?? pairs[0] ?? null;
17417
+ }
17418
+ function getDefaultBackgroundToken3(context) {
17419
+ for (const tone of PREFERRED_BACKGROUND_TONES3) {
17420
+ for (const group of context.backgroundGroups) {
17421
+ const match = group.backgrounds.find(
17422
+ (background) => background.tone === tone && (context.pairsByBackground[background.token]?.length ?? 0) > 0
17423
+ );
17424
+ if (match) {
17425
+ return match.token;
17426
+ }
17427
+ }
17428
+ }
17429
+ for (const tone of PREFERRED_BACKGROUND_TONES3) {
17430
+ for (const group of context.backgroundGroups) {
17431
+ const match = group.backgrounds.find((background) => background.tone === tone);
17432
+ if (match) {
17433
+ return match.token;
17434
+ }
17435
+ }
17436
+ }
17437
+ return context.backgrounds[0]?.token ?? "";
17438
+ }
17439
+ function resolveBackgroundToken3(context, preferredToken, preferredTone) {
17440
+ if (preferredToken && context.backgrounds.some((background) => background.token === preferredToken)) {
17441
+ return preferredToken;
17442
+ }
17443
+ if (preferredTone !== null && preferredTone !== void 0) {
17444
+ for (const group of context.backgroundGroups) {
17445
+ const match = group.backgrounds.find((background) => background.tone === preferredTone);
17446
+ if (match) {
17447
+ return match.token;
17448
+ }
17449
+ }
17450
+ }
17451
+ return getDefaultBackgroundToken3(context);
17452
+ }
17453
+ function getInitialPairingState3(searchParams) {
17454
+ const paletteParam = searchParams.get("palette");
17455
+ const primaryParam = searchParams.get("primary");
17456
+ const accentParam = searchParams.get("accent");
17457
+ const pairParam = searchParams.get("pair");
17458
+ const backgroundParam = searchParams.get("background");
17459
+ const themeCategory = paletteParam === "brand" || paletteParam === "aboriginal" ? paletteParam : "brand";
17460
+ const context = getPairingContext(themeCategory, primaryParam, accentParam);
17461
+ const shouldUseDefaultBrandExample = !backgroundParam && !pairParam && themeCategory === "brand" && context.primary.key === "blue" && context.accent.key === "red";
17462
+ const defaultBackgroundToken = shouldUseDefaultBrandExample ? context.backgrounds.some(
17463
+ (background) => background.token === DEFAULT_INITIAL_BACKGROUND_TOKEN3
17464
+ ) ? DEFAULT_INITIAL_BACKGROUND_TOKEN3 : null : null;
17465
+ const defaultPairId = shouldUseDefaultBrandExample && defaultBackgroundToken && context.pairsByBackground[defaultBackgroundToken]?.some(
17466
+ (pair) => pair.id === DEFAULT_INITIAL_PAIR_ID3
17467
+ ) ? DEFAULT_INITIAL_PAIR_ID3 : null;
17468
+ const pairBackgroundToken = context.recommendedPairs.find((pair) => pair.id === pairParam)?.background.token ?? null;
17469
+ const selectedBackgroundToken = resolveBackgroundToken3(
17470
+ context,
17471
+ backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken,
17472
+ getToneFromToken3(backgroundParam ?? pairBackgroundToken ?? defaultBackgroundToken)
17473
+ );
17474
+ const selectedPairId = getPreferredPairForBackground3(
17475
+ context.pairsByBackground[selectedBackgroundToken] ?? [],
17476
+ pairParam ?? defaultPairId
17477
+ )?.id ?? "";
17478
+ return {
17479
+ accentKey: context.accent.key,
17480
+ primaryKey: context.primary.key,
17481
+ selectedBackgroundToken,
17482
+ selectedPairId,
17483
+ themeCategory
17484
+ };
17485
+ }
17486
+ function getReadableTextColor2(tone) {
17487
+ return tone >= 600 ? "#ffffff" : "#002664";
17488
+ }
17489
+ function getBackgroundOptionName(background) {
17490
+ return background.name ?? `${background.familyLabel} ${background.tone}`;
17491
+ }
17492
+ function getResultExplanation(pair, bestPair) {
17493
+ if (!pair) {
17494
+ return "No AAA-compliant foreground options available for this selection.";
17495
+ }
17496
+ if (pair.id === bestPair?.id) {
17497
+ return "Meets AAA for normal and large text. This is the NSW-recommended starting point for this background.";
17498
+ }
17499
+ if (isWhiteForegroundPair3(pair) && isLargeTextOnlyPair(pair)) {
17500
+ return "White meets AAA for large text on this background only. Use a darker foreground for standard body copy and smaller interface text.";
17501
+ }
17502
+ if (isWhiteForegroundPair3(pair) && !pair.passes.aaaLarge) {
17503
+ return "White does not meet AAA for normal or large text on this background. Use another approved background or a darker foreground where one is available.";
17504
+ }
17505
+ return "Meets AAA for normal and large text. This is a valid alternative, while the recommended pairing remains the clearest default.";
17506
+ }
17507
+ function getBestRecommendationReason(pair, context) {
17508
+ if (isWhiteForegroundPair3(pair)) {
17509
+ return "Recommended because this background is dark enough to support white text at AAA contrast.";
17510
+ }
17511
+ if (pair.foreground.familyKey === pair.background.familyKey) {
17512
+ return "Recommended because it stays within the same colour family while keeping clear AAA contrast.";
17513
+ }
17514
+ if (pair.foreground.familyKey === context.grey.key) {
17515
+ return "Recommended because grey provides a strong neutral contrast without competing with the background.";
17516
+ }
17517
+ if (pair.foreground.familyKey === context.accent.key) {
17518
+ return "Recommended because the selected accent family adds emphasis while preserving AAA contrast.";
17519
+ }
17520
+ if (pair.foreground.familyKey === context.primary.key) {
17521
+ return "Recommended because the selected primary family gives the clearest AAA-compliant contrast for this background.";
17522
+ }
17523
+ return "Recommended because it is the clearest NSW-approved AAA pairing for this background.";
17524
+ }
17525
+ function getRecommendationCategory(pair, bestPair, context) {
17526
+ if (pair.id === bestPair?.id) return "best";
17527
+ if (isWhiteForegroundPair3(pair)) return "white";
17528
+ if (pair.foreground.familyKey === pair.background.familyKey) return "same-family";
17529
+ if (pair.foreground.familyKey === context.accent.key) return "accent-family";
17530
+ if (pair.foreground.familyKey === context.grey.key) return "grey-option";
17531
+ if (pair.foreground.familyKey === context.primary.key) return "primary-family";
17532
+ return "approved";
17533
+ }
17534
+ function getRecommendationCategoryLabel(category) {
17535
+ switch (category) {
17536
+ case "best":
17537
+ return "Best recommended";
17538
+ case "same-family":
17539
+ return "Same family";
17540
+ case "accent-family":
17541
+ return "Accent family";
17542
+ case "grey-option":
17543
+ return "Grey option";
17544
+ case "primary-family":
17545
+ return "Primary family";
17546
+ case "white":
17547
+ return "White";
17548
+ default:
17549
+ return "Approved option";
17550
+ }
17551
+ }
17552
+ function getRecommendationSortRank(category) {
17553
+ switch (category) {
17554
+ case "best":
17555
+ return 0;
17556
+ case "same-family":
17557
+ return 1;
17558
+ case "accent-family":
17559
+ return 2;
17560
+ case "grey-option":
17561
+ return 3;
17562
+ case "white":
17563
+ return 4;
17564
+ case "primary-family":
17565
+ return 5;
17566
+ default:
17567
+ return 6;
17568
+ }
17569
+ }
17570
+ function getAvailabilityMeta(isSelected, hasPairs) {
17571
+ if (isSelected && hasPairs) {
17572
+ return {
17573
+ description: "Selected background with AAA foreground options.",
17574
+ icon: Icons.check_circle,
17575
+ label: "Selected",
17576
+ tone: "selected"
17577
+ };
17578
+ }
17579
+ if (isSelected) {
17580
+ return {
17581
+ description: "Selected background with no AAA foreground options.",
17582
+ icon: Icons.warning,
17583
+ label: "Selected, no AAA",
17584
+ tone: "unavailable"
17585
+ };
17586
+ }
17587
+ if (hasPairs) {
17588
+ return {
17589
+ description: "AAA foreground options available.",
17590
+ icon: Icons.radio_button_checked,
17591
+ label: "Available",
17592
+ tone: "available"
17593
+ };
17594
+ }
17595
+ return {
17596
+ description: "No AAA foreground available.",
17597
+ icon: Icons.close,
17598
+ label: "No AAA",
17599
+ tone: "unavailable"
17600
+ };
17601
+ }
17602
+ function getPairingCopyText(pair) {
17603
+ return [
17604
+ `Background: ${pair.background.token} (${pair.background.hex})`,
17605
+ `Foreground: ${pair.foreground.token} (${pair.foreground.hex})`,
17606
+ `Contrast ratio: ${pair.contrastRatio.toFixed(2)}:1`,
17607
+ "Accessibility: Meets AAA for normal and large text"
17608
+ ].join("\n");
17609
+ }
17610
+ function getLiveAnnouncement(pair, background) {
17611
+ if (!background) {
17612
+ return "No approved background tones available.";
17613
+ }
17614
+ if (!pair) {
17615
+ return `${background.token} selected. No AAA-compliant foreground options available for this selection.`;
17616
+ }
17617
+ if (isWhiteForegroundPair3(pair) && isLargeTextOnlyPair(pair)) {
17618
+ return `${background.token} with white. Contrast ratio ${pair.contrastRatio.toFixed(2)} to 1. Meets AAA for large text only.`;
17619
+ }
17620
+ if (isWhiteForegroundPair3(pair) && !pair.passes.aaaLarge) {
17621
+ return `${background.token} with white. Contrast ratio ${pair.contrastRatio.toFixed(2)} to 1. Fails AAA for normal and large text.`;
17622
+ }
17623
+ return `${background.token} with ${pair.foreground.token}. Contrast ratio ${pair.contrastRatio.toFixed(2)} to 1. Meets AAA for normal and large text.`;
17624
+ }
17625
+ function formatValueRows(color2, visibleFormats) {
17626
+ const hasDisplayTone = color2.token !== "white";
17627
+ return [
17628
+ { key: "token", label: "Token", value: color2.token, copyable: true },
17629
+ {
17630
+ key: "tone",
17631
+ label: "Tone",
17632
+ value: hasDisplayTone ? String(color2.tone) : "Not applicable",
17633
+ copyable: hasDisplayTone
17634
+ },
17635
+ ...visibleFormats.map((format) => ({
17636
+ key: format,
17637
+ label: format.toUpperCase(),
17638
+ value: color2[format],
17639
+ copyable: true
17640
+ }))
17641
+ ];
17642
+ }
17643
+ function SelectorButton({
17644
+ description,
17645
+ isSelected,
17646
+ label,
17647
+ onClick,
17648
+ swatch
17649
+ }) {
17650
+ return /* @__PURE__ */ jsx(
17651
+ "button",
17652
+ {
17653
+ type: "button",
17654
+ "aria-pressed": isSelected,
17655
+ onClick,
17656
+ className: cn(
17657
+ "w-full rounded-sm border px-3 py-3 text-left transition-colors focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
17658
+ isSelected ? "border-primary-800 bg-primary-50" : "border-grey-300 bg-white hover:border-primary-500 hover:bg-grey-50"
17659
+ ),
17660
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
17661
+ swatch ? /* @__PURE__ */ jsx(
17662
+ "span",
17663
+ {
17664
+ "aria-hidden": "true",
17665
+ className: "mt-0.5 size-4 shrink-0 rounded-full border border-black/10",
17666
+ style: { backgroundColor: swatch }
17667
+ }
17668
+ ) : null,
17669
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
17670
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: label }),
17671
+ description ? /* @__PURE__ */ jsx("p", { className: "text-xs/5 text-muted-foreground", children: description }) : null
17672
+ ] })
17673
+ ] })
17674
+ }
17675
+ );
17676
+ }
17677
+ function BackgroundSwatchButton({
17678
+ background,
17679
+ hasPairs,
17680
+ isSelected,
17681
+ onClick
17682
+ }) {
17683
+ const status = getAvailabilityMeta(isSelected, hasPairs);
17684
+ const StatusIcon = status.icon;
17685
+ return /* @__PURE__ */ jsxs(
17686
+ "button",
17687
+ {
17688
+ type: "button",
17689
+ "aria-pressed": isSelected,
17690
+ "aria-label": `Select ${background.token} background. ${status.description}`,
17691
+ onClick,
17692
+ className: cn(
17693
+ "w-full rounded-sm border bg-white p-3 text-left transition-colors focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
17694
+ isSelected ? "border-primary-800 bg-primary-50" : hasPairs ? "border-grey-300 hover:border-primary-500 hover:bg-grey-50" : "border-grey-300 hover:border-grey-500"
17695
+ ),
17696
+ children: [
17697
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
17698
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
17699
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: getBackgroundOptionName(background) }),
17700
+ /* @__PURE__ */ jsx("p", { className: "mt-1 font-mono text-[0.72rem] break-all text-muted-foreground", children: background.token })
17701
+ ] }),
17702
+ /* @__PURE__ */ jsxs(
17703
+ "span",
17704
+ {
17705
+ className: cn(
17706
+ "inline-flex items-center gap-1 rounded-sm border px-2 py-1 text-[0.68rem] font-semibold uppercase",
17707
+ status.tone === "selected" && "border-primary-800 bg-primary-800 text-white dark:border-primary-500 dark:bg-primary-500",
17708
+ status.tone === "available" && "border-grey-300 bg-grey-50 text-foreground",
17709
+ status.tone === "unavailable" && "border-danger-300 bg-danger-50 text-danger-900 dark:border-danger-800 dark:bg-danger-950/20 dark:text-danger-200"
17710
+ ),
17711
+ children: [
17712
+ /* @__PURE__ */ jsx(StatusIcon, { "data-slot": "icon", className: "size-4" }),
17713
+ status.label
17714
+ ]
17715
+ }
17716
+ )
17717
+ ] }),
17718
+ /* @__PURE__ */ jsx("div", { className: "mt-3 overflow-hidden rounded-[2px] border border-black/10", children: /* @__PURE__ */ jsx("div", { className: "h-14 w-full", style: { backgroundColor: background.hex } }) }),
17719
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-xs/5 text-muted-foreground", children: status.description })
17720
+ ]
17721
+ }
17722
+ );
17723
+ }
17724
+ function ResultSummaryTile({
17725
+ children,
17726
+ className,
17727
+ label
17728
+ }) {
17729
+ return /* @__PURE__ */ jsxs("div", { className: cn("rounded-sm border border-grey-200 bg-white px-4 py-4 sm:px-5", className), children: [
17730
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-grey-700", children: label }),
17731
+ /* @__PURE__ */ jsx("div", { className: "mt-3", children })
17732
+ ] });
17733
+ }
17734
+ function AccessibilityCheckTile({
17735
+ className,
17736
+ label,
17737
+ passes,
17738
+ threshold
17739
+ }) {
17740
+ const status = passes === null ? "unavailable" : passes ? "pass" : "fail";
17741
+ return /* @__PURE__ */ jsx(
17742
+ "div",
17743
+ {
17744
+ className: cn(
17745
+ "rounded-sm border px-4 py-4 sm:px-5",
17746
+ className,
17747
+ status === "pass" && "border-success-200 bg-success-50",
17748
+ status === "fail" && "border-danger-200 bg-danger-50",
17749
+ status === "unavailable" && "border-grey-200 bg-white"
17750
+ ),
17751
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between sm:gap-4", children: [
17752
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
17753
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: label }),
17754
+ /* @__PURE__ */ jsx("p", { className: "text-sm/6 text-muted-foreground", children: status === "unavailable" ? "No contrast ratio available for this result." : threshold })
17755
+ ] }),
17756
+ /* @__PURE__ */ jsxs(
17757
+ "span",
17758
+ {
17759
+ className: cn(
17760
+ "inline-flex items-center gap-1 rounded-sm px-2.5 py-1 text-[0.72rem] font-semibold tracking-[0.12em] uppercase",
17761
+ status === "pass" && "bg-success-700 text-white",
17762
+ status === "fail" && "bg-danger-700 text-white",
17763
+ status === "unavailable" && "bg-grey-100 text-foreground"
17764
+ ),
17765
+ children: [
17766
+ status === "pass" ? /* @__PURE__ */ jsx(Icons.check, { "data-slot": "icon", className: "size-4" }) : status === "fail" ? /* @__PURE__ */ jsx(Icons.close, { "data-slot": "icon", className: "size-4" }) : /* @__PURE__ */ jsx(Icons.info, { "data-slot": "icon", className: "size-4" }),
17767
+ status === "pass" ? "Pass" : status === "fail" ? "Fail" : "Unavailable"
17768
+ ]
17769
+ }
17770
+ )
17771
+ ] })
17772
+ }
17773
+ );
17774
+ }
17775
+ function ResultColorSummary({
17776
+ color: color2,
17777
+ fallbackLabel
17778
+ }) {
17779
+ if (!color2) {
17780
+ return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: fallbackLabel ?? "Not available" });
17781
+ }
17782
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-4", children: [
17783
+ /* @__PURE__ */ jsx(
17784
+ "span",
17785
+ {
17786
+ "aria-hidden": "true",
17787
+ className: "mt-1 size-6 shrink-0 rounded-full border border-black/10",
17788
+ style: { backgroundColor: color2.hex }
17789
+ }
17790
+ ),
17791
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
17792
+ /* @__PURE__ */ jsx("p", { className: "leading-7 font-semibold text-foreground", children: getPairingColorDisplayName3(color2) }),
17793
+ /* @__PURE__ */ jsx("p", { className: "mt-1 font-mono text-sm break-all text-muted-foreground", children: color2.token })
17794
+ ] })
17795
+ ] });
17796
+ }
17797
+ function CurrentResultCard({
17798
+ bestPair,
17799
+ familySummary,
17800
+ pair,
17801
+ selectedBackground
17802
+ }) {
17803
+ const previewForeground = pair?.foreground.hex ?? getReadableTextColor2(selectedBackground.tone);
17804
+ const isRecommended = pair ? pair.id === bestPair?.id : false;
17805
+ const whiteForeground = pair ? isWhiteForegroundPair3(pair) : false;
17806
+ const statusLabel = pair ? pair.passes.aaaText ? "Pass" : pair.passes.aaaLarge ? "Large text only" : "Example only" : "No recommendation";
17807
+ const fauxButtonStyle = pair ? {
17808
+ "--btn-bg": pair.foreground.hex,
17809
+ "--btn-border": pair.foreground.hex,
17810
+ "--btn-text": pair.background.hex,
17811
+ "--btn-icon": pair.background.hex,
17812
+ "--btn-hover-overlay": pair.background.hex
17813
+ } : null;
17814
+ return /* @__PURE__ */ jsxs(Card, { className: "gap-0 overflow-hidden py-0", children: [
17815
+ /* @__PURE__ */ jsx("div", { className: "border-b border-grey-200 px-4 py-4 sm:px-6 sm:py-5", children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
17816
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
17817
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.12em] text-muted-foreground uppercase", children: "Current result" }),
17818
+ /* @__PURE__ */ jsx(Heading, { level: 2, size: 4, className: "text-foreground", trim: "normal", children: pair ? `${getPairingColorDisplayName3(pair.foreground)} on ${getPairingColorDisplayName3(pair.background)}` : `${getPairingColorDisplayName3(selectedBackground)} selected` })
17819
+ ] }),
17820
+ /* @__PURE__ */ jsx(Text, { size: 2, className: "max-w-3xl text-grey-700", children: getResultExplanation(pair, bestPair) })
17821
+ ] }) }),
17822
+ /* @__PURE__ */ jsx(
17823
+ "div",
17824
+ {
17825
+ className: "p-4 sm:min-h-[26rem] sm:p-8",
17826
+ style: {
17827
+ backgroundColor: selectedBackground.hex,
17828
+ color: previewForeground
17829
+ },
17830
+ children: /* @__PURE__ */ jsxs("div", { className: "flex min-h-[18rem] flex-col justify-between gap-6 sm:min-h-[22rem] sm:gap-8", children: [
17831
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
17832
+ /* @__PURE__ */ jsxs(
17833
+ "span",
17834
+ {
17835
+ className: "inline-flex items-center gap-2 rounded-full border px-3 py-1 text-[0.68rem] font-semibold tracking-[0.16em] uppercase sm:text-[0.72rem]",
17836
+ style: {
17837
+ borderColor: pair ? pair.foreground.hex : "currentColor",
17838
+ backgroundColor: pair ? pair.foreground.hex : "transparent",
17839
+ color: pair ? pair.background.hex : "currentColor"
17840
+ },
17841
+ children: [
17842
+ /* @__PURE__ */ jsx(Icons.palette, { "data-slot": "icon", className: "size-4" }),
17843
+ familySummary
17844
+ ]
17845
+ }
17846
+ ),
17847
+ pair ? /* @__PURE__ */ jsxs(
17848
+ "span",
17849
+ {
17850
+ className: "inline-flex rounded-full border px-3 py-1 text-[0.68rem] font-semibold tracking-[0.16em] uppercase sm:text-[0.72rem]",
17851
+ style: {
17852
+ borderColor: pair.foreground.hex
17853
+ },
17854
+ children: [
17855
+ pair.rating,
17856
+ " ",
17857
+ pair.contrastRatio.toFixed(2),
17858
+ ":1"
17859
+ ]
17860
+ }
17861
+ ) : null
17862
+ ] }),
17863
+ /* @__PURE__ */ jsxs("div", { className: "max-w-xl space-y-4 pb-8 sm:pb-16", children: [
17864
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold tracking-[0.22em] uppercase", children: pair ? whiteForeground && !isRecommended ? "White on colour example" : whiteForeground ? "White on colour" : "Colour on colour" : "Approved background" }),
17865
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
17866
+ /* @__PURE__ */ jsx("h3", { className: "max-w-lg text-3xl leading-tight font-bold text-current sm:text-5xl sm:leading-none", children: "Pair colour with confidence." }),
17867
+ /* @__PURE__ */ jsx("p", { className: "max-w-full text-base/6 sm:max-w-md sm:text-base/7", children: pair ? getPreviewGuidance3(pair, isRecommended) : "This approved background tone does not currently have a recommended AAA foreground in this tool. Choose another approved background tone to continue." }),
17868
+ pair && fauxButtonStyle ? /* @__PURE__ */ jsx(
17869
+ "span",
17870
+ {
17871
+ "aria-hidden": "true",
17872
+ "data-variant": "solid",
17873
+ className: cn(
17874
+ buttonVariants({ variant: "solid", size: "default" }),
17875
+ "pointer-events-none cursor-default px-6 text-[16px] font-[700] select-none sm:px-6 sm:text-[16px] sm:font-[700]"
17876
+ ),
17877
+ style: fauxButtonStyle,
17878
+ children: "Get started"
17879
+ }
17880
+ ) : null
17881
+ ] })
17882
+ ] }),
17883
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
17884
+ /* @__PURE__ */ jsxs(
17885
+ "span",
17886
+ {
17887
+ className: "inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-semibold",
17888
+ style: pair ? {
17889
+ backgroundColor: pair.foreground.hex,
17890
+ color: pair.background.hex
17891
+ } : {
17892
+ backgroundColor: "rgb(255 255 255 / 0.14)",
17893
+ color: "currentColor"
17894
+ },
17895
+ children: [
17896
+ statusLabel,
17897
+ pair && pair.passes.aaaText ? /* @__PURE__ */ jsx(Icons.check, { "data-slot": "icon", className: "size-4" }) : /* @__PURE__ */ jsx(Icons.info, { "data-slot": "icon", className: "size-4" })
17898
+ ]
17899
+ }
17900
+ ),
17901
+ /* @__PURE__ */ jsx(
17902
+ "span",
17903
+ {
17904
+ className: "inline-flex max-w-full rounded-full border px-4 py-2 text-[0.82rem] break-all sm:text-sm",
17905
+ style: {
17906
+ borderColor: pair ? pair.foreground.hex : "currentColor"
17907
+ },
17908
+ children: pair ? `${pair.background.token} / ${pair.foreground.token}` : selectedBackground.token
17909
+ }
17910
+ )
17911
+ ] })
17912
+ ] })
17913
+ }
17914
+ ),
17915
+ /* @__PURE__ */ jsx("div", { className: "space-y-5 border-t border-grey-200 bg-grey-50 px-4 py-5 sm:px-6 sm:py-6", children: /* @__PURE__ */ jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [
17916
+ /* @__PURE__ */ jsx(ResultSummaryTile, { label: "Background", children: /* @__PURE__ */ jsx(ResultColorSummary, { color: selectedBackground }) }),
17917
+ /* @__PURE__ */ jsx(ResultSummaryTile, { label: "Foreground", children: /* @__PURE__ */ jsx(
17918
+ ResultColorSummary,
17919
+ {
17920
+ color: pair?.foreground,
17921
+ fallbackLabel: "No AAA foreground available"
17922
+ }
17923
+ ) }),
17924
+ /* @__PURE__ */ jsxs(ResultSummaryTile, { label: "Contrast ratio", className: "lg:col-span-2", children: [
17925
+ /* @__PURE__ */ jsx("p", { className: "text-4xl leading-none font-bold text-foreground", children: pair ? `${pair.contrastRatio.toFixed(2)}:1` : "N/A" }),
17926
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: pair ? pair.passes.aaaText ? "Meets AAA accessibility" : pair.passes.aaaLarge ? "Meets AAA for large text only" : "Does not meet accessibility requirements" : "Does not meet accessibility requirements" })
17927
+ ] }),
17928
+ /* @__PURE__ */ jsx(
17929
+ AccessibilityCheckTile,
17930
+ {
17931
+ className: "lg:col-span-2",
17932
+ label: "AAA normal text",
17933
+ passes: pair ? pair.passes.aaaText : null,
17934
+ threshold: AAA_NORMAL_TEXT_THRESHOLD2
17935
+ }
17936
+ ),
17937
+ /* @__PURE__ */ jsx(
17938
+ AccessibilityCheckTile,
17939
+ {
17940
+ className: "lg:col-span-2",
17941
+ label: "AAA large text",
17942
+ passes: pair ? pair.passes.aaaLarge : null,
17943
+ threshold: AAA_LARGE_TEXT_THRESHOLD2
17944
+ }
17945
+ )
17946
+ ] }) })
17947
+ ] });
17948
+ }
17949
+ function BestRecommendationCard({
17950
+ copiedKey,
17951
+ isCurrentSelection,
17952
+ onCopyPairing,
17953
+ onUsePairing,
17954
+ pair,
17955
+ reason
17956
+ }) {
17957
+ return /* @__PURE__ */ jsxs(Card, { className: "gap-5 border-primary-200 bg-primary-50/60 px-6 py-6", children: [
17958
+ /* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
17959
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
17960
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
17961
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2 rounded-sm bg-primary-800 px-3 py-1 text-[0.72rem] font-semibold tracking-[0.12em] text-white uppercase", children: [
17962
+ /* @__PURE__ */ jsx(Icons.check_circle, { "data-slot": "icon", className: "size-4" }),
17963
+ "Best recommended pairing"
17964
+ ] }),
17965
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex rounded-sm border border-primary-300 px-3 py-1 text-[0.72rem] font-semibold tracking-[0.12em] text-primary-900 uppercase", children: [
17966
+ pair.contrastRatio.toFixed(2),
17967
+ ":1"
17968
+ ] })
17969
+ ] }),
17970
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
17971
+ /* @__PURE__ */ jsxs(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: [
17972
+ pair.background.token,
17973
+ " / ",
17974
+ pair.foreground.token
17975
+ ] }),
17976
+ /* @__PURE__ */ jsx(Text, { size: 2, className: "max-w-3xl text-grey-700", children: reason })
17977
+ ] })
17978
+ ] }),
17979
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center", children: [
17980
+ isCurrentSelection ? null : /* @__PURE__ */ jsx(
17981
+ Button2,
17982
+ {
17983
+ className: "w-full justify-center sm:w-auto sm:min-w-56",
17984
+ color: "primary",
17985
+ onClick: onUsePairing,
17986
+ "aria-label": `Use ${pair.foreground.token} on ${pair.background.token}`,
17987
+ children: "Use best recommendation"
17988
+ }
17989
+ ),
17990
+ /* @__PURE__ */ jsxs(
17991
+ Button2,
17992
+ {
17993
+ className: "w-full justify-center sm:w-auto sm:min-w-48",
17994
+ variant: "outline",
17995
+ color: "grey",
17996
+ onClick: onCopyPairing,
17997
+ children: [
17998
+ /* @__PURE__ */ jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
17999
+ copiedKey === "best-pairing" ? "Pairing copied" : "Copy pairing"
18000
+ ]
18001
+ }
18002
+ )
18003
+ ] })
18004
+ ] }),
18005
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
18006
+ /* @__PURE__ */ jsx(ResultSummaryTile, { label: "Background", children: /* @__PURE__ */ jsx(ResultColorSummary, { color: pair.background }) }),
18007
+ /* @__PURE__ */ jsx(ResultSummaryTile, { label: "Foreground", children: /* @__PURE__ */ jsx(ResultColorSummary, { color: pair.foreground }) }),
18008
+ /* @__PURE__ */ jsxs(ResultSummaryTile, { label: "Accessibility", className: "md:col-span-2", children: [
18009
+ /* @__PURE__ */ jsx("p", { className: "text-xl leading-8 font-semibold text-foreground", children: "Meets AAA accessibility" }),
18010
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-base/7 text-muted-foreground", children: "Best NSW default for this background." })
18011
+ ] })
18012
+ ] })
18013
+ ] });
18014
+ }
18015
+ function RecommendationCard({
18016
+ copiedKey,
18017
+ isSelected,
18018
+ item,
18019
+ onCopyPairing,
18020
+ onSelect
18021
+ }) {
18022
+ const { pair } = item;
18023
+ return /* @__PURE__ */ jsxs(
18024
+ "div",
18025
+ {
18026
+ className: cn(
18027
+ "relative rounded-sm border bg-white p-4 text-left transition-colors focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
18028
+ isSelected ? "border-primary-800 bg-primary-50/50" : "border-grey-200 hover:border-primary-500 hover:bg-grey-50"
18029
+ ),
18030
+ children: [
18031
+ /* @__PURE__ */ jsx(
18032
+ "button",
18033
+ {
18034
+ type: "button",
18035
+ "aria-pressed": isSelected,
18036
+ "aria-label": `Use ${pair.foreground.token} on ${pair.background.token}`,
18037
+ onClick: onSelect,
18038
+ className: "absolute inset-0 rounded-sm focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden"
18039
+ }
18040
+ ),
18041
+ /* @__PURE__ */ jsxs("div", { className: "pointer-events-none relative z-10", children: [
18042
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-3 sm:flex-row sm:items-start sm:justify-between", children: [
18043
+ /* @__PURE__ */ jsxs(
18044
+ "span",
18045
+ {
18046
+ className: cn(
18047
+ "inline-flex items-center gap-2 rounded-sm px-2.5 py-1 text-[0.68rem] font-semibold tracking-[0.12em] uppercase",
18048
+ item.category === "best" ? "bg-primary-800 text-white" : "border border-grey-300 bg-grey-50 text-foreground"
18049
+ ),
18050
+ children: [
18051
+ item.category === "best" ? /* @__PURE__ */ jsx(Icons.check_circle, { "data-slot": "icon", className: "size-4" }) : /* @__PURE__ */ jsx(Icons.info, { "data-slot": "icon", className: "size-4" }),
18052
+ item.categoryLabel
18053
+ ]
18054
+ }
18055
+ ),
18056
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-auto shrink-0 self-start", children: /* @__PURE__ */ jsxs(
18057
+ Button2,
18058
+ {
18059
+ variant: "ghost",
18060
+ color: "grey",
18061
+ size: "sm",
18062
+ onClick: onCopyPairing,
18063
+ "aria-label": `Copy pairing ${pair.background.token} and ${pair.foreground.token}`,
18064
+ children: [
18065
+ /* @__PURE__ */ jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
18066
+ copiedKey === `pair:${pair.id}` ? "Copied" : "Copy"
18067
+ ]
18068
+ }
18069
+ ) })
18070
+ ] }),
18071
+ /* @__PURE__ */ jsxs("div", { className: "mt-4", children: [
18072
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 sm:grid-cols-[4rem_minmax(0,1fr)]", children: [
18073
+ /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-[2px] border border-black/10", children: [
18074
+ /* @__PURE__ */ jsx("div", { className: "h-16 w-full", style: { backgroundColor: pair.background.hex } }),
18075
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-full", style: { backgroundColor: pair.foreground.hex } })
18076
+ ] }),
18077
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-2", children: [
18078
+ /* @__PURE__ */ jsxs("div", { children: [
18079
+ /* @__PURE__ */ jsx("p", { className: "text-base font-semibold text-foreground", children: getPairingColorDisplayName3(pair.foreground) }),
18080
+ /* @__PURE__ */ jsx("p", { className: "mt-1 font-mono text-[0.74rem] break-all text-muted-foreground", children: pair.foreground.token })
18081
+ ] }),
18082
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
18083
+ pair.foreground.familyLabel,
18084
+ " on ",
18085
+ pair.background.familyLabel
18086
+ ] })
18087
+ ] })
18088
+ ] }),
18089
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-col items-start gap-3 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between", children: [
18090
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
18091
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex rounded-sm border border-grey-300 px-2.5 py-1 text-sm font-semibold text-foreground", children: [
18092
+ pair.contrastRatio.toFixed(2),
18093
+ ":1"
18094
+ ] }),
18095
+ /* @__PURE__ */ jsx("span", { className: "inline-flex rounded-sm bg-success-700 px-2.5 py-1 text-[0.72rem] font-semibold tracking-[0.12em] text-white uppercase", children: "AAA" })
18096
+ ] }),
18097
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-primary-800", children: isSelected ? "Selected" : "Use pairing" })
18098
+ ] })
18099
+ ] })
18100
+ ] })
18101
+ ]
18102
+ }
18103
+ );
18104
+ }
18105
+ function TechnicalDetailsPanel({
18106
+ color: color2,
18107
+ copiedKey,
18108
+ onCopyValue,
18109
+ title,
18110
+ visibleFormats
18111
+ }) {
18112
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-sm border border-grey-200 bg-white", children: [
18113
+ /* @__PURE__ */ jsxs("div", { className: "border-b border-grey-200 px-4 py-4 sm:px-5", children: [
18114
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 6, className: "text-foreground", trim: "normal", children: title }),
18115
+ color2 ? /* @__PURE__ */ jsxs(Fragment, { children: [
18116
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: getPairingColorDisplayName3(color2) }),
18117
+ /* @__PURE__ */ jsx("div", { className: "mt-4 overflow-hidden rounded-sm border border-black/10 bg-white", children: /* @__PURE__ */ jsx("div", { className: "h-20 w-full sm:h-24", style: { backgroundColor: color2.hex } }) })
18118
+ ] }) : /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "No AAA foreground available." })
18119
+ ] }),
18120
+ color2 ? /* @__PURE__ */ jsx("div", { className: "divide-y divide-grey-200", children: formatValueRows(color2, visibleFormats).map((row) => {
18121
+ const copyKey = `${title}-${row.key}`;
18122
+ return /* @__PURE__ */ jsxs(
18123
+ "div",
18124
+ {
18125
+ className: "flex flex-col items-start gap-3 px-4 py-4 sm:flex-row sm:items-start sm:justify-between sm:gap-4 sm:px-5",
18126
+ children: [
18127
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
18128
+ /* @__PURE__ */ jsx("p", { className: "text-[0.72rem] font-semibold tracking-[0.12em] text-muted-foreground uppercase", children: row.label }),
18129
+ /* @__PURE__ */ jsx(
18130
+ "p",
18131
+ {
18132
+ className: cn(
18133
+ "mt-2 text-sm text-foreground",
18134
+ row.key !== "tone" && "font-mono break-all"
18135
+ ),
18136
+ children: row.value
18137
+ }
18138
+ )
18139
+ ] }),
18140
+ row.copyable ? /* @__PURE__ */ jsx(
18141
+ Button2,
18142
+ {
18143
+ variant: "ghost",
18144
+ color: "grey",
18145
+ size: "sm",
18146
+ className: "self-start",
18147
+ onClick: () => onCopyValue(copyKey, row.value, `${row.label} copied`),
18148
+ "aria-label": `Copy ${title.toLowerCase()} ${row.label.toLowerCase()}`,
18149
+ children: copiedKey === copyKey ? /* @__PURE__ */ jsxs(Fragment, { children: [
18150
+ /* @__PURE__ */ jsx(Icons.check_circle, { "data-slot": "icon", className: "size-5" }),
18151
+ "Copied"
18152
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
18153
+ /* @__PURE__ */ jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
18154
+ "Copy"
18155
+ ] })
18156
+ }
18157
+ ) : null
18158
+ ]
18159
+ },
18160
+ row.key
18161
+ );
18162
+ }) }) : /* @__PURE__ */ jsx("div", { className: "px-5 py-5", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No technical values are shown because there is no AAA-compliant foreground for this background." }) })
18163
+ ] });
18164
+ }
18165
+ function resolveSelectionState(nextThemeCategory, nextPrimaryKey, nextAccentKey, preferredBackgroundToken, preferredPairId) {
18166
+ const context = getPairingContext(nextThemeCategory, nextPrimaryKey, nextAccentKey);
18167
+ const selectedBackgroundToken = resolveBackgroundToken3(
18168
+ context,
18169
+ preferredBackgroundToken,
18170
+ getToneFromToken3(preferredBackgroundToken)
18171
+ );
18172
+ const selectedPairId = getPreferredPairForBackground3(
18173
+ context.pairsByBackground[selectedBackgroundToken] ?? [],
18174
+ preferredPairId
18175
+ )?.id ?? "";
18176
+ return {
18177
+ accentKey: context.accent.key,
18178
+ context,
18179
+ primaryKey: context.primary.key,
18180
+ selectedBackgroundToken,
18181
+ selectedPairId,
18182
+ themeCategory: nextThemeCategory
18183
+ };
18184
+ }
18185
+ function ColorPairingToolV3Loading() {
18186
+ return /* @__PURE__ */ jsxs("div", { className: "grid gap-8 xl:grid-cols-[minmax(18rem,24rem)_minmax(0,1fr)]", children: [
18187
+ /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
18188
+ /* @__PURE__ */ jsx("div", { className: "h-52 rounded-sm border border-grey-200 bg-grey-50" }),
18189
+ /* @__PURE__ */ jsx("div", { className: "h-[32rem] rounded-sm border border-grey-200 bg-grey-50" })
18190
+ ] }),
18191
+ /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
18192
+ /* @__PURE__ */ jsx("div", { className: "h-96 rounded-sm border border-grey-200 bg-grey-50" }),
18193
+ /* @__PURE__ */ jsx("div", { className: "h-64 rounded-sm border border-grey-200 bg-grey-50" }),
18194
+ /* @__PURE__ */ jsx("div", { className: "h-72 rounded-sm border border-grey-200 bg-grey-50" })
18195
+ ] })
18196
+ ] });
18197
+ }
18198
+ function ColorPairingToolV3Content({
18199
+ onAnalyticsEvent,
18200
+ visibleFormats
18201
+ }) {
18202
+ const searchParams = useSearchParams();
18203
+ const stickyOffset = useStickyOffset(24);
18204
+ const [initialState] = useState(() => getInitialPairingState3(searchParams));
18205
+ const [themeCategory, setThemeCategory] = useState(initialState.themeCategory);
18206
+ const [primaryFamilyKey, setPrimaryFamilyKey] = useState(initialState.primaryKey);
18207
+ const [accentFamilyKey, setAccentFamilyKey] = useState(initialState.accentKey);
18208
+ const [selectedBackgroundToken, setSelectedBackgroundToken] = useState(
18209
+ initialState.selectedBackgroundToken
18210
+ );
18211
+ const [selectedPairId, setSelectedPairId] = useState(initialState.selectedPairId);
18212
+ const [drawerStepIndex, setDrawerStepIndex] = useState(0);
18213
+ const [isCompactControlsOpen, setIsCompactControlsOpen] = useState(false);
18214
+ const [, copyToClipboardRaw] = useCopyToClipboard();
18215
+ const [copiedKey, setCopiedKey] = useState(null);
18216
+ const copiedKeyTimeoutRef = useRef(null);
18217
+ const resultSectionRef = useRef(null);
18218
+ const noValidStateRef = useRef(/* @__PURE__ */ new Set());
18219
+ const technicalDetailsOpenedRef = useRef(false);
18220
+ const emitAnalyticsEvent = useCallback(
18221
+ (event) => {
18222
+ onAnalyticsEvent(event);
18223
+ if (typeof window !== "undefined") {
18224
+ window.dispatchEvent(
18225
+ new CustomEvent(COLOR_PAIRING_TOOL_V3_ANALYTICS_EVENT, {
18226
+ detail: event
18227
+ })
18228
+ );
18229
+ }
18230
+ },
18231
+ [onAnalyticsEvent]
18232
+ );
18233
+ useEffect(() => {
18234
+ return () => {
18235
+ if (copiedKeyTimeoutRef.current) {
18236
+ clearTimeout(copiedKeyTimeoutRef.current);
18237
+ }
18238
+ };
18239
+ }, []);
18240
+ useEffect(() => {
18241
+ if (typeof window === "undefined") {
18242
+ return;
18243
+ }
18244
+ const mediaQuery = window.matchMedia(PERSISTENT_DRAWER_MIN_WIDTH_QUERY);
18245
+ const handleChange = (event) => {
18246
+ if (event?.matches ?? mediaQuery.matches) {
18247
+ setIsCompactControlsOpen(false);
18248
+ }
18249
+ };
18250
+ handleChange();
18251
+ mediaQuery.addEventListener("change", handleChange);
18252
+ return () => {
18253
+ mediaQuery.removeEventListener("change", handleChange);
18254
+ };
18255
+ }, []);
18256
+ const themeFamilies = useMemo(() => getPairingFamilies(themeCategory), [themeCategory]);
18257
+ const context = useMemo(
18258
+ () => getPairingContext(themeCategory, primaryFamilyKey, accentFamilyKey),
18259
+ [themeCategory, primaryFamilyKey, accentFamilyKey]
18260
+ );
18261
+ const selectableFamilies = useMemo(
18262
+ () => themeFamilies.filter((family) => family.key !== context.grey.key),
18263
+ [themeFamilies, context.grey.key]
18264
+ );
18265
+ const selectableAccentFamilies = useMemo(
18266
+ () => selectableFamilies.filter((family) => family.key !== context.primary.key),
18267
+ [selectableFamilies, context.primary.key]
18268
+ );
18269
+ const selectedBackground = useMemo(
18270
+ () => context.backgrounds.find((background) => background.token === selectedBackgroundToken) ?? context.backgrounds[0] ?? null,
18271
+ [context.backgrounds, selectedBackgroundToken]
18272
+ );
18273
+ const selectedBackgroundPairs = useMemo(
18274
+ () => selectedBackground ? context.pairsByBackground[selectedBackground.token] ?? [] : [],
18275
+ [context.pairsByBackground, selectedBackground]
18276
+ );
18277
+ const bestRecommendedPair = useMemo(
18278
+ () => getPreferredPairForBackground3(selectedBackgroundPairs),
18279
+ [selectedBackgroundPairs]
18280
+ );
18281
+ const selectedPair = useMemo(
18282
+ () => getPreferredPairForBackground3(selectedBackgroundPairs, selectedPairId),
18283
+ [selectedBackgroundPairs, selectedPairId]
18284
+ );
18285
+ const whiteForegroundExample = useMemo(
18286
+ () => selectedBackground && supportsWhiteForegroundPreview(selectedBackground) ? getWhiteForegroundPair(selectedBackground) : null,
18287
+ [selectedBackground]
18288
+ );
18289
+ const previewPair = selectedPair ?? whiteForegroundExample ?? null;
18290
+ const detailForeground = selectedPair?.foreground ?? whiteForegroundExample?.foreground ?? null;
18291
+ const familySummary = useMemo(
18292
+ () => [context.primary.label, context.accent.label, context.grey.label].join(" + "),
18293
+ [context.accent.label, context.grey.label, context.primary.label]
18294
+ );
18295
+ const recommendationItems = useMemo(() => {
18296
+ return selectedBackgroundPairs.map((pair) => {
18297
+ const category = getRecommendationCategory(pair, bestRecommendedPair, context);
18298
+ return {
18299
+ category,
18300
+ categoryLabel: getRecommendationCategoryLabel(category),
18301
+ pair
18302
+ };
18303
+ }).sort(
18304
+ (left, right) => getRecommendationSortRank(left.category) - getRecommendationSortRank(right.category)
18305
+ );
18306
+ }, [bestRecommendedPair, context, selectedBackgroundPairs]);
18307
+ const liveAnnouncement = useMemo(
18308
+ () => getLiveAnnouncement(previewPair, selectedBackground),
18309
+ [previewPair, selectedBackground]
18310
+ );
18311
+ const shareBackgroundToken = selectedBackground?.token ?? selectedBackgroundToken;
18312
+ const shareUrl = useMemo(() => {
18313
+ const params = new URLSearchParams();
18314
+ params.set("palette", themeCategory);
18315
+ params.set("primary", context.primary.key);
18316
+ params.set("accent", context.accent.key);
18317
+ if (shareBackgroundToken) {
18318
+ params.set("background", shareBackgroundToken);
18319
+ }
18320
+ if (selectedPairId) {
18321
+ params.set("pair", selectedPairId);
18322
+ }
18323
+ const query = params.toString();
18324
+ return `${COLOR_PAIRING_TOOL_V3_PATH}${query ? `?${query}` : ""}`;
18325
+ }, [context.accent.key, context.primary.key, shareBackgroundToken, selectedPairId, themeCategory]);
18326
+ const activeDrawerStep = COLOR_PAIRING_TOOL_DRAWER_STEPS[drawerStepIndex];
18327
+ const isFirstDrawerStep = drawerStepIndex === 0;
18328
+ const isLastDrawerStep = drawerStepIndex === COLOR_PAIRING_TOOL_DRAWER_STEPS.length - 1;
18329
+ const desktopSidebarStyle = useMemo(
18330
+ () => ({
18331
+ "--tool-sidebar-max-height": `calc(100vh - ${stickyOffset}px)`,
18332
+ "--tool-sidebar-top": `${stickyOffset}px`
18333
+ }),
18334
+ [stickyOffset]
18335
+ );
18336
+ const goToDrawerStep = useCallback((stepIndex) => {
18337
+ setDrawerStepIndex(Math.max(0, Math.min(stepIndex, COLOR_PAIRING_TOOL_DRAWER_STEPS.length - 1)));
18338
+ }, []);
18339
+ const goToNextDrawerStep = useCallback(() => {
18340
+ setDrawerStepIndex(
18341
+ (currentStep) => Math.min(currentStep + 1, COLOR_PAIRING_TOOL_DRAWER_STEPS.length - 1)
18342
+ );
18343
+ }, []);
18344
+ const goToPreviousDrawerStep = useCallback(() => {
18345
+ setDrawerStepIndex((currentStep) => Math.max(currentStep - 1, 0));
18346
+ }, []);
18347
+ const updateUrlParams = useCallback((nextState) => {
18348
+ const params = new URLSearchParams(window.location.search);
18349
+ params.delete("family");
18350
+ params.set("palette", nextState.themeCategory);
18351
+ params.set("primary", nextState.primaryKey);
18352
+ params.set("accent", nextState.accentKey);
18353
+ params.set("background", nextState.selectedBackgroundToken);
18354
+ if (nextState.selectedPairId) {
18355
+ params.set("pair", nextState.selectedPairId);
18356
+ } else {
18357
+ params.delete("pair");
18358
+ }
18359
+ window.history.replaceState(
18360
+ null,
18361
+ "",
18362
+ `${window.location.pathname}?${params.toString()}${window.location.hash}`
18363
+ );
18364
+ }, []);
18365
+ const applyResolvedSelection = useCallback(
18366
+ (nextState) => {
18367
+ setThemeCategory(nextState.themeCategory);
18368
+ setPrimaryFamilyKey(nextState.primaryKey);
18369
+ setAccentFamilyKey(nextState.accentKey);
18370
+ setSelectedBackgroundToken(nextState.selectedBackgroundToken);
18371
+ setSelectedPairId(nextState.selectedPairId);
18372
+ updateUrlParams(nextState);
18373
+ },
18374
+ [updateUrlParams]
18375
+ );
18376
+ const buildAnalyticsContext = useCallback(
18377
+ (overrides) => ({
18378
+ accentKey: context.accent.key,
18379
+ backgroundToken: selectedBackground?.token,
18380
+ foregroundToken: selectedPair?.foreground.token,
18381
+ pairId: selectedPair?.id,
18382
+ palette: themeCategory,
18383
+ primaryKey: context.primary.key,
18384
+ ...overrides
18385
+ }),
18386
+ [context.accent.key, context.primary.key, selectedBackground, selectedPair, themeCategory]
18387
+ );
18388
+ const copyValue = useCallback(
18389
+ (copyKey, value, toastLabel, analyticsEvent) => {
18390
+ copyToClipboardRaw(value);
18391
+ setCopiedKey(copyKey);
18392
+ toast(toastLabel, { duration: 2e3 });
18393
+ if (analyticsEvent) {
18394
+ emitAnalyticsEvent(analyticsEvent);
18395
+ }
18396
+ if (copiedKeyTimeoutRef.current) {
18397
+ clearTimeout(copiedKeyTimeoutRef.current);
18398
+ }
18399
+ copiedKeyTimeoutRef.current = setTimeout(() => {
18400
+ setCopiedKey(null);
18401
+ copiedKeyTimeoutRef.current = null;
18402
+ }, 2e3);
18403
+ },
18404
+ [copyToClipboardRaw, emitAnalyticsEvent]
18405
+ );
18406
+ const handleThemeCategoryChange = (nextThemeCategory) => {
18407
+ const nextState = resolveSelectionState(
18408
+ nextThemeCategory,
18409
+ primaryFamilyKey,
18410
+ accentFamilyKey,
18411
+ selectedBackgroundToken,
18412
+ selectedPairId
18413
+ );
18414
+ applyResolvedSelection(nextState);
18415
+ emitAnalyticsEvent({
18416
+ name: "palette_change",
18417
+ accentKey: nextState.accentKey,
18418
+ backgroundToken: nextState.selectedBackgroundToken,
18419
+ pairId: nextState.selectedPairId,
18420
+ palette: nextState.themeCategory,
18421
+ primaryKey: nextState.primaryKey
18422
+ });
18423
+ };
18424
+ const handlePrimaryColorChange = (nextPrimaryKey) => {
18425
+ const nextAccentKey = nextPrimaryKey === accentFamilyKey ? getDefaultAccentFamilyKey(themeCategory, nextPrimaryKey) : accentFamilyKey;
18426
+ const nextState = resolveSelectionState(
18427
+ themeCategory,
18428
+ nextPrimaryKey,
18429
+ nextAccentKey,
18430
+ selectedBackgroundToken,
18431
+ selectedPairId
18432
+ );
18433
+ applyResolvedSelection(nextState);
18434
+ emitAnalyticsEvent({
18435
+ name: "primary_change",
18436
+ accentKey: nextState.accentKey,
18437
+ backgroundToken: nextState.selectedBackgroundToken,
18438
+ pairId: nextState.selectedPairId,
18439
+ palette: nextState.themeCategory,
18440
+ primaryKey: nextState.primaryKey
18441
+ });
18442
+ };
18443
+ const handleAccentColorChange = (nextAccentKey) => {
18444
+ if (nextAccentKey === primaryFamilyKey) return;
18445
+ const nextState = resolveSelectionState(
18446
+ themeCategory,
18447
+ primaryFamilyKey,
18448
+ nextAccentKey,
18449
+ selectedBackgroundToken,
18450
+ selectedPairId
18451
+ );
18452
+ applyResolvedSelection(nextState);
18453
+ emitAnalyticsEvent({
18454
+ name: "accent_change",
18455
+ accentKey: nextState.accentKey,
18456
+ backgroundToken: nextState.selectedBackgroundToken,
18457
+ pairId: nextState.selectedPairId,
18458
+ palette: nextState.themeCategory,
18459
+ primaryKey: nextState.primaryKey
18460
+ });
18461
+ };
18462
+ const handleBackgroundChange = (nextSelectedBackgroundToken) => {
18463
+ const nextSelectedPairId = getPreferredPairForBackground3(
18464
+ context.pairsByBackground[nextSelectedBackgroundToken] ?? [],
18465
+ selectedPairId
18466
+ )?.id ?? "";
18467
+ const nextState = {
18468
+ accentKey: context.accent.key,
18469
+ context,
18470
+ primaryKey: context.primary.key,
18471
+ selectedBackgroundToken: nextSelectedBackgroundToken,
18472
+ selectedPairId: nextSelectedPairId,
18473
+ themeCategory
18474
+ };
18475
+ applyResolvedSelection(nextState);
18476
+ emitAnalyticsEvent({
18477
+ name: "background_selection",
18478
+ ...buildAnalyticsContext({
18479
+ backgroundToken: nextSelectedBackgroundToken,
18480
+ foregroundToken: context.pairsByBackground[nextSelectedBackgroundToken]?.find(
18481
+ (pair) => pair.id === nextSelectedPairId
18482
+ )?.foreground.token,
18483
+ pairId: nextSelectedPairId
18484
+ })
18485
+ });
18486
+ if (typeof window !== "undefined" && window.matchMedia(MOBILE_RESULT_SCROLL_QUERY).matches) {
18487
+ requestAnimationFrame(() => {
18488
+ resultSectionRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
18489
+ });
18490
+ }
18491
+ };
18492
+ const handlePairChange = (nextSelectedPairId, source) => {
18493
+ if (!selectedBackground) return;
18494
+ const nextPair = selectedBackgroundPairs.find((pair) => pair.id === nextSelectedPairId) ?? null;
18495
+ setSelectedPairId(nextSelectedPairId);
18496
+ updateUrlParams({
18497
+ accentKey: context.accent.key,
18498
+ context,
18499
+ primaryKey: context.primary.key,
18500
+ selectedBackgroundToken: selectedBackground.token,
18501
+ selectedPairId: nextSelectedPairId,
18502
+ themeCategory
18503
+ });
18504
+ emitAnalyticsEvent({
18505
+ name: "foreground_selection",
18506
+ ...buildAnalyticsContext({
18507
+ foregroundToken: nextPair?.foreground.token,
18508
+ pairId: nextSelectedPairId,
18509
+ source
18510
+ })
18511
+ });
18512
+ if (bestRecommendedPair && nextSelectedPairId !== bestRecommendedPair.id) {
18513
+ emitAnalyticsEvent({
18514
+ name: "alternative_combination_selected",
18515
+ ...buildAnalyticsContext({
18516
+ foregroundToken: nextPair?.foreground.token,
18517
+ pairId: nextSelectedPairId,
18518
+ source
18519
+ })
18520
+ });
18521
+ }
18522
+ };
18523
+ useEffect(() => {
18524
+ if (!selectedBackground || selectedBackgroundPairs.length > 0) {
18525
+ return;
18526
+ }
18527
+ const key = `${themeCategory}:${context.primary.key}:${context.accent.key}:${selectedBackground.token}`;
18528
+ if (noValidStateRef.current.has(key)) {
18529
+ return;
18530
+ }
18531
+ noValidStateRef.current.add(key);
18532
+ emitAnalyticsEvent({
18533
+ name: "no_valid_combination_state",
18534
+ ...buildAnalyticsContext({
18535
+ backgroundToken: selectedBackground.token
18536
+ })
18537
+ });
18538
+ }, [
18539
+ buildAnalyticsContext,
18540
+ context.accent.key,
18541
+ context.primary.key,
18542
+ emitAnalyticsEvent,
18543
+ selectedBackground,
18544
+ selectedBackgroundPairs.length,
18545
+ themeCategory
18546
+ ]);
18547
+ useEffect(() => {
18548
+ if (technicalDetailsOpenedRef.current) {
18549
+ return;
18550
+ }
18551
+ technicalDetailsOpenedRef.current = true;
18552
+ emitAnalyticsEvent({
18553
+ name: "technical_details_opened",
18554
+ ...buildAnalyticsContext({
18555
+ source: "details"
18556
+ })
18557
+ });
18558
+ }, [buildAnalyticsContext, emitAnalyticsEvent]);
18559
+ if (!selectedBackground) {
18560
+ return /* @__PURE__ */ jsxs(Card, { className: "px-6 py-6", children: [
18561
+ /* @__PURE__ */ jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "No approved background tones available" }),
18562
+ /* @__PURE__ */ jsx(Text, { size: 2, className: "mt-3", children: "No approved tones are available for the current palette and colour selection." })
18563
+ ] });
18564
+ }
18565
+ const compactControlsSummary = `${themeCategory === "brand" ? "Brand" : "Aboriginal"} palette, ${context.primary.label} primary, ${context.accent.label} accent, ${getPairingColorDisplayName3(
18566
+ selectedBackground
18567
+ )} background.`;
18568
+ const renderControlsPanel = (isOverlay = false) => /* @__PURE__ */ jsxs(Fragment, { children: [
18569
+ /* @__PURE__ */ jsx("div", { className: "border-b border-grey-200 px-5 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
18570
+ /* @__PURE__ */ jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "Configuration" }),
18571
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
18572
+ !isFirstDrawerStep ? /* @__PURE__ */ jsxs(Button2, { variant: "ghost", color: "grey", size: "sm", onClick: goToPreviousDrawerStep, children: [
18573
+ /* @__PURE__ */ jsx(Icons.west, { "data-slot": "icon", className: "size-5" }),
18574
+ "Back"
18575
+ ] }) : null,
18576
+ isOverlay ? /* @__PURE__ */ jsx(
18577
+ Button2,
18578
+ {
18579
+ variant: "ghost",
18580
+ color: "grey",
18581
+ size: "icon",
18582
+ onClick: () => setIsCompactControlsOpen(false),
18583
+ "aria-label": "Close configuration",
18584
+ children: /* @__PURE__ */ jsx(Icons.close, { "data-slot": "icon", className: "size-5" })
18585
+ }
18586
+ ) : null
18587
+ ] })
18588
+ ] }) }),
18589
+ /* @__PURE__ */ jsxs("div", { className: "border-b border-grey-200 px-5 py-4", children: [
18590
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
18591
+ COLOR_PAIRING_TOOL_DRAWER_STEPS.map((step, index) => /* @__PURE__ */ jsx(
18592
+ "button",
18593
+ {
18594
+ type: "button",
18595
+ "aria-current": index === drawerStepIndex ? "step" : void 0,
18596
+ "aria-label": `${step.eyebrow}: ${step.title}`,
18597
+ onClick: () => goToDrawerStep(index),
18598
+ className: "flex-1 rounded-sm focus-visible:ring-2 focus-visible:ring-primary-700 focus-visible:ring-offset-2 focus-visible:outline-hidden",
18599
+ children: /* @__PURE__ */ jsx(
18600
+ "span",
18601
+ {
18602
+ className: cn(
18603
+ "block h-1.5 rounded-full transition-colors",
18604
+ index <= drawerStepIndex ? "bg-primary-800" : "bg-grey-200"
18605
+ )
18606
+ }
18607
+ )
18608
+ },
18609
+ step.id
18610
+ )),
18611
+ /* @__PURE__ */ jsx("span", { className: "mt-2 basis-full text-[0.68rem] font-semibold tracking-[0.12em] text-primary-800 uppercase sm:mt-0 sm:ml-2 sm:basis-auto sm:text-[0.72rem]", children: activeDrawerStep.eyebrow })
18612
+ ] }),
18613
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 space-y-2", children: [
18614
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 5, className: "text-foreground", trim: "normal", children: activeDrawerStep.title }),
18615
+ /* @__PURE__ */ jsx(Text, { size: 2, children: activeDrawerStep.description })
18616
+ ] })
18617
+ ] }),
18618
+ /* @__PURE__ */ jsx("div", { className: "relative flex-1 overflow-hidden", children: /* @__PURE__ */ jsxs(
18619
+ "div",
18620
+ {
18621
+ className: "flex h-full transition-transform duration-300 ease-out",
18622
+ style: { transform: `translateX(-${drawerStepIndex * 100}%)` },
18623
+ children: [
18624
+ /* @__PURE__ */ jsx("section", { className: "h-full w-full shrink-0 overflow-y-auto px-5 py-5", children: /* @__PURE__ */ jsxs("div", { className: "space-y-6 pr-1", children: [
18625
+ /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
18626
+ /* @__PURE__ */ jsx(Heading, { level: 4, size: 6, className: "mb-3 text-foreground", trim: "normal", children: "Palette" }),
18627
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: ["brand", "aboriginal"].map((palette) => {
18628
+ const isSelected = themeCategory === palette;
18629
+ const label = palette === "brand" ? "Brand palette" : "Aboriginal palette";
18630
+ return /* @__PURE__ */ jsx(
18631
+ SelectorButton,
18632
+ {
18633
+ label,
18634
+ isSelected,
18635
+ onClick: () => handleThemeCategoryChange(palette)
18636
+ },
18637
+ palette
18638
+ );
18639
+ }) })
18640
+ ] }),
18641
+ /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
18642
+ /* @__PURE__ */ jsx(Heading, { level: 4, size: 6, className: "mb-3 text-foreground", trim: "normal", children: "Primary colour family" }),
18643
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: selectableFamilies.map((family) => {
18644
+ const label = getFamilySelectorLabel3(family, themeCategory, "primary colour");
18645
+ return /* @__PURE__ */ jsx(
18646
+ SelectorButton,
18647
+ {
18648
+ label,
18649
+ isSelected: family.key === context.primary.key,
18650
+ onClick: () => handlePrimaryColorChange(family.key),
18651
+ swatch: getFamilySwatchColor3(family, 800)
18652
+ },
18653
+ family.key
18654
+ );
18655
+ }) })
18656
+ ] }),
18657
+ /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
18658
+ /* @__PURE__ */ jsx(Heading, { level: 4, size: 6, className: "mb-3 text-foreground", trim: "normal", children: "Accent colour family" }),
18659
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: selectableAccentFamilies.map((family) => {
18660
+ const label = getFamilySelectorLabel3(family, themeCategory, "accent colour");
18661
+ return /* @__PURE__ */ jsx(
18662
+ SelectorButton,
18663
+ {
18664
+ label,
18665
+ isSelected: family.key === context.accent.key,
18666
+ onClick: () => handleAccentColorChange(family.key),
18667
+ swatch: getFamilySwatchColor3(family, 600)
18668
+ },
18669
+ family.key
18670
+ );
18671
+ }) })
18672
+ ] }),
18673
+ /* @__PURE__ */ jsxs("div", { className: "border-t border-grey-200 pt-4", children: [
18674
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: "Grey is always included" }),
18675
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "Neutral grey options are automatically added so every selection includes a practical fallback family." })
18676
+ ] })
18677
+ ] }) }),
18678
+ /* @__PURE__ */ jsx("section", { className: "h-full w-full shrink-0 overflow-y-auto px-5 py-5", children: /* @__PURE__ */ jsx("div", { className: "space-y-6 pr-1", children: context.backgroundGroups.map((group, index) => /* @__PURE__ */ jsxs(
18679
+ "section",
18680
+ {
18681
+ className: cn("space-y-3", index > 0 && "border-t border-grey-200 pt-6"),
18682
+ children: [
18683
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
18684
+ /* @__PURE__ */ jsxs(Heading, { level: 4, size: 6, className: "text-foreground", trim: "normal", children: [
18685
+ group.family.label,
18686
+ " backgrounds"
18687
+ ] }),
18688
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: group.label })
18689
+ ] }),
18690
+ /* @__PURE__ */ jsx("div", { className: "grid gap-3", children: group.backgrounds.map((background) => /* @__PURE__ */ jsx(
18691
+ BackgroundSwatchButton,
18692
+ {
18693
+ background,
18694
+ hasPairs: (context.pairsByBackground[background.token]?.length ?? 0) > 0,
18695
+ isSelected: selectedBackground.token === background.token,
18696
+ onClick: () => handleBackgroundChange(background.token)
18697
+ },
18698
+ background.token
18699
+ )) })
18700
+ ]
18701
+ },
18702
+ group.key
18703
+ )) }) }),
18704
+ /* @__PURE__ */ jsx("section", { className: "h-full w-full shrink-0 overflow-y-auto px-5 py-5", children: /* @__PURE__ */ jsx("div", { className: "space-y-4 pr-1", children: recommendationItems.length > 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-3", children: recommendationItems.map((item) => /* @__PURE__ */ jsx(
18705
+ RecommendationCard,
18706
+ {
18707
+ copiedKey,
18708
+ item,
18709
+ isSelected: item.pair.id === selectedPair?.id,
18710
+ onCopyPairing: () => copyValue(
18711
+ `pair:${item.pair.id}`,
18712
+ getPairingCopyText(item.pair),
18713
+ "Pairing copied",
18714
+ item.pair.id === bestRecommendedPair?.id ? {
18715
+ name: "best_recommendation_copied",
18716
+ ...buildAnalyticsContext({
18717
+ foregroundToken: item.pair.foreground.token,
18718
+ pairId: item.pair.id,
18719
+ source: "recommendations-list"
18720
+ })
18721
+ } : void 0
18722
+ ),
18723
+ onSelect: () => handlePairChange(item.pair.id, "recommendations-list")
18724
+ },
18725
+ item.pair.id
18726
+ )) }) : /* @__PURE__ */ jsxs("div", { className: "rounded-sm border border-grey-200 bg-white px-5 py-5", children: [
18727
+ /* @__PURE__ */ jsx(Heading, { level: 4, size: 6, className: "text-foreground", trim: "normal", children: "No valid combinations available" }),
18728
+ /* @__PURE__ */ jsx(Text, { size: 2, className: "mt-3", children: "No AAA-compliant foreground options are available for this background." })
18729
+ ] }) }) })
18730
+ ]
18731
+ }
18732
+ ) }),
18733
+ /* @__PURE__ */ jsx("div", { className: "border-t border-grey-200 px-5 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
18734
+ /* @__PURE__ */ jsx("div", { className: "min-h-10 flex-1", children: isLastDrawerStep ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Select a combination to update the result immediately." }) : null }),
18735
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-2 sm:w-auto sm:flex-none", children: [
18736
+ isOverlay && isLastDrawerStep ? /* @__PURE__ */ jsx(
18737
+ Button2,
18738
+ {
18739
+ color: "primary",
18740
+ className: "w-full sm:w-auto sm:min-w-40",
18741
+ onClick: () => setIsCompactControlsOpen(false),
18742
+ children: "Review result"
18743
+ }
18744
+ ) : null,
18745
+ !isLastDrawerStep ? /* @__PURE__ */ jsxs(Button2, { color: "primary", className: "w-full sm:w-auto", onClick: goToNextDrawerStep, children: [
18746
+ "Continue",
18747
+ /* @__PURE__ */ jsx(Icons.east, { "data-slot": "icon", className: "size-5" })
18748
+ ] }) : null
18749
+ ] })
18750
+ ] }) })
18751
+ ] });
18752
+ return /* @__PURE__ */ jsxs("div", { className: "grid gap-8 xl:grid-cols-[minmax(18rem,24rem)_minmax(0,1fr)]", children: [
18753
+ /* @__PURE__ */ jsx(
18754
+ "div",
18755
+ {
18756
+ "data-slot": "tool-sidebar",
18757
+ className: "hidden xl:sticky xl:top-[var(--tool-sidebar-top)] xl:block xl:self-start",
18758
+ style: desktopSidebarStyle,
18759
+ children: /* @__PURE__ */ jsx(Card, { className: "h-[40rem] max-h-[40rem] gap-0 overflow-hidden py-0 sm:h-[44rem] sm:max-h-[44rem] xl:h-[var(--tool-sidebar-max-height)] xl:max-h-[var(--tool-sidebar-max-height)]", children: renderControlsPanel() })
18760
+ }
18761
+ ),
18762
+ /* @__PURE__ */ jsxs("div", { "data-slot": "tool-results", className: "space-y-6", children: [
18763
+ /* @__PURE__ */ jsxs("section", { className: "space-y-4 xl:hidden", children: [
18764
+ /* @__PURE__ */ jsx(Card, { className: "gap-4 px-5 py-5", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between", children: [
18765
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
18766
+ /* @__PURE__ */ jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "Configuration" }),
18767
+ /* @__PURE__ */ jsx(Text, { size: 2, children: "Open the colour pairing drawer to change palette, background, and recommended combinations." }),
18768
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: compactControlsSummary })
18769
+ ] }),
18770
+ /* @__PURE__ */ jsxs(
18771
+ Button2,
18772
+ {
18773
+ color: "primary",
18774
+ className: "w-full sm:w-auto",
18775
+ onClick: () => setIsCompactControlsOpen(true),
18776
+ children: [
18777
+ /* @__PURE__ */ jsx(Icons.edit_square, { "data-slot": "icon", className: "size-5" }),
18778
+ "Open configuration"
18779
+ ]
18780
+ }
18781
+ )
18782
+ ] }) }),
18783
+ /* @__PURE__ */ jsx(Sheet, { open: isCompactControlsOpen, onOpenChange: setIsCompactControlsOpen, children: /* @__PURE__ */ jsxs(
18784
+ SheetContent,
18785
+ {
18786
+ side: "left",
18787
+ showClose: false,
18788
+ className: "w-[30rem] max-w-[90vw] overflow-hidden p-0",
18789
+ children: [
18790
+ /* @__PURE__ */ jsx(SheetTitle, { className: "sr-only", children: "Colour pairing configuration" }),
18791
+ /* @__PURE__ */ jsx("div", { className: "flex h-full flex-col bg-background", children: renderControlsPanel(true) })
18792
+ ]
18793
+ }
18794
+ ) })
18795
+ ] }),
18796
+ /* @__PURE__ */ jsxs("section", { ref: resultSectionRef, className: "space-y-6", "aria-label": "Current result", children: [
18797
+ /* @__PURE__ */ jsx("div", { className: "sr-only", "aria-live": "polite", children: liveAnnouncement }),
18798
+ /* @__PURE__ */ jsx(
18799
+ CurrentResultCard,
18800
+ {
18801
+ bestPair: bestRecommendedPair,
18802
+ familySummary,
18803
+ pair: previewPair,
18804
+ selectedBackground
18805
+ }
18806
+ )
18807
+ ] }),
18808
+ bestRecommendedPair ? /* @__PURE__ */ jsx("section", { className: "space-y-4", children: /* @__PURE__ */ jsx(
18809
+ BestRecommendationCard,
18810
+ {
18811
+ copiedKey,
18812
+ isCurrentSelection: selectedPair?.id === bestRecommendedPair.id,
18813
+ pair: bestRecommendedPair,
18814
+ reason: getBestRecommendationReason(bestRecommendedPair, context),
18815
+ onCopyPairing: () => copyValue(
18816
+ "best-pairing",
18817
+ getPairingCopyText(bestRecommendedPair),
18818
+ "Pairing copied",
18819
+ {
18820
+ name: "best_recommendation_copied",
18821
+ ...buildAnalyticsContext({
18822
+ foregroundToken: bestRecommendedPair.foreground.token,
18823
+ pairId: bestRecommendedPair.id,
18824
+ source: "best-recommendation"
18825
+ })
18826
+ }
18827
+ ),
18828
+ onUsePairing: () => handlePairChange(bestRecommendedPair.id, "best-recommendation")
18829
+ }
18830
+ ) }) : /* @__PURE__ */ jsxs(Card, { className: "px-6 py-6", children: [
18831
+ /* @__PURE__ */ jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "Best recommended pairing" }),
18832
+ /* @__PURE__ */ jsx(Text, { size: 2, className: "mt-3", children: "No AAA-compliant foreground options available for this selection." })
18833
+ ] }),
18834
+ /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
18835
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
18836
+ /* @__PURE__ */ jsx(Heading, { level: 2, size: 5, className: "text-foreground", trim: "normal", children: "Technical colour values" }),
18837
+ /* @__PURE__ */ jsx(Text, { size: 2, children: "Token, tone, HEX, RGB, HSL, and OKLCH values for the current selection." })
18838
+ ] }),
18839
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-4 lg:grid-cols-2", children: [
18840
+ /* @__PURE__ */ jsx(
18841
+ TechnicalDetailsPanel,
18842
+ {
18843
+ title: "Background values",
18844
+ color: selectedBackground,
18845
+ visibleFormats,
18846
+ copiedKey,
18847
+ onCopyValue: (copyKey, value, toastLabel) => copyValue(copyKey, value, toastLabel)
18848
+ }
18849
+ ),
18850
+ /* @__PURE__ */ jsx(
18851
+ TechnicalDetailsPanel,
18852
+ {
18853
+ title: "Foreground values",
18854
+ color: detailForeground,
18855
+ visibleFormats,
18856
+ copiedKey,
18857
+ onCopyValue: (copyKey, value, toastLabel) => copyValue(copyKey, value, toastLabel)
18858
+ }
18859
+ )
18860
+ ] }),
18861
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
18862
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: 6, className: "mb-3 text-foreground", trim: "normal", children: "Share colour pairing" }),
18863
+ /* @__PURE__ */ jsxs("div", { className: "rounded-sm border border-grey-200 bg-white p-4", children: [
18864
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-start gap-3 sm:flex-row sm:items-start sm:justify-between", children: [
18865
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Copy this URL to share your current colour pairing:" }),
18866
+ /* @__PURE__ */ jsx(
18867
+ Button2,
18868
+ {
18869
+ variant: "ghost",
18870
+ color: "grey",
18871
+ size: "sm",
18872
+ className: "shrink-0",
18873
+ onClick: () => copyValue(
18874
+ "share-url",
18875
+ typeof window === "undefined" ? shareUrl : new URL(shareUrl, window.location.origin).toString(),
18876
+ "Colour pairing link copied"
18877
+ ),
18878
+ "aria-label": copiedKey === "share-url" ? "Colour pairing URL copied to clipboard" : "Copy colour pairing URL to clipboard",
18879
+ title: copiedKey === "share-url" ? "Copied" : "Copy URL",
18880
+ children: copiedKey === "share-url" ? /* @__PURE__ */ jsxs(Fragment, { children: [
18881
+ /* @__PURE__ */ jsx(Icons.check, { "data-slot": "icon", className: "size-5" }),
18882
+ "Copied"
18883
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
18884
+ /* @__PURE__ */ jsx(Icons.content_copy, { "data-slot": "icon", className: "size-5" }),
18885
+ "Copy URL"
18886
+ ] })
18887
+ }
18888
+ )
18889
+ ] }),
18890
+ /* @__PURE__ */ jsx("code", { className: "mt-3 block w-full rounded-sm border border-grey-200 bg-background px-3 py-2 font-mono text-[11px] break-all text-foreground sm:text-xs", children: shareUrl })
18891
+ ] })
18892
+ ] })
18893
+ ] })
18894
+ ] })
18895
+ ] });
18896
+ }
18897
+ function ColorPairingToolV3({
18898
+ onAnalyticsEvent = () => {
18899
+ },
18900
+ visibleFormats = DEFAULT_VISIBLE_FORMATS3
18901
+ } = {}) {
18902
+ const normalizedVisibleFormats = [...new Set(visibleFormats)];
18903
+ return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(ColorPairingToolV3Loading, {}), children: /* @__PURE__ */ jsx(
18904
+ ColorPairingToolV3Content,
18905
+ {
18906
+ onAnalyticsEvent,
18907
+ visibleFormats: normalizedVisibleFormats
18908
+ }
18909
+ ) });
18910
+ }
16306
18911
  function ColorSwatches({ theme: theme2, format, viewMode }) {
16307
18912
  return /* @__PURE__ */ jsx(
16308
18913
  "div",
@@ -17216,23 +19821,23 @@ var ComboChart = React5__default.forwardRef((props, forwardedRef) => {
17216
19821
  });
17217
19822
  ComboChart.displayName = "ComboChart";
17218
19823
  function Dialog({ ...props }) {
17219
- return /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
19824
+ return /* @__PURE__ */ jsx(SheetPrimitive.Root, { "data-slot": "dialog", ...props });
17220
19825
  }
17221
19826
  function DialogTrigger({ ...props }) {
17222
- return /* @__PURE__ */ jsx(DialogPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
19827
+ return /* @__PURE__ */ jsx(SheetPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
17223
19828
  }
17224
19829
  function DialogPortal({ ...props }) {
17225
- return /* @__PURE__ */ jsx(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
19830
+ return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
17226
19831
  }
17227
19832
  function DialogClose({ ...props }) {
17228
- return /* @__PURE__ */ jsx(DialogPrimitive.Close, { "data-slot": "dialog-close", ...props });
19833
+ return /* @__PURE__ */ jsx(SheetPrimitive.Close, { "data-slot": "dialog-close", ...props });
17229
19834
  }
17230
19835
  function DialogOverlay({
17231
19836
  className,
17232
19837
  ...props
17233
19838
  }) {
17234
19839
  return /* @__PURE__ */ jsx(
17235
- DialogPrimitive.Overlay,
19840
+ SheetPrimitive.Overlay,
17236
19841
  {
17237
19842
  "data-slot": "dialog-overlay",
17238
19843
  className: cn(
@@ -17252,7 +19857,7 @@ function DialogContent({
17252
19857
  return /* @__PURE__ */ jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
17253
19858
  /* @__PURE__ */ jsx(DialogOverlay, {}),
17254
19859
  /* @__PURE__ */ jsxs(
17255
- DialogPrimitive.Content,
19860
+ SheetPrimitive.Content,
17256
19861
  {
17257
19862
  "data-slot": "dialog-content",
17258
19863
  className: cn(
@@ -17262,7 +19867,7 @@ function DialogContent({
17262
19867
  ...props,
17263
19868
  children: [
17264
19869
  children,
17265
- showClose && /* @__PURE__ */ jsx(DialogPrimitive.Close, { className: "absolute top-1 right-1", asChild: true, children: /* @__PURE__ */ jsxs(Button2, { variant: "ghost", size: "icon", children: [
19870
+ showClose && /* @__PURE__ */ jsx(SheetPrimitive.Close, { className: "absolute top-1 right-1", asChild: true, children: /* @__PURE__ */ jsxs(Button2, { variant: "ghost", size: "icon", children: [
17266
19871
  /* @__PURE__ */ jsx(Icons.close, { className: "size-6", "aria-hidden": "true" }),
17267
19872
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
17268
19873
  ] }) })
@@ -17293,7 +19898,7 @@ function DialogFooter({ className, ...props }) {
17293
19898
  }
17294
19899
  function DialogTitle({ className, ...props }) {
17295
19900
  return /* @__PURE__ */ jsx(
17296
- DialogPrimitive.Title,
19901
+ SheetPrimitive.Title,
17297
19902
  {
17298
19903
  "data-slot": "dialog-title",
17299
19904
  className: cn("text-lg leading-none font-semibold", className),
@@ -17306,7 +19911,7 @@ function DialogDescription({
17306
19911
  ...props
17307
19912
  }) {
17308
19913
  return /* @__PURE__ */ jsx(
17309
- DialogPrimitive.Description,
19914
+ SheetPrimitive.Description,
17310
19915
  {
17311
19916
  "data-slot": "dialog-description",
17312
19917
  className: cn("text-sm text-muted-foreground", className),
@@ -18078,7 +20683,7 @@ function DescriptionList({ className, ...props }) {
18078
20683
  "dl",
18079
20684
  {
18080
20685
  ...props,
18081
- className: clsx12(
20686
+ className: clsx13(
18082
20687
  className,
18083
20688
  "grid grid-cols-1 text-base/6 sm:grid-cols-[min(50%,--spacing(80))_auto] sm:text-sm/6"
18084
20689
  )
@@ -18090,7 +20695,7 @@ function DescriptionTerm({ className, ...props }) {
18090
20695
  "dt",
18091
20696
  {
18092
20697
  ...props,
18093
- className: clsx12(
20698
+ className: clsx13(
18094
20699
  className,
18095
20700
  "col-start-1 border-t border-grey-950/5 pt-3 text-grey-600 first:border-none sm:border-t sm:border-grey-950/5 sm:py-3 dark:border-white/5 dark:text-grey-400 sm:dark:border-white/5"
18096
20701
  )
@@ -18102,7 +20707,7 @@ function DescriptionDetails({ className, ...props }) {
18102
20707
  "dd",
18103
20708
  {
18104
20709
  ...props,
18105
- className: clsx12(
20710
+ className: clsx13(
18106
20711
  className,
18107
20712
  "pt-1 pb-3 text-grey-950 sm:border-t sm:border-grey-950/5 sm:py-3 sm:nth-2:border-none dark:text-white dark:sm:border-white/5"
18108
20713
  )
@@ -18516,7 +21121,7 @@ function Fieldset2({
18516
21121
  Headless4.Fieldset,
18517
21122
  {
18518
21123
  ...props,
18519
- className: clsx12(className, "*:data-[slot=text]:mt-1 [&>*+[data-slot=control]]:mt-6")
21124
+ className: clsx13(className, "*:data-[slot=text]:mt-1 [&>*+[data-slot=control]]:mt-6")
18520
21125
  }
18521
21126
  );
18522
21127
  }
@@ -18529,7 +21134,7 @@ function Legend6({
18529
21134
  {
18530
21135
  "data-slot": "legend",
18531
21136
  ...props,
18532
- className: clsx12(
21137
+ className: clsx13(
18533
21138
  className,
18534
21139
  "text-base/6 font-semibold text-zinc-950 data-disabled:opacity-50 sm:text-sm/6 dark:text-white"
18535
21140
  )
@@ -18537,7 +21142,7 @@ function Legend6({
18537
21142
  );
18538
21143
  }
18539
21144
  function FieldGroup({ className, ...props }) {
18540
- return /* @__PURE__ */ jsx("div", { "data-slot": "control", ...props, className: clsx12(className, "space-y-8") });
21145
+ return /* @__PURE__ */ jsx("div", { "data-slot": "control", ...props, className: clsx13(className, "space-y-8") });
18541
21146
  }
18542
21147
  function Field2({
18543
21148
  className,
@@ -18547,7 +21152,7 @@ function Field2({
18547
21152
  Headless4.Field,
18548
21153
  {
18549
21154
  ...props,
18550
- className: clsx12(
21155
+ className: clsx13(
18551
21156
  className,
18552
21157
  "[&>[data-slot=label]+[data-slot=control]]:mt-3",
18553
21158
  "[&>[data-slot=label]+[data-slot=description]]:mt-1",
@@ -18568,14 +21173,14 @@ function FieldLabel({
18568
21173
  {
18569
21174
  "data-slot": "label",
18570
21175
  ...props,
18571
- className: clsx12(
21176
+ className: clsx13(
18572
21177
  className,
18573
21178
  "text-base/6 text-zinc-950 select-none data-disabled:opacity-50 sm:text-sm/6 dark:text-white"
18574
21179
  )
18575
21180
  }
18576
21181
  );
18577
21182
  }
18578
- function Description4({
21183
+ function Description5({
18579
21184
  className,
18580
21185
  ...props
18581
21186
  }) {
@@ -18584,7 +21189,7 @@ function Description4({
18584
21189
  {
18585
21190
  "data-slot": "description",
18586
21191
  ...props,
18587
- className: clsx12(
21192
+ className: clsx13(
18588
21193
  className,
18589
21194
  "text-base/6 text-zinc-500 data-disabled:opacity-50 sm:text-sm/6 dark:text-zinc-400"
18590
21195
  )
@@ -18600,7 +21205,7 @@ function ErrorMessage({
18600
21205
  {
18601
21206
  "data-slot": "error",
18602
21207
  ...props,
18603
- className: clsx12(
21208
+ className: clsx13(
18604
21209
  className,
18605
21210
  "text-base/6 text-red-600 data-disabled:opacity-50 sm:text-sm/6 dark:text-red-500"
18606
21211
  )
@@ -18824,7 +21429,7 @@ var toggleVariants = cva(styles3.base, {
18824
21429
  variants: {
18825
21430
  variant: {
18826
21431
  ghost: "",
18827
- outline: clsx12(styles3.outline)
21432
+ outline: clsx13(styles3.outline)
18828
21433
  },
18829
21434
  size: {
18830
21435
  default: "h-9 px-2 min-w-9",
@@ -18927,7 +21532,7 @@ function FormatToggle({ format, setFormat }) {
18927
21532
 
18928
21533
  // package.json
18929
21534
  var package_default = {
18930
- version: "1.101.0"};
21535
+ version: "1.103.0"};
18931
21536
  function Logo(props) {
18932
21537
  return /* @__PURE__ */ jsxs(Fragment, { children: [
18933
21538
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "NSW Government" }),
@@ -19077,7 +21682,7 @@ function Header2({
19077
21682
  "data-slot": "header",
19078
21683
  "data-scrolled": isScrolled,
19079
21684
  id: "nsw-header",
19080
- className: clsx12(
21685
+ className: clsx13(
19081
21686
  "sticky top-0 z-50 hidden bg-white px-4 py-5 transition duration-500 sm:px-6 lg:flex lg:flex-none lg:flex-wrap lg:items-center lg:justify-between lg:px-12",
19082
21687
  !hideShadow && "shadow-md shadow-slate-900/5 dark:shadow-none",
19083
21688
  isScrolled ? "dark:bg-slate-900/95 dark:backdrop-blur-sm dark:[@supports(backdrop-filter:blur(0))]:bg-slate-900/75" : "dark:bg-transparent"
@@ -19993,7 +22598,7 @@ function Listbox2({
19993
22598
  autoFocus,
19994
22599
  "data-slot": "control",
19995
22600
  "aria-label": ariaLabel,
19996
- className: clsx12([
22601
+ className: clsx13([
19997
22602
  className,
19998
22603
  // Basic layout
19999
22604
  "group relative block w-full",
@@ -20017,7 +22622,7 @@ function Listbox2({
20017
22622
  as: "span",
20018
22623
  options,
20019
22624
  placeholder: placeholder && /* @__PURE__ */ jsx("span", { className: "block truncate text-grey-500", children: placeholder }),
20020
- className: clsx12([
22625
+ className: clsx13([
20021
22626
  "cursor-pointer",
20022
22627
  // Basic layout
20023
22628
  "relative block w-full appearance-none rounded-sm py-[calc(--spacing(4.5)-1px)] sm:py-[calc(--spacing(3.5)-1px)]",
@@ -20047,7 +22652,7 @@ function Listbox2({
20047
22652
  {
20048
22653
  transition: true,
20049
22654
  anchor: "selection start",
20050
- className: clsx12(
22655
+ className: clsx13(
20051
22656
  // Anchor positioning
20052
22657
  "[--anchor-offset:-1.625rem] [--anchor-padding:--spacing(4)] sm:[--anchor-offset:-1.375rem]",
20053
22658
  // Base styles
@@ -20073,7 +22678,7 @@ function ListboxOption2({
20073
22678
  className,
20074
22679
  ...props
20075
22680
  }) {
20076
- const sharedClasses = clsx12(
22681
+ const sharedClasses = clsx13(
20077
22682
  // Base
20078
22683
  "flex min-w-0 items-center",
20079
22684
  // Icons
@@ -20085,12 +22690,12 @@ function ListboxOption2({
20085
22690
  );
20086
22691
  return /* @__PURE__ */ jsx(Headless4.ListboxOption, { as: Fragment$1, ...props, children: ({ selectedOption }) => {
20087
22692
  if (selectedOption) {
20088
- return /* @__PURE__ */ jsx("div", { className: clsx12(className, sharedClasses), children });
22693
+ return /* @__PURE__ */ jsx("div", { className: clsx13(className, sharedClasses), children });
20089
22694
  }
20090
22695
  return /* @__PURE__ */ jsxs(
20091
22696
  "div",
20092
22697
  {
20093
- className: clsx12(
22698
+ className: clsx13(
20094
22699
  // Basic layout
20095
22700
  "group/option grid cursor-pointer grid-cols-[--spacing(5)_1fr] items-baseline gap-x-2 rounded-sm py-2.5 pr-3.5 pl-2 sm:grid-cols-[--spacing(4)_1fr] sm:py-1.5 sm:pr-3 sm:pl-1.5",
20096
22701
  // Typography
@@ -20121,7 +22726,7 @@ function ListboxOption2({
20121
22726
  )
20122
22727
  }
20123
22728
  ),
20124
- /* @__PURE__ */ jsx("span", { className: clsx12(className, sharedClasses, "col-start-2"), children })
22729
+ /* @__PURE__ */ jsx("span", { className: clsx13(className, sharedClasses, "col-start-2"), children })
20125
22730
  ]
20126
22731
  }
20127
22732
  );
@@ -20132,7 +22737,7 @@ function ListboxLabel({ className, ...props }) {
20132
22737
  "span",
20133
22738
  {
20134
22739
  ...props,
20135
- className: clsx12(className, "ml-2.5 truncate first:ml-0 sm:ml-2 sm:first:ml-0")
22740
+ className: clsx13(className, "ml-2.5 truncate first:ml-0 sm:ml-2 sm:first:ml-0")
20136
22741
  }
20137
22742
  );
20138
22743
  }
@@ -20145,7 +22750,7 @@ function ListboxDescription({
20145
22750
  "span",
20146
22751
  {
20147
22752
  ...props,
20148
- className: clsx12(
22753
+ className: clsx13(
20149
22754
  className,
20150
22755
  "flex flex-1 overflow-hidden text-grey-500 group-data-focus/option:text-white before:w-2 before:min-w-0 before:shrink dark:text-grey-400"
20151
22756
  ),
@@ -20193,102 +22798,12 @@ function Spinner({ className, size = "md", ...props }) {
20193
22798
  }
20194
22799
  ) });
20195
22800
  }
20196
- function Text({ className, trim = "normal", size = 2, label = false, ...props }) {
20197
- const textSizeClasses = {
20198
- 1: "text-[length:var(--font-size-1)] leading-[var(--line-height-28)] tracking-[var(--letter-spacing-0)]",
20199
- 2: "text-[length:var(--font-size-2)] leading-[var(--line-height-24)] tracking-[var(--letter-spacing-0)]",
20200
- 3: "text-[length:var(--font-size-3)] leading-[var(--line-height-20)] tracking-[var(--letter-spacing-0)]",
20201
- 4: "text-[length:var(--font-size-4)] leading-[var(--line-height-20)] tracking-[var(--letter-spacing-0)]"
20202
- };
20203
- const labelSizeClasses = {
20204
- 1: "text-[length:var(--font-size-1)] leading-[var(--line-height-24)] tracking-[var(--letter-spacing-0)]",
20205
- 2: "text-[length:var(--font-size-2)] leading-[var(--line-height-20)] tracking-[var(--letter-spacing-0)]",
20206
- 3: "text-[length:var(--font-size-3)] leading-[var(--line-height-16)] tracking-[var(--letter-spacing-0)]",
20207
- 4: "text-[length:var(--font-size-4)] leading-[var(--line-height-16)] tracking-[var(--letter-spacing-0)]"
20208
- };
20209
- const sizeClass = label ? labelSizeClasses[size] : textSizeClasses[size];
20210
- const trimClasses = {
20211
- normal: ["before:content-none after:content-none"],
20212
- start: [
20213
- 'before:content-[""] before:table after:content-none',
20214
- "before:mb-[calc(var(--leading-trim-start,var(--default-leading-trim-start))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
20215
- ],
20216
- end: [
20217
- 'before:content-none after:content-[""] after:table',
20218
- "after:mt-[calc(var(--leading-trim-end,var(--default-leading-trim-end))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
20219
- ],
20220
- both: [
20221
- 'before:content-[""] before:table after:content-[""] after:table',
20222
- "before:mb-[calc(var(--leading-trim-start,var(--default-leading-trim-start))-var(--line-height,calc(1em*var(--default-line-height)))/2)]",
20223
- "after:mt-[calc(var(--leading-trim-end,var(--default-leading-trim-end))-var(--line-height,calc(1em*var(--default-line-height)))/2)]"
20224
- ]
20225
- };
20226
- return /* @__PURE__ */ jsx(
20227
- "p",
20228
- {
20229
- "data-slot": "text",
20230
- ...props,
20231
- className: clsx12(className, trimClasses[trim], "text-grey-800 dark:text-grey-400", sizeClass)
20232
- }
20233
- );
20234
- }
20235
- function TextLink({ className, ...props }) {
20236
- return /* @__PURE__ */ jsx(
20237
- Link,
20238
- {
20239
- ...props,
20240
- className: clsx12(
20241
- className,
20242
- "text-primary-800 underline decoration-primary-800/50 data-hover:decoration-primary-800 dark:text-white dark:decoration-white/50 dark:data-hover:decoration-white"
20243
- )
20244
- }
20245
- );
20246
- }
20247
- function Strong({ className, ...props }) {
20248
- return /* @__PURE__ */ jsx("strong", { ...props, className: clsx12(className, "font-medium text-grey-950 dark:text-white") });
20249
- }
20250
- function Code({ className, ...props }) {
20251
- const hasLanguageClass = typeof className === "string" && className.includes("language-");
20252
- return /* @__PURE__ */ jsx(
20253
- "code",
20254
- {
20255
- ...props,
20256
- className: clsx12(
20257
- className,
20258
- !hasLanguageClass && "language-plaintext",
20259
- "text-sm sm:text-[0.8125rem]"
20260
- )
20261
- }
20262
- );
20263
- }
20264
22801
  function Loading() {
20265
22802
  return /* @__PURE__ */ jsxs("div", { className: "flex min-h-screen items-center justify-center gap-4 bg-grey-50 dark:bg-grey-900", children: [
20266
22803
  /* @__PURE__ */ jsx(Spinner, { "aria-label": "Loading...", size: "lg" }),
20267
22804
  /* @__PURE__ */ jsx(Text, { children: "Loading..." })
20268
22805
  ] });
20269
22806
  }
20270
- function useSelectorHeight(selector = "header") {
20271
- const [height, setHeight] = useState(0);
20272
- const elementRef = useRef(null);
20273
- const resizeObserverRef = useRef(null);
20274
- useEffect(() => {
20275
- const element = document.querySelector(selector);
20276
- if (!element) return;
20277
- elementRef.current = element;
20278
- const resizeObserver = new ResizeObserver((entries) => {
20279
- const entry = entries[0];
20280
- const target = entry?.target ?? elementRef.current;
20281
- if (!target) return;
20282
- setHeight(target.offsetHeight);
20283
- });
20284
- resizeObserverRef.current = resizeObserver;
20285
- resizeObserver.observe(element);
20286
- return () => {
20287
- resizeObserverRef.current?.disconnect();
20288
- };
20289
- }, [selector]);
20290
- return height;
20291
- }
20292
22807
  function MainNavigation({ navigation }) {
20293
22808
  const headerHeight = useSelectorHeight();
20294
22809
  return /* @__PURE__ */ jsx(
@@ -20820,7 +23335,7 @@ function MultiLevelPushMenu({
20820
23335
  {
20821
23336
  href: item.href,
20822
23337
  onClick: (e) => handleItemClick(item, e),
20823
- className: clsx12(
23338
+ className: clsx13(
20824
23339
  "relative flex w-full cursor-pointer items-center justify-between gap-x-6 border-l p-4 transition-colors hover:border-primary-800 hover:bg-primary-800/10",
20825
23340
  pathname === item.href ? "border-primary-800 bg-primary-800/10 font-semibold text-primary-800" : "border-transparent text-grey-800",
20826
23341
  isAnimating && "pointer-events-none"
@@ -20832,7 +23347,7 @@ function MultiLevelPushMenu({
20832
23347
  {
20833
23348
  onClick: (e) => handleItemClick(item, e),
20834
23349
  disabled: isAnimating,
20835
- className: clsx12(
23350
+ className: clsx13(
20836
23351
  "relative flex w-full cursor-pointer items-center justify-between gap-x-6 border-l p-4 transition-colors hover:border-primary-800 hover:bg-primary-800/10",
20837
23352
  pathname === item.href ? "border-primary-800 bg-primary-800/10 font-semibold text-primary-800" : "border-transparent text-grey-800",
20838
23353
  isAnimating && "pointer-events-none"
@@ -20899,7 +23414,7 @@ function MobileHeader({
20899
23414
  /* @__PURE__ */ jsxs(
20900
23415
  "div",
20901
23416
  {
20902
- className: clsx12(
23417
+ className: clsx13(
20903
23418
  "relative flex w-full items-center py-4",
20904
23419
  menu && !search && "justify-start",
20905
23420
  search && "justify-between",
@@ -20915,7 +23430,7 @@ function MobileHeader({
20915
23430
  {
20916
23431
  href: "/",
20917
23432
  "aria-label": "Home page",
20918
- className: clsx12(
23433
+ className: clsx13(
20919
23434
  "flex items-center",
20920
23435
  menu && !search && "justify-start",
20921
23436
  search && !menu && "flex-row justify-between",
@@ -20926,7 +23441,7 @@ function MobileHeader({
20926
23441
  /* @__PURE__ */ jsxs(
20927
23442
  "div",
20928
23443
  {
20929
- className: clsx12(
23444
+ className: clsx13(
20930
23445
  "flex flex-wrap items-center",
20931
23446
  menu && !search && "justify-center text-left",
20932
23447
  search && !menu && "justify-center text-left",
@@ -28937,7 +31452,7 @@ var featureBundle = {
28937
31452
  // node_modules/framer-motion/dist/es/render/components/motion/proxy.mjs
28938
31453
  var motion = /* @__PURE__ */ createMotionProxy(featureBundle, createDomVisualElement);
28939
31454
  function Navbar({ className, ...props }) {
28940
- return /* @__PURE__ */ jsx("nav", { ...props, className: clsx12(className, "flex flex-1 items-center gap-4 py-2.5") });
31455
+ return /* @__PURE__ */ jsx("nav", { ...props, className: clsx13(className, "flex flex-1 items-center gap-4 py-2.5") });
28941
31456
  }
28942
31457
  function NavbarDivider({ className, ...props }) {
28943
31458
  return /* @__PURE__ */ jsx(
@@ -28945,16 +31460,16 @@ function NavbarDivider({ className, ...props }) {
28945
31460
  {
28946
31461
  "aria-hidden": "true",
28947
31462
  ...props,
28948
- className: clsx12(className, "h-6 w-px bg-zinc-950/10 dark:bg-white/10")
31463
+ className: clsx13(className, "h-6 w-px bg-zinc-950/10 dark:bg-white/10")
28949
31464
  }
28950
31465
  );
28951
31466
  }
28952
31467
  function NavbarSection({ className, ...props }) {
28953
31468
  const id3 = useId();
28954
- return /* @__PURE__ */ jsx(LayoutGroup, { id: id3, children: /* @__PURE__ */ jsx("div", { ...props, className: clsx12(className, "flex items-center gap-3") }) });
31469
+ return /* @__PURE__ */ jsx(LayoutGroup, { id: id3, children: /* @__PURE__ */ jsx("div", { ...props, className: clsx13(className, "flex items-center gap-3") }) });
28955
31470
  }
28956
31471
  function NavbarSpacer({ className, ...props }) {
28957
- return /* @__PURE__ */ jsx("div", { "aria-hidden": "true", ...props, className: clsx12(className, "-ml-4 flex-1") });
31472
+ return /* @__PURE__ */ jsx("div", { "aria-hidden": "true", ...props, className: clsx13(className, "-ml-4 flex-1") });
28958
31473
  }
28959
31474
  var NavbarItem = forwardRef(function NavbarItem2({
28960
31475
  current,
@@ -28962,7 +31477,7 @@ var NavbarItem = forwardRef(function NavbarItem2({
28962
31477
  children,
28963
31478
  ...props
28964
31479
  }, ref) {
28965
- const classes = clsx12(
31480
+ const classes = clsx13(
28966
31481
  // Base
28967
31482
  "relative flex min-w-0 items-center gap-3 rounded-lg p-2 text-left text-base/6 font-medium text-zinc-950 sm:text-sm/5",
28968
31483
  // Leading icon/icon-only
@@ -28980,7 +31495,7 @@ var NavbarItem = forwardRef(function NavbarItem2({
28980
31495
  "dark:data-hover:bg-white/5 dark:data-hover:*:data-[slot=icon]:fill-white",
28981
31496
  "dark:data-active:bg-white/5 dark:data-active:*:data-[slot=icon]:fill-white"
28982
31497
  );
28983
- return /* @__PURE__ */ jsxs("span", { className: clsx12(className, "relative"), children: [
31498
+ return /* @__PURE__ */ jsxs("span", { className: clsx13(className, "relative"), children: [
28984
31499
  current && /* @__PURE__ */ jsx(
28985
31500
  motion.span,
28986
31501
  {
@@ -29001,7 +31516,7 @@ var NavbarItem = forwardRef(function NavbarItem2({
29001
31516
  Headless4.Button,
29002
31517
  {
29003
31518
  ...props,
29004
- className: clsx12("cursor-default", classes),
31519
+ className: clsx13("cursor-default", classes),
29005
31520
  "data-current": current ? "true" : void 0,
29006
31521
  ref,
29007
31522
  children: /* @__PURE__ */ jsx(TouchTarget, { children })
@@ -29010,14 +31525,14 @@ var NavbarItem = forwardRef(function NavbarItem2({
29010
31525
  ] });
29011
31526
  });
29012
31527
  function NavbarLabel({ className, ...props }) {
29013
- return /* @__PURE__ */ jsx("span", { ...props, className: clsx12(className, "truncate") });
31528
+ return /* @__PURE__ */ jsx("span", { ...props, className: clsx13(className, "truncate") });
29014
31529
  }
29015
31530
  function Navigation({
29016
31531
  className,
29017
31532
  onLinkClick,
29018
31533
  navigation
29019
31534
  }) {
29020
- return /* @__PURE__ */ jsx("nav", { className: clsx12("text-base lg:text-sm", className), children: /* @__PURE__ */ jsx("ul", { role: "list", className: "flex flex-col gap-9", children: navigation.map((section, index) => /* @__PURE__ */ jsxs("li", { children: [
31535
+ return /* @__PURE__ */ jsx("nav", { className: clsx13("text-base lg:text-sm", className), children: /* @__PURE__ */ jsx("ul", { role: "list", className: "flex flex-col gap-9", children: navigation.map((section, index) => /* @__PURE__ */ jsxs("li", { children: [
29021
31536
  section.links ? /* @__PURE__ */ jsx("h2", { className: "font-display font-medium text-grey-800 dark:text-white", children: section.title }) : /* @__PURE__ */ jsx("ul", { role: "list", className: "mt-2 flex flex-col gap-2 border-l lg:mt-4", children: /* @__PURE__ */ jsx("li", { className: "-ml-px flex flex-col items-start gap-2", children: /* @__PURE__ */ jsx(
29022
31537
  NavigationLink,
29023
31538
  {
@@ -29040,7 +31555,7 @@ function NavigationLink({
29040
31555
  {
29041
31556
  href,
29042
31557
  onClick,
29043
- className: clsx12(
31558
+ className: clsx13(
29044
31559
  "inline-block w-full cursor-pointer rounded-r-sm border-l py-1 pr-2 pl-4 text-left text-base/8 sm:text-sm/6",
29045
31560
  "hover:border-grey-950 hover:bg-primary-800/10 hover:font-semibold hover:text-grey-950",
29046
31561
  "dark:text-grey-400 dark:hover:border-grey-400 dark:hover:text-white",
@@ -29513,7 +32028,7 @@ function Wrapper({
29513
32028
  return /* @__PURE__ */ jsx(
29514
32029
  "div",
29515
32030
  {
29516
- className: clsx12("max-w-8xl mx-auto space-y-8 px-4 py-6 sm:px-6 lg:px-12", className),
32031
+ className: clsx13("max-w-8xl mx-auto space-y-8 px-4 py-6 sm:px-6 lg:px-12", className),
29517
32032
  ...props,
29518
32033
  children
29519
32034
  }
@@ -29527,7 +32042,7 @@ function PageHeading({
29527
32042
  return /* @__PURE__ */ jsx(
29528
32043
  "header",
29529
32044
  {
29530
- className: clsx12(
32045
+ className: clsx13(
29531
32046
  "border-b border-grey-300 bg-white dark:border-grey-700 dark:bg-grey-900",
29532
32047
  className
29533
32048
  ),
@@ -29554,7 +32069,7 @@ function Pagination({
29554
32069
  children,
29555
32070
  ...props
29556
32071
  }) {
29557
- return /* @__PURE__ */ jsx("nav", { "aria-label": ariaLabel, className: clsx12(containerStyles[variant], className), ...props, children: /* @__PURE__ */ jsx(PaginationVariantContext.Provider, { value: variant, children }) });
32072
+ return /* @__PURE__ */ jsx("nav", { "aria-label": ariaLabel, className: clsx13(containerStyles[variant], className), ...props, children: /* @__PURE__ */ jsx(PaginationVariantContext.Provider, { value: variant, children }) });
29558
32073
  }
29559
32074
  function PaginationPrevious({ href = null, className, children = "Previous" }) {
29560
32075
  const variant = React5.useContext(PaginationVariantContext);
@@ -29577,7 +32092,7 @@ function PaginationPrevious({ href = null, className, children = "Previous" }) {
29577
32092
  }
29578
32093
  ) });
29579
32094
  }
29580
- return /* @__PURE__ */ jsx("span", { className: clsx12(className, "grow basis-0"), children: /* @__PURE__ */ jsxs(
32095
+ return /* @__PURE__ */ jsx("span", { className: clsx13(className, "grow basis-0"), children: /* @__PURE__ */ jsxs(
29581
32096
  Button2,
29582
32097
  {
29583
32098
  ...href === null ? { disabled: true } : { href },
@@ -29611,7 +32126,7 @@ function PaginationNext({ href = null, className, children = "Next" }) {
29611
32126
  }
29612
32127
  ) });
29613
32128
  }
29614
- return /* @__PURE__ */ jsx("span", { className: clsx12(className, "flex grow basis-0 justify-end"), children: /* @__PURE__ */ jsxs(
32129
+ return /* @__PURE__ */ jsx("span", { className: clsx13(className, "flex grow basis-0 justify-end"), children: /* @__PURE__ */ jsxs(
29615
32130
  Button2,
29616
32131
  {
29617
32132
  ...href === null ? { disabled: true } : { href },
@@ -29627,9 +32142,9 @@ function PaginationNext({ href = null, className, children = "Next" }) {
29627
32142
  function PaginationList({ className, ...props }) {
29628
32143
  const variant = React5.useContext(PaginationVariantContext);
29629
32144
  if (variant === "line") {
29630
- return /* @__PURE__ */ jsx("div", { className: clsx12(listStyles.line, className), ...props });
32145
+ return /* @__PURE__ */ jsx("div", { className: clsx13(listStyles.line, className), ...props });
29631
32146
  }
29632
- return /* @__PURE__ */ jsx("span", { className: clsx12(listStyles.default, className), ...props });
32147
+ return /* @__PURE__ */ jsx("span", { className: clsx13(listStyles.default, className), ...props });
29633
32148
  }
29634
32149
  function PaginationPage({
29635
32150
  href,
@@ -29661,7 +32176,7 @@ function PaginationPage({
29661
32176
  "aria-current": current ? "page" : void 0,
29662
32177
  variant: current ? "solid" : "ghost",
29663
32178
  color: current ? "accent" : "light",
29664
- className: clsx12(
32179
+ className: clsx13(
29665
32180
  className,
29666
32181
  "leading-none before:absolute before:-inset-px before:rounded-sm",
29667
32182
  "min-h-8 min-w-8 sm:px-[calc(--spacing(4))] sm:py-[calc(--spacing(3))]",
@@ -29682,7 +32197,7 @@ function PaginationGap({
29682
32197
  "span",
29683
32198
  {
29684
32199
  "aria-hidden": "true",
29685
- className: clsx12(
32200
+ className: clsx13(
29686
32201
  "inline-flex items-center border-t-2 border-transparent px-4 pt-4 text-sm font-medium text-grey-800 select-none",
29687
32202
  className
29688
32203
  ),
@@ -29696,7 +32211,7 @@ function PaginationGap({
29696
32211
  {
29697
32212
  "aria-hidden": "true",
29698
32213
  ...props,
29699
- className: clsx12(
32214
+ className: clsx13(
29700
32215
  className,
29701
32216
  "w-9 text-center text-sm/6 font-semibold text-grey-950 select-none dark:text-white"
29702
32217
  ),
@@ -29716,7 +32231,7 @@ function PrevNextLinksPageLink({
29716
32231
  Link13,
29717
32232
  {
29718
32233
  href,
29719
- className: clsx12(
32234
+ className: clsx13(
29720
32235
  "flex items-center gap-x-1 text-base font-semibold text-slate-500 hover:text-slate-600 dark:text-slate-400 dark:hover:text-slate-300",
29721
32236
  dir === "previous" && "flex-row-reverse"
29722
32237
  ),
@@ -29725,7 +32240,7 @@ function PrevNextLinksPageLink({
29725
32240
  /* @__PURE__ */ jsx(
29726
32241
  Icons.east,
29727
32242
  {
29728
- className: clsx12("size-5 flex-none fill-current", dir === "previous" && "-scale-x-100")
32243
+ className: clsx13("size-5 flex-none fill-current", dir === "previous" && "-scale-x-100")
29729
32244
  }
29730
32245
  )
29731
32246
  ]
@@ -29999,7 +32514,7 @@ function Prose({
29999
32514
  return /* @__PURE__ */ jsx(
30000
32515
  Component2,
30001
32516
  {
30002
- className: clsx12(
32517
+ className: clsx13(
30003
32518
  className,
30004
32519
  "prose max-w-none dark:!prose-invert",
30005
32520
  // headings
@@ -30053,110 +32568,6 @@ function ResizableHandle({
30053
32568
  }
30054
32569
  );
30055
32570
  }
30056
- function Sheet({ ...props }) {
30057
- return /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "sheet", ...props });
30058
- }
30059
- function SheetTrigger({ ...props }) {
30060
- return /* @__PURE__ */ jsx(DialogPrimitive.Trigger, { "data-slot": "sheet-trigger", ...props });
30061
- }
30062
- function SheetClose({ ...props }) {
30063
- return /* @__PURE__ */ jsx(DialogPrimitive.Close, { "data-slot": "sheet-close", ...props });
30064
- }
30065
- function SheetPortal({ ...props }) {
30066
- return /* @__PURE__ */ jsx(DialogPrimitive.Portal, { "data-slot": "sheet-portal", ...props });
30067
- }
30068
- function SheetOverlay({
30069
- className,
30070
- ...props
30071
- }) {
30072
- return /* @__PURE__ */ jsx(
30073
- DialogPrimitive.Overlay,
30074
- {
30075
- "data-slot": "sheet-overlay",
30076
- className: cn(
30077
- "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
30078
- className
30079
- ),
30080
- ...props
30081
- }
30082
- );
30083
- }
30084
- function SheetContent({
30085
- className,
30086
- children,
30087
- side = "right",
30088
- showClose = true,
30089
- ...props
30090
- }) {
30091
- return /* @__PURE__ */ jsxs(SheetPortal, { children: [
30092
- /* @__PURE__ */ jsx(SheetOverlay, {}),
30093
- /* @__PURE__ */ jsxs(
30094
- DialogPrimitive.Content,
30095
- {
30096
- "data-slot": "sheet-content",
30097
- className: cn(
30098
- "fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=closed]:animate-out data-[state=open]:duration-500 data-[state=open]:animate-in",
30099
- side === "right" && "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
30100
- side === "left" && "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
30101
- side === "top" && "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
30102
- side === "bottom" && "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
30103
- className
30104
- ),
30105
- ...props,
30106
- children: [
30107
- children,
30108
- showClose && /* @__PURE__ */ jsx(DialogPrimitive.Close, { "data-slot": "sheet-close", className: "absolute top-4 right-4", asChild: true, children: /* @__PURE__ */ jsxs(Button2, { variant: "ghost", size: "icon", children: [
30109
- /* @__PURE__ */ jsx(Icons.close, { className: "size-6", "aria-hidden": "true" }),
30110
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
30111
- ] }) })
30112
- ]
30113
- }
30114
- )
30115
- ] });
30116
- }
30117
- function SheetHeader({ className, ...props }) {
30118
- return /* @__PURE__ */ jsx(
30119
- "div",
30120
- {
30121
- "data-slot": "sheet-header",
30122
- className: cn("flex flex-col gap-1.5 p-4", className),
30123
- ...props
30124
- }
30125
- );
30126
- }
30127
- function SheetFooter({ className, ...props }) {
30128
- return /* @__PURE__ */ jsx(
30129
- "div",
30130
- {
30131
- "data-slot": "sheet-footer",
30132
- className: cn("mt-auto flex flex-col gap-2 p-4", className),
30133
- ...props
30134
- }
30135
- );
30136
- }
30137
- function SheetTitle({ className, ...props }) {
30138
- return /* @__PURE__ */ jsx(
30139
- DialogPrimitive.Title,
30140
- {
30141
- "data-slot": "sheet-title",
30142
- className: cn("font-semibold text-foreground", className),
30143
- ...props
30144
- }
30145
- );
30146
- }
30147
- function SheetDescription({
30148
- className,
30149
- ...props
30150
- }) {
30151
- return /* @__PURE__ */ jsx(
30152
- DialogPrimitive.Description,
30153
- {
30154
- "data-slot": "sheet-description",
30155
- className: cn("text-sm text-muted-foreground", className),
30156
- ...props
30157
- }
30158
- );
30159
- }
30160
32571
  function Skeleton({ className, ...props }) {
30161
32572
  return /* @__PURE__ */ jsx(
30162
32573
  "div",
@@ -30771,7 +33182,7 @@ function SidebarNavigation({
30771
33182
  navigation
30772
33183
  }) {
30773
33184
  const pathname = usePathname();
30774
- return /* @__PURE__ */ jsx("nav", { className: clsx12("text-base lg:text-sm", className), children: /* @__PURE__ */ jsx("ul", { role: "list", className: "flex flex-col gap-9", children: navigation.map((section, sectionIndex) => /* @__PURE__ */ jsxs("li", { children: [
33185
+ return /* @__PURE__ */ jsx("nav", { className: clsx13("text-base lg:text-sm", className), children: /* @__PURE__ */ jsx("ul", { role: "list", className: "flex flex-col gap-9", children: navigation.map((section, sectionIndex) => /* @__PURE__ */ jsxs("li", { children: [
30775
33186
  section.links ? /* @__PURE__ */ jsx("h2", { className: "font-display font-medium text-foreground dark:text-white", children: section.title }) : /* @__PURE__ */ jsx(
30776
33187
  "ul",
30777
33188
  {
@@ -30806,7 +33217,7 @@ function SidebarLink({ link, pathname, onLinkClick, depth }) {
30806
33217
  const hasChildren = Array.isArray(link.links) && link.links.length > 0;
30807
33218
  const isActive = pathname === link.href;
30808
33219
  const isActiveOrHasActiveDescendant = isLinkOrDescendantActive(link, pathname);
30809
- const baseLinkClasses = clsx12(
33220
+ const baseLinkClasses = clsx13(
30810
33221
  "w-full cursor-pointer rounded-r-sm border-l py-1 pr-2 pl-4 text-left text-base/8 sm:text-sm/6",
30811
33222
  "hover:border-grey-950 hover:bg-primary-800/10 hover:font-semibold hover:text-grey-950",
30812
33223
  "dark:text-grey-400 dark:hover:border-grey-400 dark:hover:text-white",
@@ -30816,13 +33227,13 @@ function SidebarLink({ link, pathname, onLinkClick, depth }) {
30816
33227
  /* @__PURE__ */ jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs(
30817
33228
  "button",
30818
33229
  {
30819
- className: clsx12(baseLinkClasses, "group flex items-center justify-between gap-1"),
33230
+ className: clsx13(baseLinkClasses, "group flex items-center justify-between gap-1"),
30820
33231
  children: [
30821
33232
  /* @__PURE__ */ jsx("span", { children: link.title }),
30822
33233
  /* @__PURE__ */ jsx(
30823
33234
  Icons.chevron_right,
30824
33235
  {
30825
- className: clsx12(
33236
+ className: clsx13(
30826
33237
  "ml-2 size-5 transition-transform duration-200",
30827
33238
  "group-data-[state=open]:rotate-90"
30828
33239
  )
@@ -30831,7 +33242,7 @@ function SidebarLink({ link, pathname, onLinkClick, depth }) {
30831
33242
  ]
30832
33243
  }
30833
33244
  ) }),
30834
- /* @__PURE__ */ jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsx("ul", { className: clsx12("mt-2 ml-5 flex flex-col gap-1 border-l pl-0"), children: link.links && link.links.map((childLink) => /* @__PURE__ */ jsx(
33245
+ /* @__PURE__ */ jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsx("ul", { className: clsx13("mt-2 ml-5 flex flex-col gap-1 border-l pl-0"), children: link.links && link.links.map((childLink) => /* @__PURE__ */ jsx(
30835
33246
  SidebarLink,
30836
33247
  {
30837
33248
  link: childLink,
@@ -31160,7 +33571,7 @@ var StepIndicator = React5.forwardRef(
31160
33571
  return /* @__PURE__ */ jsx("ul", { role: "list", ref, className: cn("w-full", className), ...props, children: array.map((step, stepIdx) => /* @__PURE__ */ jsx(
31161
33572
  "li",
31162
33573
  {
31163
- className: clsx12(stepIdx !== array.length - 1 ? "pb-3" : "", "relative"),
33574
+ className: clsx13(stepIdx !== array.length - 1 ? "pb-3" : "", "relative"),
31164
33575
  children: step.href === pathname && !(step.status === "completed" || step.status === "error" || step.status === "saved" || step.status === "cannot-start") ? /* @__PURE__ */ jsx(Fragment, { children: step.status === "in-progress" ? /* @__PURE__ */ jsxs(Fragment, { children: [
31165
33576
  stepIdx !== array.length - 1 ? /* @__PURE__ */ jsx(
31166
33577
  "div",
@@ -31406,7 +33817,7 @@ function StepNavigation({
31406
33817
  })),
31407
33818
  [navigation, formStatus, getStatus]
31408
33819
  );
31409
- return /* @__PURE__ */ jsx("nav", { className: clsx12("text-base lg:text-sm", className), children: /* @__PURE__ */ jsx("ul", { role: "list", className: "space-y-9", children: navigationWithStatus.map((section) => /* @__PURE__ */ jsxs("li", { children: [
33820
+ return /* @__PURE__ */ jsx("nav", { className: clsx13("text-base lg:text-sm", className), children: /* @__PURE__ */ jsx("ul", { role: "list", className: "space-y-9", children: navigationWithStatus.map((section) => /* @__PURE__ */ jsxs("li", { children: [
31410
33821
  /* @__PURE__ */ jsx("h2", { className: "font-display font-medium text-slate-900 dark:text-white", children: section.title }),
31411
33822
  /* @__PURE__ */ jsx(StepIndicator, { className: "mt-2 lg:mt-4", array: section.links })
31412
33823
  ] }, section.title)) }) });
@@ -31434,7 +33845,7 @@ function SwitchGroup({ className, ...props }) {
31434
33845
  {
31435
33846
  "data-slot": "control",
31436
33847
  ...props,
31437
- className: clsx12(
33848
+ className: clsx13(
31438
33849
  className,
31439
33850
  // Basic groups
31440
33851
  "space-y-3 **:data-[slot=label]:font-normal",
@@ -31453,7 +33864,7 @@ function SwitchField({
31453
33864
  {
31454
33865
  "data-slot": "field",
31455
33866
  ...props,
31456
- className: clsx12(
33867
+ className: clsx13(
31457
33868
  className,
31458
33869
  // Base layout
31459
33870
  "grid grid-cols-[1fr_auto] gap-x-8 gap-y-1 sm:grid-cols-[1fr_auto]",
@@ -31517,7 +33928,7 @@ function Switch2({
31517
33928
  {
31518
33929
  "data-slot": "control",
31519
33930
  ...props,
31520
- className: clsx12(
33931
+ className: clsx13(
31521
33932
  className,
31522
33933
  // Base styles
31523
33934
  "group relative isolate inline-flex h-6 w-10 cursor-default rounded-full p-[3px] sm:h-5 sm:w-8",
@@ -31544,7 +33955,7 @@ function Switch2({
31544
33955
  "span",
31545
33956
  {
31546
33957
  "aria-hidden": "true",
31547
- className: clsx12(
33958
+ className: clsx13(
31548
33959
  // Basic layout
31549
33960
  "pointer-events-none relative inline-block size-4.5 rounded-full sm:size-3.5",
31550
33961
  // Transition
@@ -31653,7 +34064,7 @@ function TableOfContents({ tableOfContents }) {
31653
34064
  "ol",
31654
34065
  {
31655
34066
  role: "list",
31656
- className: clsx12(
34067
+ className: clsx13(
31657
34068
  "mt-3 flex flex-col gap-2",
31658
34069
  "border-l border-grey-900/10 dark:border-white/10",
31659
34070
  "text-sm/6 text-grey-700 dark:text-grey-400"
@@ -31664,7 +34075,7 @@ function TableOfContents({ tableOfContents }) {
31664
34075
  {
31665
34076
  href: `#${section.id}`,
31666
34077
  prefetch: false,
31667
- className: clsx12(
34078
+ className: clsx13(
31668
34079
  "-ml-px inline-block border-l pl-4",
31669
34080
  "hover:border-primary-800 dark:hover:border-white",
31670
34081
  isActive(section) ? "border-primary-800 font-semibold text-primary-800 dark:border-white dark:text-white" : "border-transparent"
@@ -31677,7 +34088,7 @@ function TableOfContents({ tableOfContents }) {
31677
34088
  {
31678
34089
  href: `#${subSection.id}`,
31679
34090
  prefetch: false,
31680
- className: clsx12(
34091
+ className: clsx13(
31681
34092
  "-ml-px inline-block border-l pl-8",
31682
34093
  "hover:border-primary-800 dark:hover:border-white",
31683
34094
  isActive(subSection) ? "border-primary-800 font-semibold text-primary-800 dark:border-white dark:text-white" : "border-transparent"
@@ -34884,13 +37295,24 @@ function getHeadings(slugify = slugifyWithCounter()) {
34884
37295
  });
34885
37296
  return result;
34886
37297
  }
34887
- function usePageHeadings() {
37298
+ function areHeadingTreesEqual(left, right) {
37299
+ return JSON.stringify(left) === JSON.stringify(right);
37300
+ }
37301
+ function usePageHeadings(enabled = true) {
34888
37302
  const [headings, setHeadings] = useState([]);
34889
37303
  const pathname = usePathname();
34890
37304
  const observerRef = useRef(null);
34891
37305
  const observedElRef = useRef(null);
34892
37306
  useEffect(() => {
34893
- const update = () => setHeadings(getHeadings());
37307
+ if (!enabled) {
37308
+ return;
37309
+ }
37310
+ const update = () => {
37311
+ const nextHeadings = getHeadings();
37312
+ setHeadings(
37313
+ (currentHeadings) => areHeadingTreesEqual(currentHeadings, nextHeadings) ? currentHeadings : nextHeadings
37314
+ );
37315
+ };
34894
37316
  const attachToCurrentArticle = () => {
34895
37317
  const article = document.querySelector("article");
34896
37318
  if (!article || observedElRef.current === article) return;
@@ -34937,16 +37359,8 @@ function usePageHeadings() {
34937
37359
  observerRef.current = null;
34938
37360
  observedElRef.current = null;
34939
37361
  };
34940
- }, [pathname]);
34941
- return headings;
34942
- }
34943
- function useStickyOffset(extraPadding = 0) {
34944
- const headerHeight = useSelectorHeight("#nsw-header");
34945
- const navigationHeight = useSelectorHeight("#nsw-main-navigation");
34946
- return useMemo(() => {
34947
- const total = headerHeight + navigationHeight + extraPadding;
34948
- return total > 0 ? total : 0;
34949
- }, [extraPadding, headerHeight, navigationHeight]);
37362
+ }, [enabled, pathname]);
37363
+ return enabled ? headings : [];
34950
37364
  }
34951
37365
  function createFormStore(opts) {
34952
37366
  const { storageKey, initialFormData, initialFormStatus } = opts;
@@ -34993,6 +37407,6 @@ var languages = [
34993
37407
  "html"
34994
37408
  ];
34995
37409
 
34996
- 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, 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, Description4 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 };
37410
+ 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, 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 };
34997
37411
  //# sourceMappingURL=index.js.map
34998
37412
  //# sourceMappingURL=index.js.map