@sankhyatronics/sankhya-cms 0.1.16 → 0.2.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.
Files changed (111) hide show
  1. package/custom-elements.json +842 -213
  2. package/dist/bento-grid/index.d.ts +8 -1
  3. package/dist/bento-grid/index.js +2 -1
  4. package/dist/card/index.d.ts +3 -4
  5. package/dist/card/index.js +1 -1
  6. package/dist/{chunk-LEXZKGQX.js → chunk-2DXHPEB5.js} +1 -1
  7. package/dist/chunk-2DXHPEB5.js.map +1 -0
  8. package/dist/{chunk-R5G6KFTJ.js → chunk-2FJDNJ7R.js} +1 -1
  9. package/dist/chunk-2FJDNJ7R.js.map +1 -0
  10. package/dist/{chunk-ZN4LIKVG.js → chunk-3OEEOBHB.js} +1 -1
  11. package/dist/chunk-3OEEOBHB.js.map +1 -0
  12. package/dist/{chunk-BMHMNXIA.js → chunk-4AFOKKSU.js} +1 -1
  13. package/dist/chunk-4AFOKKSU.js.map +1 -0
  14. package/dist/{chunk-76AVBQUA.js → chunk-5C6C6K5U.js} +98 -4
  15. package/dist/chunk-5C6C6K5U.js.map +1 -0
  16. package/dist/{chunk-7NLZND6Q.js → chunk-5F5PTVWR.js} +27 -2
  17. package/dist/chunk-5F5PTVWR.js.map +1 -0
  18. package/dist/chunk-5MY6OWMK.js +125 -0
  19. package/dist/chunk-5MY6OWMK.js.map +1 -0
  20. package/dist/{chunk-FLY7TNRT.js → chunk-7NIWQWTA.js} +1 -1
  21. package/dist/chunk-7NIWQWTA.js.map +1 -0
  22. package/dist/{chunk-ALI26WOB.js → chunk-EE6PAN3B.js} +33 -2
  23. package/dist/chunk-EE6PAN3B.js.map +1 -0
  24. package/dist/chunk-FML6AG2V.js +107 -0
  25. package/dist/chunk-FML6AG2V.js.map +1 -0
  26. package/dist/{chunk-VWS53WY4.js → chunk-HMUZON6I.js} +49 -4
  27. package/dist/chunk-HMUZON6I.js.map +1 -0
  28. package/dist/{chunk-G3CF7MBO.js → chunk-J6EO4R73.js} +27 -1
  29. package/dist/{chunk-G3CF7MBO.js.map → chunk-J6EO4R73.js.map} +1 -1
  30. package/dist/chunk-O4FCRKDX.js +178 -0
  31. package/dist/chunk-O4FCRKDX.js.map +1 -0
  32. package/dist/{chunk-SMLR736E.js → chunk-OELI3IWC.js} +1 -1
  33. package/dist/chunk-OELI3IWC.js.map +1 -0
  34. package/dist/{chunk-JQY2G4QK.js → chunk-OLA35A2O.js} +1 -1
  35. package/dist/chunk-OLA35A2O.js.map +1 -0
  36. package/dist/{chunk-YQ42EBK5.js → chunk-PHEGSCOM.js} +1 -1
  37. package/dist/chunk-PHEGSCOM.js.map +1 -0
  38. package/dist/{chunk-5EBWMPJS.js → chunk-QLA4BH2B.js} +5 -5
  39. package/dist/chunk-QLA4BH2B.js.map +1 -0
  40. package/dist/{chunk-JKBWZLG4.js → chunk-SQ3OZO32.js} +141 -3
  41. package/dist/chunk-SQ3OZO32.js.map +1 -0
  42. package/dist/chunk-UAIUBPDN.js +11 -0
  43. package/dist/chunk-UAIUBPDN.js.map +1 -0
  44. package/dist/{chunk-XWB4CKDU.js → chunk-XUGEXERO.js} +6 -6
  45. package/dist/chunk-XUGEXERO.js.map +1 -0
  46. package/dist/chunk-ZRC5BVDX.js +219 -0
  47. package/dist/chunk-ZRC5BVDX.js.map +1 -0
  48. package/dist/cms-theme.css +7 -0
  49. package/dist/content-block/index.d.ts +2 -3
  50. package/dist/content-block/index.js +3 -2
  51. package/dist/dropdown/index.d.ts +8 -11
  52. package/dist/dropdown/index.js +1 -1
  53. package/dist/feature-split/index.js +2 -1
  54. package/dist/features-section/index.d.ts +4 -4
  55. package/dist/features-section/index.js +4 -3
  56. package/dist/flow/index.d.ts +35 -0
  57. package/dist/flow/index.js +9 -0
  58. package/dist/flow/index.js.map +1 -0
  59. package/dist/header/index.d.ts +8 -15
  60. package/dist/header/index.js +1 -1
  61. package/dist/hero/index.d.ts +18 -3
  62. package/dist/hero/index.js +1 -1
  63. package/dist/icon-button/index.d.ts +2 -4
  64. package/dist/icon-button/index.js +1 -1
  65. package/dist/index.d.ts +3 -0
  66. package/dist/index.js +38 -25
  67. package/dist/items-accordion/index.d.ts +5 -0
  68. package/dist/items-accordion/index.js +2 -1
  69. package/dist/markdown/index.d.ts +1 -2
  70. package/dist/markdown/index.js +2 -1
  71. package/dist/mega-menu/index.d.ts +2 -2
  72. package/dist/mega-menu/index.js +1 -1
  73. package/dist/menu-grid/index.d.ts +2 -3
  74. package/dist/menu-grid/index.js +1 -1
  75. package/dist/menu-grid-item/index.d.ts +6 -8
  76. package/dist/menu-grid-item/index.js +1 -1
  77. package/dist/menu-item/index.d.ts +5 -7
  78. package/dist/menu-item/index.js +1 -1
  79. package/dist/promo-banner/index.d.ts +14 -3
  80. package/dist/promo-banner/index.js +1 -1
  81. package/dist/schema/index.d.ts +3 -0
  82. package/dist/schema/index.js +3 -0
  83. package/dist/schema/index.js.map +1 -1
  84. package/dist/section/index.d.ts +3 -0
  85. package/dist/section/index.js +1 -1
  86. package/dist/steps/index.d.ts +33 -0
  87. package/dist/steps/index.js +10 -0
  88. package/dist/steps/index.js.map +1 -0
  89. package/dist/tag-strip/index.d.ts +26 -0
  90. package/dist/tag-strip/index.js +9 -0
  91. package/dist/tag-strip/index.js.map +1 -0
  92. package/dist/tooltip/index.d.ts +18 -6
  93. package/dist/tooltip/index.js +1 -1
  94. package/package.json +14 -2
  95. package/dist/chunk-5EBWMPJS.js.map +0 -1
  96. package/dist/chunk-76AVBQUA.js.map +0 -1
  97. package/dist/chunk-7NLZND6Q.js.map +0 -1
  98. package/dist/chunk-ALI26WOB.js.map +0 -1
  99. package/dist/chunk-BMHMNXIA.js.map +0 -1
  100. package/dist/chunk-FLY7TNRT.js.map +0 -1
  101. package/dist/chunk-JKBWZLG4.js.map +0 -1
  102. package/dist/chunk-JQY2G4QK.js.map +0 -1
  103. package/dist/chunk-LEXZKGQX.js.map +0 -1
  104. package/dist/chunk-R5G6KFTJ.js.map +0 -1
  105. package/dist/chunk-SMLR736E.js.map +0 -1
  106. package/dist/chunk-VWS53WY4.js.map +0 -1
  107. package/dist/chunk-XCA3XFFG.js +0 -74
  108. package/dist/chunk-XCA3XFFG.js.map +0 -1
  109. package/dist/chunk-XWB4CKDU.js.map +0 -1
  110. package/dist/chunk-YQ42EBK5.js.map +0 -1
  111. package/dist/chunk-ZN4LIKVG.js.map +0 -1
@@ -3,6 +3,7 @@ import { LitElement } from 'lit';
3
3
 
4
4
  interface BentoGridItem {
5
5
  title: string;
6
+ /** Markdown. */
6
7
  description?: string;
7
8
  /** Iconify icon name, e.g. `mdi:home`. */
8
9
  icon?: string;
@@ -10,11 +11,17 @@ interface BentoGridItem {
10
11
  imageAlt?: string;
11
12
  colSpan?: 1 | 2 | 3 | 4;
12
13
  rowSpan?: 1 | 2;
13
- /** Turns the card into a link. */
14
+ /** Without `actionLabel`, turns the whole card into a link. */
14
15
  href?: string;
16
+ /** `default` (surface), `primary` (brand fill, white text) or `dark` (navy fill, light text). */
17
+ variant?: 'default' | 'primary' | 'dark';
18
+ /** With `href`, renders a button-style link inside the card instead of linking the whole card. */
19
+ actionLabel?: string;
15
20
  }
16
21
  /**
17
22
  * A responsive 4-column bento grid of icon/image cards. Items are set via the `items` property.
23
+ * Descriptions are Markdown. A card links as a whole when it has `href` alone; with `actionLabel`
24
+ * the link becomes a button inside the card.
18
25
  *
19
26
  * @cssprop --st-bento-grid-padding - Overrides the block's padding.
20
27
  */
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  BentoGrid
3
- } from "../chunk-76AVBQUA.js";
3
+ } from "../chunk-5C6C6K5U.js";
4
+ import "../chunk-UAIUBPDN.js";
4
5
  import "../chunk-FZ36KL73.js";
5
6
  import "../chunk-KMU6ABQF.js";
6
7
  import "../chunk-EUXUH3YW.js";
@@ -2,10 +2,9 @@ import * as lit from 'lit';
2
2
  import { LitElement } from 'lit';
3
3
 
4
4
  /**
5
- * A surfaced container — content goes in the default slot. Ports `SankhyaUI`'s React `Card`
6
- * (`variant`, `padding`, `elevation`, `hoverable`, `inverted`); `onClick` is just a native `click`
7
- * listener on the element. `padding` takes `none | small | medium | large` (the source's
8
- * `sm|md|lg`, spelled like `paddingScaleStyles`); `elevation` takes `none | sm | md | lg`.
5
+ * A surfaced container — content goes in the default slot. Attributes: `variant`, `padding`,
6
+ * `elevation`, `hoverable`, `inverted`; a click handler is just a native `click` listener on the
7
+ * element. `padding` takes `none | small | medium | large`; `elevation` takes `none | sm | md | lg`.
9
8
  */
10
9
  declare class Card extends LitElement {
11
10
  static styles: lit.CSSResult;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Card
3
- } from "../chunk-ZN4LIKVG.js";
3
+ } from "../chunk-3OEEOBHB.js";
4
4
  import "../chunk-KMU6ABQF.js";
5
5
  import "../chunk-EUXUH3YW.js";
6
6
  export {
@@ -571,4 +571,4 @@ Dropdown = __decorateClass([
571
571
  export {
572
572
  Dropdown
573
573
  };
574
- //# sourceMappingURL=chunk-LEXZKGQX.js.map
574
+ //# sourceMappingURL=chunk-2DXHPEB5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/dropdown/Dropdown.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { chevronIcon } from '../shared/icons';\nimport { buttonResetStyles, controlBaseStyles, fontFamilyStyles } from '../shared/styles';\nimport type { DropdownToggleEventDetail } from './DropdownEvents';\n\n/**\n * A labeled trigger + slotted dropdown panel — nav menus (typically holding an `st-menu-grid`),\n * action menus, anything \"click a trigger, show content under it\". Markup\n * (`.menu` > `.menu-title` + `.menu-dropdown`), sizes, 0.3s slide/fade, and behavior —\n *\n * - only one dropdown is open at a time (a shared provider is built in, so no provider element\n * is needed);\n * - a mousedown outside, Escape, or a click inside the panel closes it;\n * - an `href` trigger toggles the panel when it has content, and is a plain link when it doesn't;\n * - `inline` opens the panel in the flow, the source's `.touch-device` layout.\n *\n * Colors and the panel's surface come from the suite theme. The panel is never 100vw wide at\n * <=768px (it would overflow the screen from wherever the trigger sits; use `inline` in headers\n * instead), and slotted children are not clipped with `overflow: hidden` (that would cut off their\n * focus rings). Other attributes: `align`, `active`, `disabled`, `inline`, the `dropdown-toggle`\n * event, and `mega` plus `open-on-hover` for a mega menu (see `st-mega-menu`).\n *\n * @cssprop --st-mega-menu-max-width - Maximum width of a `mega` panel (default `1400px`).\n * @cssprop --st-mega-menu-inset - Minimum space between a `mega` panel and the header's sides (default `1rem`).\n * @cssprop --st-mega-menu-gap - Space between the header and a `mega` panel (default `12px`).\n * @cssprop --st-mega-menu-radius - Corner radius of a `mega` panel (default `24px`).\n */\n@customElement('st-dropdown')\nexport class Dropdown extends LitElement {\n /** The open dropdown, if any — the source's `DropdownContext.activeDropdown`. */\n private static openDropdown: Dropdown | null = null;\n\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: inline-block;\n position: relative;\n ${fontFamilyStyles}\n }\n\n .menu-title {\n ${buttonResetStyles}\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n min-height: 40px;\n padding: 12px;\n gap: 8px;\n text-align: center;\n width: fit-content;\n border-radius: var(--st-radius-sm);\n /* --st-nav-*: set by a host bar (st-header's transparent state) to recolour its nav items. */\n color: var(--st-nav-color, var(--st-color-text));\n font-size: 0.875rem;\n text-decoration: none;\n white-space: nowrap;\n transition: background-color 0.3s ease;\n }\n\n .menu-title:hover,\n .menu-title[aria-expanded='true'] {\n background: var(--st-nav-hover-bg, var(--st-color-hover));\n color: var(--st-nav-color, var(--st-color-text-strong));\n }\n\n :host([active]) .menu-title {\n background: var(--st-color-accent-subtle);\n color: var(--st-color-accent-text);\n }\n\n :host([disabled]) .menu-title {\n color: var(--st-color-text-muted);\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .icon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n }\n\n .icon[hidden] {\n display: none;\n }\n\n .arrow {\n display: inline-block;\n margin-left: 8px;\n font-size: 0.75rem;\n transition: transform 0.3s ease;\n }\n\n .menu-title[aria-expanded='true'] .arrow {\n transform: rotate(180deg);\n }\n\n .menu-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 100;\n padding: 16px;\n background: var(--st-color-surface);\n color: var(--st-color-text);\n /* The panel has its own surface: items in it never take the bar's nav colours. */\n --st-nav-color: initial;\n --st-nav-hover-bg: initial;\n border: 1px solid var(--st-color-border);\n border-radius: var(--st-radius-sm);\n box-shadow: 0 4px 16px var(--st-shadow-color-sm);\n opacity: 0;\n visibility: hidden;\n transform: translateY(-10px);\n /* visibility flips at once on open (so keyboard focus can move into the panel on the same\n frame) and only after the 0.3s fade on close. */\n transition:\n opacity 0.3s ease,\n transform 0.3s ease,\n visibility 0s linear 0.3s;\n pointer-events: none;\n }\n\n .menu-dropdown.align-right {\n left: auto;\n right: 0;\n }\n\n .menu-dropdown.show {\n opacity: 1;\n visibility: visible;\n transform: translateY(0);\n pointer-events: auto;\n transition-delay: 0s;\n }\n\n /* Inline: the panel opens in the flow under its trigger and pushes what follows down, instead\n of floating — the source's .touch-device layout. st-header turns this on for its menu while\n the hamburger panel is showing. */\n :host([inline]) {\n display: block;\n }\n\n :host([inline]) .menu-title {\n width: 100%;\n justify-content: flex-start;\n }\n\n :host([inline]) .arrow {\n margin-left: auto;\n }\n\n :host([inline]) .menu-dropdown {\n display: none;\n position: relative;\n top: auto;\n left: auto;\n right: auto;\n width: 100%;\n box-sizing: border-box;\n box-shadow: none;\n opacity: 1;\n visibility: visible;\n transform: none;\n }\n\n :host([inline]) .menu-dropdown.show {\n display: block;\n pointer-events: auto;\n }\n\n /* Mega (okta.com): the panel is a large rounded card floating under the whole bar, centred on\n the nearest positioned ancestor (st-header) instead of hanging off the trigger — the host\n stops being the panel's containing block. */\n :host([mega]:not([inline])) {\n position: static;\n }\n\n :host([mega]:not([inline])) .menu-dropdown {\n top: calc(100% + var(--st-mega-menu-gap, 12px));\n left: var(--st-mega-menu-inset, 1rem);\n right: var(--st-mega-menu-inset, 1rem);\n max-width: var(--st-mega-menu-max-width, 1400px);\n margin: 0 auto;\n padding: 0;\n max-height: calc(100dvh - var(--st-mega-menu-offset, 96px));\n overflow-y: auto;\n border: 0;\n border-radius: var(--st-mega-menu-radius, 24px);\n box-shadow: 0 24px 48px var(--st-shadow-color-md);\n }\n\n /* The open section's trigger becomes an accent pill — also for a plain dropdown marked \\`bar\\`,\n so it matches the mega triggers (and st-menu-item variant=\"bar\") beside it. */\n :host([mega]:not([inline])) .menu-title,\n :host([bar]:not([inline])) .menu-title {\n border-radius: 9999px;\n }\n\n :host([mega]:not([inline])) .menu-title[aria-expanded='true'],\n :host([bar]:not([inline])) .menu-title[aria-expanded='true'] {\n background: var(--st-color-accent);\n color: var(--st-color-on-solid);\n }\n\n .mega-back-bar,\n .mega-heading {\n display: none;\n }\n\n /* Mega in st-header's hamburger panel: rather than an accordion, the panel slides in over the\n whole screen with a Back button (okta.com's phone menu). Fixed to the viewport, stacked\n inside the header's own full-screen layer, so the header's close toggle stays on top. */\n :host([mega][inline]) .menu-dropdown {\n display: block;\n position: fixed;\n inset: 0;\n z-index: 1;\n padding: 0 1.5rem 2rem;\n overflow-y: auto;\n border: 0;\n border-radius: 0;\n visibility: hidden;\n transform: translateX(100%);\n transition:\n transform 0.3s ease,\n visibility 0s linear 0.3s;\n }\n\n :host([mega][inline]) .menu-dropdown.show {\n visibility: visible;\n transform: none;\n transition-delay: 0s;\n }\n\n :host([mega][inline]) .mega-back-bar {\n display: flex;\n align-items: center;\n position: sticky;\n top: 0;\n z-index: 1;\n height: 64px;\n margin: 0 -1.5rem;\n padding: 0 1rem;\n background: inherit;\n border-bottom: 1px solid var(--st-color-border);\n }\n\n .mega-back {\n ${buttonResetStyles}\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 40px;\n padding: 0 12px 0 6px;\n border-radius: var(--st-radius-sm);\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--st-color-text-strong);\n }\n\n .mega-back:hover {\n background: var(--st-color-hover);\n }\n\n :host([mega][inline]) .mega-heading {\n display: block;\n margin: 1.25rem 0 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--st-color-text-strong);\n }\n\n /* The drill-down replaces the trigger's open state, so the caret points the way it goes. */\n :host([mega][inline]) .arrow {\n transform: rotate(-90deg);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .menu-dropdown,\n .arrow,\n :host([mega][inline]) .menu-dropdown {\n transition: none;\n }\n }\n `;\n\n /** Trigger label text (source: `title`, renamed because `title` is the native tooltip\n * attribute). Leave empty to show only `slot=\"icon\"`. */\n @property({ type: String })\n label = '';\n\n /** Renders the trigger as an `<a href>`. With panel content the click toggles the panel (as in\n * the source); with none it navigates. */\n @property({ type: String })\n href = '';\n\n @property({ type: String, attribute: 'icon-position' })\n iconPosition: 'left' | 'right' = 'left';\n\n /** Inline `width`/`height` of the `slot=\"icon\"` wrapper (source: `iconSize`, default `1.2rem`). */\n @property({ type: String, attribute: 'icon-size' })\n iconSize = '1.2rem';\n\n /** Inline `color` of the `slot=\"icon\"` wrapper (source: `iconColor`). */\n @property({ type: String, attribute: 'icon-color' })\n iconColor = 'currentColor';\n\n /** Which edge of the trigger the panel lines up with. */\n @property({ type: String })\n align: 'left' | 'right' = 'left';\n\n /** `target` of an `href` trigger (source default `_self`). */\n @property({ type: String })\n target = '_self';\n\n /** Extra class(es) on the trigger (source: `className`; a `class` on `st-dropdown` styles the host). */\n @property({ type: String, attribute: 'trigger-class-name' })\n triggerClassName = '';\n\n /** Extra class(es) on the panel (source: `itemGroupClassName`). */\n @property({ type: String, attribute: 'item-group-class-name' })\n itemGroupClassName = '';\n\n /** Unused, as in the source (`itemClassName` is never read there); kept for prop parity. */\n @property({ type: String, attribute: 'item-class-name' })\n itemClassName = '';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /** Highlights the trigger as the current section (e.g. the current page is one of its items). */\n @property({ type: Boolean, reflect: true })\n active = false;\n\n /** Opens the panel in the flow under the trigger instead of floating over the page (see the\n * styles). `st-header` sets this on its own menu's dropdowns while its hamburger panel shows. */\n @property({ type: Boolean, reflect: true })\n inline = false;\n\n /** Whether the panel is showing. Follows user toggles; may also be set from outside. */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n /**\n * Mega-menu panel (okta.com style), typically holding an `st-mega-menu`: the panel spans the\n * full width of the nearest positioned ancestor — `st-header` — right under it, instead of\n * hanging off the trigger. In `st-header`'s hamburger layout (`inline`) it slides in over the\n * screen with a Back button rather than opening as an accordion. A click inside the panel only\n * closes it when it lands on a link.\n */\n @property({ type: Boolean, reflect: true })\n mega = false;\n\n /** Styles a non-`mega` trigger like a mega one — a pill that turns solid accent while open — so\n * a plain dropdown (e.g. \"+ New\") lines up with mega triggers in the same header bar. */\n @property({ type: Boolean, reflect: true })\n bar = false;\n\n /** Opens the panel while a mouse hovers the trigger or panel (touch and keyboard still click). Off while `inline`. */\n @property({ type: Boolean, attribute: 'open-on-hover' })\n openOnHover = false;\n\n /** Text of the Back button in the `mega` + `inline` drill-down panel. */\n @property({ type: String, attribute: 'back-label' })\n backLabel = 'Back';\n\n private hoverTimer = 0;\n\n /** When hover last opened the panel — a click right after that keeps it open instead of toggling it shut. */\n private hoverOpenedAt = 0;\n\n /** Whether the default slot has content — the source's `children` check. */\n @state() private hasContent = false;\n\n /** Whether `slot=\"icon\"` has content. */\n @state() private hasIcon = false;\n\n connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('mousedown', this.closeOnOutsideMouseDown);\n window.addEventListener('keydown', this.closeOnEscape);\n this.addEventListener('pointerenter', this.onPointerEnter);\n this.addEventListener('pointerleave', this.onPointerLeave);\n }\n\n disconnectedCallback(): void {\n document.removeEventListener('mousedown', this.closeOnOutsideMouseDown);\n window.removeEventListener('keydown', this.closeOnEscape);\n this.removeEventListener('pointerenter', this.onPointerEnter);\n this.removeEventListener('pointerleave', this.onPointerLeave);\n clearTimeout(this.hoverTimer);\n if (Dropdown.openDropdown === this) Dropdown.openDropdown = null;\n super.disconnectedCallback();\n }\n\n protected updated(changed: Map<string, unknown>): void {\n if (!changed.has('open')) return;\n if (this.open) {\n const previous = Dropdown.openDropdown;\n Dropdown.openDropdown = this;\n if (previous && previous !== this) previous.setOpen(false);\n } else if (Dropdown.openDropdown === this) {\n Dropdown.openDropdown = null;\n }\n }\n\n private setOpen(open: boolean): void {\n if (this.open === open) return;\n this.open = open;\n this.dispatchEvent(new CustomEvent<DropdownToggleEventDetail>('dropdown-toggle', { detail: { open }, bubbles: true, composed: true }));\n }\n\n private hovers(event: PointerEvent): boolean {\n return this.openOnHover && !this.inline && !this.disabled && this.hasContent && event.pointerType === 'mouse';\n }\n\n /** Short delays so a pointer crossing the gap between trigger and panel doesn't close it. */\n private onPointerEnter = (event: PointerEvent): void => {\n if (!this.hovers(event)) return;\n clearTimeout(this.hoverTimer);\n this.hoverTimer = window.setTimeout(() => {\n if (!this.open) this.hoverOpenedAt = Date.now();\n this.setOpen(true);\n }, 80);\n };\n\n private onPointerLeave = (event: PointerEvent): void => {\n if (!this.hovers(event)) return;\n clearTimeout(this.hoverTimer);\n this.hoverTimer = window.setTimeout(() => this.setOpen(false), 200);\n };\n\n private onBackClick = (event: Event): void => {\n event.stopPropagation();\n this.setOpen(false);\n this.trigger()?.focus();\n };\n\n private closeOnOutsideMouseDown = (event: Event): void => {\n if (this.open && !event.composedPath().includes(this)) this.setOpen(false);\n };\n\n private closeOnEscape = (event: KeyboardEvent): void => {\n if (!this.open || event.key !== 'Escape') return;\n const focusWasInside = event.composedPath().includes(this);\n this.setOpen(false);\n if (focusWasInside) this.trigger()?.focus();\n };\n\n private trigger(): HTMLElement | null {\n return this.renderRoot.querySelector<HTMLElement>('.menu-title');\n }\n\n /** Keyboard-reachable entries in the panel, in order: menu items (they delegate focus to their\n * own link) plus any plain links/buttons/tabbable elements a caller slots in. */\n private panelItems(): HTMLElement[] {\n const slot = this.renderRoot.querySelector<HTMLSlotElement>('.menu-dropdown slot');\n if (!slot) return [];\n const selector =\n 'st-menu-item, st-menu-grid-item, st-mega-menu-feature, a[href], button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n const items: HTMLElement[] = [];\n for (const el of slot.assignedElements({ flatten: true })) {\n if (el.matches(selector)) items.push(el as HTMLElement);\n items.push(...Array.from(el.querySelectorAll<HTMLElement>(selector)));\n }\n return items;\n }\n\n /** Moves focus into the panel once it has become visible (it is `visibility: hidden` until the\n * `show` class lands, and hidden elements can't take focus). */\n private focusItem(pick: (items: HTMLElement[]) => HTMLElement | undefined): void {\n void this.updateComplete.then(() => pick(this.panelItems())?.focus());\n }\n\n /** Enter/Space/ArrowDown open the panel and focus its first entry; ArrowUp its last. */\n private onTitleKeyDown = (event: KeyboardEvent): void => {\n if (!this.hasContent || this.disabled) return;\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n event.stopPropagation();\n this.setOpen(true);\n this.focusItem((items) => items[0]);\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n event.stopPropagation();\n this.setOpen(true);\n this.focusItem((items) => items[items.length - 1]);\n }\n };\n\n /** Arrow keys/Home/End move between the panel's entries; Tab closes the panel and moves on. */\n private onPanelKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Tab') {\n this.setOpen(false);\n return;\n }\n if (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) return;\n const items = this.panelItems();\n if (items.length === 0) return;\n event.preventDefault();\n event.stopPropagation();\n const path = event.composedPath();\n const current = items.findIndex((item) => path.includes(item));\n const last = items.length - 1;\n const next =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? last\n : event.key === 'ArrowDown'\n ? current < 0 || current === last ? 0 : current + 1\n : current <= 0 ? last : current - 1;\n items[next].focus();\n };\n\n private onTitleClick = (event: Event): void => {\n event.stopPropagation();\n if (!this.hasContent) return;\n event.preventDefault();\n clearTimeout(this.hoverTimer);\n if (this.open && Date.now() - this.hoverOpenedAt < 400) return;\n this.setOpen(!this.open);\n };\n\n /** A click anywhere inside the panel closes it, as in the source — for `mega`, only a click on a\n * link: a big panel has headings and gaps, and a click there shouldn't also close st-header's\n * hamburger layer. */\n private onPanelClick = (event: Event): void => {\n if (this.mega && !event.composedPath().some((node) => node instanceof HTMLAnchorElement)) {\n event.stopPropagation();\n return;\n }\n this.setOpen(false);\n };\n\n private onContentSlotChange = (event: Event): void => {\n this.hasContent = (event.target as HTMLSlotElement).assignedNodes({ flatten: true }).some(\n (node) => node.nodeType === Node.ELEMENT_NODE || !!node.textContent?.trim()\n );\n };\n\n private onIconSlotChange = (event: Event): void => {\n this.hasIcon = (event.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;\n };\n\n render() {\n const icon = html`<span\n class=\"icon ${this.iconPosition === 'left' ? 'icon-left' : 'icon-right'}\"\n ?hidden=${!this.hasIcon}\n style=\"width:${this.iconSize};height:${this.iconSize};color:${this.iconColor}\"\n ><slot name=\"icon\" @slotchange=${this.onIconSlotChange}></slot\n ></span>`;\n const titleContent = html`\n ${this.iconPosition === 'left' ? icon : nothing} ${this.label ? html`<span part=\"label\">${this.label}</span>` : nothing}\n ${this.iconPosition === 'right' ? icon : nothing}\n ${this.hasContent ? html`<span class=\"arrow\" part=\"caret\" aria-hidden=\"true\">▼</span>` : nothing}\n `;\n const titleClass = `menu-title ${this.triggerClassName} ${this.open ? 'active' : ''}`;\n\n return html`\n <div class=\"menu\" part=\"menu\">\n ${this.href\n ? html`\n <a\n part=\"trigger\"\n class=${titleClass}\n href=${this.href}\n target=${this.target}\n aria-haspopup=${this.hasContent ? 'true' : 'false'}\n aria-expanded=${this.open}\n aria-disabled=${this.disabled ? 'true' : nothing}\n @click=${this.onTitleClick}\n @keydown=${this.onTitleKeyDown}\n >\n ${titleContent}\n </a>\n `\n : html`\n <button\n part=\"trigger\"\n class=${titleClass}\n type=\"button\"\n aria-haspopup=\"true\"\n aria-expanded=${this.open}\n ?disabled=${this.disabled}\n @click=${this.onTitleClick}\n @keydown=${this.onTitleKeyDown}\n >\n ${titleContent}\n </button>\n `}\n <div\n part=\"panel\"\n class=\"menu-dropdown align-${this.align} ${this.itemGroupClassName} ${this.open ? 'show' : ''}\"\n role=\"menu\"\n @click=${this.onPanelClick}\n @keydown=${this.onPanelKeyDown}\n >\n ${this.mega\n ? html`\n <div class=\"mega-back-bar\" part=\"back-bar\">\n <button type=\"button\" class=\"mega-back\" part=\"back\" @click=${this.onBackClick}>\n ${chevronIcon('left', 16)} ${this.backLabel}\n </button>\n </div>\n ${this.label ? html`<p class=\"mega-heading\" part=\"mobile-heading\">${this.label}</p>` : nothing}\n `\n : nothing}\n <slot @slotchange=${this.onContentSlotChange}></slot>\n </div>\n </div>\n `;\n }\n}\n"],"mappings":"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","names":[]}
@@ -391,4 +391,4 @@ MenuItem = __decorateClass([
391
391
  export {
392
392
  MenuItem
393
393
  };
394
- //# sourceMappingURL=chunk-R5G6KFTJ.js.map
394
+ //# sourceMappingURL=chunk-2FJDNJ7R.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/menu-item/MenuItem.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\n\nimport { arrowUpRightIcon } from '../shared/icons';\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\nimport type { MenuItemSelectEventDetail } from './MenuItemEvents';\n\n/**\n * A single flat nav row — icon (`slot=\"icon\"`) + title + badge on one line, an optional\n * description below — as opposed to `st-menu-grid-item`'s card for a multi-column grid. Effects\n * are CSS: nudges right and scales to 1.01 on hover / 0.99 while pressed, the icon tilts on hover,\n * the badge pops in, the description fades in. Colors come from the suite theme rather than\n * per-item utility classes.\n *\n * Renders a real `<a href>` but fires a *cancelable* `menu-item-select` event (detail: `{ href }`)\n * before navigating — a host doing client-side routing calls `event.preventDefault()` on it.\n *\n * @slot icon - The row's icon, sized to `icon-size` (16px, or 14px when `compact`).\n * @cssprop --st-menu-item-icon-size - Width and height of the slotted icon; `icon-size` sets it.\n */\n@customElement('st-menu-item')\nexport class MenuItem extends LitElement {\n /** `focus()` on the element focuses its link, so `st-dropdown` can arrow-key between items. */\n static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };\n\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n ${fontFamilyStyles}\n }\n\n @keyframes st-menu-item-badge-pop {\n from {\n transform: scale(0);\n }\n 70% {\n transform: scale(1.12);\n }\n to {\n transform: scale(1);\n }\n }\n\n @keyframes st-menu-item-fade-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n .menu-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px 16px;\n font-size: 0.875rem;\n text-decoration: none;\n /* --st-nav-*: set by a host bar (st-header's transparent state) to recolour its nav items. */\n color: var(--st-nav-color, var(--st-color-text));\n border-radius: 6px;\n /* The source's 'all 0.15s', minus visibility: animating the visibility this link inherits\n from a dropdown panel kept it unfocusable for a frame after the panel opened. */\n transition-property: background-color, color, padding, transform, border-color;\n transition-duration: 0.15s;\n transition-timing-function: ease;\n box-sizing: border-box;\n }\n\n /* The source's hover nudge (x: 4px) is done with padding, not a transform: a transform would\n spill past a scrolling panel's edge (st-source-bar's menus) and show a horizontal scrollbar.\n Keyboard focus gets the same treatment as hover. */\n .menu-item:hover,\n .menu-item:focus-visible {\n background: var(--st-nav-hover-bg, var(--st-color-hover));\n color: var(--st-nav-color, var(--st-color-text-strong));\n padding-left: 20px;\n transition-duration: 0.1s;\n }\n\n .menu-item.compact:hover,\n .menu-item.compact:focus-visible {\n padding-left: 16px;\n }\n\n .menu-item:active {\n transform: scale(0.99);\n transition-duration: 0.1s;\n }\n\n .menu-item.active {\n background-color: var(--st-color-accent-subtle);\n color: var(--st-color-accent-text);\n border-left: 4px solid var(--st-color-accent);\n }\n\n .menu-item-icon {\n display: flex;\n flex-shrink: 0;\n margin-top: 2px;\n transition: transform 0.2s ease;\n }\n\n .menu-item-icon:hover {\n transform: rotate(5deg);\n }\n\n .menu-item-icon[hidden] {\n display: none;\n }\n\n .menu-item-icon ::slotted(*) {\n width: var(--st-menu-item-icon-size, 16px);\n height: var(--st-menu-item-icon-size, 16px);\n }\n\n .menu-item-content {\n flex: 1;\n min-width: 0;\n }\n\n .menu-item-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n }\n\n .menu-item-title {\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .menu-item-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n font-size: 0.75rem;\n font-weight: 500;\n border-radius: 9999px;\n flex-shrink: 0;\n background: var(--st-color-accent-subtle);\n color: var(--st-color-accent-text);\n animation: st-menu-item-badge-pop 0.35s ease-out;\n }\n\n .menu-item-description {\n display: -webkit-box;\n margin: 4px 0 0;\n font-size: 0.75rem;\n color: var(--st-color-text-muted);\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n animation: st-menu-item-fade-in 0.2s ease;\n }\n\n .menu-item.compact {\n padding: 8px 12px;\n gap: 8px;\n }\n\n .menu-item.compact .menu-item-icon ::slotted(*) {\n width: var(--st-menu-item-icon-size, 14px);\n height: var(--st-menu-item-icon-size, 14px);\n }\n\n .menu-item.compact .menu-item-title {\n font-size: 0.75rem;\n }\n\n .menu-item.compact .menu-item-description {\n font-size: 0.75rem;\n }\n\n /* link: a plain text link (okta.com mega-menu columns) — no box, no nudge, the badge right\n after the title, long titles wrap. */\n .menu-item.link {\n padding: 7px 0;\n gap: 10px;\n font-size: 0.9375rem;\n color: var(--st-nav-color, var(--st-color-text));\n }\n\n .menu-item.link:hover,\n .menu-item.link:focus-visible {\n padding-left: 0;\n background: transparent;\n color: var(--st-nav-color, var(--st-color-text-strong));\n }\n\n .menu-item.link:hover .menu-item-title,\n .menu-item.link:focus-visible .menu-item-title {\n text-decoration: underline;\n text-underline-offset: 4px;\n }\n\n .menu-item.link:active {\n transform: none;\n }\n\n .menu-item.link.active {\n border-left: 0;\n background: transparent;\n font-weight: 600;\n }\n\n .menu-item.link .menu-item-header {\n justify-content: flex-start;\n }\n\n .menu-item.link .menu-item-title {\n white-space: normal;\n font-weight: 400;\n }\n\n .menu-item.link .menu-item-description {\n margin-top: 2px;\n font-size: 0.8125rem;\n }\n\n /* bar: a top-level item in a header bar next to mega st-dropdowns (e.g. \"Dashboard\" beside\n \"Masters ▼\") — the same pill, size and active look as their triggers, so the row reads as\n one set. Wins over compact (declared after it). */\n .menu-item.bar {\n align-items: center;\n min-height: 40px;\n padding: 12px;\n gap: 8px;\n border-radius: 9999px;\n white-space: nowrap;\n }\n\n /* Hover fills like a mega trigger opening on hover. */\n .menu-item.bar:hover,\n .menu-item.bar:focus-visible {\n padding-left: 12px;\n background: var(--st-color-accent);\n color: var(--st-color-on-solid);\n }\n\n .menu-item.bar.active {\n border-left: 0;\n }\n\n .menu-item.bar .menu-item-icon {\n margin-top: 0;\n }\n\n .menu-item.bar .menu-item-title {\n font-size: 0.875rem;\n font-weight: 400;\n }\n\n .external {\n display: inline-flex;\n margin-left: 3px;\n vertical-align: 0.05em;\n }\n\n .menu-item.no-description {\n align-items: center;\n }\n\n .menu-item.no-description .menu-item-icon {\n margin-top: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .menu-item,\n .menu-item-icon {\n transition: none;\n }\n\n .menu-item:active,\n .menu-item-icon:hover {\n transform: none;\n }\n\n .menu-item-badge,\n .menu-item-description {\n animation: none;\n }\n }\n `;\n\n @property({ type: String })\n title = '';\n\n @property({ type: String })\n href = '';\n\n @property({ type: String })\n description = '';\n\n /** Small trailing label, e.g. a count or \"New\"/\"Beta\" — omit for none. */\n @property({ type: String })\n badge = '';\n\n /** Highlights this row as the current page (source: `isActive`). */\n @property({ type: Boolean, reflect: true })\n active = false;\n\n @property({ type: Boolean, reflect: true })\n compact = false;\n\n /** Suppresses the description even when `description` is set (source: `showDescription`, default `true`). */\n @property({ type: Boolean, attribute: 'show-description' })\n showDescription = true;\n\n /** `target` for the `<a>` (source default `_self`). */\n @property({ type: String })\n target = '_self';\n\n /** `default` (a row with a hover box), `link` (a plain text link, as in `st-mega-menu-column`;\n * marked with an arrow when it opens a new tab) or `bar` (a top-level item in a header bar,\n * shaped like a mega `st-dropdown`'s trigger pill so it lines up with the dropdowns beside it). */\n @property({ type: String, reflect: true })\n variant: 'default' | 'link' | 'bar' = 'default';\n\n /** Size of the slotted icon, any CSS length (e.g. `36px`); empty keeps 16px (14px when `compact`). */\n @property({ type: String, attribute: 'icon-size' })\n iconSize = '';\n\n /** Whether `slot=\"icon\"` has content, so an omitted icon leaves no empty box. */\n @state() private hasIcon = false;\n\n private onIconSlotChange = (event: Event): void => {\n this.hasIcon = (event.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;\n };\n\n private onClick = (event: MouseEvent): void => {\n const selectEvent = new CustomEvent<MenuItemSelectEventDetail>('menu-item-select', {\n detail: { href: this.href },\n bubbles: true,\n composed: true,\n cancelable: true\n });\n this.dispatchEvent(selectEvent);\n if (selectEvent.defaultPrevented) event.preventDefault();\n };\n\n render() {\n const showDescription = !!this.description && this.showDescription;\n const link = this.variant === 'link';\n const classes = [\n 'menu-item',\n link ? 'link' : '',\n this.variant === 'bar' ? 'bar' : '',\n this.active ? 'active' : '',\n this.compact ? 'compact' : '',\n showDescription ? '' : 'no-description'\n ]\n .filter(Boolean)\n .join(' ');\n const external = link && this.target === '_blank';\n return html`\n <a\n part=\"item\"\n class=${classes}\n href=${this.href}\n target=${this.target}\n rel=${this.target === '_blank' ? 'noopener noreferrer' : nothing}\n @click=${this.onClick}\n >\n <span\n class=\"menu-item-icon\"\n part=\"icon\"\n ?hidden=${!this.hasIcon}\n style=${this.iconSize ? `--st-menu-item-icon-size: ${this.iconSize}` : nothing}\n ><slot name=\"icon\" @slotchange=${this.onIconSlotChange}></slot\n ></span>\n <span class=\"menu-item-content\" part=\"content\">\n <span class=\"menu-item-header\" part=\"header\">\n <span part=\"title\" class=\"menu-item-title\"\n >${this.title}${external ? html`<span class=\"external\">${arrowUpRightIcon(11)}</span>` : nothing}</span\n >\n ${this.badge ? html`<span part=\"badge\" class=\"menu-item-badge\">${this.badge}</span>` : nothing}\n </span>\n ${showDescription ? html`<p part=\"description\" class=\"menu-item-description\">${this.description}</p>` : nothing}\n </span>\n </a>\n `;\n }\n}\n"],"mappings":"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","names":[]}
@@ -115,4 +115,4 @@ Card = __decorateClass([
115
115
  export {
116
116
  Card
117
117
  };
118
- //# sourceMappingURL=chunk-ZN4LIKVG.js.map
118
+ //# sourceMappingURL=chunk-3OEEOBHB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/card/Card.ts"],"sourcesContent":["import { LitElement, css, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { controlBaseStyles, cardShellStyles, fontFamilyStyles } from '../shared/styles';\n\n/**\n * A surfaced container — content goes in the default slot. Attributes: `variant`, `padding`,\n * `elevation`, `hoverable`, `inverted`; a click handler is just a native `click` listener on the\n * element. `padding` takes `none | small | medium | large`; `elevation` takes `none | sm | md | lg`.\n */\n@customElement('st-card')\nexport class Card extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n ${fontFamilyStyles}\n ${cardShellStyles}\n border-radius: var(--st-radius-lg);\n overflow: hidden;\n position: relative;\n transition:\n transform 0.3s ease,\n box-shadow 0.3s ease,\n border-color 0.3s ease;\n }\n\n :host([variant='bordered']) {\n border-color: var(--st-color-border-strong);\n }\n\n :host([elevation='sm']) {\n box-shadow: 0 1px 2px var(--st-shadow-color-sm);\n }\n\n :host([elevation='md']) {\n box-shadow: 0 4px 6px -1px var(--st-shadow-color-md);\n }\n\n :host([elevation='lg']) {\n box-shadow: 0 10px 15px -3px var(--st-shadow-color-lg);\n }\n\n :host([hoverable]:hover) {\n transform: translateY(-4px);\n box-shadow: 0 20px 25px -5px var(--st-shadow-color-xl);\n border-color: var(--st-color-border-strong);\n }\n\n :host([inverted]) {\n background: var(--st-color-text-strong);\n color: var(--st-color-on-solid);\n border-color: var(--st-color-text-strong);\n }\n\n .body {\n padding: var(--st-space-24);\n }\n\n :host([padding='none']) .body {\n padding: 0;\n }\n\n :host([padding='small']) .body {\n padding: var(--st-space-16);\n }\n\n :host([padding='large']) .body {\n padding: var(--st-space-32);\n }\n\n @media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n :host([hoverable]:hover) {\n transform: none;\n }\n }\n `;\n\n @property({ type: String, reflect: true })\n variant: 'default' | 'bordered' = 'default';\n\n @property({ type: String, reflect: true })\n padding: 'none' | 'small' | 'medium' | 'large' = 'medium';\n\n @property({ type: String, reflect: true })\n elevation: 'none' | 'sm' | 'md' | 'lg' = 'sm';\n\n @property({ type: Boolean, reflect: true })\n hoverable = false;\n\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n render() {\n return html`<div class=\"body\" part=\"body\"><slot></slot></div>`;\n }\n}\n"],"mappings":";;;;;;;;;;AAAA,SAAS,YAAY,KAAK,YAAY;AACtC,SAAS,eAAe,gBAAgB;AAUjC,IAAM,OAAN,cAAmB,WAAW;AAAA,EAA9B;AAAA;AAyEL,mBAAkC;AAGlC,mBAAiD;AAGjD,qBAAyC;AAGzC,qBAAY;AAGZ,oBAAW;AAAA;AAAA,EAEX,SAAS;AACP,WAAO;AAAA,EACT;AACF;AA1Fa,KACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA,QAIf,gBAAgB;AAAA,QAChB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkErB;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAxE9B,KAyEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GA3E9B,KA4EX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GA9E9B,KA+EX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAjF/B,KAkFX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GApF/B,KAqFX;AArFW,OAAN;AAAA,EADN,cAAc,SAAS;AAAA,GACX;","names":[]}
@@ -155,4 +155,4 @@ ContentBlock = __decorateClass([
155
155
  export {
156
156
  ContentBlock
157
157
  };
158
- //# sourceMappingURL=chunk-BMHMNXIA.js.map
158
+ //# sourceMappingURL=chunk-4AFOKKSU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/content-block/ContentBlock.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\nimport { sectionSubtitleStyles, sectionTitleStyles, sectionHeaderStyles } from '../shared/section-styles';\nimport '../markdown';\n\n/**\n * A long-form article section: centered title/subtitle, an optional featured image with caption,\n * then Markdown body text. The body comes from `content-src` (a Markdown URL) or an inline\n * `content` string (so the block works without a fetch); `content-src` wins when both are set.\n *\n * @cssprop --st-content-block-padding - Overrides the block's padding.\n */\n@customElement('st-content-block')\nexport class ContentBlock extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n ${fontFamilyStyles}\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\n padding; override with --st-content-block-padding instead. */\n padding: var(--st-content-block-padding, var(--st-space-24)) !important;\n background: var(--st-color-surface);\n color: var(--st-color-text-strong);\n }\n\n :host([inverted]) {\n background: var(--st-color-text-strong);\n color: var(--st-color-on-solid);\n }\n\n .container {\n max-width: var(--st-cms-container-max);\n padding: 0 var(--st-space-48);\n margin: 0 auto;\n }\n\n .header {\n ${sectionHeaderStyles}\n }\n\n .title {\n ${sectionTitleStyles}\n line-height: 1.1;\n }\n\n .subtitle {\n ${sectionSubtitleStyles}\n }\n\n :host([inverted]) .title,\n :host([inverted]) .subtitle {\n color: inherit;\n }\n\n .featured-image {\n margin: 0 0 var(--st-space-48);\n border-radius: var(--st-radius-lg);\n overflow: hidden;\n }\n\n .featured-image img {\n width: 100%;\n height: auto;\n display: block;\n }\n\n figcaption {\n padding: var(--st-space-12);\n text-align: center;\n color: var(--st-color-text-muted);\n font-size: var(--st-text-xs);\n }\n\n st-markdown {\n color: var(--st-color-text);\n font-size: var(--st-text-xl);\n }\n\n :host([inverted]) st-markdown {\n color: inherit;\n }\n\n @media (max-width: 768px) {\n :host {\n padding: var(--st-content-block-padding, var(--st-space-48) var(--st-space-24)) !important;\n }\n\n .container {\n padding: 0;\n }\n }\n `;\n\n @property({ type: String })\n title = '';\n\n @property({ type: String })\n subtitle = '';\n\n /** URL of a Markdown file. */\n @property({ type: String, attribute: 'content-src' })\n contentSrc = '';\n\n /** Inline Markdown, used when `content-src` is not set. */\n @property({ type: String })\n content = '';\n\n @property({ type: String, attribute: 'image-src' })\n imageSrc = '';\n\n @property({ type: String, attribute: 'image-alt' })\n imageAlt = '';\n\n @property({ type: String, attribute: 'image-caption' })\n imageCaption = '';\n\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n render() {\n return html`\n <section class=\"container\" part=\"container\">\n <div class=\"header\" part=\"header\">\n ${this.title ? html`<div class=\"title\" part=\"title\">${this.title}</div>` : nothing}\n ${this.subtitle ? html`<div class=\"subtitle\" part=\"subtitle\">${this.subtitle}</div>` : nothing}\n </div>\n ${this.imageSrc\n ? html`\n <figure class=\"featured-image\" part=\"image\">\n <img src=${this.imageSrc} alt=${this.imageAlt || this.title} />\n ${this.imageCaption ? html`<figcaption>${this.imageCaption}</figcaption>` : nothing}\n </figure>\n `\n : nothing}\n <st-markdown part=\"body\" .src=${this.contentSrc} .content=${this.content}></st-markdown>\n </section>\n `;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,eAAe;AAC/C,SAAS,eAAe,gBAAgB;AAcjC,IAAM,eAAN,cAA2B,WAAW;AAAA,EAAtC;AAAA;AAmFL,iBAAQ;AAGR,oBAAW;AAIX,sBAAa;AAIb,mBAAU;AAGV,oBAAW;AAGX,oBAAW;AAGX,wBAAe;AAGf,oBAAW;AAAA;AAAA,EAEX,SAAS;AACP,WAAO;AAAA;AAAA;AAAA,YAGC,KAAK,QAAQ,uCAAuC,KAAK,KAAK,WAAW,OAAO;AAAA,YAChF,KAAK,WAAW,6CAA6C,KAAK,QAAQ,WAAW,OAAO;AAAA;AAAA,UAE9F,KAAK,WACH;AAAA;AAAA,2BAEe,KAAK,QAAQ,QAAQ,KAAK,YAAY,KAAK,KAAK;AAAA,kBACzD,KAAK,eAAe,mBAAmB,KAAK,YAAY,kBAAkB,OAAO;AAAA;AAAA,gBAGvF,OAAO;AAAA,wCACqB,KAAK,UAAU,aAAa,KAAK,OAAO;AAAA;AAAA;AAAA,EAG9E;AACF;AA/Ha,aACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA;AAAA,QAIf,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAoBhB,mBAAmB;AAAA;AAAA;AAAA;AAAA,QAInB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,QAKlB,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgD3B;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAlFf,aAmFX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GArFf,aAsFX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,cAAc,CAAC;AAAA,GAzFzC,aA0FX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA7Ff,aA8FX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,YAAY,CAAC;AAAA,GAhGvC,aAiGX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,YAAY,CAAC;AAAA,GAnGvC,aAoGX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,WAAW,gBAAgB,CAAC;AAAA,GAtG3C,aAuGX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAzG/B,aA0GX;AA1GW,eAAN;AAAA,EADN,cAAc,kBAAkB;AAAA,GACpB;","names":[]}
@@ -1,5 +1,9 @@
1
+ import {
2
+ renderMarkdown
3
+ } from "./chunk-UAIUBPDN.js";
1
4
  import {
2
5
  cardTitleStyles,
6
+ ctaLinkStyles,
3
7
  iconTileStyles,
4
8
  invertedSectionTextStyles,
5
9
  reducedMotionStyles,
@@ -18,6 +22,7 @@ import {
18
22
  // src/bento-grid/BentoGrid.ts
19
23
  import { LitElement, css, html, nothing } from "lit";
20
24
  import { customElement, property } from "lit/decorators.js";
25
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
21
26
  import "iconify-icon";
22
27
  var BentoGrid = class extends LitElement {
23
28
  constructor() {
@@ -28,7 +33,8 @@ var BentoGrid = class extends LitElement {
28
33
  this.items = [];
29
34
  }
30
35
  renderCard(item) {
31
- const classes = `card col-${item.colSpan ?? 1} row-${item.rowSpan ?? 1} ${item.imageSrc ? "has-image" : ""}`;
36
+ const variant = item.variant ?? "default";
37
+ const classes = `card col-${item.colSpan ?? 1} row-${item.rowSpan ?? 1} ${item.imageSrc ? "has-image" : ""} ${variant === "default" ? "" : variant}`;
32
38
  const body = html`
33
39
  ${item.imageSrc ? html`<div class="image-wrapper" part="image-wrapper">
34
40
  <img class="image" part="image" src=${item.imageSrc} alt=${item.imageAlt ?? item.title} />
@@ -37,11 +43,12 @@ var BentoGrid = class extends LitElement {
37
43
  ${item.icon ? html`<div class="icon" part="icon"><iconify-icon icon=${item.icon}></iconify-icon></div>` : nothing}
38
44
  <div class="text">
39
45
  <h3 class="card-title" part="card-title">${item.title}</h3>
40
- ${item.description ? html`<p class="card-description" part="card-description">${item.description}</p>` : nothing}
46
+ ${item.description ? html`<div class="card-description" part="card-description">${unsafeHTML(renderMarkdown(item.description))}</div>` : nothing}
41
47
  </div>
48
+ ${item.href && item.actionLabel ? html`<a class="action" part="action" href=${item.href}>${item.actionLabel}</a>` : nothing}
42
49
  </div>
43
50
  `;
44
- return item.href ? html`<a part="card" class=${classes} href=${item.href}>${body}</a>` : html`<div part="card" class=${classes}>${body}</div>`;
51
+ return item.href && !item.actionLabel ? html`<a part="card" class=${classes} href=${item.href}>${body}</a>` : html`<div part="card" class=${classes}>${body}</div>`;
45
52
  }
46
53
  render() {
47
54
  return html`
@@ -199,6 +206,93 @@ BentoGrid.styles = css`
199
206
  backdrop-filter: blur(4px);
200
207
  }
201
208
 
209
+ /* variant: prefixed with :host so it outranks the :host([inverted]) card rules above. */
210
+ :host .card.primary {
211
+ background: var(--st-color-accent);
212
+ border-color: var(--st-color-accent);
213
+ color: var(--st-color-on-solid);
214
+ }
215
+
216
+ :host .card.dark {
217
+ background: var(--st-cms-navy);
218
+ border-color: var(--st-cms-navy);
219
+ color: var(--st-cms-on-dark);
220
+ }
221
+
222
+ :host .card.primary .card-title {
223
+ color: var(--st-color-on-solid);
224
+ }
225
+
226
+ :host .card.dark .card-title {
227
+ color: var(--st-cms-on-dark);
228
+ }
229
+
230
+ :host .card.primary .card-description {
231
+ color: color-mix(in oklch, var(--st-color-on-solid) 85%, transparent);
232
+ }
233
+
234
+ :host .card.dark .card-description {
235
+ color: color-mix(in oklch, var(--st-cms-on-dark) 80%, transparent);
236
+ }
237
+
238
+ :host .card.primary .icon {
239
+ background: color-mix(in oklch, var(--st-color-on-solid) 18%, transparent);
240
+ color: var(--st-color-on-solid);
241
+ }
242
+
243
+ :host .card.dark .icon {
244
+ background: color-mix(in oklch, var(--st-cms-on-dark) 12%, transparent);
245
+ color: var(--st-cms-on-dark);
246
+ }
247
+
248
+ .card-description > :first-child {
249
+ margin-top: 0;
250
+ }
251
+
252
+ .card-description > :last-child {
253
+ margin-bottom: 0;
254
+ }
255
+
256
+ .card-description p {
257
+ margin: 0 0 var(--st-space-8);
258
+ }
259
+
260
+ .card-description a {
261
+ color: inherit;
262
+ text-decoration: underline;
263
+ text-underline-offset: 3px;
264
+ }
265
+
266
+ .action {
267
+ ${ctaLinkStyles}
268
+ align-self: flex-start;
269
+ margin-top: var(--st-space-8);
270
+ background: var(--st-button-primary-bg);
271
+ color: var(--st-button-primary-color);
272
+ font-weight: var(--st-button-font-weight);
273
+ position: relative;
274
+ z-index: 1;
275
+ }
276
+
277
+ .action:hover {
278
+ transform: scale(1.03);
279
+ }
280
+
281
+ .action:focus-visible {
282
+ outline: var(--st-focus-ring);
283
+ outline-offset: 2px;
284
+ }
285
+
286
+ .card.primary .action {
287
+ background: var(--st-cms-on-dark);
288
+ color: var(--st-color-accent);
289
+ }
290
+
291
+ .card.dark .action {
292
+ background: var(--st-cms-highlight);
293
+ color: var(--st-cms-navy);
294
+ }
295
+
202
296
  .col-1 { grid-column: span 1; }
203
297
  .col-2 { grid-column: span 2; }
204
298
  .col-3 { grid-column: span 3; }
@@ -249,4 +343,4 @@ BentoGrid = __decorateClass([
249
343
  export {
250
344
  BentoGrid
251
345
  };
252
- //# sourceMappingURL=chunk-76AVBQUA.js.map
346
+ //# sourceMappingURL=chunk-5C6C6K5U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bento-grid/BentoGrid.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport 'iconify-icon';\n\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\nimport { renderMarkdown } from '../shared/markdown';\nimport {\n cardTitleStyles,\n ctaLinkStyles,\n iconTileStyles,\n reducedMotionStyles,\n sectionHeaderStyles,\n sectionSubtitleStyles,\n sectionTitleStyles, invertedSectionTextStyles } from '../shared/section-styles';\n\nexport interface BentoGridItem {\n title: string;\n /** Markdown. */\n description?: string;\n /** Iconify icon name, e.g. `mdi:home`. */\n icon?: string;\n imageSrc?: string;\n imageAlt?: string;\n colSpan?: 1 | 2 | 3 | 4;\n rowSpan?: 1 | 2;\n /** Without `actionLabel`, turns the whole card into a link. */\n href?: string;\n /** `default` (surface), `primary` (brand fill, white text) or `dark` (navy fill, light text). */\n variant?: 'default' | 'primary' | 'dark';\n /** With `href`, renders a button-style link inside the card instead of linking the whole card. */\n actionLabel?: string;\n}\n\n/**\n * A responsive 4-column bento grid of icon/image cards. Items are set via the `items` property.\n * Descriptions are Markdown. A card links as a whole when it has `href` alone; with `actionLabel`\n * the link becomes a button inside the card.\n *\n * @cssprop --st-bento-grid-padding - Overrides the block's padding.\n */\n@customElement('st-bento-grid')\nexport class BentoGrid extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n display: block;\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\n padding; override with --st-bento-grid-padding instead. */\n padding: var(--st-bento-grid-padding, var(--st-cms-section-padding) var(--st-space-24)) !important;\n background: var(--st-color-page);\n ${fontFamilyStyles}\n }\n\n :host([inverted]) {\n background: var(--st-color-text-strong);\n }\n\n .container {\n max-width: var(--st-cms-container-max);\n margin: 0 auto;\n }\n\n .header {\n ${sectionHeaderStyles}\n }\n\n .title {\n ${sectionTitleStyles}\n }\n\n .subtitle {\n ${sectionSubtitleStyles}\n margin-bottom: 0;\n }\n\n ${invertedSectionTextStyles}\n\n .grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n grid-auto-rows: minmax(240px, auto);\n gap: var(--st-space-24);\n }\n\n .card {\n position: relative;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border: 1px solid var(--st-color-border);\n border-radius: var(--st-space-24);\n background: var(--st-color-surface);\n color: inherit;\n text-decoration: none;\n transition:\n transform 0.3s ease,\n box-shadow 0.3s ease;\n }\n\n :host([inverted]) .card {\n background: var(--st-color-text-strong);\n border-color: var(--st-color-text);\n }\n\n .card:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px -10px var(--st-shadow-color-lg);\n z-index: 1;\n }\n\n .image-wrapper {\n position: absolute;\n inset: 0;\n }\n\n .image-wrapper::after {\n content: '';\n position: absolute;\n inset: 0;\n background: linear-gradient(to bottom, transparent 0%, var(--st-shadow-color-xl) 100%);\n }\n\n .image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n transition: transform 0.5s ease;\n }\n\n .card:hover .image {\n transform: scale(1.05);\n }\n\n .content {\n position: relative;\n z-index: 1;\n margin-top: auto;\n padding: var(--st-space-24);\n display: flex;\n flex-direction: column;\n gap: var(--st-space-16);\n }\n\n .icon {\n ${iconTileStyles}\n width: var(--st-size-40);\n height: var(--st-size-40);\n font-size: 24px;\n }\n\n .text {\n padding: var(--st-space-16);\n border-radius: var(--st-radius-md);\n }\n\n .card-title {\n ${cardTitleStyles}\n font-size: var(--st-text-lg);\n }\n\n .card-description {\n margin: 0;\n font-size: var(--st-text-md);\n color: var(--st-color-text-muted);\n }\n\n :host([inverted]) .card-title {\n color: var(--st-color-on-solid);\n }\n\n :host([inverted]) .card-description {\n color: var(--st-color-border);\n }\n\n .card.has-image .card-title,\n .card.has-image .card-description {\n color: var(--st-color-on-solid);\n }\n\n .card.has-image .icon {\n background: var(--st-shadow-color-lg);\n color: var(--st-color-on-solid);\n backdrop-filter: blur(4px);\n }\n\n /* variant: prefixed with :host so it outranks the :host([inverted]) card rules above. */\n :host .card.primary {\n background: var(--st-color-accent);\n border-color: var(--st-color-accent);\n color: var(--st-color-on-solid);\n }\n\n :host .card.dark {\n background: var(--st-cms-navy);\n border-color: var(--st-cms-navy);\n color: var(--st-cms-on-dark);\n }\n\n :host .card.primary .card-title {\n color: var(--st-color-on-solid);\n }\n\n :host .card.dark .card-title {\n color: var(--st-cms-on-dark);\n }\n\n :host .card.primary .card-description {\n color: color-mix(in oklch, var(--st-color-on-solid) 85%, transparent);\n }\n\n :host .card.dark .card-description {\n color: color-mix(in oklch, var(--st-cms-on-dark) 80%, transparent);\n }\n\n :host .card.primary .icon {\n background: color-mix(in oklch, var(--st-color-on-solid) 18%, transparent);\n color: var(--st-color-on-solid);\n }\n\n :host .card.dark .icon {\n background: color-mix(in oklch, var(--st-cms-on-dark) 12%, transparent);\n color: var(--st-cms-on-dark);\n }\n\n .card-description > :first-child {\n margin-top: 0;\n }\n\n .card-description > :last-child {\n margin-bottom: 0;\n }\n\n .card-description p {\n margin: 0 0 var(--st-space-8);\n }\n\n .card-description a {\n color: inherit;\n text-decoration: underline;\n text-underline-offset: 3px;\n }\n\n .action {\n ${ctaLinkStyles}\n align-self: flex-start;\n margin-top: var(--st-space-8);\n background: var(--st-button-primary-bg);\n color: var(--st-button-primary-color);\n font-weight: var(--st-button-font-weight);\n position: relative;\n z-index: 1;\n }\n\n .action:hover {\n transform: scale(1.03);\n }\n\n .action:focus-visible {\n outline: var(--st-focus-ring);\n outline-offset: 2px;\n }\n\n .card.primary .action {\n background: var(--st-cms-on-dark);\n color: var(--st-color-accent);\n }\n\n .card.dark .action {\n background: var(--st-cms-highlight);\n color: var(--st-cms-navy);\n }\n\n .col-1 { grid-column: span 1; }\n .col-2 { grid-column: span 2; }\n .col-3 { grid-column: span 3; }\n .col-4 { grid-column: span 4; }\n .row-1 { grid-row: span 1; }\n .row-2 { grid-row: span 2; }\n\n @media (max-width: 1024px) {\n .grid {\n grid-template-columns: repeat(2, 1fr);\n }\n .col-3,\n .col-4 {\n grid-column: span 2;\n }\n }\n\n @media (max-width: 640px) {\n .grid {\n grid-template-columns: 1fr;\n }\n .col-1,\n .col-2,\n .col-3,\n .col-4 {\n grid-column: span 1;\n }\n }\n\n ${reducedMotionStyles}\n `;\n\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n @property({ type: String })\n title = '';\n\n @property({ type: String })\n subtitle = '';\n\n @property({ attribute: false })\n items: BentoGridItem[] = [];\n\n private renderCard(item: BentoGridItem) {\n const variant = item.variant ?? 'default';\n const classes = `card col-${item.colSpan ?? 1} row-${item.rowSpan ?? 1} ${item.imageSrc ? 'has-image' : ''} ${variant === 'default' ? '' : variant}`;\n const body = html`\n ${item.imageSrc\n ? html`<div class=\"image-wrapper\" part=\"image-wrapper\">\n <img class=\"image\" part=\"image\" src=${item.imageSrc} alt=${item.imageAlt ?? item.title} />\n </div>`\n : nothing}\n <div class=\"content\" part=\"content\">\n ${item.icon ? html`<div class=\"icon\" part=\"icon\"><iconify-icon icon=${item.icon}></iconify-icon></div>` : nothing}\n <div class=\"text\">\n <h3 class=\"card-title\" part=\"card-title\">${item.title}</h3>\n ${item.description\n ? html`<div class=\"card-description\" part=\"card-description\">${unsafeHTML(renderMarkdown(item.description))}</div>`\n : nothing}\n </div>\n ${item.href && item.actionLabel\n ? html`<a class=\"action\" part=\"action\" href=${item.href}>${item.actionLabel}</a>`\n : nothing}\n </div>\n `;\n return item.href && !item.actionLabel\n ? html`<a part=\"card\" class=${classes} href=${item.href}>${body}</a>`\n : html`<div part=\"card\" class=${classes}>${body}</div>`;\n }\n\n render() {\n return html`\n <div class=\"container\" part=\"container\">\n ${this.title || this.subtitle\n ? html`<div class=\"header\" part=\"header\">\n ${this.title ? html`<h2 class=\"title\" part=\"title\">${this.title}</h2>` : nothing}\n ${this.subtitle ? html`<p class=\"subtitle\" part=\"subtitle\">${this.subtitle}</p>` : nothing}\n </div>`\n : nothing}\n <div class=\"grid\" part=\"grid\">${this.items.map((item) => this.renderCard(item))}</div>\n </div>\n `;\n }\n}\n"],"mappings":"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","names":[]}
@@ -23,6 +23,7 @@ var Section = class extends LitElement {
23
23
  this.spacingAbove = "m";
24
24
  this.spacingBelow = "m";
25
25
  this.width = "contained";
26
+ this.columns = 1;
26
27
  this.textAlignment = "left";
27
28
  }
28
29
  render() {
@@ -34,7 +35,9 @@ var Section = class extends LitElement {
34
35
  ${this.title ? html`<h2 class="title" part="title">${this.title}</h2>` : nothing}
35
36
  ${this.subtitle ? html`<p class="subtitle" part="subtitle">${this.subtitle}</p>` : nothing}
36
37
  </div>` : nothing}
37
- <slot></slot>
38
+ <div class="content" part="content">
39
+ <slot></slot>
40
+ </div>
38
41
  </div>
39
42
  `;
40
43
  }
@@ -109,6 +112,18 @@ Section.styles = css`
109
112
  max-width: none;
110
113
  }
111
114
 
115
+ /* columns="2": the slotted children sit in two equal columns; they stack below 720px. */
116
+ .content {
117
+ display: block;
118
+ }
119
+
120
+ :host([columns='2']) .content {
121
+ display: grid;
122
+ grid-template-columns: repeat(2, minmax(0, 1fr));
123
+ gap: var(--st-space-48);
124
+ align-items: start;
125
+ }
126
+
112
127
  .header {
113
128
  margin-bottom: var(--st-space-48);
114
129
  }
@@ -164,6 +179,13 @@ Section.styles = css`
164
179
  color: color-mix(in oklch, var(--st-color-on-solid) 80%, transparent);
165
180
  }
166
181
 
182
+ @media (max-width: 720px) {
183
+ :host([columns='2']) .content {
184
+ grid-template-columns: minmax(0, 1fr);
185
+ gap: var(--st-space-24);
186
+ }
187
+ }
188
+
167
189
  @media (max-width: 768px) {
168
190
  :host {
169
191
  --st-section-space-l: 3.5rem;
@@ -194,6 +216,9 @@ __decorateClass([
194
216
  __decorateClass([
195
217
  property({ type: String, reflect: true })
196
218
  ], Section.prototype, "width", 2);
219
+ __decorateClass([
220
+ property({ type: Number, reflect: true })
221
+ ], Section.prototype, "columns", 2);
197
222
  __decorateClass([
198
223
  property({ type: String, reflect: true, attribute: "text-alignment" })
199
224
  ], Section.prototype, "textAlignment", 2);
@@ -204,4 +229,4 @@ Section = __decorateClass([
204
229
  export {
205
230
  Section
206
231
  };
207
- //# sourceMappingURL=chunk-7NLZND6Q.js.map
232
+ //# sourceMappingURL=chunk-5F5PTVWR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/section/Section.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { controlBaseStyles, rootFontFamilyStyles } from '../shared/styles';\nimport { sectionSubtitleStyles, sectionTitleStyles } from '../shared/section-styles';\n\n/**\n * A page band that holds other content: sets the background, the spacing above and below, and\n * the content width, with an optional eyebrow/title/subtitle heading over its slotted children.\n * Use it to give a run of components one dark or tinted backdrop and a consistent vertical rhythm,\n * the way enterprise marketing pages stack full-width sections.\n *\n * @slot - The section's content.\n * @cssprop --st-section-bg - Overrides the background colour picked by `background`.\n * @cssprop --st-section-padding-inline - Overrides the left/right padding (not with `width=\"full\"`).\n * @csspart inner - The width-limited content box.\n * @csspart header - The heading block.\n * @csspart content - The wrapper around the slot (the grid when `columns` is 2).\n */\n@customElement('st-section')\nexport class Section extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n\n :host {\n --st-section-space-none: 0;\n --st-section-space-s: var(--st-space-24);\n --st-section-space-m: var(--st-space-48);\n --st-section-space-l: 4.5rem;\n --st-section-space-xl: 6rem;\n --st-section-space-xxl: 8rem;\n\n display: block;\n box-sizing: border-box;\n width: 100%;\n /* !important on every padding rule: a page-level reset (e.g. Tailwind Preflight) otherwise\n zeroes a shadow host's padding. Rescale it with the --st-section-space-* tokens. */\n padding: var(--st-section-space-m) var(--st-section-padding-inline, var(--st-space-24)) !important;\n background: var(--st-section-bg, var(--st-color-surface));\n color: var(--st-color-text-strong);\n ${rootFontFamilyStyles}\n }\n\n :host([background='subtle']) {\n background: var(--st-section-bg, var(--st-color-subtle));\n }\n\n :host([background='dark']) {\n background: var(--st-section-bg, var(--st-cms-band-dark-bg));\n color: var(--st-cms-band-dark-color);\n }\n\n :host([background='accent']) {\n background: var(--st-section-bg, var(--st-color-accent));\n color: var(--st-color-on-solid);\n }\n\n :host([background='transparent']) {\n background: var(--st-section-bg, transparent);\n }\n\n :host([spacing-above='none']) { padding-top: var(--st-section-space-none) !important; }\n :host([spacing-above='s']) { padding-top: var(--st-section-space-s) !important; }\n :host([spacing-above='l']) { padding-top: var(--st-section-space-l) !important; }\n :host([spacing-above='xl']) { padding-top: var(--st-section-space-xl) !important; }\n :host([spacing-above='xxl']) { padding-top: var(--st-section-space-xxl) !important; }\n\n :host([spacing-below='none']) { padding-bottom: var(--st-section-space-none) !important; }\n :host([spacing-below='s']) { padding-bottom: var(--st-section-space-s) !important; }\n :host([spacing-below='l']) { padding-bottom: var(--st-section-space-l) !important; }\n :host([spacing-below='xl']) { padding-bottom: var(--st-section-space-xl) !important; }\n :host([spacing-below='xxl']) { padding-bottom: var(--st-section-space-xxl) !important; }\n\n :host([width='full']) {\n padding-left: 0 !important;\n padding-right: 0 !important;\n }\n\n .inner {\n max-width: var(--st-cms-container-max);\n margin: 0 auto;\n }\n\n :host([width='narrow']) .inner {\n max-width: 800px;\n }\n\n :host([width='full']) .inner {\n max-width: none;\n }\n\n /* columns=\"2\": the slotted children sit in two equal columns; they stack below 720px. */\n .content {\n display: block;\n }\n\n :host([columns='2']) .content {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--st-space-48);\n align-items: start;\n }\n\n .header {\n margin-bottom: var(--st-space-48);\n }\n\n :host([text-alignment='center']) .header {\n text-align: center;\n }\n\n :host([text-alignment='center']) .subtitle {\n margin-inline: auto;\n }\n\n :host([width='full']) .header {\n max-width: var(--st-cms-container-max);\n margin-inline: auto;\n padding-inline: var(--st-space-24);\n box-sizing: border-box;\n }\n\n .eyebrow {\n margin: 0 0 var(--st-space-12);\n font-size: var(--st-text-sm);\n font-weight: var(--st-font-weight-bold);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: var(--st-color-text-muted);\n }\n\n .title {\n ${sectionTitleStyles}\n color: inherit;\n letter-spacing: -0.02em;\n max-width: 24ch;\n }\n\n :host([text-alignment='center']) .title {\n margin-inline: auto;\n }\n\n .subtitle {\n ${sectionSubtitleStyles}\n max-width: 60ch;\n margin-bottom: 0;\n }\n\n :host([background='dark']) .eyebrow,\n :host([background='dark']) .subtitle {\n color: color-mix(in oklch, var(--st-cms-band-dark-color) 80%, transparent);\n }\n\n :host([background='accent']) .eyebrow,\n :host([background='accent']) .subtitle {\n color: color-mix(in oklch, var(--st-color-on-solid) 80%, transparent);\n }\n\n @media (max-width: 720px) {\n :host([columns='2']) .content {\n grid-template-columns: minmax(0, 1fr);\n gap: var(--st-space-24);\n }\n }\n\n @media (max-width: 768px) {\n :host {\n --st-section-space-l: 3.5rem;\n --st-section-space-xl: 4.5rem;\n --st-section-space-xxl: 5.5rem;\n --st-section-padding-inline: var(--st-space-20);\n }\n }\n `;\n\n @property({ type: String })\n eyebrow = '';\n\n @property({ type: String })\n title = '';\n\n @property({ type: String })\n subtitle = '';\n\n /** `default` (page surface), `subtle`, `dark`, `accent` or `transparent`. */\n @property({ type: String, reflect: true })\n background: 'default' | 'subtle' | 'dark' | 'accent' | 'transparent' = 'default';\n\n /** Space above the content: `none`, `s`, `m` (default), `l`, `xl` or `xxl`. */\n @property({ type: String, reflect: true, attribute: 'spacing-above' })\n spacingAbove: 'none' | 's' | 'm' | 'l' | 'xl' | 'xxl' = 'm';\n\n /** Space below the content: `none`, `s`, `m` (default), `l`, `xl` or `xxl`. */\n @property({ type: String, reflect: true, attribute: 'spacing-below' })\n spacingBelow: 'none' | 's' | 'm' | 'l' | 'xl' | 'xxl' = 'm';\n\n /** `contained` (default, the page container width), `narrow` (reading width) or `full` (edge to edge). */\n @property({ type: String, reflect: true })\n width: 'contained' | 'narrow' | 'full' = 'contained';\n\n /** Columns for the slotted children: `1` (default, stacked) or `2` (two equal columns, stacked again below 720px). */\n @property({ type: Number, reflect: true })\n columns: 1 | 2 = 1;\n\n /** Alignment of the heading. */\n @property({ type: String, reflect: true, attribute: 'text-alignment' })\n textAlignment: 'left' | 'center' = 'left';\n\n render() {\n const heading = this.eyebrow || this.title || this.subtitle;\n return html`\n <div class=\"inner\" part=\"inner\">\n ${heading\n ? html`<div class=\"header\" part=\"header\">\n ${this.eyebrow ? html`<p class=\"eyebrow\" part=\"eyebrow\">${this.eyebrow}</p>` : nothing}\n ${this.title ? html`<h2 class=\"title\" part=\"title\">${this.title}</h2>` : nothing}\n ${this.subtitle ? html`<p class=\"subtitle\" part=\"subtitle\">${this.subtitle}</p>` : nothing}\n </div>`\n : nothing}\n <div class=\"content\" part=\"content\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,125 @@
1
+ import {
2
+ controlBaseStyles,
3
+ fontFamilyStyles
4
+ } from "./chunk-KMU6ABQF.js";
5
+ import {
6
+ __decorateClass
7
+ } from "./chunk-EUXUH3YW.js";
8
+
9
+ // src/tag-strip/TagStrip.ts
10
+ import { LitElement, css, html, nothing } from "lit";
11
+ import { customElement, property } from "lit/decorators.js";
12
+ var TagStrip = class extends LitElement {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.label = "";
16
+ this.items = [];
17
+ this.inverted = false;
18
+ }
19
+ render() {
20
+ return html`
21
+ <div class="strip" part="strip">
22
+ ${this.label ? html`<p class="label" part="label">${this.label}</p>` : nothing}
23
+ <ul class="items" part="items">
24
+ ${this.items.map((item) => html`<li class="item" part="item">${item}</li>`)}
25
+ </ul>
26
+ </div>
27
+ `;
28
+ }
29
+ };
30
+ TagStrip.styles = css`
31
+ ${controlBaseStyles}
32
+ ${fontFamilyStyles}
33
+
34
+ :host {
35
+ display: block;
36
+ box-sizing: border-box;
37
+ /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's
38
+ padding; override with --st-tag-strip-padding instead. */
39
+ padding: var(--st-tag-strip-padding, var(--st-space-24)) var(--st-space-24) !important;
40
+ background: var(--st-color-page);
41
+ }
42
+
43
+ :host([inverted]) {
44
+ background: var(--st-cms-band-dark-bg);
45
+ }
46
+
47
+ .strip {
48
+ display: flex;
49
+ flex-wrap: wrap;
50
+ align-items: center;
51
+ gap: var(--st-space-16) var(--st-space-32);
52
+ box-sizing: border-box;
53
+ max-width: var(--st-cms-container-max);
54
+ margin: 0 auto;
55
+ padding: var(--st-space-20) var(--st-space-28, 28px);
56
+ border: 1px solid var(--st-color-border);
57
+ border-radius: var(--st-radius-lg);
58
+ background: var(--st-color-surface);
59
+ }
60
+
61
+ :host([inverted]) .strip {
62
+ background: transparent;
63
+ border-color: color-mix(in oklch, var(--st-cms-band-dark-color) 22%, transparent);
64
+ }
65
+
66
+ .label {
67
+ margin: 0;
68
+ flex-shrink: 0;
69
+ font-size: var(--st-text-sm);
70
+ font-weight: var(--st-font-weight-bold);
71
+ letter-spacing: var(--st-tracking-wider);
72
+ text-transform: uppercase;
73
+ color: var(--st-color-text-muted);
74
+ }
75
+
76
+ :host([inverted]) .label {
77
+ color: color-mix(in oklch, var(--st-cms-band-dark-color) 75%, transparent);
78
+ }
79
+
80
+ .items {
81
+ display: flex;
82
+ flex-wrap: wrap;
83
+ flex: 1 1 auto;
84
+ gap: var(--st-space-12) var(--st-space-28, 28px);
85
+ margin: 0;
86
+ padding: 0;
87
+ list-style: none;
88
+ }
89
+
90
+ .item {
91
+ margin: 0;
92
+ font-size: var(--st-text-lg);
93
+ font-weight: var(--st-font-weight-bold);
94
+ color: var(--st-color-text-strong);
95
+ }
96
+
97
+ :host([inverted]) .item {
98
+ color: var(--st-cms-band-dark-color);
99
+ }
100
+
101
+ @media (max-width: 600px) {
102
+ .strip {
103
+ flex-direction: column;
104
+ align-items: flex-start;
105
+ padding: var(--st-space-16) var(--st-space-20);
106
+ }
107
+ }
108
+ `;
109
+ __decorateClass([
110
+ property({ type: String })
111
+ ], TagStrip.prototype, "label", 2);
112
+ __decorateClass([
113
+ property({ attribute: false })
114
+ ], TagStrip.prototype, "items", 2);
115
+ __decorateClass([
116
+ property({ type: Boolean, reflect: true })
117
+ ], TagStrip.prototype, "inverted", 2);
118
+ TagStrip = __decorateClass([
119
+ customElement("st-tag-strip")
120
+ ], TagStrip);
121
+
122
+ export {
123
+ TagStrip
124
+ };
125
+ //# sourceMappingURL=chunk-5MY6OWMK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tag-strip/TagStrip.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\n\n/**\n * A single bordered band: a small uppercase label on the left and a run of bold items beside it\n * (e.g. \"Supported platforms: AWS · Azure · GCP\"). Items wrap onto new lines on narrow screens.\n * `inverted` puts the band on the dark band (`--st-cms-band-dark-bg`).\n *\n * @cssprop --st-tag-strip-padding - Overrides the block's padding.\n * @csspart strip - The bordered band.\n * @csspart label - The uppercase label.\n * @csspart items - The list of items.\n * @csspart item - Each item (an `li`).\n */\n@customElement('st-tag-strip')\nexport class TagStrip extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n ${fontFamilyStyles}\n\n :host {\n display: block;\n box-sizing: border-box;\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\n padding; override with --st-tag-strip-padding instead. */\n padding: var(--st-tag-strip-padding, var(--st-space-24)) var(--st-space-24) !important;\n background: var(--st-color-page);\n }\n\n :host([inverted]) {\n background: var(--st-cms-band-dark-bg);\n }\n\n .strip {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--st-space-16) var(--st-space-32);\n box-sizing: border-box;\n max-width: var(--st-cms-container-max);\n margin: 0 auto;\n padding: var(--st-space-20) var(--st-space-28, 28px);\n border: 1px solid var(--st-color-border);\n border-radius: var(--st-radius-lg);\n background: var(--st-color-surface);\n }\n\n :host([inverted]) .strip {\n background: transparent;\n border-color: color-mix(in oklch, var(--st-cms-band-dark-color) 22%, transparent);\n }\n\n .label {\n margin: 0;\n flex-shrink: 0;\n font-size: var(--st-text-sm);\n font-weight: var(--st-font-weight-bold);\n letter-spacing: var(--st-tracking-wider);\n text-transform: uppercase;\n color: var(--st-color-text-muted);\n }\n\n :host([inverted]) .label {\n color: color-mix(in oklch, var(--st-cms-band-dark-color) 75%, transparent);\n }\n\n .items {\n display: flex;\n flex-wrap: wrap;\n flex: 1 1 auto;\n gap: var(--st-space-12) var(--st-space-28, 28px);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .item {\n margin: 0;\n font-size: var(--st-text-lg);\n font-weight: var(--st-font-weight-bold);\n color: var(--st-color-text-strong);\n }\n\n :host([inverted]) .item {\n color: var(--st-cms-band-dark-color);\n }\n\n @media (max-width: 600px) {\n .strip {\n flex-direction: column;\n align-items: flex-start;\n padding: var(--st-space-16) var(--st-space-20);\n }\n }\n `;\n\n /** Small uppercase label at the start of the band. Omit it for items alone. */\n @property({ type: String })\n label = '';\n\n /** The items, shown in order. */\n @property({ attribute: false })\n items: string[] = [];\n\n /** Puts the band on the dark band (`--st-cms-band-dark-bg`), which stays dark in the dark theme. */\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n render() {\n return html`\n <div class=\"strip\" part=\"strip\">\n ${this.label ? html`<p class=\"label\" part=\"label\">${this.label}</p>` : nothing}\n <ul class=\"items\" part=\"items\">\n ${this.items.map(item => html`<li class=\"item\" part=\"item\">${item}</li>`)}\n </ul>\n </div>\n `;\n }\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,eAAe;AAC/C,SAAS,eAAe,gBAAgB;AAgBjC,IAAM,WAAN,cAAuB,WAAW;AAAA,EAAlC;AAAA;AAmFL,iBAAQ;AAIR,iBAAkB,CAAC;AAInB,oBAAW;AAAA;AAAA,EAEX,SAAS;AACP,WAAO;AAAA;AAAA,UAED,KAAK,QAAQ,qCAAqC,KAAK,KAAK,SAAS,OAAO;AAAA;AAAA,YAE1E,KAAK,MAAM,IAAI,UAAQ,oCAAoC,IAAI,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA,EAIjF;AACF;AAvGa,SACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA,MACjB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgFpB;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAlFf,SAmFX;AAIA;AAAA,EADC,SAAS,EAAE,WAAW,MAAM,CAAC;AAAA,GAtFnB,SAuFX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GA1F/B,SA2FX;AA3FW,WAAN;AAAA,EADN,cAAc,cAAc;AAAA,GAChB;","names":[]}