@arclux/arc-ui 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arclux/arc-ui",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "ARC UI — Lit Web Components implementing the Arclight design system.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -157,7 +157,7 @@
157
157
  "src/",
158
158
  "types/"
159
159
  ],
160
- "sideEffects": false,
160
+ "sideEffects": true,
161
161
  "dependencies": {
162
162
  "lit": "^3.3.0"
163
163
  },
@@ -4,6 +4,7 @@ import { tokenStyles } from '../shared-styles.js';
4
4
  export class ArcCard extends LitElement {
5
5
  static properties = {
6
6
  href: { type: String },
7
+ _hasFooter: { state: true },
7
8
  };
8
9
 
9
10
  static styles = [
@@ -34,6 +35,8 @@ export class ArcCard extends LitElement {
34
35
  padding: var(--space-xl) var(--space-lg);
35
36
  flex: 1;
36
37
  min-height: 0;
38
+ display: flex;
39
+ flex-direction: column;
37
40
  transition: box-shadow var(--transition-slow);
38
41
  }
39
42
 
@@ -43,6 +46,18 @@ export class ArcCard extends LitElement {
43
46
 
44
47
  .card:focus-visible { outline: none; box-shadow: var(--focus-glow); border-radius: var(--radius-lg); }
45
48
 
49
+ .card__body {
50
+ flex: 1;
51
+ }
52
+
53
+ .card__footer {
54
+ margin-top: var(--space-md);
55
+ }
56
+
57
+ .card__footer--empty {
58
+ display: none;
59
+ }
60
+
46
61
  @media (max-width: 768px) {
47
62
  .card__inner { padding: var(--space-lg) var(--space-md); }
48
63
  }
@@ -62,13 +77,25 @@ export class ArcCard extends LitElement {
62
77
  constructor() {
63
78
  super();
64
79
  this.href = '';
80
+ this._hasFooter = false;
81
+ }
82
+
83
+ _onFooterSlotChange(e) {
84
+ this._hasFooter = e.target.assignedNodes({ flatten: true }).length > 0;
65
85
  }
66
86
 
67
87
  render() {
88
+ const content = html`
89
+ <div class="card__body" part="body"><slot></slot></div>
90
+ <div class="card__footer ${this._hasFooter ? '' : 'card__footer--empty'}" part="footer">
91
+ <slot name="footer" @slotchange=${this._onFooterSlotChange}></slot>
92
+ </div>
93
+ `;
94
+
68
95
  if (this.href) {
69
- return html`<a class="card" href=${this.href} part="card"><div class="card__inner" part="inner"><slot></slot></div></a>`;
96
+ return html`<a class="card" href=${this.href} part="card"><div class="card__inner" part="inner">${content}</div></a>`;
70
97
  }
71
- return html`<div class="card" part="card"><div class="card__inner" part="inner"><slot></slot></div></div>`;
98
+ return html`<div class="card" part="card"><div class="card__inner" part="inner">${content}</div></div>`;
72
99
  }
73
100
  }
74
101
 
@@ -0,0 +1,126 @@
1
+ import { LitElement, html, css } from 'lit';
2
+ import { tokenStyles } from '../shared-styles.js';
3
+
4
+ /**
5
+ * @arc-prism content — call-to-action banner with gradient background
6
+ */
7
+ export class ArcCtaBanner extends LitElement {
8
+ static properties = {
9
+ eyebrow: { type: String },
10
+ headline: { type: String },
11
+ nogradient: { type: Boolean, reflect: true },
12
+ };
13
+
14
+ static styles = [
15
+ tokenStyles,
16
+ css`
17
+ :host { display: block; position: relative; overflow: hidden; }
18
+
19
+ .cta {
20
+ position: relative;
21
+ padding: var(--space-3xl) var(--space-lg);
22
+ }
23
+
24
+ .cta__bg {
25
+ position: absolute;
26
+ inset: 0;
27
+ background:
28
+ radial-gradient(ellipse at 30% 50%, rgba(var(--accent-primary-rgb), 0.1), transparent 60%),
29
+ radial-gradient(ellipse at 70% 50%, rgba(var(--accent-secondary-rgb), 0.08), transparent 60%);
30
+ pointer-events: none;
31
+ }
32
+
33
+ :host([nogradient]) .cta__bg { display: none; }
34
+
35
+ .cta__inner {
36
+ position: relative;
37
+ max-width: var(--max-width, 1200px);
38
+ margin-inline: auto;
39
+ display: flex;
40
+ flex-direction: column;
41
+ align-items: center;
42
+ text-align: center;
43
+ gap: var(--space-md);
44
+ }
45
+
46
+ .cta__eyebrow {
47
+ font-family: var(--font-accent);
48
+ font-weight: 600;
49
+ font-size: var(--text-xs);
50
+ letter-spacing: 4px;
51
+ text-transform: uppercase;
52
+ background: var(--gradient-accent-text);
53
+ -webkit-background-clip: text;
54
+ -webkit-text-fill-color: transparent;
55
+ background-clip: text;
56
+ }
57
+
58
+ .cta__headline {
59
+ font-size: clamp(28px, 4vw, 40px);
60
+ font-weight: 500;
61
+ letter-spacing: -1px;
62
+ background: var(--gradient-display-text);
63
+ -webkit-background-clip: text;
64
+ -webkit-text-fill-color: transparent;
65
+ background-clip: text;
66
+ margin: 0;
67
+ }
68
+
69
+ .cta__body {
70
+ color: var(--text-secondary);
71
+ font-size: var(--text-md);
72
+ max-width: 480px;
73
+ text-wrap: balance;
74
+ line-height: 1.7;
75
+ }
76
+
77
+ .cta__body ::slotted(*) { margin: 0; }
78
+
79
+ .cta__actions {
80
+ display: flex;
81
+ gap: var(--space-md);
82
+ margin-top: var(--space-sm);
83
+ }
84
+
85
+ @media (max-width: 768px) {
86
+ .cta { padding: var(--space-xl) var(--space-md); }
87
+ .cta__actions { flex-direction: column; align-items: center; }
88
+ }
89
+ `,
90
+ ];
91
+
92
+ constructor() {
93
+ super();
94
+ this.eyebrow = '';
95
+ this.headline = '';
96
+ this.nogradient = false;
97
+ }
98
+
99
+ render() {
100
+ return html`
101
+ <div class="cta" part="container">
102
+ <div class="cta__bg" part="background"></div>
103
+ <div class="cta__inner" part="inner">
104
+ ${this.eyebrow ? html`
105
+ <span class="cta__eyebrow" part="eyebrow">
106
+ <slot name="eyebrow">${this.eyebrow}</slot>
107
+ </span>
108
+ ` : html`<slot name="eyebrow"></slot>`}
109
+ ${this.headline ? html`
110
+ <h2 class="cta__headline" part="headline">
111
+ <slot name="headline">${this.headline}</slot>
112
+ </h2>
113
+ ` : html`<slot name="headline"></slot>`}
114
+ <div class="cta__body" part="body">
115
+ <slot></slot>
116
+ </div>
117
+ <div class="cta__actions" part="actions">
118
+ <slot name="actions"></slot>
119
+ </div>
120
+ </div>
121
+ </div>
122
+ `;
123
+ }
124
+ }
125
+
126
+ customElements.define('arc-cta-banner', ArcCtaBanner);
@@ -15,6 +15,7 @@ export { ArcCodeBlock } from './code-block.js';
15
15
  export { ArcCollapsible } from './collapsible.js';
16
16
  export { ArcColorSwatch } from './color-swatch.js';
17
17
  export { ArcColumn } from './column.js';
18
+ export { ArcCtaBanner } from './cta-banner.js';
18
19
  export { ArcDataTable } from './data-table.js';
19
20
  export { ArcDivider } from './divider.js';
20
21
  export { ArcEmptyState } from './empty-state.js';
package/src/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // ARC UI — Web Components
2
2
  // Re-exports from all tiers
3
3
 
4
- export { ArcAccordion, ArcAccordionItem, ArcAnimatedNumber, ArcAspectRatio, ArcAvatar, ArcAvatarGroup, ArcBadge, ArcCallout, ArcCard, ArcCarousel, ArcCodeBlock, ArcCollapsible, ArcColorSwatch, ArcColumn, ArcDataTable, ArcDivider, ArcEmptyState, ArcFeatureCard, ArcHighlight, ArcIcon, ArcIconLibrary, iconRegistry, ArcInfiniteScroll, ArcKbd, ArcMarkdown, ArcMarquee, ArcMeter, ArcScrollArea, ArcSkeleton, ArcSpinner, ArcStack, ArcStat, ArcStep, ArcStepper, ArcTable, ArcTag, ArcText, ArcTimeline, ArcTimelineItem, ArcTruncate, ArcValueCard } from './content/index.js';
4
+ export { ArcAccordion, ArcAccordionItem, ArcAnimatedNumber, ArcAspectRatio, ArcAvatar, ArcAvatarGroup, ArcBadge, ArcCallout, ArcCard, ArcCarousel, ArcCodeBlock, ArcCollapsible, ArcColorSwatch, ArcColumn, ArcDataTable, ArcDivider, ArcEmptyState, ArcFeatureCard, ArcHighlight, ArcIcon, ArcIconLibrary, iconRegistry, ArcInfiniteScroll, ArcKbd, ArcMarkdown, ArcMarquee, ArcMeter, ArcScrollArea, ArcSkeleton, ArcSpinner, ArcStack, ArcStat, ArcStep, ArcStepper, ArcTable, ArcTag, ArcText, ArcTimeline, ArcTimelineItem, ArcTruncate, ArcValueCard , ArcCtaBanner } from './content/index.js';
5
5
  export { ArcButton, ArcCalendar, ArcCheckbox, ArcChip, ArcColorPicker, ArcCombobox, ArcCopyButton, ArcDatePicker, ArcFileUpload, ArcForm, ArcIconButton, ArcInput, ArcMultiSelect, ArcNumberInput, ArcOtpInput, ArcPinInput, ArcRadio, ArcRadioGroup, ArcRating, ArcSearch, ArcSegmentedControl, ArcSelect, ArcSlider, ArcSortableList, ArcSuggestion, ArcTextarea, ArcThemeToggle, ArcToggle } from './input/index.js';
6
6
  export { ArcAlert, ArcCommandItem, ArcCommandPalette, ArcContextMenu, ArcDialog, ArcDropdownMenu, ArcHoverCard, ArcModal, ArcNotificationPanel, ArcPopover, ArcProgress, ArcSheet, ArcToast, ArcTooltip } from './feedback/index.js';
7
7
  export { ArcBreadcrumb, ArcBreadcrumbItem, ArcDrawer, ArcFooter, ArcLink, ArcNavItem, ArcNavigationMenu, ArcPagination, ArcScrollSpy, ArcScrollToTop, ArcSidebar, ArcSidebarLink, ArcSidebarSection, ArcSpyLink, ArcTab, ArcTabs, ArcTopBar, ArcTreeItem, ArcTreeView } from './navigation/index.js';
package/src/input/form.js CHANGED
@@ -1,11 +1,15 @@
1
- import { LitElement, html, css } from 'lit';
1
+ import { LitElement, html, css, nothing } from 'lit';
2
2
  import { tokenStyles } from '../shared-styles.js';
3
3
 
4
4
  export class ArcForm extends LitElement {
5
5
  static properties = {
6
- action: { type: String },
7
- method: { type: String },
8
- novalidate: { type: Boolean },
6
+ action: { type: String },
7
+ method: { type: String },
8
+ novalidate: { type: Boolean },
9
+ loading: { type: Boolean, reflect: true },
10
+ disabled: { type: Boolean, reflect: true },
11
+ errorSummary: { type: Boolean, attribute: 'error-summary' },
12
+ _errors: { state: true },
9
13
  };
10
14
 
11
15
  static styles = [
@@ -26,6 +30,45 @@ export class ArcForm extends LitElement {
26
30
  ::slotted(*) {
27
31
  margin: 0;
28
32
  }
33
+
34
+ /* Loading state */
35
+ :host([loading]) .form-layout {
36
+ pointer-events: none;
37
+ opacity: 0.7;
38
+ }
39
+
40
+ /* Disabled state */
41
+ :host([disabled]) .form-layout {
42
+ pointer-events: none;
43
+ opacity: 0.5;
44
+ }
45
+
46
+ /* Error summary */
47
+ .form-errors {
48
+ border: 1px solid var(--color-error, #ef4444);
49
+ border-radius: var(--radius-md);
50
+ background: rgba(239, 68, 68, 0.06);
51
+ padding: var(--space-sm) var(--space-md);
52
+ margin-bottom: var(--space-sm);
53
+ }
54
+
55
+ .form-errors__title {
56
+ font-family: var(--font-accent);
57
+ font-size: var(--text-xs);
58
+ font-weight: 600;
59
+ letter-spacing: 1px;
60
+ text-transform: uppercase;
61
+ color: var(--color-error, #ef4444);
62
+ margin: 0 0 var(--space-xs) 0;
63
+ }
64
+
65
+ .form-errors__list {
66
+ margin: 0;
67
+ padding: 0 0 0 var(--space-md);
68
+ font-size: var(--text-sm);
69
+ color: var(--color-error, #ef4444);
70
+ line-height: 1.6;
71
+ }
29
72
  `,
30
73
  ];
31
74
 
@@ -34,15 +77,18 @@ export class ArcForm extends LitElement {
34
77
  this.action = '';
35
78
  this.method = '';
36
79
  this.novalidate = false;
80
+ this.loading = false;
81
+ this.disabled = false;
82
+ this.errorSummary = true;
83
+ this._errors = [];
37
84
  }
38
85
 
39
- _collectValues() {
86
+ /** Gather all form controls and propagate disabled */
87
+ _getFormControls() {
40
88
  const slot = this.shadowRoot.querySelector('slot');
41
89
  const children = slot ? slot.assignedElements({ flatten: true }) : [];
42
- const values = {};
43
- const errors = [];
90
+ const controls = [];
44
91
 
45
- const formControls = [];
46
92
  const gather = (elements) => {
47
93
  for (const el of elements) {
48
94
  const tag = el.tagName?.toLowerCase();
@@ -54,7 +100,7 @@ export class ArcForm extends LitElement {
54
100
  tag === 'arc-toggle' ||
55
101
  tag === 'arc-radio-group'
56
102
  ) {
57
- formControls.push(el);
103
+ controls.push(el);
58
104
  }
59
105
  if (!el.shadowRoot && el.children?.length) {
60
106
  gather([...el.children]);
@@ -63,15 +109,42 @@ export class ArcForm extends LitElement {
63
109
  };
64
110
 
65
111
  gather(children);
112
+ return controls;
113
+ }
114
+
115
+ updated(changed) {
116
+ super.updated(changed);
117
+
118
+ if (changed.has('disabled')) {
119
+ const controls = this._getFormControls();
120
+ for (const control of controls) {
121
+ if (this.disabled) {
122
+ control.setAttribute('disabled', '');
123
+ } else {
124
+ control.removeAttribute('disabled');
125
+ }
126
+ }
127
+ }
128
+ }
129
+
130
+ _collectValues() {
131
+ const controls = this._getFormControls();
132
+ const values = {};
133
+ const formData = new FormData();
134
+ const errors = [];
66
135
 
67
- for (const control of formControls) {
136
+ for (const control of controls) {
68
137
  const name = control.getAttribute('name') || control.label || control.tagName.toLowerCase();
69
138
  const tag = control.tagName.toLowerCase();
70
139
 
71
140
  if (tag === 'arc-checkbox' || tag === 'arc-toggle') {
72
141
  values[name] = control.checked ?? false;
142
+ if (control.checked) {
143
+ formData.append(name, 'on');
144
+ }
73
145
  } else {
74
146
  values[name] = control.value ?? '';
147
+ formData.append(name, control.value ?? '');
75
148
  }
76
149
 
77
150
  const required = control.hasAttribute('required');
@@ -93,14 +166,20 @@ export class ArcForm extends LitElement {
93
166
  }
94
167
  }
95
168
 
96
- return { values, errors, valid: errors.length === 0 };
169
+ return { values, formData, errors, valid: errors.length === 0 };
97
170
  }
98
171
 
99
172
  _handleSubmit(e) {
100
- const { values, errors, valid } = this._collectValues();
173
+ if (this.loading) {
174
+ e.preventDefault();
175
+ return;
176
+ }
177
+
178
+ const { values, formData, errors, valid } = this._collectValues();
101
179
 
102
180
  if (!valid && !this.novalidate) {
103
181
  e.preventDefault();
182
+ this._errors = errors;
104
183
  this.dispatchEvent(new CustomEvent('arc-invalid', {
105
184
  detail: { errors },
106
185
  bubbles: true,
@@ -109,10 +188,12 @@ export class ArcForm extends LitElement {
109
188
  return;
110
189
  }
111
190
 
191
+ this._errors = [];
192
+
112
193
  // Native form submission — let the browser handle it
113
194
  if (this.action) {
114
195
  this.dispatchEvent(new CustomEvent('arc-submit', {
115
- detail: { values, valid },
196
+ detail: { values, formData, valid },
116
197
  bubbles: true,
117
198
  composed: true,
118
199
  }));
@@ -123,7 +204,7 @@ export class ArcForm extends LitElement {
123
204
  // JS-only mode — prevent default and let the listener handle it
124
205
  e.preventDefault();
125
206
  this.dispatchEvent(new CustomEvent('arc-submit', {
126
- detail: { values, valid },
207
+ detail: { values, formData, valid },
127
208
  bubbles: true,
128
209
  composed: true,
129
210
  }));
@@ -136,27 +217,26 @@ export class ArcForm extends LitElement {
136
217
 
137
218
  /** Reset error states on child controls */
138
219
  reset() {
139
- const slot = this.shadowRoot.querySelector('slot');
140
- const children = slot ? slot.assignedElements({ flatten: true }) : [];
220
+ const controls = this._getFormControls();
141
221
 
142
- const clearErrors = (elements) => {
143
- for (const el of elements) {
144
- if (typeof el.error !== 'undefined') {
145
- el.error = '';
146
- }
147
- if (typeof el.value === 'string') {
148
- el.value = '';
149
- }
150
- if (typeof el.checked === 'boolean') {
151
- el.checked = false;
152
- }
153
- if (!el.shadowRoot && el.children?.length) {
154
- clearErrors([...el.children]);
155
- }
222
+ for (const control of controls) {
223
+ if (typeof control.error !== 'undefined') {
224
+ control.error = '';
156
225
  }
157
- };
226
+ if (typeof control.value === 'string') {
227
+ control.value = '';
228
+ }
229
+ if (typeof control.checked === 'boolean') {
230
+ control.checked = false;
231
+ }
232
+ }
233
+
234
+ this._errors = [];
158
235
 
159
- clearErrors(children);
236
+ this.dispatchEvent(new CustomEvent('arc-reset', {
237
+ bubbles: true,
238
+ composed: true,
239
+ }));
160
240
  }
161
241
 
162
242
  render() {
@@ -169,6 +249,14 @@ export class ArcForm extends LitElement {
169
249
  @submit=${this._handleSubmit}
170
250
  >
171
251
  <div class="form-layout" part="layout">
252
+ ${this.errorSummary && this._errors.length > 0 ? html`
253
+ <div class="form-errors" role="alert" part="errors">
254
+ <p class="form-errors__title">Please fix the following errors</p>
255
+ <ul class="form-errors__list">
256
+ ${this._errors.map(err => html`<li>${err.message}</li>`)}
257
+ </ul>
258
+ </div>
259
+ ` : nothing}
172
260
  <slot></slot>
173
261
  </div>
174
262
  </form>
@@ -5,6 +5,7 @@ export class ArcPageHeader extends LitElement {
5
5
  static properties = {
6
6
  heading: { type: String },
7
7
  description: { type: String },
8
+ border: { type: Boolean, reflect: true },
8
9
  };
9
10
 
10
11
  static styles = [
@@ -17,10 +18,13 @@ export class ArcPageHeader extends LitElement {
17
18
 
18
19
  .page-header {
19
20
  padding: var(--space-lg) 0 var(--space-md);
21
+ }
22
+
23
+ :host([border]) .page-header {
20
24
  border-bottom: 1px solid var(--border-subtle);
21
25
  }
22
26
 
23
- .page-header__breadcrumb {
27
+ .page-header__above {
24
28
  margin-bottom: var(--space-sm);
25
29
  }
26
30
 
@@ -35,13 +39,13 @@ export class ArcPageHeader extends LitElement {
35
39
  .page-header__heading {
36
40
  margin: 0;
37
41
  font-family: var(--font-body);
38
- font-size: 28px; /* size-variant, keep hardcoded */
42
+ font-size: 28px;
39
43
  font-weight: 700;
40
44
  color: var(--text-primary);
41
45
  line-height: 1.2;
42
46
  }
43
47
 
44
- .page-header__actions {
48
+ .page-header__aside {
45
49
  display: flex;
46
50
  align-items: center;
47
51
  gap: var(--space-sm);
@@ -55,7 +59,7 @@ export class ArcPageHeader extends LitElement {
55
59
  line-height: 1.5;
56
60
  }
57
61
 
58
- .page-header__tabs {
62
+ .page-header__below {
59
63
  margin-top: var(--space-md);
60
64
  }
61
65
 
@@ -69,25 +73,26 @@ export class ArcPageHeader extends LitElement {
69
73
  super();
70
74
  this.heading = '';
71
75
  this.description = '';
76
+ this.border = false;
72
77
  }
73
78
 
74
79
  render() {
75
80
  return html`
76
81
  <div class="page-header" part="base">
77
- <div class="page-header__breadcrumb" part="breadcrumb">
78
- <slot name="breadcrumb"></slot>
82
+ <div class="page-header__above" part="above">
83
+ <slot name="above"></slot>
79
84
  </div>
80
85
  <div class="page-header__title-row" part="title-row">
81
86
  <h1 class="page-header__heading" part="heading">${this.heading}</h1>
82
- <div class="page-header__actions" part="actions">
83
- <slot name="actions"></slot>
87
+ <div class="page-header__aside" part="aside">
88
+ <slot name="aside"></slot>
84
89
  </div>
85
90
  </div>
86
91
  ${this.description
87
92
  ? html`<p class="page-header__description" part="description">${this.description}</p>`
88
93
  : ''}
89
- <div class="page-header__tabs" part="tabs">
90
- <slot name="tabs"></slot>
94
+ <div class="page-header__below" part="below">
95
+ <slot name="below"></slot>
91
96
  </div>
92
97
  <div class="page-header__content" part="content">
93
98
  <slot></slot>
@@ -7,6 +7,7 @@ export class ArcNavItem extends LitElement {
7
7
  static properties = {
8
8
  href: { type: String, reflect: true },
9
9
  active: { type: Boolean, reflect: true },
10
+ muted: { type: Boolean, reflect: true },
10
11
  description: { type: String },
11
12
  };
12
13
 
@@ -18,6 +19,7 @@ export class ArcNavItem extends LitElement {
18
19
  super();
19
20
  this.href = '';
20
21
  this.active = false;
22
+ this.muted = false;
21
23
  this.description = '';
22
24
  }
23
25
 
@@ -71,6 +71,18 @@ export class ArcNavigationMenu extends LitElement {
71
71
  box-shadow: inset 0 0 8px rgba(var(--accent-primary-rgb), 0.08), 0 0 12px rgba(var(--accent-primary-rgb), 0.12);
72
72
  }
73
73
 
74
+ .nav__trigger--muted {
75
+ color: var(--text-muted);
76
+ font-weight: 500;
77
+ border-color: transparent;
78
+ }
79
+
80
+ .nav__trigger--muted:hover {
81
+ color: var(--text-secondary);
82
+ background: transparent;
83
+ border-color: transparent;
84
+ }
85
+
74
86
  .nav__trigger:focus-visible {
75
87
  outline: none;
76
88
  box-shadow: var(--focus-glow);
@@ -112,7 +124,6 @@ export class ArcNavigationMenu extends LitElement {
112
124
 
113
125
  .nav__dropdown-item {
114
126
  display: block;
115
- width: 100%;
116
127
  text-align: left;
117
128
  background: none;
118
129
  border: none;
@@ -294,6 +305,15 @@ export class ArcNavigationMenu extends LitElement {
294
305
  background: rgba(var(--accent-primary-rgb), 0.1);
295
306
  }
296
307
 
308
+ .mobile-trigger--muted {
309
+ color: var(--text-muted);
310
+ font-weight: 400;
311
+ }
312
+
313
+ .mobile-trigger--muted:hover {
314
+ color: var(--text-secondary);
315
+ }
316
+
297
317
  .mobile-chevron {
298
318
  width: 12px;
299
319
  height: 12px;
@@ -569,7 +589,7 @@ export class ArcNavigationMenu extends LitElement {
569
589
  >
570
590
  ${hasChildren ? html`
571
591
  <button
572
- class="nav__trigger nav__trigger--has-children ${isOpen ? 'nav__trigger--open' : ''} ${item.active ? 'nav__trigger--active' : ''}"
592
+ class="nav__trigger nav__trigger--has-children ${isOpen ? 'nav__trigger--open' : ''} ${item.active ? 'nav__trigger--active' : ''} ${item.muted ? 'nav__trigger--muted' : ''}"
573
593
  @click=${(e) => this._handleTriggerClick(e, item, i)}
574
594
  aria-expanded=${String(isOpen)}
575
595
  aria-haspopup="true"
@@ -582,7 +602,7 @@ export class ArcNavigationMenu extends LitElement {
582
602
  </button>
583
603
  ` : html`
584
604
  <a
585
- class="nav__trigger ${item.active ? 'nav__trigger--active' : ''}"
605
+ class="nav__trigger ${item.active ? 'nav__trigger--active' : ''} ${item.muted ? 'nav__trigger--muted' : ''}"
586
606
  href=${item.href}
587
607
  @click=${(e) => this._handleTriggerClick(e, item, i)}
588
608
  part="trigger"
@@ -643,7 +663,7 @@ export class ArcNavigationMenu extends LitElement {
643
663
  <li class="mobile-item" style="animation-delay: ${i * 60}ms">
644
664
  ${hasChildren ? html`
645
665
  <button
646
- class="mobile-trigger ${item.active ? 'mobile-trigger--active' : ''}"
666
+ class="mobile-trigger ${item.active ? 'mobile-trigger--active' : ''} ${item.muted ? 'mobile-trigger--muted' : ''}"
647
667
  @click=${() => this._toggleMobileDropdown(i)}
648
668
  aria-expanded=${String(isExpanded)}
649
669
  >
@@ -668,7 +688,7 @@ export class ArcNavigationMenu extends LitElement {
668
688
  </div>
669
689
  ` : html`
670
690
  <a
671
- class="mobile-trigger ${item.active ? 'mobile-trigger--active' : ''}"
691
+ class="mobile-trigger ${item.active ? 'mobile-trigger--active' : ''} ${item.muted ? 'mobile-trigger--muted' : ''}"
672
692
  href=${item.href}
673
693
  @click=${(e) => this._handleMobileTriggerClick(e, item, i)}
674
694
  >