@rdlabo/ionic-theme-ios27 0.2.1 → 1.0.1-beta.pr194.sha00da872ba249

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 (34) hide show
  1. package/README.md +134 -122
  2. package/dist/css/components/ion-segment.css +1 -1
  3. package/dist/css/components/ion-toolbar.css +1 -1
  4. package/dist/css/ionic-theme-ios27-dark-always.css +1 -1
  5. package/dist/css/ionic-theme-ios27-dark-class.css +1 -1
  6. package/dist/css/ionic-theme-ios27-dark-system.css +1 -1
  7. package/dist/css/ionic-theme-ios27.css +1 -1
  8. package/dist/css/utils/structured-list.css +1 -0
  9. package/dist/native/components/searchable-tabs.d.ts +2 -0
  10. package/dist/native/components/searchable-tabs.d.ts.map +1 -1
  11. package/dist/native/components/searchable-tabs.js +131 -21
  12. package/dist/native/runtime.d.ts.map +1 -1
  13. package/dist/native/runtime.js +14 -7
  14. package/docs/migration.md +105 -3
  15. package/docs/native-ui-shell.md +15 -3
  16. package/docs/special-markup.md +9 -0
  17. package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellSearchController.swift +243 -64
  18. package/ios/Sources/IonicNativeUIShellPlugin/Components/ShellTabBar.swift +77 -6
  19. package/ios/Sources/IonicNativeUIShellPlugin/IonicNativeUIShellPlugin.swift +79 -12
  20. package/ios/Tests/IonicNativeUIShellPluginTests/ShellSnapshotTests.swift +258 -2
  21. package/node_modules/@rdlabo/ionic-theme-utils/package.json +4 -0
  22. package/node_modules/@rdlabo/ionic-theme-utils/scripts/copy-structured-list.mjs +17 -0
  23. package/package.json +4 -3
  24. package/src/native/components/searchable-tabs.ts +142 -22
  25. package/src/native/runtime.ts +11 -6
  26. package/src/styles/components/ion-list.scss +1 -1
  27. package/src/styles/components/ion-segment.scss +19 -0
  28. package/src/styles/components/ion-toolbar.scss +11 -0
  29. package/src/styles/md-ion-list-inset.scss +1 -1
  30. package/src/styles/utils/dark/ion-list.scss +1 -1
  31. package/src/styles/utils/dark/ion-segment.scss +20 -0
  32. package/src/styles/utils/structured-list.scss +310 -0
  33. package/docs/ios-adaptive.md +0 -90
  34. /package/docs/{experimental-animation.md → animation.md} +0 -0
package/README.md CHANGED
@@ -1,13 +1,8 @@
1
1
  # Ionic Theme iOS27
2
2
 
3
- A CSS/JS theme library that brings the iOS 27 Liquid Glass appearance and navigation animations to Ionic applications while preserving Ionic components and conventions.
3
+ A theme for Ionic apps that brings iOS 27 Liquid Glass and motion to the Web. Capacitor iOS apps can also opt into an experimental Native UI Shell for supported controls.
4
4
 
5
- > [!IMPORTANT]
6
- > This `main` branch contains the iOS 27 theme under the package name `@rdlabo/ionic-theme-ios27`. For the iOS 26 theme (`@rdlabo/ionic-theme-ios26`), see the [`ios26` branch](https://github.com/rdlabo-dev/ionic-theme-ios27/tree/ios26).
7
-
8
- > All versions before 1.0.0 are release candidates (RC). APIs, CSS variables, classes, styling, and behavior may change without backward compatibility, including in minor and patch releases. A stable compatibility commitment starts with 1.0.0.
9
-
10
- [Try the iOS 27 demo](https://ionic-theme-ios27.rdlabo.dev/).
5
+ **[Ionic 9 demo](https://ionic-theme-ios27.rdlabo.dev/) · [Ionic 8 demo](https://ionic8-theme-ios27.rdlabo.dev/) · [Documentation](https://docs.rdlabo.dev/projects/ionic-theme-ios27)**
11
6
 
12
7
  <!-- rdlabo-docs-pick -->
13
8
 
@@ -19,80 +14,89 @@ A CSS/JS theme library that brings the iOS 27 Liquid Glass appearance and naviga
19
14
 
20
15
  <!-- /rdlabo-docs-pick -->
21
16
 
22
- ## Installation
17
+ ## Features
18
+
19
+ ### Bring the iOS 27 look to Ionic
20
+
21
+ Give familiar Ionic screens the iOS 27 visual language: Liquid Glass, styled toolbars and tabs, lists, buttons, search, overlays, page transitions, and coordinated light and dark appearances. See the result in the [Ionic 9 demo](https://ionic-theme-ios27.rdlabo.dev/) and [Ionic 8 demo](https://ionic8-theme-ios27.rdlabo.dev/).
22
+
23
+ ### Project your Ionic UI into Native UI
24
+
25
+ On Capacitor iOS, the optional, experimental [Native UI Shell](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/native-ui-shell) reads supported fixed controls from your existing Ionic markup. It projects their text, resolved `ion-icon` artwork or supported static SVGs, and selection state into UIKit controls with system Liquid Glass. Changes and native actions flow through the original Ionic components, so the Web and native presentations share one UI definition. Page content and routing stay in the WebView; unsupported layouts keep their Web presentation.
23
26
 
24
- Capacitor apps can optionally use an experimental [Native UI Shell](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/native-ui-shell): fixed Ionic navigation and action controls rendered by UIKit with system Liquid Glass, while page content, application logic and routing remain in the WebView. The guide covers the idea's origins, the one-time startup call, supported components and fallback behavior.
27
+ **Tab drag on iOS 27:** The same Library screen with Native UI Shell off (Web) and on (UIKit). Both frames were captured while dragging the selected tab; the lower panels enlarge the glass around the tab bar.
25
28
 
26
- Requires `@ionic/core` 8.8.1 or later (Ionic 8 and 9). Install it in an existing Ionic project:
29
+ [![Native UI Shell off and on during the same Library tab drag, with enlarged tab bars](./screenshots/native-ui-shell-drag/comparison.png)](./screenshots/native-ui-shell-drag/comparison.png)
30
+
31
+ ### Follow the user's device
32
+
33
+ Pair the iOS 26 and iOS 27 themes so supported Safari versions can present the design of each generation: the iOS 26 look for iOS 26 users and the iOS 27 look for iOS 27 users. The [default setup](https://docs.rdlabo.dev/projects/ionic-theme-ios27#get-started) uses browser feature checks to select the corresponding **styles**; it does not read the iOS version. When both packages are installed, keep the **page transition** on the iOS 27 animation. On even earlier iOS versions, Ionic's default iOS appearance remains when Safari supports neither feature. In a Capacitor iOS app, Native UI Shell's UIKit material follows the installed iOS version.
34
+
35
+ ## Get started
36
+
37
+ Install both themes in an existing Ionic 8 or 9 app (`@ionic/core` 8.8.1 or later):
27
38
 
28
39
  ```bash
29
- npm install @rdlabo/ionic-theme-ios27
40
+ npm install @rdlabo/ionic-theme-ios26 @rdlabo/ionic-theme-ios27
30
41
  ```
31
42
 
32
- And import the theme in your project's main CSS file (e.g., `src/styles.scss`).
43
+ In your global Sass stylesheet (for example, `src/styles.scss`), load the styles by browser capability:
33
44
 
34
- ```css
35
- @import '@rdlabo/ionic-theme-ios27/dist/css/default-variables.css';
36
- @import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27.css';
45
+ ```scss
46
+ @use 'sass:meta';
47
+
48
+ @supports (overflow-anchor: auto) {
49
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/default-variables');
50
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27');
51
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27-dark-class');
52
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/md-remove-ios-class-effect');
53
+ }
54
+
55
+ @supports (text-wrap: pretty) and (not (overflow-anchor: auto)) {
56
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/default-variables');
57
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26');
58
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26-dark-class');
59
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/md-remove-ios-class-effect');
60
+ }
61
+ ```
37
62
 
38
- /**
39
- * Keep Material Design mode unaffected by the iOS theme
40
- * when the same markup is used in both modes.
41
- * Note: This stylesheet is not included in `@rdlabo/ionic-theme-md3`.
42
- */
43
- @import '@rdlabo/ionic-theme-ios27/dist/css/md-remove-ios-class-effect.css';
63
+ If compilation reports `Can't find stylesheet to import.` for a `meta.load-css()` call, make `node_modules` available to Sass. In Angular, add this under the app's build `options` in `angular.json`:
44
64
 
45
- /**
46
- * If you will use the design of ion-item-group with ion-list on Android as well, import it.
47
- * More info: https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/using-ion-item-group
48
- * Note: This stylesheet is included in `@rdlabo/ionic-theme-md3`.
49
- * @import '@rdlabo/ionic-theme-ios27/dist/css/md-ion-list-inset.css';
50
- */
51
-
52
- /*
53
- * Support Dark Mode
54
- * We support Ionic Dark Mode. More information is here: https://ionicframework.com/docs/theming/dark-mode
55
- * use Always: @import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27-dark-always.css'
56
- * use System: @import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27-dark-system.css'
57
- * use CSS Class: @import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27-dark-class.css'
58
- */
65
+ ```json
66
+ "stylePreprocessorOptions": {
67
+ "includePaths": ["node_modules"]
68
+ }
59
69
  ```
60
70
 
71
+ Alternatively, use a relative path from the Sass file containing `meta.load-css()` to the installed package, such as `../node_modules/@rdlabo/ionic-theme-ios27/src/styles/default-variables` from `src/styles.scss`. Adjust the `../` prefix for your file's location, and apply the same change to each theme import.
72
+
73
+ These checks select styles by browser features, not by iOS version. Browsers without either feature retain Ionic's default iOS appearance. The example uses class-based dark mode: also load [Ionic's matching dark palette](https://ionicframework.com/docs/theming/dark-mode). For system or always-dark mode, replace both `-dark-class` imports with the matching variant. The `md-remove-ios-class-effect` styles prevent iOS-specific classes from affecting Material Design mode.
74
+
61
75
  ### Configure animations
62
76
 
63
- If you installed only the iOS 27 theme, configure its animations as follows.
77
+ Keep the iOS 27 page transition and popover animations for both styled generations. Resolve these options before Ionic initializes. For Angular:
64
78
 
65
79
  ```ts
66
- import { isPlatform } from '@ionic/core'; // or @ionic/angular (Ionic 9), @ionic/angular/standalone (Ionic 8), @ionic/react, @ionic/vue
80
+ import { isPlatform, provideIonicAngular } from '@ionic/angular/standalone'; // Ionic 8
67
81
  import { iosTransitionAnimation, popoverEnterAnimation, popoverLeaveAnimation } from '@rdlabo/ionic-theme-ios27';
68
82
 
69
- // Angular
70
- provideIonicAngular({
71
- ...
72
- navAnimation: isPlatform('ios') ? iosTransitionAnimation: undefined,
73
- popoverEnter: isPlatform('ios') ? popoverEnterAnimation: undefined,
74
- popoverLeave: isPlatform('ios') ? popoverLeaveAnimation: undefined,
75
- });
76
-
77
- // React
78
- setupIonicReact({
79
- ...
80
- navAnimation: isPlatform('ios') ? iosTransitionAnimation: undefined,
81
- popoverEnter: isPlatform('ios') ? popoverEnterAnimation: undefined,
82
- popoverLeave: isPlatform('ios') ? popoverLeaveAnimation: undefined,
83
- });
84
-
85
- // Vue
86
- createApp(App)
87
- .use(IonicVue, {
88
- ...
89
- navAnimation: isPlatform('ios') ? iosTransitionAnimation: undefined,
90
- popoverEnter: isPlatform('ios') ? popoverEnterAnimation: undefined,
91
- popoverLeave: isPlatform('ios') ? popoverLeaveAnimation: undefined,
92
- })
83
+ function loadIOSAnimations() {
84
+ if (typeof CSS === 'undefined') return {};
85
+ if (!CSS.supports('overflow-anchor: auto') && !CSS.supports('text-wrap: pretty')) return {};
86
+
87
+ return {
88
+ navAnimation: iosTransitionAnimation,
89
+ popoverEnter: popoverEnterAnimation,
90
+ popoverLeave: popoverLeaveAnimation,
91
+ };
92
+ }
93
+
94
+ provideIonicAngular(isPlatform('ios') ? loadIOSAnimations() : {});
93
95
  ```
94
96
 
95
- The page-transition radius defaults to `0`. Native apps can update it after measuring the web view:
97
+ For Ionic 9 Angular, import `isPlatform` and `provideIonicAngular` from `@ionic/angular`. React and Vue can pass the same options to `setupIonicReact` or `IonicVue` during initialization. In server-rendered apps, run the selection during browser initialization.
98
+
99
+ The page-transition radius defaults to `0`. Native apps can update it after measuring the WebView:
96
100
 
97
101
  ```ts
98
102
  import { setConfig } from '@rdlabo/ionic-theme-ios27';
@@ -115,79 +119,101 @@ Use this markup to preview the inset grouped list look. For the list structure t
115
119
  </ion-list>
116
120
  ```
117
121
 
118
- ### Optional: use the iOS 27 and MD3 themes together
122
+ ## Optional setups
119
123
 
120
- Install the MD3 theme to style both Ionic modes from the same application.
124
+ ### Use only the iOS 27 theme
121
125
 
122
- The current releases of both themes require `@ionic/core` 8.8.1 or later.
126
+ Install only `@rdlabo/ionic-theme-ios27` and import its styles unconditionally in your global stylesheet:
127
+
128
+ ```css
129
+ @import '@rdlabo/ionic-theme-ios27/dist/css/default-variables.css';
130
+ @import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27.css';
131
+ @import '@rdlabo/ionic-theme-ios27/dist/css/md-remove-ios-class-effect.css';
132
+ @import '@rdlabo/ionic-theme-ios27/dist/css/ionic-theme-ios27-dark-class.css';
133
+ ```
134
+
135
+ The last import uses class-based dark mode; choose the `-dark-system` or `-dark-always` variant and matching Ionic palette for another mode. Configure the iOS 27 animations with `isPlatform('ios')` as above, without the browser feature checks.
136
+
137
+ ### Other options
138
+
139
+ - **Native controls:** Follow the [Native UI Shell setup guide](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/native-ui-shell). Stylesheet imports alone do not enable it.
140
+ - **Inset lists on Android:** Load the matching package's `md-ion-list-inset` stylesheet inside each `@supports` branch if needed. It is already included in `@rdlabo/ionic-theme-md3`.
141
+
142
+ ### Use with the MD3 theme
143
+
144
+ Install all three themes to use iOS 27 on supported Safari versions, fall back to iOS 26 on the preceding Safari generation, and use MD3 whenever Ionic runs in Material Design mode. All three themes require `@ionic/core` 8.8.1 or later:
123
145
 
124
146
  ```bash
125
- npm install @rdlabo/ionic-theme-md3
147
+ npm install @rdlabo/ionic-theme-ios26 @rdlabo/ionic-theme-ios27 @rdlabo/ionic-theme-md3
126
148
  ```
127
149
 
128
- When your global stylesheet uses Sass, initialize the themes in this order:
150
+ Keep the two iOS themes behind the same browser feature checks used by the default setup, then load MD3 unconditionally. Using `meta.load-css()` throughout also keeps the MD3 styles after the conditional iOS styles in the generated CSS:
129
151
 
130
152
  ```scss
131
- @use '@rdlabo/ionic-theme-ios27/src/styles/default-variables.scss' as ios27-vars;
132
- @use '@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27.scss';
133
- @use '@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27-dark-class.scss';
134
- @use '@rdlabo/ionic-theme-ios27/src/styles/md-remove-ios-class-effect.scss';
135
- @use '@rdlabo/ionic-theme-md3/dist/css/default-variables.css' as md3-vars;
136
- @use '@rdlabo/ionic-theme-md3/dist/css/ionic-theme-md3.css';
153
+ @use 'sass:meta';
154
+
155
+ @supports (overflow-anchor: auto) {
156
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/default-variables');
157
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27');
158
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/ionic-theme-ios27-dark-class');
159
+ @include meta.load-css('@rdlabo/ionic-theme-ios27/src/styles/md-remove-ios-class-effect');
160
+ }
161
+
162
+ @supports (text-wrap: pretty) and (not (overflow-anchor: auto)) {
163
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/default-variables');
164
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26');
165
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/ionic-theme-ios26-dark-class');
166
+ @include meta.load-css('@rdlabo/ionic-theme-ios26/src/styles/md-remove-ios-class-effect');
167
+ }
168
+
169
+ @include meta.load-css('@rdlabo/ionic-theme-md3/dist/css/default-variables.css');
170
+ @include meta.load-css('@rdlabo/ionic-theme-md3/dist/css/ionic-theme-md3.css');
137
171
  ```
138
172
 
139
- The example uses Ionic's class-based dark mode. Your global stylesheet must also load Ionic's matching dark palette, such as `@ionic/angular/css/palettes/dark.class.css` for Angular. When using `dark-system` or `dark-always`, select the same variant for both Ionic's palette and the iOS 27 theme. See Ionic's [Dark Mode documentation](https://ionicframework.com/docs/theming/dark-mode). The explicit `ios27-vars` and `md3-vars` namespaces prevent the two variable modules from using the same default namespace.
173
+ The iOS styles apply only to Ionic's `ios` mode, while MD3 applies to `md` mode. The `md-remove-ios-class-effect` stylesheet in each iOS branch prevents iOS-only utility classes from leaking into MD mode. MD3 already includes its inset-list styles, so do not load either iOS package's optional `md-ion-list-inset` stylesheet in this configuration.
174
+
175
+ Load Ionic's matching dark palette too. The example uses class-based dark mode; for system or always-dark mode, select the matching variant for Ionic and both iOS themes.
140
176
 
141
- Configure both transition implementations when both themes are installed:
177
+ Keep the iOS 27 transition for both iOS theme generations and select the MD3 transition in Material Design mode. Extend the animation setup above as follows:
142
178
 
143
179
  ```ts
144
- import { isPlatform } from '@ionic/core'; // or @ionic/angular (Ionic 9), @ionic/angular/standalone (Ionic 8), @ionic/react, @ionic/vue
180
+ import { isPlatform, provideIonicAngular } from '@ionic/angular/standalone'; // Ionic 8
145
181
  import { iosTransitionAnimation, popoverEnterAnimation, popoverLeaveAnimation } from '@rdlabo/ionic-theme-ios27';
146
182
  import { mdTransitionAnimation } from '@rdlabo/ionic-theme-md3';
147
183
 
148
- // Angular
149
- provideIonicAngular({
150
- ...
151
- navAnimation: isPlatform('ios') ? iosTransitionAnimation : mdTransitionAnimation,
152
- popoverEnter: isPlatform('ios') ? popoverEnterAnimation : undefined,
153
- popoverLeave: isPlatform('ios') ? popoverLeaveAnimation : undefined,
154
- });
155
-
156
- // React
157
- setupIonicReact({
158
- ...
159
- navAnimation: isPlatform('ios') ? iosTransitionAnimation : mdTransitionAnimation,
160
- popoverEnter: isPlatform('ios') ? popoverEnterAnimation : undefined,
161
- popoverLeave: isPlatform('ios') ? popoverLeaveAnimation : undefined,
162
- });
163
-
164
- // Vue
165
- createApp(App)
166
- .use(IonicVue, {
167
- ...
168
- navAnimation: isPlatform('ios') ? iosTransitionAnimation : mdTransitionAnimation,
169
- popoverEnter: isPlatform('ios') ? popoverEnterAnimation : undefined,
170
- popoverLeave: isPlatform('ios') ? popoverLeaveAnimation : undefined,
171
- });
184
+ function loadAnimations() {
185
+ if (!isPlatform('ios')) return { navAnimation: mdTransitionAnimation };
186
+ if (typeof CSS === 'undefined') return {};
187
+ if (!CSS.supports('overflow-anchor: auto') && !CSS.supports('text-wrap: pretty')) return {};
188
+
189
+ return {
190
+ navAnimation: iosTransitionAnimation,
191
+ popoverEnter: popoverEnterAnimation,
192
+ popoverLeave: popoverLeaveAnimation,
193
+ };
194
+ }
195
+
196
+ provideIonicAngular(loadAnimations());
172
197
  ```
173
198
 
199
+ For Ionic 9 Angular, import `isPlatform` and `provideIonicAngular` from `@ionic/angular`. React and Vue can pass the same returned options to `setupIonicReact` or `IonicVue`. If Sass cannot resolve a package in `meta.load-css()`, use the `stylePreprocessorOptions.includePaths` or relative-path setup described in Get started.
200
+
174
201
  ## Documentation
175
202
 
176
203
  **Full documentation:** [Ionic Theme iOS27](https://docs.rdlabo.dev/projects/ionic-theme-ios27)
177
204
 
178
- - [Adaptive iOS themes](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/ios-adaptive) — conditionally load iOS 26 or iOS 27 styles.
179
205
  - [Using ion-item-group](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/using-ion-item-group) — required markup for inset lists.
180
206
  - [Special markup and classes](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/special-markup) — opt-in markup and utility classes used by the theme.
181
207
  - [ESLint](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/eslint) — check list structure with ESLint rules.
182
208
  - [Features](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/features) — CSS variables, Liquid Glass, selective imports, and dark mode.
183
- - [Native UI Shell (Experimental)](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/native-ui-shell) — native controls around Web content, using the included Capacitor plugin.
184
- - [Animation](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/experimental-animation) — tab bar and searchable effects.
185
- - [Migration](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/migration) — stylesheet, class, and CSS variable naming changes.
209
+ - [Native UI Shell (Experimental)](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/native-ui-shell) — project supported Ionic controls, text, and icons into UIKit.
210
+ - [Animation](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/animation) — tab, segment, and searchable effects.
211
+ - [Migration from iOS 26](https://docs.rdlabo.dev/projects/ionic-theme-ios27/docs/migration) — upgrade an existing app, including stylesheet, class, and CSS variable changes.
186
212
  - [iOS 26 migration history](https://docs.rdlabo.dev/projects/ionic-theme-ios26/docs/migration) — earlier major-version changes for the previous package.
187
213
 
188
214
  <!-- rdlabo-docs-omit -->
189
215
 
190
- **iOS 26 documentation:** See the [iOS 26 documentation](https://docs.rdlabo.dev/projects/ionic-theme-ios26) for the previous theme.
216
+ **iOS 26 theme:** See the [iOS 26 documentation](https://docs.rdlabo.dev/projects/ionic-theme-ios26).
191
217
 
192
218
  ## Development & Testing
193
219
 
@@ -208,7 +234,7 @@ npm start
208
234
 
209
235
  ### Visual Regression Testing
210
236
 
211
- We use Playwright for visual regression testing to ensure consistent styling across all components. The test suite automatically captures screenshots of all routes in both light and dark modes.
237
+ Playwright compares screenshots of demo routes in light and dark modes against stored baselines to catch unintended visual changes. These regression tests do not measure similarity to iOS 27 reference screens.
212
238
 
213
239
  #### Running Tests
214
240
 
@@ -228,23 +254,9 @@ npm run test:e2e:debug
228
254
  npm run test:e2e:update
229
255
  ```
230
256
 
231
- ### Prerelease channels
232
-
233
- An open, non-draft pull request can be published to the npm `beta` dist-tag after its `Lint`, `E2E Screenshot Tests Pull Request`, and `Package Candidate` workflows pass. A repository owner or maintainer must add a comment whose entire body is:
234
-
235
- ```text
236
- /beta
237
- ```
238
-
239
- The request authorizes only the pull request head SHA and base branch that existed when the comment was added. The workflow revalidates the owner or maintainer permission, head SHA, and base branch immediately before publishing. Any new commit or retargeting invalidates the request; the new state must pass CI and receive a fresh owner or maintainer `/beta` comment. Fork pull requests are supported. Pull requests that change a release-gating workflow cannot be beta-published until those workflow changes land on their target branch.
240
-
241
- Beta versions use `<base>-beta.pr<PR number>.sha<12-character SHA>`. The pull request receives a comment containing the immutable version and exact `npm install` command.
242
-
243
- When a pull request is merged into `main` or `ios26`, it is automatically published to the npm `beta` dist-tag only after `Lint`, `E2E Screenshot Tests`, and `Package Candidate` all succeed for that exact merge commit. Direct pushes do not publish a candidate. Merge candidates use `<base>-beta.pr<PR number>.sha<12-character SHA>` and the merged pull request receives the exact install command.
244
-
245
- Candidate code is built in a read-only workflow without npm publishing credentials. The privileged release workflow never checks out or executes pull request code; it revalidates the source workflow and package identity, then publishes only the immutable packed artifact with lifecycle scripts disabled. The install-command comment is a separate best-effort notification and cannot invalidate a successful npm publish.
257
+ ### Releases
246
258
 
247
- Only `npm run release` can create a release tag. Stable `ios27-vX.Y.Z` tags (major, minor, or patch releases) publish to npm `latest`; revision/prerelease tags publish to `next`. Neither `beta` nor `next` publishing changes the npm `latest` dist-tag.
259
+ Stable `ios27-vX.Y.Z` tags publish to npm `latest` through the [release workflow](./.github/workflows/release.yml). Maintainers create release tags with `npm run release`. Pull request and merge candidates use the npm `beta` tag; prerelease tags use `next`.
248
260
 
249
261
  <!-- /rdlabo-docs-omit -->
250
262
 
@@ -1 +1 @@
1
- ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled){--border-radius: 16px;--ios27-segment-scale: 1.113;min-height:32px}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled):not(.segment-scrollable){overflow:visible}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled):not(.segment-scrollable).ios27-enable-gesture{contain:layout style}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled){border-radius:var(--border-radius)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).in-toolbar:not(.segment-expand){--border-radius: 24px;min-height:48px;transition:transform 517ms linear(0, 0.1367 6.38%, 0.4112 12.96%, 0.6945 19.34%, 0.9159 25.73%, 1 29.01%, 1.0912 35.4%, 1.1213 41.97%, 1.1089 48.36%, 1.0584 58.03%, 1 70.99%, 0.9858 83.75%, 1)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).in-toolbar:not(.segment-expand):not(.segment-disabled):is(.ios27-segment-pressed,:not(.ios27-enable-gesture):is(.segment-activated,:has(ion-segment-button.ion-activated))){transform:scale(var(--ios27-segment-scale));transition:transform 367ms linear(0, 0.1656 8.99%, 0.4905 18.26%, 0.7836 27.25%, 0.974 36.24%, 1.0625 45.5%, 1.0802 54.5%, 1.0634 63.49%, 1.0368 72.75%, 1.0147 81.74%, 1.0005 90.74%, 1)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).in-toolbar:not(.segment-expand) ion-segment-button{min-height:44px;margin:2px 0;font-size:.94rem}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) ion-segment-button:is(.in-toolbar-color,.in-segment-color)::part(indicator-background){background:var(--indicator-color)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).ion-color ion-segment-button.in-segment-color.segment-button-checked::part(native){color:var(--color-checked)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).in-toolbar-color:not(.in-segment-color) ion-segment-button:not(.segment-button-checked)::part(native){color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 1)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled):not(.ios27-enable-gesture,.segment-disabled):is(.segment-activated,:has(ion-segment-button:is(:active,.ion-activated))) ion-segment-button.segment-button-checked:not(.segment-button-disabled)::part(indicator-background){scale:1.35 1.4;background:rgba(0,0,0,0);background:linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.011) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.009) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%),rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 1);backdrop-filter:blur(0) saturate(104%);box-shadow:inset 0 0 0 .5px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.6),inset 0 0 1px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.18),inset 0 1px 2px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.8),inset 0 -1px 2px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.5),0 .5px 1px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.18);transform:translateZ(0);-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).ios27-enable-gesture.ios27-animated ion-segment-button{z-index:2}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).ios27-enable-gesture.ios27-animated ion-segment-button::part(indicator){opacity:0}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) .ios27-segment-lens{box-sizing:border-box;position:absolute;top:0;left:0;border-radius:999px;pointer-events:none;z-index:1}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) .ios27-segment-edge{backdrop-filter:blur(0) saturate(104%);border:.5px solid;border-top-color:rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 1);border-right-color:rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.8);border-bottom-color:rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 1);border-left-color:rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.6)}@supports(color: color-mix(in srgb, white, black)){ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) .ios27-segment-edge{border-top-color:color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 12%);border-right-color:color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 32%);border-bottom-color:color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 16%);border-left-color:color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 28%)}}@supports(background-clip: border-area) and (color: color-mix(in srgb, white, black)){ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) .ios27-segment-edge{border-color:rgba(0,0,0,0);background-image:linear-gradient(180deg, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 12%) 0%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 18%) 7%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 29%) 25%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 36%) 50%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 28%) 75%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 18%) 93%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 16%) 100%),linear-gradient(transparent, transparent);background-origin:border-box,padding-box;background-clip:border-area,padding-box}}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) .ios27-segment-edge{transform:translateZ(0);-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;box-shadow:inset 0 2px 3px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.06),inset 0 -1px 2px hsla(0,0%,100%,.8),0 0 0 .5px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.06),0 2px 5px rgba(0,0,0,.06);position:absolute;inset:0;border-radius:inherit;pointer-events:none}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).segment-expand{width:calc(100% - var(--ion-safe-area-left, 0px) - var(--ion-safe-area-right, 0px) - 24px)}@media(prefers-reduced-motion: reduce){ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled){--ios27-segment-scale: 1;transition:none}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).in-toolbar:not(.segment-expand){transform:none;transition:none}}ion-toolbar.ios:has(>ion-segment.ios27-enable-gesture:not(.segment-scrollable,.ios-theme-disabled,.ios26-disabled)){contain:layout style}ion-toolbar.ios:has(>ion-segment.ios27-enable-gesture:not(.segment-scrollable,.ios-theme-disabled,.ios26-disabled))::part(container){contain:layout style;overflow:visible}ion-segment-button.ios:not(.ios-theme-disabled,.ios26-disabled){--border-width: 0;--border-radius: 999px;--indicator-box-shadow: none;--padding-start: 8px;--padding-end: 8px;min-width:65px;min-height:28px;margin:2px 0;font-size:.81rem;font-weight:500;line-height:normal}ion-segment-button.ios:not(.ios-theme-disabled,.ios26-disabled).segment-button-disabled{opacity:.2}ion-segment-button.ios:not(.ios-theme-disabled,.ios26-disabled)::part(indicator-background){transition:var(--indicator-transition),scale 250ms ease-out,background 200ms ease}@media(prefers-reduced-motion: reduce){ion-segment-button.ios:not(.ios-theme-disabled,.ios26-disabled)::part(indicator-background){scale:1 !important;transition:none}}:where(ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled)){--background: rgba(var(--ion-color-medium-rgb, 99, 100, 105), 0.11)}:where(ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) ion-segment-button){--indicator-color: var(--ion-background-color, #fff)}:where(ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).ion-color ion-segment-button.in-segment-color){--indicator-color: var(--ion-color-base);--color-checked: var(--ion-color-contrast)}
1
+ ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled){--border-radius: 16px;--ios27-segment-scale: 1.113;min-height:32px}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled):not(.segment-scrollable){overflow:visible}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled):not(.segment-scrollable).ios27-enable-gesture{contain:layout style}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled){border-radius:var(--border-radius)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).segment-style-glass{--background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.53);box-sizing:border-box;position:relative;z-index:0;background:var(--background);backdrop-filter:blur(6px) saturate(180%) brightness(1.05);box-shadow:inset 0 1px 2px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.25),inset 0 -1px 2px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.3),0 -0.5px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.65),0 .5px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.65),0 0 0 .5px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.22),0 .5px 1px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08);border:.5px solid rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)));background-image:linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%);background-origin:padding-box;background-clip:border-box;border-inline-color:rgba(0,0,0,0)}@supports(background-clip: border-area){ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).segment-style-glass{border-color:rgba(0,0,0,0);background-image:linear-gradient(180deg, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), transparent 50%, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)))),linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%),linear-gradient(transparent, transparent);background-origin:border-box,padding-box,border-box;background-clip:border-area,padding-box,border-box}}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).segment-style-glass ion-segment-button{--indicator-color: rgba( var(--ios-theme-button-color-selected-rgb, var(--ios26-button-color-selected-rgb, var(--ios27-button-color-selected-default-rgb))), 0.095 )}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).in-toolbar:not(.segment-expand){--border-radius: 24px;min-height:48px;transition:transform 517ms linear(0, 0.1367 6.38%, 0.4112 12.96%, 0.6945 19.34%, 0.9159 25.73%, 1 29.01%, 1.0912 35.4%, 1.1213 41.97%, 1.1089 48.36%, 1.0584 58.03%, 1 70.99%, 0.9858 83.75%, 1)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).in-toolbar:not(.segment-expand):not(.segment-disabled):is(.ios27-segment-pressed,:not(.ios27-enable-gesture):is(.segment-activated,:has(ion-segment-button.ion-activated))){transform:scale(var(--ios27-segment-scale));transition:transform 367ms linear(0, 0.1656 8.99%, 0.4905 18.26%, 0.7836 27.25%, 0.974 36.24%, 1.0625 45.5%, 1.0802 54.5%, 1.0634 63.49%, 1.0368 72.75%, 1.0147 81.74%, 1.0005 90.74%, 1)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).in-toolbar:not(.segment-expand) ion-segment-button{min-height:44px;margin:2px 0;font-size:.94rem}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) ion-segment-button:is(.in-toolbar-color,.in-segment-color)::part(indicator-background){background:var(--indicator-color)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).ion-color ion-segment-button.in-segment-color.segment-button-checked::part(native){color:var(--color-checked)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).in-toolbar-color:not(.in-segment-color) ion-segment-button:not(.segment-button-checked)::part(native){color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 1)}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled):not(.ios27-enable-gesture,.segment-disabled):is(.segment-activated,:has(ion-segment-button:is(:active,.ion-activated))) ion-segment-button.segment-button-checked:not(.segment-button-disabled)::part(indicator-background){scale:1.35 1.4;background:rgba(0,0,0,0);background:linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.011) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.009) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%),rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 1);backdrop-filter:blur(0) saturate(104%);box-shadow:inset 0 0 0 .5px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.6),inset 0 0 1px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.18),inset 0 1px 2px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.8),inset 0 -1px 2px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.5),0 .5px 1px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.18);transform:translateZ(0);-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).ios27-enable-gesture.ios27-animated ion-segment-button{z-index:2}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).ios27-enable-gesture.ios27-animated ion-segment-button::part(indicator){opacity:0}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) .ios27-segment-lens{box-sizing:border-box;position:absolute;top:0;left:0;border-radius:999px;pointer-events:none;z-index:1}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) .ios27-segment-edge{backdrop-filter:blur(0) saturate(104%);border:.5px solid;border-top-color:rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 1);border-right-color:rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.8);border-bottom-color:rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 1);border-left-color:rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.6)}@supports(color: color-mix(in srgb, white, black)){ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) .ios27-segment-edge{border-top-color:color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 12%);border-right-color:color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 32%);border-bottom-color:color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 16%);border-left-color:color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 28%)}}@supports(background-clip: border-area) and (color: color-mix(in srgb, white, black)){ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) .ios27-segment-edge{border-color:rgba(0,0,0,0);background-image:linear-gradient(180deg, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 12%) 0%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 18%) 7%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 29%) 25%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 36%) 50%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 28%) 75%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 18%) 93%, color-mix(in srgb, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), rgb(var(--ion-text-color-rgb, 0, 0, 0)) 16%) 100%),linear-gradient(transparent, transparent);background-origin:border-box,padding-box;background-clip:border-area,padding-box}}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) .ios27-segment-edge{transform:translateZ(0);-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;box-shadow:inset 0 2px 3px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.06),inset 0 -1px 2px hsla(0,0%,100%,.8),0 0 0 .5px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.06),0 2px 5px rgba(0,0,0,.06);position:absolute;inset:0;border-radius:inherit;pointer-events:none}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).segment-expand{width:calc(100% - var(--ion-safe-area-left, 0px) - var(--ion-safe-area-right, 0px) - 24px)}@media(prefers-reduced-motion: reduce){ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled){--ios27-segment-scale: 1;transition:none}ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).in-toolbar:not(.segment-expand){transform:none;transition:none}}ion-toolbar.ios:has(>ion-segment.ios27-enable-gesture:not(.segment-scrollable,.ios-theme-disabled,.ios26-disabled)){contain:layout style}ion-toolbar.ios:has(>ion-segment.ios27-enable-gesture:not(.segment-scrollable,.ios-theme-disabled,.ios26-disabled))::part(container){contain:layout style;overflow:visible}ion-segment-button.ios:not(.ios-theme-disabled,.ios26-disabled){--border-width: 0;--border-radius: 999px;--indicator-box-shadow: none;--padding-start: 8px;--padding-end: 8px;min-width:65px;min-height:28px;margin:2px 0;font-size:.81rem;font-weight:500;line-height:normal}ion-segment-button.ios:not(.ios-theme-disabled,.ios26-disabled).segment-button-disabled{opacity:.2}ion-segment-button.ios:not(.ios-theme-disabled,.ios26-disabled)::part(indicator-background){transition:var(--indicator-transition),scale 250ms ease-out,background 200ms ease}@media(prefers-reduced-motion: reduce){ion-segment-button.ios:not(.ios-theme-disabled,.ios26-disabled)::part(indicator-background){scale:1 !important;transition:none}}:where(ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled)){--background: rgba(var(--ion-color-medium-rgb, 99, 100, 105), 0.11)}:where(ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled) ion-segment-button){--indicator-color: var(--ion-background-color, #fff)}:where(ion-segment.ios:not(.ios-theme-disabled,.ios26-disabled).ion-color ion-segment-button.in-segment-color){--indicator-color: var(--ion-color-base);--color-checked: var(--ion-color-contrast)}