@studiocms/ui 0.4.17 → 1.0.0-beta.1

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 (70) hide show
  1. package/dist/components/Accordion/Accordion.astro +1 -0
  2. package/dist/components/Accordion/Item.astro +8 -6
  3. package/dist/components/Accordion/accordion.css +35 -21
  4. package/dist/components/Accordion/accordion.d.ts +46 -1
  5. package/dist/components/Accordion/accordion.js +95 -70
  6. package/dist/components/Badge/Badge.astro +2 -2
  7. package/dist/components/Badge/badge.css +32 -32
  8. package/dist/components/Breadcrumbs/breadcrumbs.css +1 -1
  9. package/dist/components/Button/button.css +93 -93
  10. package/dist/components/Card/card.css +4 -4
  11. package/dist/components/Checkbox/checkbox.css +26 -26
  12. package/dist/components/Divider/Divider.astro +1 -1
  13. package/dist/components/Divider/divider.css +2 -2
  14. package/dist/components/Dropdown/Dropdown.astro +2 -2
  15. package/dist/components/Dropdown/dropdown.css +26 -26
  16. package/dist/components/Footer/footer.css +4 -4
  17. package/dist/components/Group/group.css +12 -6
  18. package/dist/components/Icon/Icon.astro +114 -6
  19. package/dist/components/Icon/IconBase.astro +108 -7
  20. package/dist/components/Icon/errors.d.ts +29 -0
  21. package/dist/components/Icon/errors.js +25 -0
  22. package/dist/components/Input/Input.astro +43 -1
  23. package/dist/components/Input/input.css +39 -9
  24. package/dist/components/Modal/Modal.astro +1 -1
  25. package/dist/components/Modal/modal.css +4 -4
  26. package/dist/components/Progress/progress.css +7 -7
  27. package/dist/components/RadioGroup/radiogroup.css +21 -21
  28. package/dist/components/SearchSelect/SearchSelect.astro +2 -2
  29. package/dist/components/SearchSelect/searchselect.css +28 -22
  30. package/dist/components/Select/Select.astro +2 -2
  31. package/dist/components/Select/select.css +36 -30
  32. package/dist/components/Sidebar/Double.astro +4 -4
  33. package/dist/components/Sidebar/Single.astro +2 -2
  34. package/dist/components/Skeleton/Skeleton.astro +61 -0
  35. package/dist/components/Skeleton/skeleton.css +111 -0
  36. package/dist/components/Skeleton/skeleton.d.ts +161 -0
  37. package/dist/components/Skeleton/skeleton.js +71 -0
  38. package/dist/components/Tabs/TabItem.astro +14 -9
  39. package/dist/components/Tabs/Tabs.astro +91 -54
  40. package/dist/components/Tabs/tabs.css +14 -14
  41. package/dist/components/Tabs/tabs.d.ts +17 -1
  42. package/dist/components/Tabs/tabs.js +99 -76
  43. package/dist/components/Textarea/textarea.css +8 -8
  44. package/dist/components/Toast/toaster.css +26 -23
  45. package/dist/components/Toast/toaster.js +4 -0
  46. package/dist/components/Toggle/toggle.css +13 -13
  47. package/dist/components/Tooltip/Tooltip.astro +119 -0
  48. package/dist/components/Tooltip/tooltip.css +187 -0
  49. package/dist/components/Tooltip/tooltip.d.ts +46 -0
  50. package/dist/components/Tooltip/tooltip.js +330 -0
  51. package/dist/components/User/User.astro +1 -1
  52. package/dist/components/User/user.css +3 -3
  53. package/dist/css/colors.css +85 -83
  54. package/dist/css/prose.css +360 -0
  55. package/dist/css/resets.css +3 -3
  56. package/dist/events.d.ts +104 -0
  57. package/dist/index.d.ts +25 -0
  58. package/dist/index.js +120 -313
  59. package/dist/toolbar/index.js +5 -5
  60. package/dist/types/index.d.ts +2 -0
  61. package/dist/utils/iconifyUtils.d.ts +1 -1
  62. package/dist/virtuals.d.js +0 -0
  63. package/dist/virtuals.d.ts +564 -0
  64. package/package.json +5 -1
  65. package/dist/components/Icon/iconType.d.ts +0 -2
  66. package/dist/components/ThemeToggle/ThemeToggle.astro +0 -21
  67. package/dist/components/ThemeToggle/themetoggle.css +0 -17
  68. package/dist/components/ThemeToggle/themetoggle.d.ts +0 -1
  69. package/dist/components/ThemeToggle/themetoggle.js +0 -4
  70. /package/dist/{components/Icon/iconType.js → events.d.js} +0 -0
@@ -18,6 +18,7 @@ const { style = 'outlined', multipleOpen = true } = Astro.props;
18
18
  <div class="sui-accordion" class:list={[style]} data-multiple={multipleOpen}>
19
19
  <slot />
20
20
  </div>
21
+
21
22
  <script>
22
23
  import 'studiocms:ui/scripts/accordion';
23
24
  </script>
@@ -8,14 +8,16 @@ interface Props {
8
8
  const { open = false } = Astro.props;
9
9
  ---
10
10
 
11
- <div class="sui-accordion-item" class:list={{ active: open }} data-open={open}>
12
- <div class="sui-accordion-summary not-content" tabindex="0">
13
- <Icon name="chevron-right-20-solid" class='sui-summary-chevron' width={20} height={20} />
11
+ <div class="sui-accordion-item" data-open={open}>
12
+ <button class="sui-accordion-summary not-content" type="button" aria-expanded={open}>
13
+ <Icon name="heroicons:chevron-right-20-solid" class='sui-summary-chevron' width={20} height={20} />
14
14
  <div class="sui-accordion-summary-content">
15
15
  <slot name="summary" />
16
16
  </div>
17
- </div>
18
- <div class="sui-accordion-details" class:list={{ active: open, open: open, initial: !open }}>
19
- <slot name="default" />
17
+ </button>
18
+ <div class="sui-accordion-details" aria-hidden={!open}>
19
+ <div class="sui-accordion-content">
20
+ <slot name="default" />
21
+ </div>
20
22
  </div>
21
23
  </div>
@@ -7,47 +7,43 @@
7
7
  }
8
8
  .sui-accordion-details {
9
9
  margin-left: calc(2.25rem);
10
- }
11
- .sui-accordion-details.initial {
12
- visibility: hidden;
13
- transition: none;
14
- max-height: none;
15
- position: absolute;
16
- top: -200vh;
17
- left: -200vh;
18
- }
19
- .sui-accordion-details.active {
20
- overflow: hidden;
21
- max-height: 0;
22
- transition: all .3s ease;
10
+ display: grid;
11
+ grid-template-rows: 0fr;
23
12
  position: relative;
13
+ bottom: 0;
14
+ transition: grid-template-rows 0.3s ease, bottom 0.3s ease;
15
+ overflow: hidden;
16
+ }
17
+ .sui-accordion-item[data-open=true] > .sui-accordion-details {
24
18
  bottom: .25rem;
19
+ grid-template-rows: 1fr;
25
20
  }
26
- .sui-accordion-details.open {
27
- max-height: none;
21
+ .sui-accordion-content {
22
+ min-height: 0;
23
+ overflow: hidden;
28
24
  }
29
25
  .sui-accordion.outlined,
30
26
  .sui-accordion.filled {
31
- border: 1px solid hsl(var(--border));
27
+ border: 1px solid var(--border);
32
28
  border-radius: var(--radius-sm);
33
29
  }
34
30
  .sui-accordion.filled {
35
- background-color: hsl(var(--background-step-1));
31
+ background-color: var(--background-step-1);
36
32
  }
37
33
  .sui-accordion.separated .sui-accordion-item,
38
34
  .sui-accordion.outlined .sui-accordion-item,
39
35
  .sui-accordion.filled .sui-accordion-item {
40
- border-bottom: 1px solid hsl(var(--border));
36
+ border-bottom: 1px solid var(--border);
41
37
  }
42
38
  .sui-accordion.separated .sui-accordion-item:first-of-type {
43
- border-top: 1px solid hsl(var(--border));
39
+ border-top: 1px solid var(--border);
44
40
  }
45
41
  .sui-accordion.filled .sui-accordion-item:last-of-type,
46
42
  .sui-accordion.outlined .sui-accordion-item:last-of-type {
47
43
  border-bottom: none;
48
44
  }
49
45
  .sui-accordion-summary {
50
- color: hsl(var(--text-normal));
46
+ color: var(--text-normal);
51
47
  display: flex;
52
48
  flex-direction: row;
53
49
  gap: .5rem;
@@ -55,10 +51,28 @@
55
51
  padding-left: .5rem;
56
52
  padding-bottom: .5rem;
57
53
  padding-top: .5rem;
54
+ user-select: none;
55
+ width: 100%;
56
+ border: none;
57
+ background: transparent;
58
+ cursor: pointer;
59
+ text-align: left;
60
+ }
61
+ .sui-accordion-summary:focus-visible {
62
+ outline: 2px solid var(--text-normal);
63
+ outline-offset: 2px;
58
64
  }
59
65
  .sui-summary-chevron {
60
66
  transition: all .3s ease;
61
67
  }
62
- .sui-accordion-item.active .sui-summary-chevron {
68
+ .sui-accordion-item[data-open=true] > .sui-accordion-summary .sui-summary-chevron {
63
69
  transform: rotate(90deg);
64
70
  }
71
+ @media (prefers-reduced-motion: reduce) {
72
+ .sui-accordion-details {
73
+ transition: none;
74
+ }
75
+ .sui-summary-chevron {
76
+ transition: none;
77
+ }
78
+ }
@@ -1 +1,46 @@
1
- declare function loadAccordions(): void;
1
+ /**
2
+ * Finds the owning accordion element for a given accordion item. Used for nested accordions.
3
+ * @param accordionItem The accordion item element to find the owning accordion for.
4
+ * @returns The owning accordion element or null if not found.
5
+ */
6
+ declare const findOwningAccordion: (accordionItem: HTMLDivElement) => HTMLDivElement | null;
7
+ /**
8
+ * Gets the direct accordion items for a given accordion. Supports nested accordions.
9
+ * @param accordion The accordion element to get direct items from.
10
+ * @returns An array of direct accordion item elements that are direct children of the given accordion.
11
+ */
12
+ declare const getDirectAccordionItems: (accordion: HTMLDivElement) => HTMLDivElement[];
13
+ /**
14
+ * Updates the ARIA attributes for a given accordion item.
15
+ * @param item The accordion item element to update ARIA attributes for.
16
+ * @param isOpen Whether the accordion item is currently open or closed.
17
+ */
18
+ declare const updateAccordionARIA: (item: HTMLDivElement, isOpen: boolean) => void;
19
+ /**
20
+ * Toggles the open state of a given accordion item.
21
+ * @param accordionItem The accordion item element to toggle.
22
+ * @param accordion The accordion element that contains the item.
23
+ * @returns void
24
+ */
25
+ declare const toggleAccordionItem: (accordionItem: HTMLDivElement, accordion: HTMLDivElement) => void;
26
+ /**
27
+ * Focuses the next or previous accordion item within a given accordion.
28
+ * @param accordion The accordion element to focus an item within.
29
+ * @param direction The direction to focus the item in (next or previous).
30
+ * @param currentItem The currently focused accordion item.
31
+ * @returns void
32
+ */
33
+ declare const focusAccordionItem: (accordion: HTMLDivElement, direction: "next" | "prev", currentItem: HTMLDivElement) => void;
34
+ /**
35
+ * Initializes the ARIA states for all accordion items on page load.
36
+ */
37
+ declare const initializeAccordionStates: () => void;
38
+ declare let listenersAdded: boolean;
39
+ /**
40
+ * Toggles the open state of a given accordion item.
41
+ * @param event The event that triggered the interaction (click or keydown).
42
+ * @param isKeyboard Whether the interaction was triggered by a keyboard event.
43
+ * @returns void
44
+ */
45
+ declare const handleAccordionInteraction: (event: Event, isKeyboard?: boolean) => void;
46
+ declare const loadAccordions: () => void;
@@ -1,73 +1,98 @@
1
- function loadAccordions() {
2
- const allAccordions = document.querySelectorAll(".sui-accordion");
3
- for (const accordion of allAccordions) {
4
- const multipleOpen = accordion.dataset.multiple === "true";
5
- const items = accordion.querySelectorAll(".sui-accordion-item");
6
- for (const item of items) {
7
- const summary = item.querySelector(".sui-accordion-summary");
8
- const content = item.querySelector(".sui-accordion-details");
9
- if (!content || !summary) continue;
10
- const itemWidth = item.getBoundingClientRect().width;
11
- content.style.width = `${itemWidth - 36}px`;
12
- let contentBoundingBox = content.getBoundingClientRect();
13
- content.style.width = "auto";
14
- if (content.classList.contains("initial")) {
15
- content.classList.remove("initial");
16
- content.classList.add("active");
17
- }
18
- const open = item.dataset.open === "true";
19
- if (open) {
20
- item.classList.add("active");
21
- content.style.maxHeight = `${contentBoundingBox.height}px`;
22
- }
23
- const toggleElement = () => {
24
- if (!multipleOpen) {
25
- for (const otherItem of items) {
26
- if (otherItem !== item) {
27
- otherItem.classList.remove("active");
28
- const otherContent = otherItem.querySelector(".sui-accordion-details");
29
- if (otherContent) {
30
- otherContent.style.maxHeight = "0";
31
- }
32
- }
33
- }
34
- }
35
- item.classList.toggle("active");
36
- if (item.classList.contains("active")) {
37
- content.style.maxHeight = `${contentBoundingBox.height}px`;
38
- } else {
39
- content.style.maxHeight = "0";
40
- content.classList.remove("open");
41
- }
42
- };
43
- summary.addEventListener("click", toggleElement);
44
- summary.addEventListener("keydown", (event) => {
45
- if (event.key === "Enter" || event.key === " ") {
46
- toggleElement();
47
- }
48
- });
49
- let resetting = false;
50
- window.addEventListener("resize", async () => {
51
- if (item.classList.contains("active")) {
52
- content.style.maxHeight = "none";
53
- contentBoundingBox = content.getBoundingClientRect();
54
- content.style.maxHeight = `${contentBoundingBox.height}px`;
55
- } else if (!resetting) {
56
- resetting = true;
57
- content.classList.remove("active");
58
- content.classList.add("initial");
59
- const itemWidth2 = item.getBoundingClientRect().width;
60
- content.style.width = `${itemWidth2 - 36}px`;
61
- content.style.maxHeight = "none";
62
- contentBoundingBox = content.getBoundingClientRect();
63
- content.style.width = "auto";
64
- content.style.maxHeight = "0";
65
- content.classList.add("active");
66
- content.classList.remove("initial");
67
- resetting = false;
68
- }
69
- });
1
+ const findOwningAccordion = (accordionItem) => {
2
+ let current = accordionItem.parentElement;
3
+ while (current) {
4
+ if (current.classList.contains("sui-accordion")) {
5
+ return current;
70
6
  }
7
+ current = current.parentElement;
71
8
  }
72
- }
9
+ return null;
10
+ };
11
+ const getDirectAccordionItems = (accordion) => {
12
+ const allItems = accordion.querySelectorAll(".sui-accordion-item");
13
+ const directItems = [];
14
+ for (let i = 0; i < allItems.length; i++) {
15
+ if (findOwningAccordion(allItems[i]) === accordion) {
16
+ directItems.push(allItems[i]);
17
+ }
18
+ }
19
+ return directItems;
20
+ };
21
+ const updateAccordionARIA = (item, isOpen) => {
22
+ const summary = item.querySelector(".sui-accordion-summary");
23
+ const details = item.querySelector(".sui-accordion-details");
24
+ if (summary) summary.setAttribute("aria-expanded", isOpen.toString());
25
+ if (details) details.setAttribute("aria-hidden", (!isOpen).toString());
26
+ };
27
+ const toggleAccordionItem = (accordionItem, accordion) => {
28
+ const isAlreadyOpen = accordionItem.dataset.open === "true";
29
+ const newState = !isAlreadyOpen;
30
+ if (accordion.dataset.multiple === "true") {
31
+ accordionItem.dataset.open = newState.toString();
32
+ } else {
33
+ const directItems = getDirectAccordionItems(accordion);
34
+ for (let i = 0; i < directItems.length; i++) {
35
+ const item = directItems[i];
36
+ const shouldBeOpen = item === accordionItem;
37
+ item.dataset.open = shouldBeOpen.toString();
38
+ updateAccordionARIA(item, shouldBeOpen);
39
+ }
40
+ return;
41
+ }
42
+ updateAccordionARIA(accordionItem, newState);
43
+ };
44
+ const focusAccordionItem = (accordion, direction, currentItem) => {
45
+ const items = getDirectAccordionItems(accordion);
46
+ const currentIndex = items.indexOf(currentItem);
47
+ if (currentIndex === -1) return;
48
+ const targetIndex = direction === "next" ? (currentIndex + 1) % items.length : (currentIndex - 1 + items.length) % items.length;
49
+ const targetSummary = items[targetIndex]?.querySelector(".sui-accordion-summary");
50
+ targetSummary?.focus();
51
+ };
52
+ const initializeAccordionStates = () => {
53
+ const allAccordionItems = document.querySelectorAll(".sui-accordion-item");
54
+ for (let i = 0; i < allAccordionItems.length; i++) {
55
+ const item = allAccordionItems[i];
56
+ const isOpen = item.dataset.open === "true";
57
+ updateAccordionARIA(item, isOpen);
58
+ }
59
+ };
60
+ let listenersAdded = false;
61
+ const handleAccordionInteraction = (event, isKeyboard = false) => {
62
+ const target = event.target;
63
+ const accordionSummary = target.closest(".sui-accordion-summary");
64
+ if (!accordionSummary) return;
65
+ const accordionItem = accordionSummary.closest(".sui-accordion-item");
66
+ const accordion = accordionItem && findOwningAccordion(accordionItem);
67
+ if (!accordionItem || !accordion) return;
68
+ if (isKeyboard) {
69
+ const keyEvent = event;
70
+ switch (keyEvent.key) {
71
+ case "Enter":
72
+ case " ":
73
+ event.preventDefault();
74
+ toggleAccordionItem(accordionItem, accordion);
75
+ break;
76
+ case "ArrowDown":
77
+ event.preventDefault();
78
+ focusAccordionItem(accordion, "next", accordionItem);
79
+ break;
80
+ case "ArrowUp":
81
+ event.preventDefault();
82
+ focusAccordionItem(accordion, "prev", accordionItem);
83
+ break;
84
+ }
85
+ } else {
86
+ event.preventDefault();
87
+ toggleAccordionItem(accordionItem, accordion);
88
+ }
89
+ };
90
+ const loadAccordions = () => {
91
+ initializeAccordionStates();
92
+ if (!listenersAdded) {
93
+ document.addEventListener("click", handleAccordionInteraction);
94
+ document.addEventListener("keydown", (e) => handleAccordionInteraction(e, true));
95
+ listenersAdded = true;
96
+ }
97
+ };
73
98
  document.addEventListener("astro:page-load", loadAccordions);
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  import type { StudioCMSColorway } from '../../utils/colors.js';
3
3
  import './badge.css';
4
+ import type { AvailableIcons } from 'studiocms:ui/icons';
4
5
  import type { HTMLAttributes } from 'astro/types';
5
6
  import Icon from '../Icon/Icon.astro';
6
- import type { HeroIconName } from '../Icon/iconType.js';
7
7
 
8
8
  interface Props extends Omit<HTMLAttributes<'span'>, 'color'> {
9
9
  /**
@@ -13,7 +13,7 @@ interface Props extends Omit<HTMLAttributes<'span'>, 'color'> {
13
13
  /**
14
14
  * The icon to display in the badge.
15
15
  */
16
- icon?: HeroIconName;
16
+ icon?: AvailableIcons;
17
17
  /**
18
18
  * The icon position. Defaults to `left`.
19
19
  */
@@ -11,82 +11,82 @@
11
11
  border-radius: var(--radius-md);
12
12
  }
13
13
  .sui-badge.primary {
14
- background-color: hsl(var(--primary-base));
15
- color: hsl(var(--text-inverted));
14
+ background-color: var(--primary-base);
15
+ color: var(--text-inverted);
16
16
  }
17
17
  .sui-badge.primary.flat,
18
18
  .sui-badge.primary.outlined {
19
- background-color: hsla(var(--primary-flat));
20
- color: hsl(var(--primary-base));
19
+ background-color: var(--primary-flat);
20
+ color: var(--primary-base);
21
21
  }
22
22
  .sui-badge.primary.outlined {
23
- border: 1px solid hsl(var(--primary-base));
23
+ border: 1px solid var(--primary-base);
24
24
  }
25
25
  .sui-badge.success {
26
- background-color: hsl(var(--success-base));
27
- color: hsl(var(--text-inverted));
26
+ background-color: var(--success-base);
27
+ color: var(--text-inverted);
28
28
  }
29
29
  .sui-badge.success.flat,
30
30
  .sui-badge.success.outlined {
31
- background-color: hsla(var(--success-flat));
32
- color: hsl(var(--success-base));
31
+ background-color: var(--success-flat);
32
+ color: var(--success-base);
33
33
  }
34
34
  .sui-badge.success.outlined {
35
- border: 1px solid hsl(var(--success-base));
35
+ border: 1px solid var(--success-base);
36
36
  }
37
37
  .sui-badge.warning {
38
- background-color: hsl(var(--warning-base));
39
- color: hsl(var(--text-inverted));
38
+ background-color: var(--warning-base);
39
+ color: var(--text-inverted);
40
40
  }
41
41
  .sui-badge.warning.flat,
42
42
  .sui-badge.warning.outlined {
43
- background-color: hsla(var(--warning-flat));
44
- color: hsl(var(--warning-base));
43
+ background-color: var(--warning-flat);
44
+ color: var(--warning-base);
45
45
  }
46
46
  .sui-badge.warning.outlined {
47
- border: 1px solid hsl(var(--warning-base));
47
+ border: 1px solid var(--warning-base);
48
48
  }
49
49
  .sui-badge.danger {
50
- background-color: hsl(var(--danger-base));
51
- color: hsl(var(--text-normal));
50
+ background-color: var(--danger-base);
51
+ color: var(--text-normal);
52
52
  }
53
53
  .sui-badge.danger.flat,
54
54
  .sui-badge.danger.outlined {
55
- background-color: hsla(var(--danger-flat));
56
- color: hsl(var(--danger-base));
55
+ background-color: var(--danger-flat);
56
+ color: var(--danger-base);
57
57
  }
58
58
  .sui-badge.danger.outlined {
59
- border: 1px solid hsl(var(--danger-base));
59
+ border: 1px solid var(--danger-base);
60
60
  }
61
61
  .sui-badge.info {
62
- background-color: hsl(var(--info-base));
63
- color: hsl(var(--text-normal));
62
+ background-color: var(--info-base);
63
+ color: var(--text-normal);
64
64
  }
65
65
  .sui-badge.info.flat,
66
66
  .sui-badge.info.outlined {
67
- background-color: hsla(var(--info-flat));
68
- color: hsl(var(--info-base));
67
+ background-color: var(--info-flat);
68
+ color: var(--info-base);
69
69
  }
70
70
  .sui-badge.info.outlined {
71
- border: 1px solid hsl(var(--info-base));
71
+ border: 1px solid var(--info-base);
72
72
  }
73
73
  .sui-badge.mono {
74
- background-color: hsl(var(--mono-base));
75
- color: hsl(var(--text-inverted));
74
+ background-color: var(--mono-base);
75
+ color: var(--text-inverted);
76
76
  }
77
77
  .sui-badge.mono.flat,
78
78
  .sui-badge.mono.outlined {
79
- background-color: hsla(var(--mono-flat));
80
- color: hsl(var(--mono-base));
79
+ background-color: var(--mono-flat);
80
+ color: var(--mono-base);
81
81
  }
82
82
  .sui-badge.mono.outlined {
83
- border: 1px solid hsl(var(--mono-base));
83
+ border: 1px solid var(--mono-base);
84
84
  }
85
85
  [data-theme=light] .sui-badge.danger {
86
- color: hsl(var(--text-inverted));
86
+ color: var(--text-inverted);
87
87
  }
88
88
  [data-theme=light] .sui-badge.info {
89
- color: hsl(var(--text-inverted));
89
+ color: var(--text-inverted);
90
90
  }
91
91
  .sui-badge.sm {
92
92
  padding: .125rem .75rem;
@@ -7,7 +7,7 @@
7
7
  display: none;
8
8
  }
9
9
  .sui-breadcrumbs a {
10
- color: hsl(var(--primary-base));
10
+ color: var(--primary-base);
11
11
  text-decoration: none;
12
12
  }
13
13
  .sui-breadcrumbs a:hover {