highsoft-ui 1.0.172 → 1.0.174

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.
Files changed (84) hide show
  1. package/CLAUDE.md +88 -0
  2. package/README.md +1 -0
  3. package/dist/{BrowserFrame-CisPLoTR.js → BrowserFrame-_qNod9an.js} +5 -5
  4. package/dist/{Button-CdrrwvXk.js → Button-DFcjZsF4.js} +1 -1
  5. package/dist/{ButtonGroup-JtJaVLlu.js → ButtonGroup-dTeFICBP.js} +1 -1
  6. package/dist/{Checkbox-DU_KGp-P.js → Checkbox-X7FrR_6F.js} +1 -1
  7. package/dist/{CodeBlock-CGBo8nwy.js → CodeBlock-rPC0sIvR.js} +4 -4
  8. package/dist/{CookiePolicyModal-xPb4G_hM.js → CookiePolicyModal-D-IOZSoU.js} +2 -2
  9. package/dist/{CopyCode-72gVieQO.js → CopyCode-DS2T69as.js} +2 -2
  10. package/dist/{Dropdown-DLRtYhFa.js → Dropdown-Ck7IASlc.js} +1 -1
  11. package/dist/{Features-BS-_cksu.js → Features-BQ5o3wcc.js} +8 -8
  12. package/dist/{Footer-CqtCkr_g.js → Footer-C2tXo3oR.js} +7 -7
  13. package/dist/{FooterBottom-B8GCRg2o.js → FooterBottom-BPuLsXI1.js} +24 -24
  14. package/dist/{FooterHelp-D5X2Pco9.js → FooterHelp-99gRcRar.js} +22 -22
  15. package/dist/{FooterLinks-yn_sgcbu.js → FooterLinks-DXTz-d8e.js} +7 -7
  16. package/dist/{Header-CQKgp8xy.js → Header-DqE0a41T.js} +49 -49
  17. package/dist/ImagePair-BH6ZnPcE.js +44 -0
  18. package/dist/{InputGrouped-DLghbzO7.js → InputGrouped-DNiMvxxa.js} +13 -13
  19. package/dist/{Label-B-Xt6XQQ.js → Label-DTIv_3zs.js} +1 -1
  20. package/dist/{List-B1zRI6pm.js → List-CdwPhveO.js} +11 -11
  21. package/dist/{LogoCarousel-TbyB0ot0.js → LogoCarousel-BsmxIlzx.js} +2 -2
  22. package/dist/{NewsletterSignup-BPLup66s.js → NewsletterSignup-CTbjNSnk.js} +12 -12
  23. package/dist/{Notification-DtqcW5FH.js → Notification-CTSGBhJk.js} +3 -3
  24. package/dist/{PrefPanel-6oTpfC5q.js → PrefPanel-CwrWfi3R.js} +8 -8
  25. package/dist/{PrevNextNav-XaxS2FTm.js → PrevNextNav-BwP-lRaG.js} +1 -1
  26. package/dist/{RoadmapDetails-CLQzIxv7.js → RoadmapDetails-B-2pgXHz.js} +5 -5
  27. package/dist/{SearchDropdown-Ow5_Hu21.js → SearchDropdown-g3g30peB.js} +1 -1
  28. package/dist/TableOfContents-d26S7KYx.js +93 -0
  29. package/dist/{VideoCover-25FfvhPg.js → VideoCover-DdN1nXfu.js} +5 -5
  30. package/dist/{VideoPlayer-CB2lOh95.js → VideoPlayer-C0pHiwYx.js} +7 -7
  31. package/dist/{VideoPlayerModal-CVJbPd6n.js → VideoPlayerModal-Bh2u5h8g.js} +2 -2
  32. package/dist/{YoutubeModal-j51vfjYk.js → YoutubeModal-CXSHjsEd.js} +2 -2
  33. package/dist/components/BrowserFrame/index.js +1 -1
  34. package/dist/components/Button/index.js +1 -1
  35. package/dist/components/ButtonGroup/index.js +1 -1
  36. package/dist/components/Checkbox/index.js +1 -1
  37. package/dist/components/CodeBlock/index.js +1 -1
  38. package/dist/components/CopyCode/index.js +1 -1
  39. package/dist/components/Dropdown/index.js +1 -1
  40. package/dist/components/Features/index.js +1 -1
  41. package/dist/components/Figure/ImagePair.js +2 -0
  42. package/dist/components/Figure/ZoomImage.js +70 -0
  43. package/dist/components/Figure/index.js +43 -0
  44. package/dist/components/Footer/CookiePolicyModal.js +1 -1
  45. package/dist/components/Footer/FooterBottom.js +1 -1
  46. package/dist/components/Footer/FooterHelp.js +1 -1
  47. package/dist/components/Footer/FooterLinks.js +1 -1
  48. package/dist/components/Footer/YoutubeModal.js +1 -1
  49. package/dist/components/Footer/index.js +1 -1
  50. package/dist/components/Header/index.js +1 -1
  51. package/dist/components/InputGrouped/index.js +1 -1
  52. package/dist/components/Label/index.js +1 -1
  53. package/dist/components/List/index.js +1 -1
  54. package/dist/components/LogoCarousel/index.js +1 -1
  55. package/dist/components/Modal/ModalContactFooter.js +2 -2
  56. package/dist/components/Modal/index.js +2 -2
  57. package/dist/components/NewsletterSignup/index.js +1 -1
  58. package/dist/components/Notification/index.js +1 -1
  59. package/dist/components/PrefPanel/index.js +1 -1
  60. package/dist/components/PrevNextNav/index.js +1 -1
  61. package/dist/components/RoadmapDetails/index.js +1 -1
  62. package/dist/components/Search/SearchDialog.js +10 -10
  63. package/dist/components/Search/index.js +2 -2
  64. package/dist/components/SearchDropdown/index.js +1 -1
  65. package/dist/components/Sidebar/NavDisclosure.js +1 -1
  66. package/dist/components/Sidebar/NavGroup.js +1 -1
  67. package/dist/components/Sidebar/Sidebar.js +10 -10
  68. package/dist/components/Sidebar/SidebarLayout.js +1 -1
  69. package/dist/components/Sidebar/SidebarSwitcher.js +1 -1
  70. package/dist/components/TableOfContents/index.js +2 -0
  71. package/dist/components/VideoCover/index.js +1 -1
  72. package/dist/components/VideoPlayer/VideoPlayerModal.js +1 -1
  73. package/dist/components/VideoPlayer/index.js +1 -1
  74. package/dist/{create-element-DvDqDt-f.js → create-element-DHbI55TT.js} +1 -1
  75. package/dist/{esm-zUd-Cmgs.js → esm-DQBytmnt.js} +24 -10
  76. package/dist/highsoft-ui.css +1 -1
  77. package/dist/lib/components/Figure/ImagePair.d.ts +20 -0
  78. package/dist/lib/components/Figure/ZoomImage.d.ts +18 -0
  79. package/dist/lib/components/Figure/index.d.ts +96 -0
  80. package/dist/lib/components/TableOfContents/index.d.ts +67 -0
  81. package/dist/lib/main.d.ts +4 -0
  82. package/dist/main.js +54 -52
  83. package/dist/{prism-light-oph9ikSp.js → prism-light-D9OePufj.js} +1 -1
  84. package/package.json +11 -4
package/CLAUDE.md CHANGED
@@ -687,6 +687,46 @@ Browser-window chrome around embedded content — a real `<iframe>` via `src`, o
687
687
  - The frame itself is a non-interactive `<div>` — nothing in the tab order beyond its controls; no authored motion, so there's nothing to gate on `prefers-reduced-motion` beyond the shared Button tokens.
688
688
  - `background` is a static surface with no state, so it changes nothing for keyboard or AT. The named values are semantic tokens and remap in dark mode; a raw CSS value does not, so prefer the tokens unless the embed is a fixed colour in both themes.
689
689
 
690
+ ### Figure
691
+ A `<figure>` with a `<figcaption>`: an image, or any wrapped content (a `BrowserFrame`, `VideoPlayer`, `CodeBlock`, a chart), with the sentence or two that explain it. The caption is what crawlers, AI agents and screen readers get instead of the image or the iframe's contents, so write it as the explanation, not as a label.
692
+ ```tsx
693
+ // An image: alt says what it shows, caption says what to notice
694
+ <Figure
695
+ src="/images/pyramid-3d.png"
696
+ alt="A pyramid in three stacked segments labelled Leads, Trials and Customers."
697
+ width={640}
698
+ height={360}
699
+ caption="A 3D pyramid with one segment per data point. The largest values form the widest part of the pyramid."
700
+ />
701
+
702
+ // A live demo: wrap the BrowserFrame, the paragraph under it becomes the figcaption
703
+ <Figure caption="This demo shows a 3D pyramid with one segment per data point.">
704
+ <BrowserFrame variant="mini" src={demoUrl} title="3D pyramid demo" aspectRatio="16 / 10" />
705
+ </Figure>
706
+
707
+ // Centered, smaller caption
708
+ <Figure src={src} alt={alt} caption={caption} align="center" captionSize={75} />
709
+
710
+ // A light/dark pair: the page's data-theme picks one
711
+ <Figure src="/images/diagram.svg" srcDark="/images/diagram.dark.svg" alt={alt} caption={caption} />
712
+ ```
713
+ - **`src` + `alt`:** renders the `<img>`. `alt` is required with `src` (the types enforce it): one sentence on what the image shows, `""` for a decorative image. `width`/`height` reserve the space before load; `loading`, `srcSet` and `sizes` pass through.
714
+ - **`srcDark`:** dark-theme variant of the image. Both render with the same `alt`; `[data-theme='dark']` on `<html>` (ThemeLoader sets it before first paint) shows one and hides the other, and `prefers-color-scheme` decides when no attribute is set. Without it the one image serves both themes: nothing is dimmed or inverted, since a filter would distort a chart's colours.
715
+ - **`zoom`:** click to enlarge (default `false`). The image becomes a `<button>` (cursor `zoom-in`, the shared focus ring) that opens it in a native `<dialog>` over the page: the picture floats on the dimmed backdrop with its own shadow, the close button sits in a row above it, outside the picture, and the caption is repeated under it in white. Escape, the close button, or a click on the backdrop closes it; the browser returns focus to the image. Enter and exit are CSS on `--animations-fade-*` / `--animations-bounce-default` with `@starting-style`, off under `prefers-reduced-motion`; the page behind does not scroll. `zoomLabel` and `closeLabel` name the two controls. The enlarge badge is the VideoCover playback control: a 28px disc bottom-right on the themed surface, hidden at rest and shown on hover or keyboard focus, so a chart's credits or last label stay readable until the reader reaches for it. Hover or keyboard focus lifts the picture 2px and scales it 1% on `--animations-bounce-default`, the cover-tile gesture that says "clickable", and deepens the shadow to `--shadow-size-200`. Opt in for screenshots and diagrams whose detail matters, not for every image.
716
+ - **`children`:** the alternative to `src`: a `BrowserFrame`, `VideoPlayer`, `CodeBlock` or anything else. The figure only stops it from overflowing; the child draws its own frame.
717
+ - **`caption`:** rendered as `<figcaption>` under the content, in `Typography` size `100` (or `captionSize={75}`) and `secondary` color (`captionColor` takes any `TypographyColor`). Capped at 72ch (`--hsui-figure-caption-width`) so a line under a wide demo stays readable. No caption, no `<figcaption>`.
718
+ - **`align`:** `start` (default) or `center` for both content and caption.
719
+ - **`frame`:** how an image sits on the page. `hairline` (default): border-100 and 8px radius (`--hsui-figure-radius`), the BrowserFrame shell look. `card`: the same plus `--shadow-size-100`, the BrowserFrame shadow, for an illustration that should read as a picture placed on the page. `none`: the bare image. Ignored for wrapped children, which draw their own frame.
720
+ - 10px between content and caption (the List marker gap); no outer margin. The page sets the rhythm around a figure, as it does for a BrowserFrame.
721
+
722
+ **Accessibility:**
723
+ - A real `<figure>`; its accessible name is the `<figcaption>`, so assistive technology announces the figure by its caption and a screen-reader user can skip or jump to it as a landmark-like region.
724
+ - `alt` and `caption` have different jobs: `alt` describes the image for someone who cannot see it, the caption explains it for everyone. Do not repeat one in the other. An empty `alt` hides a decorative image from the reader while the caption still reads.
725
+ - With `zoom`, the trigger is a real `<button>` named "Enlarge image" (`zoomLabel`), so it is reachable by keyboard and announced as a button; the `<dialog>` is modal (`showModal`), named by the image's `alt`, trapped for focus, closed by Escape, and the browser returns focus to the button. The close control is a `Button` named by `closeLabel`. The zoom badge is `aria-hidden` decoration; the button's name carries the meaning, and keyboard focus shows the same lift and badge as hover, so the control is discoverable without a mouse; on touch there is no hover, and the whole picture is the tap target. Under `prefers-reduced-motion` the picture does not move. The transitions respect `prefers-reduced-motion`.
726
+ - With `srcDark` the hidden variant is `display: none`, so assistive technology meets one image, not two with the same `alt`.
727
+ - For wrapped content the child owns its own accessibility (a BrowserFrame's iframe `title`, a VideoPlayer's tracks); the figure adds the caption as the figure's name.
728
+ - Nothing is interactive, nothing animates, colours are tokens, so dark mode and reduced motion need nothing extra.
729
+
690
730
  ### Layout
691
731
  ```tsx
692
732
  <Header />
@@ -960,6 +1000,42 @@ import NextLink from 'next/link'
960
1000
  - The disabled edge card is a non-interactive `aria-disabled` span — not focusable, so keyboard users skip straight to the real links, while AT can still read "Previous —" as "there is no previous page".
961
1001
  - DOM order is prev → back → next, matching the desktop visual order, so focus moves left-to-right across the row.
962
1002
 
1003
+ ### TableOfContents
1004
+ "On this page" navigation for an article: a rule down the left, a semibold title and one link per heading. Uncontrolled by default with a built-in scroll spy; pass `activeId` to drive the highlight yourself.
1005
+
1006
+ ```tsx
1007
+ const items: TableOfContentsItem[] = [
1008
+ { id: 'requirements', title: 'Requirements' },
1009
+ { id: 'install', title: '1. Install Highcharts React' },
1010
+ { id: 'customize', title: '3. Customize your chart' },
1011
+ { id: 'chart-elements', title: 'Chart elements', level: 2 }, // indented under the row above
1012
+ ]
1013
+
1014
+ // Scroll spy on: the current row is the last heading past the fold line.
1015
+ // Set spyOffset to the sticky header's height (plus the headings' scroll-margin-top).
1016
+ <TableOfContents items={items} spyOffset={96} style={{ position: 'sticky', top: 96 }} />
1017
+
1018
+ // Controlled: you own the highlight; onActiveChange reports clicks
1019
+ <TableOfContents items={items} activeId={active} onActiveChange={setActive} />
1020
+
1021
+ // Take over the navigation (eased scroll with a header offset) — the row still goes current
1022
+ <TableOfContents items={items} onItemClick={(item, e) => { e.preventDefault(); scrollTo(item.id) }} />
1023
+ ```
1024
+
1025
+ - **`items`:** `TableOfContentsItem[]` — `{ id, title, level?, href? }`. `id` is the heading element's id: the link target (`#id`) and what the spy watches. `level` `1` (default) | `2` | `3` indents 12px per step. `href` overrides the `#id` target. Renders nothing when empty.
1026
+ - **`title`:** the heading above the list (default `'On this page'`); `null` hides it.
1027
+ - **`activeId` / `onActiveChange(id)`:** controlled highlight; `null` highlights nothing. When `activeId` is given the spy is off. `onActiveChange` fires on spy changes and on clicks. **`defaultActiveId`** seeds the highlight in uncontrolled mode; the spy takes over once it finds headings, and while there are none (not rendered yet, or `spy={false}`) the highlight stays put and clicks move it.
1028
+ - **`spy`** (default `true`) / **`spyOffset`** (default `0`): the current heading is the last one whose top has crossed `spyOffset` px from the top of the viewport. The listener runs in the capture phase, so a scrolling container works as well as the window. **A clicked row stays current while its heading is on screen** even if it can't reach the fold line (a short last section never can); any wheel, touch or key input hands control back to the spy. A hash in the URL on mount pins its row the same way.
1029
+ - **`onItemClick(item, event)`:** runs before the hash navigation; `preventDefault()` to take it over.
1030
+ - Rows are 14px/1.3 tertiary text on a 25px pitch (7px gap), text 15px in from the rule, 32px above the title and 12px below the last row — the Figma geometry. Hover lifts a row to `--HS-text-primary-default` and grows a 2px `--HS-surface-ui-border-300` bar over the rule; the current row keeps the bar in `--HS-surface-ui-border-1000`. The bar is a `::before` whose width animates in and out on `--hsui-toc-bar-bounce` (default `--animations-bounce-fast`, so it overshoots a touch and settles); it isn't a border, so the text never moves. **Colours are not transitioned** — neither the text nor the bar — for the same reason as ButtonGroup: a colour transition can't tell a hover from a `data-theme` flip, so it would fade the rail behind the rest of the page on a theme change. The rule is a pseudo-element too, so the bar can cover it. Everything is `--HS-*` tokens, so dark mode is automatic (border-1000 remaps to neutral-0). Width, stickiness and the breakpoint that hides the rail belong to the page.
1031
+
1032
+ **Accessibility:**
1033
+ - A real `<nav>` named by its visible title via `aria-labelledby` (AT announces "On this page, navigation"); with `title={null}` it takes `aria-label`, falling back to "On this page". Pass `aria-label` explicitly to override either way.
1034
+ - The rows are a `<ul role="list">` of real links (the role keeps Safari/VoiceOver from dropping list semantics from an unstyled list), so a screen reader hears "list, 6 items" and can jump between them. The current row carries `aria-current="location"` — the value for "where you are within the page" — so it is announced whichever way it was reached.
1035
+ - Keyboard: Tab through the links, Enter follows the hash and marks the row current; `:focus-visible` draws the shared two-tone brand focus ring (the `a11y-focus-ring` mixin, animating on `--animations-bounce-default`). Keyboard scrolling counts as reader input and releases a pinned row to the spy.
1036
+ - Hover and current states pair the bar with a text-colour change, so neither rests on colour alone. The bar's width grows on the bounce token and is instant under `prefers-reduced-motion: reduce`, which leaves nothing animating; colours switch instantly in every mode. The spy only swaps which row is current.
1037
+ - Rows are 18px tall on a 25px pitch: under the 24px minimum of WCAG 2.5.8, but the pitch keeps every target at least 24px from the next, which is the criterion's spacing exception. Nested rows indent without shrinking.
1038
+
963
1039
  ## Hooks
964
1040
 
965
1041
  ### useSuccessFlash
@@ -1137,6 +1213,18 @@ All components use the same `iconLeft` / `iconRight` naming:
1137
1213
  - **Do** pass an icon component to `icon` for a custom bullet
1138
1214
  - **Don't** write bullets or numbers into the item text (`•`, `1.`) — the component draws them
1139
1215
 
1216
+ ### Figure
1217
+ - **Do** put the explanation in `caption` and what the image shows in `alt`
1218
+ - **Don't** repeat the caption as the alt text, or leave the alt as a file name
1219
+ - **Do** wrap a `BrowserFrame` in a `Figure` when the demo needs a sentence under it
1220
+ - **Don't** add margins inside the figure — the page sets the spacing around it
1221
+ - **Do** pass `srcDark` for diagrams and UI screenshots that have a dark version
1222
+ - **Don't** dim or invert a light image for dark mode — a filter changes a chart's colours
1223
+ - **Do** turn on `zoom` for screenshots and diagrams whose detail matters
1224
+ - **Don't** zoom a small illustration or an icon — there is nothing more to see
1225
+ - **Do** use `frame="card"` for an illustration that should read as a picture on the page, the way a BrowserFrame does
1226
+ - **Don't** put `card` on every screenshot — the hairline is the default for a reason
1227
+
1140
1228
  ### Features
1141
1229
  - **Do** swap the icon per feature, and color it with `iconColor` when the section calls for it
1142
1230
  - **Do** keep `descriptionColor="tertiary"` for white/background-0 surfaces — on the page background or any grey it fails contrast
package/README.md CHANGED
@@ -15,6 +15,7 @@ The Highsoft design system — a React component library, design tokens, a Story
15
15
  | --- | --- | --- | --- |
16
16
  | `lib/` | The component library (the published package) | `npm run build` → `dist/` | npm — `highsoft-ui` |
17
17
  | `src/` | The Astro docs site (multi-page, React islands) | `npm run build:app` → `dist-app/` | design.highdev.dev |
18
+ | `tools/icon-studio/` | 3D icon studio and local Blender helper | `npm run build:app` | Design site only — never npm |
18
19
  | `stories/` | Storybook stories | `npm run build-storybook` | storybook.highdev.dev |
19
20
 
20
21
  `lib/` is the source of truth; the docs site and Storybook both consume it directly (via the `highsoft-ui` alias), so a change to a component shows up in all three.
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { t as e } from "./clsx-BWCAbrjV.js";
3
- import { G as t, L as n, R as r, k as i } from "./esm-zUd-Cmgs.js";
4
- import { t as a } from "./Button-CdrrwvXk.js";
3
+ import { A as t, K as n, R as r, z as i } from "./esm-DQBytmnt.js";
4
+ import { t as a } from "./Button-DFcjZsF4.js";
5
5
  import { forwardRef as o, useCallback as s, useEffect as c, useRef as l, useState as u } from "react";
6
6
  import { jsx as d, jsxs as f } from "react/jsx-runtime";
7
7
  var p = {
@@ -52,13 +52,13 @@ var h = o(({ variant: o = "full", src: h, displayUrl: g, href: _, action: v = "v
52
52
  }, [G]), X = o === "full" && v !== "none" ? v === "fullscreen" ? /* @__PURE__ */ d(a, {
53
53
  variant: "soft",
54
54
  size: 100,
55
- iconRight: d(V ? i : t, {}),
55
+ iconRight: d(V ? t : n, {}),
56
56
  onClick: Y,
57
57
  children: y ?? (V ? "Exit fullscreen" : "Fullscreen")
58
58
  }) : G ? /* @__PURE__ */ d(a, {
59
59
  variant: "soft",
60
60
  size: 100,
61
- iconRight: /* @__PURE__ */ d(r, {}),
61
+ iconRight: /* @__PURE__ */ d(i, {}),
62
62
  href: G,
63
63
  target: "_blank",
64
64
  rel: "noreferrer",
@@ -117,7 +117,7 @@ var h = o(({ variant: o = "full", src: h, displayUrl: g, href: _, action: v = "v
117
117
  children: S.map((e) => /* @__PURE__ */ d(a, {
118
118
  variant: "soft",
119
119
  size: 100,
120
- iconRight: /* @__PURE__ */ d(n, {}),
120
+ iconRight: /* @__PURE__ */ d(r, {}),
121
121
  href: e.href,
122
122
  target: "_blank",
123
123
  rel: "noreferrer",
@@ -1,5 +1,5 @@
1
1
  import { t as e } from "./clsx-BWCAbrjV.js";
2
- import { F as t } from "./esm-zUd-Cmgs.js";
2
+ import { I as t } from "./esm-DQBytmnt.js";
3
3
  import { forwardRef as n } from "react";
4
4
  import { jsx as r, jsxs as i } from "react/jsx-runtime";
5
5
  var a = {
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { t as e } from "./clsx-BWCAbrjV.js";
3
- import { t } from "./Button-CdrrwvXk.js";
3
+ import { t } from "./Button-DFcjZsF4.js";
4
4
  import { useEffect as n, useState as r } from "react";
5
5
  import { jsx as i } from "react/jsx-runtime";
6
6
  var a = {
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { t as e } from "./clsx-BWCAbrjV.js";
3
- import { P as t } from "./esm-zUd-Cmgs.js";
3
+ import { F as t } from "./esm-DQBytmnt.js";
4
4
  import { createContext as n, useCallback as r, useContext as i, useEffect as a, useId as o, useRef as s, useState as c } from "react";
5
5
  import { jsx as l, jsxs as u } from "react/jsx-runtime";
6
6
  var d = {
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { r as e, s as t } from "./utils-bAjntFD8.js";
3
3
  import { t as n } from "./clsx-BWCAbrjV.js";
4
- import { q as r, tt as i } from "./esm-zUd-Cmgs.js";
5
- import { t as a } from "./Button-CdrrwvXk.js";
4
+ import { J as r, nt as i } from "./esm-DQBytmnt.js";
5
+ import { t as a } from "./Button-DFcjZsF4.js";
6
6
  import { t as o } from "./FrameworkIcon-B8GmMx0r.js";
7
7
  import { Fragment as s, forwardRef as c, useCallback as l, useEffect as u, useMemo as d, useState as f } from "react";
8
8
  import { jsx as p, jsxs as m } from "react/jsx-runtime";
@@ -23,8 +23,8 @@ var h = {
23
23
  }, g = null;
24
24
  function _() {
25
25
  return g ||= Promise.all([
26
- import("./prism-light-oph9ikSp.js"),
27
- import("./create-element-DvDqDt-f.js").then((e) => e.n),
26
+ import("./prism-light-D9OePufj.js"),
27
+ import("./create-element-DHbI55TT.js").then((e) => e.n),
28
28
  import("./jsx-B57trbk8.js"),
29
29
  import("./tsx-CJFgwLf7.js"),
30
30
  import("./json-Bfzk2Msc.js"),
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { t as e } from "./esm-zUd-Cmgs.js";
3
- import { t } from "./Button-CdrrwvXk.js";
2
+ import { n as e } from "./esm-DQBytmnt.js";
3
+ import { t } from "./Button-DFcjZsF4.js";
4
4
  import { a as n, i as r, n as i, o as a, r as o, s, t as c } from "./dist-DWZ0DflU.js";
5
5
  import { useEffect as l, useRef as u, useState as d } from "react";
6
6
  import { jsx as f, jsxs as p } from "react/jsx-runtime";
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { r as e, s as t } from "./utils-bAjntFD8.js";
3
3
  import { t as n } from "./clsx-BWCAbrjV.js";
4
- import { q as r, tt as i } from "./esm-zUd-Cmgs.js";
5
- import { t as a } from "./Button-CdrrwvXk.js";
4
+ import { J as r, nt as i } from "./esm-DQBytmnt.js";
5
+ import { t as a } from "./Button-DFcjZsF4.js";
6
6
  import { forwardRef as o, useCallback as s } from "react";
7
7
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
8
8
  var u = {
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { t as e } from "./clsx-BWCAbrjV.js";
3
- import { tt as t } from "./esm-zUd-Cmgs.js";
3
+ import { nt as t } from "./esm-DQBytmnt.js";
4
4
  import { t as n } from "./Icon-DJTgdvsG.js";
5
5
  import { _ as r, a as i, c as a, d as o, g as s, h as c, i as l, l as u, m as d, n as f, o as p, p as m, r as h, t as g, u as _, v, y } from "./es2015-DGI5uxql.js";
6
6
  import { a as b, i as x, n as S, r as C, t as w } from "./dist-BAH-0dTg.js";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { t as e } from "./clsx-BWCAbrjV.js";
3
- import { t } from "./Icon-DJTgdvsG.js";
4
- import { t as n } from "./Typography-DI1AkqiO.js";
3
+ import { t } from "./Typography-DI1AkqiO.js";
4
+ import { t as n } from "./Icon-DJTgdvsG.js";
5
5
  import { createContext as r, forwardRef as i, useContext as a } from "react";
6
6
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
7
  var c = {
@@ -14,10 +14,10 @@ var c = {
14
14
  };
15
15
  //#endregion
16
16
  //#region lib/components/Features/index.tsx
17
- function l({ iconColor: e, descriptionColor: t }) {
17
+ function l({ iconColor: e, descriptionColor: n }) {
18
18
  return {
19
- ...e && { "--hsui-feature-icon-color": n[e] },
20
- ...t && { "--hsui-feature-description-color": n[t] }
19
+ ...e && { "--hsui-feature-icon-color": t[e] },
20
+ ...n && { "--hsui-feature-description-color": t[n] }
21
21
  };
22
22
  }
23
23
  var u = r(!1), d = i(({ columns: t = 3, iconColor: n, descriptionColor: r, className: i, style: a, children: s, ...d }, f) => /* @__PURE__ */ o(u.Provider, {
@@ -39,7 +39,7 @@ var u = r(!1), d = i(({ columns: t = 3, iconColor: n, descriptionColor: r, class
39
39
  })
40
40
  }));
41
41
  d.displayName = "Features";
42
- var f = i(({ icon: n, title: r, headingLevel: i, iconColor: d, descriptionColor: f, className: p, style: m, children: h, ...g }, _) => {
42
+ var f = i(({ icon: t, title: r, headingLevel: i, iconColor: d, descriptionColor: f, className: p, style: m, children: h, ...g }, _) => {
43
43
  let v = a(u) ? "li" : "div", y = i ? `h${i}` : null;
44
44
  return /* @__PURE__ */ s(v, {
45
45
  className: e("hsui-feature-item", p, c.item),
@@ -55,8 +55,8 @@ var f = i(({ icon: n, title: r, headingLevel: i, iconColor: d, descriptionColor:
55
55
  children: [/* @__PURE__ */ o("span", {
56
56
  className: c.icon,
57
57
  "aria-hidden": "true",
58
- children: /* @__PURE__ */ o(t, {
59
- name: n,
58
+ children: /* @__PURE__ */ o(n, {
59
+ name: t,
60
60
  size: 20
61
61
  })
62
62
  }), y ? /* @__PURE__ */ s("div", {
@@ -1,15 +1,15 @@
1
1
  "use client";
2
2
  import { r as e } from "./utils-bAjntFD8.js";
3
- import { J as t, tt as n } from "./esm-zUd-Cmgs.js";
4
- import { t as r } from "./Button-CdrrwvXk.js";
3
+ import { Y as t, nt as n } from "./esm-DQBytmnt.js";
4
+ import { t as r } from "./Button-DFcjZsF4.js";
5
5
  import { t as i } from "./Container-BDssaLig.js";
6
6
  import { t as a } from "./DiscordInvite-DfPVlJ5G.js";
7
7
  import { t as o } from "./Logo-Bz0G2G-k.js";
8
- import { t as s } from "./NewsletterSignup-BPLup66s.js";
9
- import { t as c } from "./FooterBottom-B8GCRg2o.js";
10
- import { t as l } from "./FooterHelp-D5X2Pco9.js";
11
- import { t as u } from "./FooterLinks-yn_sgcbu.js";
12
- import { t as d } from "./YoutubeModal-j51vfjYk.js";
8
+ import { t as s } from "./NewsletterSignup-CTbjNSnk.js";
9
+ import { t as c } from "./FooterBottom-BPuLsXI1.js";
10
+ import { t as l } from "./FooterHelp-99gRcRar.js";
11
+ import { t as u } from "./FooterLinks-DXTz-d8e.js";
12
+ import { t as d } from "./YoutubeModal-CXSHjsEd.js";
13
13
  import { jsx as f, jsxs as p } from "react/jsx-runtime";
14
14
  var m = {
15
15
  discordCard: "_4W4F3q_discordCard",
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import { a as e, t } from "./utils-bAjntFD8.js";
3
- import { a as n, c as r, i, n as a, o, r as s, s as c, t as l } from "./fa-B95RwBpz.js";
4
- import { n as u } from "./Typography-DI1AkqiO.js";
5
- import { t as d } from "./CookiePolicyModal-xPb4G_hM.js";
3
+ import { n } from "./Typography-DI1AkqiO.js";
4
+ import { a as r, c as i, i as a, n as o, o as s, r as c, s as l, t as u } from "./fa-B95RwBpz.js";
5
+ import { t as d } from "./CookiePolicyModal-D-IOZSoU.js";
6
6
  import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
7
7
  //#region node_modules/react-icons/fa6/index.mjs
8
8
  function h(e) {
9
- return r({
9
+ return i({
10
10
  tag: "svg",
11
11
  attr: { viewBox: "0 0 512 512" },
12
12
  child: [{
@@ -30,12 +30,12 @@ function _(e, t) {
30
30
  }
31
31
  var v = [
32
32
  {
33
- icon: /* @__PURE__ */ p(o, {}),
33
+ icon: /* @__PURE__ */ p(s, {}),
34
34
  url: "https://stackoverflow.com/questions/tagged/highcharts",
35
35
  label: "StackOverlow"
36
36
  },
37
37
  {
38
- icon: /* @__PURE__ */ p(s, {}),
38
+ icon: /* @__PURE__ */ p(c, {}),
39
39
  url: "https://github.com/highcharts/highcharts",
40
40
  label: "GitHub"
41
41
  },
@@ -45,33 +45,33 @@ var v = [
45
45
  label: "X"
46
46
  },
47
47
  {
48
- icon: /* @__PURE__ */ p(a, {}),
48
+ icon: /* @__PURE__ */ p(o, {}),
49
49
  url: "https://www.facebook.com/Highcharts",
50
50
  label: "Facebook"
51
51
  },
52
52
  {
53
- icon: /* @__PURE__ */ p(i, {}),
53
+ icon: /* @__PURE__ */ p(a, {}),
54
54
  url: "https://www.instagram.com/highsoftcompany/",
55
55
  label: "Instagram"
56
56
  },
57
57
  {
58
- icon: /* @__PURE__ */ p(n, {}),
58
+ icon: /* @__PURE__ */ p(r, {}),
59
59
  url: "https://www.linkedin.com/company/highsoft",
60
60
  label: "LinkedIn"
61
61
  },
62
62
  {
63
- icon: /* @__PURE__ */ p(l, {}),
63
+ icon: /* @__PURE__ */ p(u, {}),
64
64
  url: "https://www.highcharts.com/highcharts-discord/",
65
65
  label: "Discord"
66
66
  },
67
67
  {
68
- icon: /* @__PURE__ */ p(c, {}),
68
+ icon: /* @__PURE__ */ p(l, {}),
69
69
  url: "https://www.youtube.com/channel/UCzxXofPTQ0DoT7uIy3Fxw7A",
70
70
  label: "Youtube"
71
71
  }
72
72
  ];
73
- function y({ link: n = "a", host: r = "https://www.highcharts.com" }) {
74
- let i = e(`(min-width: ${t.tablet}px) and (max-width: ${t.laptop - 1}px)`), a = /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ m(u, {
73
+ function y({ link: r = "a", host: i = "https://www.highcharts.com" }) {
74
+ let a = e(`(min-width: ${t.tablet}px) and (max-width: ${t.laptop - 1}px)`), o = /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ m(n, {
75
75
  as: "span",
76
76
  size: 100,
77
77
  color: "secondary",
@@ -84,18 +84,18 @@ function y({ link: n = "a", host: r = "https://www.highcharts.com" }) {
84
84
  }), /* @__PURE__ */ m("div", {
85
85
  className: g.bottomLinks,
86
86
  children: [
87
- /* @__PURE__ */ p(n, {
88
- href: _("https://www.highcharts.com/blog/article/accessibility-statement/", r),
89
- children: /* @__PURE__ */ p(u, {
87
+ /* @__PURE__ */ p(r, {
88
+ href: _("https://www.highcharts.com/blog/article/accessibility-statement/", i),
89
+ children: /* @__PURE__ */ p(n, {
90
90
  as: "span",
91
91
  size: 100,
92
92
  color: "secondary",
93
93
  children: "Accessibility Statement"
94
94
  })
95
95
  }),
96
- /* @__PURE__ */ p(n, {
97
- href: _("https://www.highcharts.com/sitemap.xml", r),
98
- children: /* @__PURE__ */ p(u, {
96
+ /* @__PURE__ */ p(r, {
97
+ href: _("https://www.highcharts.com/sitemap.xml", i),
98
+ children: /* @__PURE__ */ p(n, {
99
99
  as: "span",
100
100
  size: 100,
101
101
  color: "secondary",
@@ -105,7 +105,7 @@ function y({ link: n = "a", host: r = "https://www.highcharts.com" }) {
105
105
  /* @__PURE__ */ p("button", {
106
106
  type: "button",
107
107
  onClick: () => window.CookieConsent?.renew(),
108
- children: /* @__PURE__ */ p(u, {
108
+ children: /* @__PURE__ */ p(n, {
109
109
  as: "span",
110
110
  size: 100,
111
111
  color: "secondary",
@@ -114,7 +114,7 @@ function y({ link: n = "a", host: r = "https://www.highcharts.com" }) {
114
114
  }),
115
115
  /* @__PURE__ */ p(d, {})
116
116
  ]
117
- })] }), o = /* @__PURE__ */ p("ul", {
117
+ })] }), s = /* @__PURE__ */ p("ul", {
118
118
  className: g.socials,
119
119
  children: v.map(({ icon: e, url: t, label: n }, r) => /* @__PURE__ */ p("li", { children: /* @__PURE__ */ p("a", {
120
120
  href: t,
@@ -124,10 +124,10 @@ function y({ link: n = "a", host: r = "https://www.highcharts.com" }) {
124
124
  });
125
125
  return /* @__PURE__ */ p("div", {
126
126
  className: g.bottom,
127
- children: i ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("div", {
127
+ children: a ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("div", {
128
128
  className: g.tabletBottomLeft,
129
- children: a
130
- }), o] }) : /* @__PURE__ */ m(f, { children: [a, o] })
129
+ children: o
130
+ }), s] }) : /* @__PURE__ */ m(f, { children: [o, s] })
131
131
  });
132
132
  }
133
133
  //#endregion
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import { a as e, t } from "./utils-bAjntFD8.js";
3
- import { d as n, g as r } from "./esm-zUd-Cmgs.js";
4
- import { t as i } from "./Icon-DJTgdvsG.js";
5
- import { o as a, r as o } from "./fa-B95RwBpz.js";
6
- import { n as s } from "./Typography-DI1AkqiO.js";
3
+ import { _ as n, f as r } from "./esm-DQBytmnt.js";
4
+ import { n as i } from "./Typography-DI1AkqiO.js";
5
+ import { t as a } from "./Icon-DJTgdvsG.js";
6
+ import { o, r as s } from "./fa-B95RwBpz.js";
7
7
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
8
8
  var u = {
9
9
  help: "vfdIHG_help",
@@ -23,8 +23,8 @@ function d(e, t) {
23
23
  }
24
24
  var f = [
25
25
  {
26
- icon: /* @__PURE__ */ c(i, {
27
- name: n,
26
+ icon: /* @__PURE__ */ c(a, {
27
+ name: r,
28
28
  size: 20
29
29
  }),
30
30
  subtitle: "Ask tech and sales questions with",
@@ -32,8 +32,8 @@ var f = [
32
32
  url: "https://www.highcharts.com/chat/gpt/"
33
33
  },
34
34
  {
35
- icon: /* @__PURE__ */ c(i, {
36
- name: a,
35
+ icon: /* @__PURE__ */ c(a, {
36
+ name: o,
37
37
  size: 20
38
38
  }),
39
39
  subtitle: "Search answers on",
@@ -41,8 +41,8 @@ var f = [
41
41
  url: "https://stackoverflow.com/questions/tagged/highcharts"
42
42
  },
43
43
  {
44
- icon: /* @__PURE__ */ c(i, {
45
- name: o,
44
+ icon: /* @__PURE__ */ c(a, {
45
+ name: s,
46
46
  size: 20
47
47
  }),
48
48
  subtitle: "Report issues on",
@@ -50,8 +50,8 @@ var f = [
50
50
  url: "https://github.com/highcharts/highcharts/issues"
51
51
  },
52
52
  {
53
- icon: /* @__PURE__ */ c(i, {
54
- name: r,
53
+ icon: /* @__PURE__ */ c(a, {
54
+ name: n,
55
55
  size: 20
56
56
  }),
57
57
  subtitle: "Contact sales about",
@@ -60,53 +60,53 @@ var f = [
60
60
  }
61
61
  ];
62
62
  function p({ link: n = "a", host: r = "https://www.highcharts.com" }) {
63
- let i = e(`(max-width: ${t.tablet - 1}px)`);
63
+ let a = e(`(max-width: ${t.tablet - 1}px)`);
64
64
  return /* @__PURE__ */ l("div", {
65
65
  className: u.help,
66
66
  children: [/* @__PURE__ */ l("div", {
67
67
  className: u.helpWays,
68
- children: [/* @__PURE__ */ c(s, {
68
+ children: [/* @__PURE__ */ c(i, {
69
69
  as: "span",
70
70
  size: 100,
71
71
  weight: "semi",
72
72
  color: "primary",
73
73
  className: u.helpEyebrow,
74
74
  children: "Ways to get help"
75
- }), /* @__PURE__ */ l(s, {
75
+ }), /* @__PURE__ */ l(i, {
76
76
  as: "p",
77
77
  size: 75,
78
78
  color: "secondary",
79
79
  className: u.helpSchedule,
80
80
  children: [
81
81
  "We operate in CET",
82
- i ? " " : /* @__PURE__ */ c("br", {}),
82
+ a ? " " : /* @__PURE__ */ c("br", {}),
83
83
  "Monday - Friday"
84
84
  ]
85
85
  })]
86
- }), f.map(({ icon: e, subtitle: t, title: i, url: a }, o) => /* @__PURE__ */ l(n, {
87
- href: d(a, r),
86
+ }), f.map(({ icon: e, subtitle: t, title: a, url: o }, s) => /* @__PURE__ */ l(n, {
87
+ href: d(o, r),
88
88
  className: u.helpItem,
89
89
  children: [/* @__PURE__ */ c("div", {
90
90
  className: u.helpBall,
91
91
  children: e
92
92
  }), /* @__PURE__ */ l("div", {
93
93
  className: u.helpContent,
94
- children: [/* @__PURE__ */ c(s, {
94
+ children: [/* @__PURE__ */ c(i, {
95
95
  as: "span",
96
96
  size: 75,
97
97
  color: "secondary",
98
98
  className: u.helpSubtitle,
99
99
  children: t
100
- }), /* @__PURE__ */ c(s, {
100
+ }), /* @__PURE__ */ c(i, {
101
101
  as: "span",
102
102
  size: 100,
103
103
  weight: "semi",
104
104
  color: "primary",
105
105
  className: u.helpTitle,
106
- children: i
106
+ children: a
107
107
  })]
108
108
  })]
109
- }, o))]
109
+ }, s))]
110
110
  });
111
111
  }
112
112
  //#endregion
@@ -1,8 +1,8 @@
1
1
  import { t as e } from "./clsx-BWCAbrjV.js";
2
- import { I as t } from "./esm-zUd-Cmgs.js";
3
- import { t as n } from "./Icon-DJTgdvsG.js";
4
- import { n as r } from "./Typography-DI1AkqiO.js";
5
- import { t as i } from "./Label-B-Xt6XQQ.js";
2
+ import { L as t } from "./esm-DQBytmnt.js";
3
+ import { n } from "./Typography-DI1AkqiO.js";
4
+ import { t as r } from "./Icon-DJTgdvsG.js";
5
+ import { t as i } from "./Label-DTIv_3zs.js";
6
6
  import { jsx as a, jsxs as o } from "react/jsx-runtime";
7
7
  var s = {
8
8
  externalIcon: "N4RQEq_externalIcon",
@@ -267,7 +267,7 @@ var l = {
267
267
  function u({ link: u = "a", host: d = "https://www.highcharts.com" }) {
268
268
  return /* @__PURE__ */ a("div", {
269
269
  className: s.links,
270
- children: Object.entries(l).map(([l, f], p) => /* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a(r, {
270
+ children: Object.entries(l).map(([l, f], p) => /* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a(n, {
271
271
  as: "h2",
272
272
  size: 100,
273
273
  weight: "medium",
@@ -278,12 +278,12 @@ function u({ link: u = "a", host: d = "https://www.highcharts.com" }) {
278
278
  href: c(f, d),
279
279
  className: e({ [s.tagged]: p }),
280
280
  target: f.includes("highcharts.com") ? void 0 : "_blank",
281
- children: [/* @__PURE__ */ o(r, {
281
+ children: [/* @__PURE__ */ o(n, {
282
282
  as: "span",
283
283
  size: 100,
284
284
  color: "secondary",
285
285
  className: s.linkLabel,
286
- children: [l, !f.includes("highcharts.com") && /* @__PURE__ */ a(n, {
286
+ children: [l, !f.includes("highcharts.com") && /* @__PURE__ */ a(r, {
287
287
  name: t,
288
288
  size: 12,
289
289
  className: s.externalIcon