@swiftbrowser/web 0.18.3 → 0.19.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/src/styles.css CHANGED
@@ -67,6 +67,9 @@
67
67
  --sb-color-tertiary-system-background: #ffffff;
68
68
  --sb-color-tertiary-system-grouped-background: #f2f2f7;
69
69
  --sb-color-opaque-separator: #c6c6c8;
70
+ /* The stepper's capsule and the line between its halves. */
71
+ --sb-stepper-fill: var(--sb-color-tertiary-fill);
72
+ --sb-stepper-divider: var(--sb-color-opaque-separator);
70
73
  --sb-color-system-gray2: #aeaeb2;
71
74
  --sb-color-system-gray3: #c7c7cc;
72
75
  --sb-color-system-gray4: #d1d1d6;
@@ -115,7 +118,7 @@
115
118
  --sb-color-segment-selected: #ffffff;
116
119
  /* Menus, floating sheets and alerts are Liquid Glass too: translucent
117
120
  over a heavier backdrop blur, with the glass rim. */
118
- --sb-color-menu-background: rgba(250, 250, 250, 0.82);
121
+ --sb-color-menu-background: rgba(250, 250, 250, 0.97);
119
122
  --sb-sheet-glass: rgba(255, 255, 255, 0.55);
120
123
  }
121
124
 
@@ -141,6 +144,11 @@
141
144
  --sb-color-tertiary-system-background: #2c2c2e;
142
145
  --sb-color-tertiary-system-grouped-background: #2c2c2e;
143
146
  --sb-color-opaque-separator: #38383a;
147
+ /* iOS 26 in dark mode, measured: a fainter capsule than the tertiary fill
148
+ (rgba(120,120,128,.15) reads (18,18,19) over black) and a divider in the
149
+ tertiary label color ((83,83,86) over it). */
150
+ --sb-stepper-fill: rgba(120, 120, 128, 0.15);
151
+ --sb-stepper-divider: rgba(235, 235, 245, 0.3);
144
152
  --sb-color-system-gray2: #636366;
145
153
  --sb-color-system-gray3: #48484a;
146
154
  --sb-color-system-gray4: #3a3a3c;
@@ -177,7 +185,7 @@
177
185
  --sb-color-tabbar-background: rgba(29, 29, 29, 0.94);
178
186
  --sb-color-segment-track: rgba(118, 118, 128, 0.24);
179
187
  --sb-color-segment-selected: #5a5a5f;
180
- --sb-color-menu-background: rgba(37, 37, 37, 0.82);
188
+ --sb-color-menu-background: rgba(44, 44, 46, 0.97);
181
189
  /* The iPhone's dark floating sheet reads 42 over black: dark gray glass. */
182
190
  --sb-sheet-glass: rgba(60, 60, 60, 0.7);
183
191
  }
@@ -417,6 +425,16 @@ html[data-sb-mode="device"] .device {
417
425
  }
418
426
 
419
427
  html[data-sb-mode="device"] .device::before,
428
+ /* `.statusBarHidden` on the screen showing: the drawn status bar fades, as
429
+ iOS fades the real one (the safe area stays, as it does under a notch). */
430
+ .status-bar {
431
+ transition: opacity 0.25s ease;
432
+ }
433
+
434
+ html[data-sb-status-hidden] .status-bar {
435
+ opacity: 0;
436
+ }
437
+
420
438
  html[data-sb-mode="device"] .device::after,
421
439
  html[data-sb-mode="device"] .dynamic-island,
422
440
  html[data-sb-mode="device"] .status-bar,
@@ -585,6 +603,21 @@ html[data-sb-mode="device"] .device-screen {
585
603
  user-select: none;
586
604
  }
587
605
 
606
+ /* Text is not selectable, as on iOS, unless `.textSelection(.enabled)` is
607
+ on it or above it (the renderer marks that box). Fields and editors are
608
+ inputs, selectable as ever. */
609
+ .sb-text {
610
+ user-select: none;
611
+ -webkit-user-select: none;
612
+ }
613
+
614
+ [data-sb-text-selection] .sb-text,
615
+ .sb-text[data-sb-text-selection] {
616
+ user-select: text;
617
+ -webkit-user-select: text;
618
+ -webkit-touch-callout: default;
619
+ }
620
+
588
621
  /* Image(systemName:): a 1em glyph centered in its line-height square; the
589
622
  renderer sets font-size from the resolved font. */
590
623
  .sb-image {
@@ -1010,6 +1043,13 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
1010
1043
  background: transparent;
1011
1044
  }
1012
1045
 
1046
+ /* A card of clear rows alone paints nothing, so it clips nothing either: a
1047
+ search field drawn in such a row (Notes', Reminders', Files') keeps its own
1048
+ corners instead of the card's larger ones cutting them. */
1049
+ .sb-section-rows:not(:has(> [data-sb-id]:not([data-sb-row-background='clear']))) {
1050
+ overflow: visible;
1051
+ }
1052
+
1013
1053
  .sb-list-content > :not(.sb-section):first-child,
1014
1054
  .sb-list-content > .sb-section + :not(.sb-section) {
1015
1055
  border-top-left-radius: 26px;
@@ -1127,6 +1167,12 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
1127
1167
  background: var(--sb-color-grouped-background);
1128
1168
  }
1129
1169
 
1170
+ /* So does a tab with a list as its content: the list is inset from the
1171
+ horizontal safe area (a phone on its side), the tab fills it. */
1172
+ .sb-tab:has(> .sb-list:not([data-sb-background="hidden"])) {
1173
+ background: var(--sb-color-grouped-background);
1174
+ }
1175
+
1130
1176
  /* Screens below the top one slide partially left and are hidden once the
1131
1177
  transition has finished. */
1132
1178
  .sb-navscreen[data-sb-nav-position="below"] {
@@ -1220,6 +1266,19 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
1220
1266
  pointer-events: auto;
1221
1267
  }
1222
1268
 
1269
+ /* `.toolbar(.hidden, for: .navigationBar)`: the bar fades where it was (its
1270
+ items are gone from the layout; the capsules play their exit). */
1271
+ .sb-navbar {
1272
+ transition:
1273
+ opacity 0.25s ease,
1274
+ visibility 0.25s;
1275
+ }
1276
+
1277
+ .sb-navscreen[data-sb-bar-hidden] > .sb-navbar {
1278
+ opacity: 0;
1279
+ visibility: hidden;
1280
+ }
1281
+
1223
1282
  .sb-navbar-trailing:empty {
1224
1283
  pointer-events: none;
1225
1284
  }
@@ -1810,24 +1869,26 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
1810
1869
  background: var(--sb-color-system-background);
1811
1870
  }
1812
1871
 
1813
- /* `sidebar` (iPadOS; a NavigationSplitView's sidebar list): the rows sit on
1814
- the list's background, without cards or hairlines, and only a selected
1815
- row is filled (its rounded fill, below). The engine lays it out like
1816
- `insetGrouped` with 44pt rows. */
1817
- .sb-list[data-sb-list-style="sidebar"] .sb-section-rows,
1818
- .sb-list[data-sb-list-style="sidebar"] .sb-section-rows > [data-sb-id],
1819
- .sb-list[data-sb-list-style="sidebar"] .sb-section-rows > [data-sb-ghost],
1820
- .sb-list[data-sb-list-style="sidebar"] > .sb-list-content > :not(.sb-section) {
1872
+ /* `sidebar` (iPadOS; a NavigationSplitView's sidebar list) in a regular
1873
+ width (layoutDom's `data-sb-list-look`): the rows sit on the list's
1874
+ background, without cards or hairlines, and only a selected row is filled
1875
+ (its rounded fill, below). The engine lays it out like `insetGrouped` with
1876
+ 44pt rows. In a compact width the list looks like `insetGrouped`; its
1877
+ sections still fold (above). */
1878
+ .sb-list[data-sb-list-look="sidebar"] .sb-section-rows,
1879
+ .sb-list[data-sb-list-look="sidebar"] .sb-section-rows > [data-sb-id],
1880
+ .sb-list[data-sb-list-look="sidebar"] .sb-section-rows > [data-sb-ghost],
1881
+ .sb-list[data-sb-list-look="sidebar"] > .sb-list-content > :not(.sb-section) {
1821
1882
  background: transparent;
1822
1883
  border-radius: 0;
1823
1884
  }
1824
1885
 
1825
- .sb-list[data-sb-list-style="sidebar"] .sb-section-rows > *::after,
1826
- .sb-list[data-sb-list-style="sidebar"] > .sb-list-content > :not(.sb-section)::after {
1886
+ .sb-list[data-sb-list-look="sidebar"] .sb-section-rows > *::after,
1887
+ .sb-list[data-sb-list-look="sidebar"] > .sb-list-content > :not(.sb-section)::after {
1827
1888
  display: none;
1828
1889
  }
1829
1890
 
1830
- .sb-list[data-sb-list-style="sidebar"] :is(.sb-section-rows, .sb-list-content) > :is(input, textarea) {
1891
+ .sb-list[data-sb-list-look="sidebar"] :is(.sb-section-rows, .sb-list-content) > :is(input, textarea) {
1831
1892
  background-image: none;
1832
1893
  }
1833
1894
 
@@ -2118,13 +2179,17 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
2118
2179
  stroke-width: 2.5;
2119
2180
  }
2120
2181
 
2121
- /* The option menu: anchored under (or above) the control by the renderer.
2182
+ /* The option menu, as iOS 26 draws one: an inset panel (10px above and
2183
+ below the rows, 12px beside them) with large rounded corners, anchored
2184
+ under (or above) the control by the renderer, over a toolbar button.
2122
2185
  Closed, it fades out where it was (`.sb-picker-menu-exit`) and leaves. */
2123
2186
  .sb-picker-menu,
2124
2187
  .sb-picker-menu-exit {
2125
2188
  position: absolute;
2126
2189
  z-index: 6;
2127
- border-radius: 13px;
2190
+ box-sizing: border-box;
2191
+ padding: 10px 12px;
2192
+ border-radius: 26px;
2128
2193
  background: var(--sb-color-menu-background);
2129
2194
  backdrop-filter: blur(40px) saturate(180%);
2130
2195
  -webkit-backdrop-filter: blur(40px) saturate(180%);
@@ -2154,12 +2219,13 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
2154
2219
  appearance: none;
2155
2220
  display: flex;
2156
2221
  align-items: center;
2157
- gap: 8px;
2222
+ gap: 13px;
2158
2223
  width: 100%;
2159
2224
  height: 44px;
2160
2225
  margin: 0;
2161
2226
  padding: 0 16px;
2162
2227
  border: 0;
2228
+ border-radius: 14px;
2163
2229
  background: none;
2164
2230
  color: var(--sb-color-primary);
2165
2231
  font: 400 var(--sb-font-size-body) / 1.3 var(--sb-font-family);
@@ -2169,19 +2235,19 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
2169
2235
  -webkit-tap-highlight-color: transparent;
2170
2236
  }
2171
2237
 
2172
- :is(.sb-picker-menu-item, .sb-picker-menu-static) + :is(.sb-picker-menu-item, .sb-picker-menu-static) {
2173
- box-shadow: inset 0 1px 0 var(--sb-color-separator);
2174
- }
2175
-
2176
2238
  .sb-picker-menu-item:active {
2177
2239
  background: var(--sb-color-fill);
2178
2240
  }
2179
2241
 
2242
+ /* The checkmark's column (iOS 26): in a menu with checkable rows every item
2243
+ keeps it, empty unless checked, so titles and symbols line up; it sits
2244
+ closer to what follows than a symbol does. */
2180
2245
  .sb-picker-menu-check {
2181
2246
  display: inline-flex;
2182
2247
  align-items: center;
2183
2248
  justify-content: center;
2184
- width: 20px;
2249
+ width: 16px;
2250
+ margin-right: -4px;
2185
2251
  flex-shrink: 0;
2186
2252
  visibility: hidden;
2187
2253
  }
@@ -2191,8 +2257,8 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
2191
2257
  }
2192
2258
 
2193
2259
  .sb-picker-menu-check > svg {
2194
- width: 1em;
2195
- height: 1em;
2260
+ width: 0.95em;
2261
+ height: 0.95em;
2196
2262
  stroke: currentColor;
2197
2263
  stroke-width: 2.5;
2198
2264
  }
@@ -2204,6 +2270,47 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
2204
2270
  white-space: nowrap;
2205
2271
  }
2206
2272
 
2273
+ /* A menu with a check column (iOS 26): the check sits 24px in from the
2274
+ panel's edge, plain titles and section titles start together after it, and
2275
+ a symbol's column starts a little past them, its title further in. */
2276
+ .sb-picker-menu[data-sb-checks] .sb-picker-menu-item {
2277
+ padding-left: 12px;
2278
+ }
2279
+
2280
+ .sb-picker-menu[data-sb-checks] .sb-picker-menu-check {
2281
+ margin-right: -5px;
2282
+ }
2283
+
2284
+ .sb-picker-menu[data-sb-checks] .sb-picker-menu-symbol {
2285
+ width: 28px;
2286
+ margin: 0 4px 0 2px;
2287
+ }
2288
+
2289
+ .sb-picker-menu[data-sb-checks] .sb-picker-menu-caption {
2290
+ padding-left: 36px;
2291
+ }
2292
+
2293
+ /* A title with a subtitle under it, in a taller row. */
2294
+ .sb-picker-menu-item[data-sb-subtitled] {
2295
+ height: 58px;
2296
+ }
2297
+
2298
+ .sb-picker-menu-titles {
2299
+ display: flex;
2300
+ flex: 1 1 auto;
2301
+ flex-direction: column;
2302
+ min-width: 0;
2303
+ }
2304
+
2305
+ .sb-picker-menu-subtitle {
2306
+ overflow: hidden;
2307
+ color: var(--sb-color-secondary);
2308
+ font-size: 15px;
2309
+ line-height: 20px;
2310
+ text-overflow: ellipsis;
2311
+ white-space: nowrap;
2312
+ }
2313
+
2207
2314
  @keyframes sb-menu-in {
2208
2315
  from {
2209
2316
  opacity: 0;
@@ -2342,15 +2449,15 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
2342
2449
  border-radius: 6px;
2343
2450
  }
2344
2451
 
2345
- /* Popover rows for menu items: a tap row shows its symbol trailing; a
2346
- destructive role is red; a disabled item dims; section headers are 32px
2347
- captions; `text` items are static 44px rows; groups are split by 8px bands. */
2452
+ /* Popover rows for menu items (iOS 26): a tap row's symbol leads its title;
2453
+ a destructive role is red; a disabled item dims; section headers are 30px
2454
+ captions; `text` items are static 44px rows; groups are split by a hairline
2455
+ with 9px above and below, inset from the panel's edges. No lines between items. */
2348
2456
  .sb-picker-menu-symbol {
2349
2457
  display: inline-flex;
2350
2458
  align-items: center;
2351
2459
  justify-content: center;
2352
- width: 22px;
2353
- margin-left: auto;
2460
+ width: 24px;
2354
2461
  flex-shrink: 0;
2355
2462
  }
2356
2463
 
@@ -2372,10 +2479,10 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
2372
2479
  .sb-picker-menu-caption {
2373
2480
  display: flex;
2374
2481
  align-items: center;
2375
- height: 32px;
2482
+ height: 30px;
2376
2483
  padding: 0 16px;
2377
2484
  color: var(--sb-color-secondary);
2378
- font: 400 13px/16px var(--sb-font-family);
2485
+ font: 400 15px/20px var(--sb-font-family);
2379
2486
  white-space: nowrap;
2380
2487
  overflow: hidden;
2381
2488
  text-overflow: ellipsis;
@@ -2394,8 +2501,9 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
2394
2501
  }
2395
2502
 
2396
2503
  .sb-picker-menu-separator {
2397
- height: 8px;
2398
- background: var(--sb-color-fill);
2504
+ height: 1px;
2505
+ margin: 9px 12px;
2506
+ background: var(--sb-color-separator);
2399
2507
  }
2400
2508
 
2401
2509
  /* Inline picker: a dim label row (when the label is non-empty) and 44px
@@ -3656,7 +3764,8 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
3656
3764
  .sb-alert-layer > [hidden],
3657
3765
  .sb-datepicker > [hidden],
3658
3766
  .sb-stepper > [hidden],
3659
- .sb-slider > [hidden] {
3767
+ .sb-slider > [hidden],
3768
+ .sb-slider-labels > [hidden] {
3660
3769
  display: none;
3661
3770
  }
3662
3771
 
@@ -3897,7 +4006,7 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
3897
4006
  display: flex;
3898
4007
  box-sizing: border-box;
3899
4008
  border-radius: 16px;
3900
- background: var(--sb-color-tertiary-fill);
4009
+ background: var(--sb-stepper-fill);
3901
4010
  overflow: hidden;
3902
4011
  }
3903
4012
 
@@ -3930,7 +4039,7 @@ svg[data-sb-symbol="progress.indicator"] > line:nth-child(8) { animation-delay:
3930
4039
  top: 7px;
3931
4040
  bottom: 7px;
3932
4041
  width: 1px;
3933
- background: var(--sb-color-opaque-separator);
4042
+ background: var(--sb-stepper-divider);
3934
4043
  }
3935
4044
 
3936
4045
  .sb-stepper-button > svg {
@@ -4213,3 +4322,66 @@ svg.sb-path {
4213
4322
  .sb-styled[data-sb-hover] {
4214
4323
  pointer-events: auto;
4215
4324
  }
4325
+
4326
+ /* ---------------------------------------------------------------------------
4327
+ `disclosuregroup`: the label (the first child) with a chevron at its
4328
+ trailing edge that turns down as the content opens below it; a button
4329
+ over the label takes the tap (layoutDom places both from the label's
4330
+ frame). `section` headers of `Section(isExpanded:)` get the chevron too,
4331
+ in a sidebar-style list, where the section collapses as on iOS.
4332
+ --------------------------------------------------------------------------- */
4333
+ .sb-disclosure-toggle {
4334
+ position: absolute;
4335
+ margin: 0;
4336
+ padding: 0;
4337
+ border: 0;
4338
+ background: transparent;
4339
+ cursor: pointer;
4340
+ -webkit-tap-highlight-color: transparent;
4341
+ }
4342
+
4343
+ .sb-disclosure-chevron {
4344
+ position: absolute;
4345
+ stroke-width: 2.5;
4346
+ color: var(--sb-color-accent);
4347
+ pointer-events: none;
4348
+ transition: transform 0.25s ease-in-out;
4349
+ }
4350
+
4351
+ .sb-disclosuregroup[data-sb-expanded] > .sb-disclosure-chevron {
4352
+ transform: rotate(90deg);
4353
+ }
4354
+
4355
+ /* Collapsed: the content (a disclosure group's, a sidebar section's rows) is hidden by the engine, without a frame. */
4356
+ .sb-disclosuregroup > .sb-slot > [data-sb-id][hidden],
4357
+ .sb-disclosuregroup > .sb-slot > [data-sb-ghost][hidden],
4358
+ .sb-section[data-sb-collapsible] .sb-section-rows > [data-sb-id][hidden],
4359
+ .sb-section[data-sb-collapsible] .sb-section-rows > [data-sb-ghost][hidden] {
4360
+ display: none;
4361
+ }
4362
+
4363
+ .sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible] > .sb-section-header,
4364
+ .sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible] .sb-sectionheader {
4365
+ cursor: pointer;
4366
+ }
4367
+
4368
+ .sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible] > .sb-section-header::after,
4369
+ .sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible] .sb-sectionheader::after {
4370
+ /* Centered 10 in from the content's trailing edge, over the rows' own chevrons (the engine's 20pt chevron box). */
4371
+ content: '';
4372
+ position: absolute;
4373
+ right: 6.5px;
4374
+ top: 50%;
4375
+ width: 7px;
4376
+ height: 7px;
4377
+ margin-top: -5px;
4378
+ border-right: 2px solid var(--sb-color-accent);
4379
+ border-bottom: 2px solid var(--sb-color-accent);
4380
+ transform: rotate(-45deg);
4381
+ transition: transform 0.25s ease-in-out;
4382
+ }
4383
+
4384
+ .sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible][data-sb-expanded] > .sb-section-header::after,
4385
+ .sb-list[data-sb-list-style='sidebar'] .sb-section[data-sb-collapsible][data-sb-expanded] .sb-sectionheader::after {
4386
+ transform: rotate(45deg);
4387
+ }
package/src/styles.ts CHANGED
@@ -147,13 +147,6 @@ const HIERARCHICAL_TEXT: Record<1 | 2 | 3 | 4, string> = {
147
147
  * colors' ratio has it).
148
148
  */
149
149
  export const HIERARCHY_OPACITY: Record<1 | 2 | 3 | 4, number> = { 1: 1, 2: 0.5, 3: 0.25, 4: 0.18 };
150
- const HIERARCHICAL_PAINT: Record<1 | 2 | 3 | 4, string> = {
151
- 1: 'var(--sb-color-fill)',
152
- 2: 'var(--sb-color-secondary-fill)',
153
- 3: 'var(--sb-color-tertiary-fill)',
154
- 4: 'var(--sb-color-quaternary-fill)',
155
- };
156
-
157
150
  /** Opacity of the system background each material shows over the blurred backdrop. */
158
151
  export const MATERIAL_ALPHA: Record<Exclude<MaterialName, 'glass' | 'glassClear'>, number> = {
159
152
  ultraThin: 0.55,
@@ -178,7 +171,7 @@ export function materialAlpha(name: MaterialName): number {
178
171
  * stand out. A non-color style's top-level `opacity` multiplies the result
179
172
  * (each stop of a gradient, the material's alpha) like a semantic color's `a`.
180
173
  */
181
- export function styleToCSS(style: ShapeStyle, role: PaintRole): PaintCSS {
174
+ export function styleToCSS(style: ShapeStyle, _role: PaintRole): PaintCSS {
182
175
  if (isColor(style)) {
183
176
  const value = colorToCSS(style);
184
177
  return { kind: 'color', value, solid: value };
@@ -186,7 +179,9 @@ export function styleToCSS(style: ShapeStyle, role: PaintRole): PaintCSS {
186
179
  const opacity = style.opacity;
187
180
  if (isHierarchicalStyle(style)) {
188
181
  const level = hierarchicalLevel(style.hierarchical);
189
- const value = withOpacity(role === 'text' ? HIERARCHICAL_TEXT[level] : HIERARCHICAL_PAINT[level], opacity);
182
+ // The levels of the foreground, as SwiftUI paints them in any role: a
183
+ // shape filled or stroked with `.primary` is the label color, not a fill gray.
184
+ const value = withOpacity(HIERARCHICAL_TEXT[level], opacity);
190
185
  return { kind: 'color', value, solid: value };
191
186
  }
192
187
  if (isLinearGradientStyle(style)) {
package/src/symbols.ts CHANGED
@@ -294,6 +294,7 @@ import {
294
294
  Puzzle,
295
295
  QrCode,
296
296
  Rabbit,
297
+ Rainbow,
297
298
  Radio,
298
299
  RectangleHorizontal,
299
300
  RectangleVertical,
@@ -748,6 +749,9 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
748
749
  bolt: outline(Zap),
749
750
  'bolt.fill': solid(Zap),
750
751
  sparkles: outline(Sparkles),
752
+ // Apple Intelligence's mark: the sparkles stand in for it.
753
+ 'apple.intelligence': outline(Sparkles),
754
+ rainbow: outline(Rainbow),
751
755
 
752
756
  // Chevrons and arrows
753
757
  'chevron.left': outline(ChevronLeft),
@@ -773,6 +777,7 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
773
777
  'arrow.left.circle': outline(CircleArrowLeft),
774
778
  'arrow.right.circle': outline(CircleArrowRight),
775
779
  'arrow.up.circle': outline(CircleArrowUp),
780
+ 'arrow.up.circle.fill': knockout(CircleArrowUp),
776
781
  'arrow.down.circle': outline(CircleArrowDown),
777
782
  'arrow.down.to.line': outline(ArrowDownToLine),
778
783
  'arrow.up.to.line': outline(ArrowUpFromLine),
@@ -898,6 +903,7 @@ export const SF_SYMBOLS: Readonly<Record<string, SymbolGlyph>> = {
898
903
  'pause.circle': outline(CirclePause),
899
904
  'pause.circle.fill': knockout(CirclePause),
900
905
  'stop.circle': outline(CircleStop),
906
+ 'stop.circle.fill': knockout(CircleStop),
901
907
  pause: outline(Pause),
902
908
  'pause.fill': solid(Pause),
903
909
  stop: outline(Square),