neba 1.18.0 → 1.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/dist/a2ui/adapter-catalog.json +1 -1
- package/dist/a2ui/catalog.json +2 -2
- package/dist/components/accordion/Accordion.js +1 -1
- package/dist/components/agent-steps/AgentSteps.js +1 -1
- package/dist/components/alert/Alert.js +1 -1
- package/dist/components/anchor/Anchor.js +1 -1
- package/dist/components/animate-counter/AnimateCounter.js +1 -1
- package/dist/components/animate-headline/AnimateHeadline.js +1 -1
- package/dist/components/animate-lighting/AnimateLighting.js +1 -1
- package/dist/components/animate-marquee/AnimateMarquee.js +1 -1
- package/dist/components/animate-scramble/AnimateScramble.js +1 -1
- package/dist/components/animate-typing/AnimateTyping.js +1 -1
- package/dist/components/app-logo/AppLogo.js +1 -1
- package/dist/components/approval/Approval.js +1 -1
- package/dist/components/aspect-ratio/AspectRatio.js +1 -1
- package/dist/components/avatar/Avatar.js +1 -1
- package/dist/components/badge/Badge.js +1 -1
- package/dist/components/bar-chart/BarChart.js +1 -1
- package/dist/components/blockquote/Blockquote.js +1 -1
- package/dist/components/bottom-navigation/BottomNavigation.js +1 -1
- package/dist/components/breadcrumb/Breadcrumb.js +1 -1
- package/dist/components/button/Button.js +1 -1
- package/dist/components/button-group/ButtonGroup.js +1 -1
- package/dist/components/calendar/Calendar.js +1 -1
- package/dist/components/carousel/Carousel.js +1 -1
- package/dist/components/chat-bubble/ChatBubble.js +1 -1
- package/dist/components/checkbox/Checkbox.js +1 -1
- package/dist/components/checkbox/index.d.ts +1 -1
- package/dist/components/checkbox-group/CheckboxGroup.d.ts +84 -0
- package/dist/components/checkbox-group/CheckboxGroup.js +1 -0
- package/dist/components/checkbox-group/index.d.ts +2 -0
- package/dist/components/checkbox-group/index.js +1 -0
- package/dist/components/chip/Chip.d.ts +32 -3
- package/dist/components/chip/Chip.js +1 -1
- package/dist/components/code-block/CodeBlock.js +1 -1
- package/dist/components/collapsible/Collapsible.js +1 -1
- package/dist/components/color-picker/ColorPicker.js +1 -1
- package/dist/components/combobox/Combobox.d.ts +11 -0
- package/dist/components/combobox/Combobox.js +1 -1
- package/dist/components/combobox/index.d.ts +1 -1
- package/dist/components/command-palette/CommandPalette.d.ts +21 -5
- package/dist/components/command-palette/CommandPalette.js +1 -1
- package/dist/components/command-palette/CommandPaletteSheet.d.ts +27 -0
- package/dist/components/command-palette/CommandPaletteSheet.js +1 -0
- package/dist/components/command-palette/index.d.ts +1 -1
- package/dist/components/confirm/Confirm.d.ts +7 -5
- package/dist/components/confirm/Confirm.js +1 -1
- package/dist/components/data-list/DataList.js +1 -1
- package/dist/components/data-table/DataTable.js +1 -1
- package/dist/components/data-table/RowsPerPage.d.ts +43 -0
- package/dist/components/data-table/RowsPerPage.js +1 -0
- package/dist/components/date-picker/DatePicker.js +1 -1
- package/dist/components/date-range-picker/DateRangePicker.js +1 -1
- package/dist/components/date-time-picker/DateTimePicker.js +1 -1
- package/dist/components/dialog/Dialog.js +1 -1
- package/dist/components/dialog/index.d.ts +1 -1
- package/dist/components/drawer/Drawer.d.ts +1 -1
- package/dist/components/drawer/Drawer.js +1 -1
- package/dist/components/empty/Empty.js +1 -1
- package/dist/components/fieldset/Fieldset.d.ts +12 -1
- package/dist/components/fieldset/Fieldset.js +1 -1
- package/dist/components/file-picker/FilePicker.js +1 -1
- package/dist/components/floating-action-button/FloatingActionButton.js +1 -1
- package/dist/components/floating-action-button/index.d.ts +1 -0
- package/dist/components/floating-bottom-navigation/FloatingBottomNavigation.js +1 -1
- package/dist/components/footer/Footer.js +1 -1
- package/dist/components/form/Form.d.ts +8 -2
- package/dist/components/form/Form.js +1 -1
- package/dist/components/gallery/Gallery.js +1 -1
- package/dist/components/gauge-chart/GaugeChart.js +1 -1
- package/dist/components/header/Header.js +1 -1
- package/dist/components/heatmap-chart/HeatmapChart.js +1 -1
- package/dist/components/highlight/Highlight.js +1 -1
- package/dist/components/hover-card/HoverCard.js +1 -1
- package/dist/components/how-to-steps/HowToSteps.d.ts +3 -0
- package/dist/components/how-to-steps/HowToSteps.js +1 -1
- package/dist/components/image/Image.js +1 -1
- package/dist/components/inline-citation/InlineCitation.d.ts +24 -0
- package/dist/components/inline-citation/InlineCitation.js +1 -1
- package/dist/components/list/List.d.ts +9 -0
- package/dist/components/list/List.js +1 -1
- package/dist/components/menu/Menu.js +1 -1
- package/dist/components/menubar/Menubar.js +1 -1
- package/dist/components/meter/Meter.js +1 -1
- package/dist/components/mockup/Mockup.js +1 -1
- package/dist/components/navigation-menu/NavigationMenu.d.ts +2 -1
- package/dist/components/navigation-menu/NavigationMenu.js +1 -1
- package/dist/components/number-field/NumberField.js +1 -1
- package/dist/components/number-field/index.d.ts +1 -1
- package/dist/components/overlay/Overlay.js +1 -1
- package/dist/components/page-layout/PageLayout.js +1 -1
- package/dist/components/pagination/Pagination.js +1 -1
- package/dist/components/panes/Panes.js +1 -1
- package/dist/components/pie-chart/PieChart.js +1 -1
- package/dist/components/pill/Pill.js +1 -1
- package/dist/components/popover/Popover.js +1 -1
- package/dist/components/progress-box/ProgressBox.js +1 -1
- package/dist/components/progress-circular/ProgressCircular.js +1 -1
- package/dist/components/progress-linear/ProgressLinear.js +1 -1
- package/dist/components/prompt-input/PromptInput.js +1 -1
- package/dist/components/provider/NebaProvider.d.ts +3 -2
- package/dist/components/provider/NebaProvider.js +1 -1
- package/dist/components/radio-group/RadioGroup.d.ts +13 -0
- package/dist/components/radio-group/RadioGroup.js +1 -1
- package/dist/components/radio-group/index.d.ts +1 -1
- package/dist/components/rating/Rating.js +1 -1
- package/dist/components/reasoning/Reasoning.js +1 -1
- package/dist/components/scatter-chart/ScatterChart.js +1 -1
- package/dist/components/scroll-area/ScrollArea.js +1 -1
- package/dist/components/scroll-zone/ScrollZone.js +1 -1
- package/dist/components/segmented-button/SegmentedButton.js +1 -1
- package/dist/components/select/Select.d.ts +12 -0
- package/dist/components/select/Select.js +1 -1
- package/dist/components/select/index.d.ts +1 -1
- package/dist/components/shortcut/Shortcut.js +1 -1
- package/dist/components/sidebar/Sidebar.js +1 -1
- package/dist/components/sidebar/SidebarTrigger.js +1 -1
- package/dist/components/skeleton/Skeleton.js +1 -1
- package/dist/components/slider/Slider.js +1 -1
- package/dist/components/slider/index.d.ts +1 -1
- package/dist/components/sources/Sources.js +1 -1
- package/dist/components/sparkline/Sparkline.d.ts +7 -0
- package/dist/components/sparkline/Sparkline.js +1 -1
- package/dist/components/spoiler/Spoiler.js +1 -1
- package/dist/components/statistic/Statistic.js +1 -1
- package/dist/components/streaming-text/StreamingText.d.ts +10 -6
- package/dist/components/streaming-text/StreamingText.js +1 -1
- package/dist/components/switch/Switch.js +1 -1
- package/dist/components/switch/index.d.ts +1 -1
- package/dist/components/table/Table.js +1 -1
- package/dist/components/table/index.d.ts +1 -1
- package/dist/components/tabs/Tabs.js +1 -1
- package/dist/components/text-field/TextField.js +1 -1
- package/dist/components/text-field/index.d.ts +1 -1
- package/dist/components/text-link/TextLink.js +1 -1
- package/dist/components/time-picker/TimePicker.js +1 -1
- package/dist/components/timeline-chart/TimelineChart.js +1 -1
- package/dist/components/toast/Toast.d.ts +38 -5
- package/dist/components/toast/Toast.js +1 -1
- package/dist/components/toast/index.d.ts +2 -2
- package/dist/components/toast/index.js +1 -1
- package/dist/components/toggle/Toggle.js +1 -1
- package/dist/components/toggle-group/ToggleGroup.js +1 -1
- package/dist/components/tool-call/ToolCall.js +1 -1
- package/dist/components/toolbar/Toolbar.js +1 -1
- package/dist/components/tooltip/Tooltip.js +1 -1
- package/dist/components/tour/Tour.js +1 -1
- package/dist/components/tour/index.d.ts +1 -1
- package/dist/components/transfer/Transfer.d.ts +7 -0
- package/dist/components/transfer/Transfer.js +1 -1
- package/dist/components/tree-select/TreeSelect.js +1 -1
- package/dist/components/tree-view/TreeView.js +1 -1
- package/dist/components/window-pane/WindowPane.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/internal/animate.d.ts +34 -2
- package/dist/internal/animate.js +1 -1
- package/dist/internal/cache.d.ts +7 -1
- package/dist/internal/cache.js +1 -1
- package/dist/internal/calendar.d.ts +40 -1
- package/dist/internal/calendar.js +1 -1
- package/dist/internal/chart-frame.d.ts +86 -8
- package/dist/internal/chart-frame.js +1 -1
- package/dist/internal/chart-line.js +1 -1
- package/dist/internal/chart.d.ts +13 -0
- package/dist/internal/chart.js +1 -1
- package/dist/internal/checkbox-group.d.ts +29 -0
- package/dist/internal/checkbox-group.js +1 -0
- package/dist/internal/data-table.d.ts +7 -1
- package/dist/internal/data-table.js +1 -1
- package/dist/internal/date.d.ts +10 -0
- package/dist/internal/date.js +1 -1
- package/dist/internal/defaults.d.ts +14 -2
- package/dist/internal/idle.d.ts +10 -0
- package/dist/internal/idle.js +1 -0
- package/dist/internal/link.d.ts +4 -3
- package/dist/internal/media.js +1 -1
- package/dist/internal/observe.d.ts +4 -0
- package/dist/internal/observe.js +1 -1
- package/dist/internal/page-layout.d.ts +30 -2
- package/dist/internal/page-layout.js +1 -1
- package/dist/internal/picker.js +1 -1
- package/dist/internal/progress.d.ts +17 -0
- package/dist/internal/progress.js +1 -1
- package/dist/internal/refs.d.ts +18 -0
- package/dist/internal/refs.js +1 -0
- package/dist/internal/run.d.ts +34 -19
- package/dist/internal/run.js +1 -1
- package/dist/internal/sizer.d.ts +9 -4
- package/dist/internal/sizer.js +1 -1
- package/dist/internal/styles.d.ts +27 -1
- package/dist/internal/styles.js +1 -1
- package/dist/internal/tile.d.ts +34 -0
- package/dist/internal/tile.js +1 -0
- package/dist/internal/wheel.d.ts +24 -1
- package/dist/internal/wheel.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +369 -62
- package/dist/types.d.ts +4 -2
- package/package.json +2 -2
package/dist/tailwind.css
CHANGED
|
@@ -100,6 +100,16 @@
|
|
|
100
100
|
--neba-fill-alpha: 88%;
|
|
101
101
|
--neba-blur: blur(9px) saturate(1.5);
|
|
102
102
|
|
|
103
|
+
/* What every translucent sheet and fill is laid over before it reaches the
|
|
104
|
+
page. `transparent` is the acrylic: the page shows through, and the blur
|
|
105
|
+
above is what keeps it from being read. `var(--neba-surface)` stops it,
|
|
106
|
+
and each sheet comes out the colour the acrylic has over a plain page —
|
|
107
|
+
which is what the reduced-transparency block below the dark theme sets,
|
|
108
|
+
together with `--neba-blur: none`. One value for both themes, so it is declared here
|
|
109
|
+
only; the rule that changes it has to name every theme root, because the
|
|
110
|
+
surface it resolves against is that root's. */
|
|
111
|
+
--neba-backing: transparent;
|
|
112
|
+
|
|
103
113
|
/* How much of the family's accent a focus ring is. The ring sits 2px off the
|
|
104
114
|
control, so what it is read against is the page, and on a white sheet 55%
|
|
105
115
|
of any accent is 2.2 to 2.6:1 — under the 3:1 a focus indicator needs, on
|
|
@@ -129,8 +139,12 @@
|
|
|
129
139
|
any backdrop that is not pure white it settled into grey. Raising it to 66%
|
|
130
140
|
is the one place alpha is the right lever rather than the blur: the blur
|
|
131
141
|
decides whether the backdrop is *legible*, and 9px still hides it. This
|
|
132
|
-
decides whether the sheet reads as white, and it has to.
|
|
133
|
-
|
|
142
|
+
decides whether the sheet reads as white, and it has to.
|
|
143
|
+
|
|
144
|
+
The white is mixed into `--neba-backing` rather than written with an
|
|
145
|
+
alpha, and so are the panel steps below. Into `transparent` the two are
|
|
146
|
+
the same colour. */
|
|
147
|
+
--neba-glass-bg: color-mix(in srgb, white 66%, var(--neba-backing));
|
|
134
148
|
|
|
135
149
|
/* The container surface, in the three strengths a panel-shaped component
|
|
136
150
|
needs — Box, Card and TextField read these directly.
|
|
@@ -146,9 +160,9 @@
|
|
|
146
160
|
|
|
147
161
|
The ladder is opacity, not lightness — the sheet catches more light as it
|
|
148
162
|
is engaged, rather than turning grey. */
|
|
149
|
-
--neba-panel:
|
|
150
|
-
--neba-panel-hover:
|
|
151
|
-
--neba-panel-press:
|
|
163
|
+
--neba-panel: color-mix(in srgb, white 66%, var(--neba-backing));
|
|
164
|
+
--neba-panel-hover: color-mix(in srgb, white 82%, var(--neba-backing));
|
|
165
|
+
--neba-panel-press: color-mix(in srgb, white 92%, var(--neba-backing));
|
|
152
166
|
|
|
153
167
|
/* The one surface in the library that is a groove rather than a sheet: the
|
|
154
168
|
track a Switch's thumb runs along.
|
|
@@ -165,7 +179,13 @@
|
|
|
165
179
|
surface here does — the blur behind it is what makes it acrylic rather than
|
|
166
180
|
paint — and it stays neutral because the family is what "on" says. On the
|
|
167
181
|
dark theme the panel was already darker than the thumb, so these are the
|
|
168
|
-
panel's own two steps and nothing moves.
|
|
182
|
+
panel's own two steps and nothing moves.
|
|
183
|
+
|
|
184
|
+
It is not mixed into `--neba-backing`, and neither is any wash: a groove,
|
|
185
|
+
a `soft` tint or a hairline is cut into a sheet or laid on one, and once
|
|
186
|
+
the sheet is opaque nothing behind it shows through them either. Mixed
|
|
187
|
+
into the page's own colour, a track inside a dark Card would be the
|
|
188
|
+
Card's colour and the groove would be gone. */
|
|
169
189
|
--neba-groove: rgb(16 24 40 / 0.14);
|
|
170
190
|
--neba-groove-hover: rgb(16 24 40 / 0.19);
|
|
171
191
|
|
|
@@ -219,7 +239,9 @@
|
|
|
219
239
|
tooltip, a toast. One number, because they are all the same kind of thing
|
|
220
240
|
— something drawn over the page the reader was looking at — and because
|
|
221
241
|
the value a host needs is its own. A site whose fixed header is at 1200
|
|
222
|
-
sets this once rather than beating fourteen `z-50`s with a selector.
|
|
242
|
+
sets this once rather than beating fourteen `z-50`s with a selector.
|
|
243
|
+
The toast stack reads `--neba-z-toast`, which is not declared here: the
|
|
244
|
+
viewport falls back to one above this, so it follows a host's value. */
|
|
223
245
|
--neba-z-portal: 50;
|
|
224
246
|
|
|
225
247
|
/* Color families -------------------------------------------------------
|
|
@@ -233,7 +255,8 @@
|
|
|
233
255
|
fill is only 88% opaque, and the pair has to clear 4.5:1 over a white page
|
|
234
256
|
— which pins every family with white text to the high 40s / low 50s. A
|
|
235
257
|
brighter *fill* means a dark ink, which is why `warning` is the one family
|
|
236
|
-
that already goes there. Verified per step, including hover and active
|
|
258
|
+
that already goes there. Verified per step, including hover and active, in
|
|
259
|
+
every theme: `test/styles/fill-contrast.test.ts` holds it.
|
|
237
260
|
|
|
238
261
|
`success` moved 152 → 148 and `info` 218 → 223. Both are hue regions where
|
|
239
262
|
sRGB is starved at mid lightness, and a few degrees toward the gamut's wide
|
|
@@ -479,11 +502,11 @@
|
|
|
479
502
|
--neba-plate-top: rgb(255 255 255 / 0.16);
|
|
480
503
|
--neba-sheen: linear-gradient(148deg, rgb(255 255 255 / 0.09), rgb(255 255 255 / 0) 52%);
|
|
481
504
|
|
|
482
|
-
--neba-glass-bg:
|
|
505
|
+
--neba-glass-bg: color-mix(in srgb, white 5%, var(--neba-backing));
|
|
483
506
|
|
|
484
|
-
--neba-panel:
|
|
485
|
-
--neba-panel-hover:
|
|
486
|
-
--neba-panel-press:
|
|
507
|
+
--neba-panel: color-mix(in srgb, white 5%, var(--neba-backing));
|
|
508
|
+
--neba-panel-hover: color-mix(in srgb, white 7%, var(--neba-backing));
|
|
509
|
+
--neba-panel-press: color-mix(in srgb, white 9%, var(--neba-backing));
|
|
487
510
|
|
|
488
511
|
--neba-groove: rgb(255 255 255 / 0.05);
|
|
489
512
|
--neba-groove-hover: rgb(255 255 255 / 0.07);
|
|
@@ -496,7 +519,7 @@
|
|
|
496
519
|
--neba-shadow-ambient: rgb(0 0 0 / 0.55);
|
|
497
520
|
|
|
498
521
|
--neba-primary-solid: oklch(57% 0.208 262);
|
|
499
|
-
--neba-primary-solid-hover: oklch(
|
|
522
|
+
--neba-primary-solid-hover: oklch(61% 0.181 262);
|
|
500
523
|
--neba-primary-solid-active: oklch(48% 0.196 262);
|
|
501
524
|
--neba-primary-on-solid: oklch(99% 0.004 262);
|
|
502
525
|
--neba-primary-accent: oklch(78% 0.103 262);
|
|
@@ -515,7 +538,7 @@
|
|
|
515
538
|
|
|
516
539
|
--neba-warning-solid: oklch(76% 0.145 80);
|
|
517
540
|
--neba-warning-solid-hover: oklch(81% 0.154 80);
|
|
518
|
-
--neba-warning-solid-active: oklch(
|
|
541
|
+
--neba-warning-solid-active: oklch(69.5% 0.126 80);
|
|
519
542
|
--neba-warning-on-solid: oklch(25% 0.06 70);
|
|
520
543
|
--neba-warning-accent: oklch(82% 0.14 80);
|
|
521
544
|
|
|
@@ -620,11 +643,11 @@
|
|
|
620
643
|
--neba-plate-top: rgb(255 255 255 / 0.16);
|
|
621
644
|
--neba-sheen: linear-gradient(148deg, rgb(255 255 255 / 0.09), rgb(255 255 255 / 0) 52%);
|
|
622
645
|
|
|
623
|
-
--neba-glass-bg:
|
|
646
|
+
--neba-glass-bg: color-mix(in srgb, white 5%, var(--neba-backing));
|
|
624
647
|
|
|
625
|
-
--neba-panel:
|
|
626
|
-
--neba-panel-hover:
|
|
627
|
-
--neba-panel-press:
|
|
648
|
+
--neba-panel: color-mix(in srgb, white 5%, var(--neba-backing));
|
|
649
|
+
--neba-panel-hover: color-mix(in srgb, white 7%, var(--neba-backing));
|
|
650
|
+
--neba-panel-press: color-mix(in srgb, white 9%, var(--neba-backing));
|
|
628
651
|
|
|
629
652
|
--neba-groove: rgb(255 255 255 / 0.05);
|
|
630
653
|
--neba-groove-hover: rgb(255 255 255 / 0.07);
|
|
@@ -637,7 +660,7 @@
|
|
|
637
660
|
--neba-shadow-ambient: rgb(0 0 0 / 0.55);
|
|
638
661
|
|
|
639
662
|
--neba-primary-solid: oklch(57% 0.208 262);
|
|
640
|
-
--neba-primary-solid-hover: oklch(
|
|
663
|
+
--neba-primary-solid-hover: oklch(61% 0.181 262);
|
|
641
664
|
--neba-primary-solid-active: oklch(48% 0.196 262);
|
|
642
665
|
--neba-primary-on-solid: oklch(99% 0.004 262);
|
|
643
666
|
--neba-primary-accent: oklch(78% 0.103 262);
|
|
@@ -656,7 +679,7 @@
|
|
|
656
679
|
|
|
657
680
|
--neba-warning-solid: oklch(76% 0.145 80);
|
|
658
681
|
--neba-warning-solid-hover: oklch(81% 0.154 80);
|
|
659
|
-
--neba-warning-solid-active: oklch(
|
|
682
|
+
--neba-warning-solid-active: oklch(69.5% 0.126 80);
|
|
660
683
|
--neba-warning-on-solid: oklch(25% 0.06 70);
|
|
661
684
|
--neba-warning-accent: oklch(82% 0.14 80);
|
|
662
685
|
|
|
@@ -717,6 +740,53 @@
|
|
|
717
740
|
--neba-chart-on-8: var(--neba-surface);
|
|
718
741
|
}
|
|
719
742
|
|
|
743
|
+
/* ---------------------------------------------------------------------------
|
|
744
|
+
* Reduced transparency
|
|
745
|
+
*
|
|
746
|
+
* A reader whose system is set to reduce transparency gets opaque sheets and no
|
|
747
|
+
* backdrop blur. Taking the blur away alone is not enough, and is worse than
|
|
748
|
+
* leaving it: the blur is what keeps the page behind a sheet from being read,
|
|
749
|
+
* so with nothing else changed a menu over a paragraph in the dark theme is
|
|
750
|
+
* nine per cent of white over sharp text, and a light Card shows a ghost of the
|
|
751
|
+
* words under it.
|
|
752
|
+
*
|
|
753
|
+
* So the sheets and the fills are laid on the page's own surface instead of on
|
|
754
|
+
* whatever is behind them. Each one comes out the colour the acrylic has over a
|
|
755
|
+
* plain page — plain white for every light sheet, white over white being
|
|
756
|
+
* white — and its ink was measured on exactly that colour. What is lost
|
|
757
|
+
* is the compounding on the dark side: a sheet inside a sheet is no longer
|
|
758
|
+
* lighter than the one around it, because both are laid on the page. The
|
|
759
|
+
* hairline and the plate edge still say where the inner one begins, and the
|
|
760
|
+
* muted ink reads better on it than it did. Washes, grooves and hairlines stay
|
|
761
|
+
* as they are; they sit on a sheet, and the sheet is opaque now. The scrim
|
|
762
|
+
* behind a modal stays as well, since showing the page dimmed is its job.
|
|
763
|
+
*
|
|
764
|
+
* It also takes the most expensive thing off the page: a backdrop filter is
|
|
765
|
+
* applied again on every frame the page moves, so a scroll pays for the blur
|
|
766
|
+
* under every surface on the screen.
|
|
767
|
+
*
|
|
768
|
+
* Every theme root is named, because `var(--neba-surface)` resolves on the
|
|
769
|
+
* element that declares it, and on `:root` alone a `.dark` box inside a light
|
|
770
|
+
* page would lay its sheets on the light page's white.
|
|
771
|
+
* ------------------------------------------------------------------------- */
|
|
772
|
+
|
|
773
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
774
|
+
:root,
|
|
775
|
+
.dark,
|
|
776
|
+
.light,
|
|
777
|
+
[data-theme='dark'],
|
|
778
|
+
[data-theme='light'] {
|
|
779
|
+
--neba-backing: var(--neba-surface);
|
|
780
|
+
--neba-blur: none;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/* The system-dark block declares the blur on `:root` at three classes'
|
|
784
|
+
weight, which the one class above does not beat. */
|
|
785
|
+
:root:not(.light):not([data-theme='light']) {
|
|
786
|
+
--neba-blur: none;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
720
790
|
/* ---------------------------------------------------------------------------
|
|
721
791
|
* Derived tokens
|
|
722
792
|
*
|
|
@@ -741,6 +811,12 @@
|
|
|
741
811
|
* blue — and the worst family on the strongest wash clears 4.5:1 in both.
|
|
742
812
|
* `accent` itself is untouched, so what a TextLink or a Statistic's delta is
|
|
743
813
|
* written in on the bare sheet does not change.
|
|
814
|
+
*
|
|
815
|
+
* A fill is the family's solid mixed into `--neba-backing` rather than into
|
|
816
|
+
* `transparent`, so that it turns opaque with the sheets when the reader asks
|
|
817
|
+
* for less transparency. It keeps `--neba-fill-alpha` when it does: the ink on
|
|
818
|
+
* a fill was solved against that much of it over the page, and the whole solid
|
|
819
|
+
* instead would take the dark theme's primary hover from about 4.5:1 to 3.6:1.
|
|
744
820
|
* ------------------------------------------------------------------------- */
|
|
745
821
|
|
|
746
822
|
:root,
|
|
@@ -767,17 +843,17 @@
|
|
|
767
843
|
--neba-primary-fill: color-mix(
|
|
768
844
|
in srgb,
|
|
769
845
|
var(--neba-primary-solid) var(--neba-fill-alpha),
|
|
770
|
-
|
|
846
|
+
var(--neba-backing)
|
|
771
847
|
);
|
|
772
848
|
--neba-primary-fill-hover: color-mix(
|
|
773
849
|
in srgb,
|
|
774
850
|
var(--neba-primary-solid-hover) var(--neba-fill-alpha),
|
|
775
|
-
|
|
851
|
+
var(--neba-backing)
|
|
776
852
|
);
|
|
777
853
|
--neba-primary-fill-active: color-mix(
|
|
778
854
|
in srgb,
|
|
779
855
|
var(--neba-primary-solid-active) var(--neba-fill-alpha),
|
|
780
|
-
|
|
856
|
+
var(--neba-backing)
|
|
781
857
|
);
|
|
782
858
|
--neba-primary-soft: color-mix(in srgb, var(--neba-primary-accent) 10%, transparent);
|
|
783
859
|
--neba-primary-soft-hover: color-mix(in srgb, var(--neba-primary-accent) 17%, transparent);
|
|
@@ -805,17 +881,17 @@
|
|
|
805
881
|
--neba-secondary-fill: color-mix(
|
|
806
882
|
in srgb,
|
|
807
883
|
var(--neba-secondary-solid) var(--neba-fill-alpha),
|
|
808
|
-
|
|
884
|
+
var(--neba-backing)
|
|
809
885
|
);
|
|
810
886
|
--neba-secondary-fill-hover: color-mix(
|
|
811
887
|
in srgb,
|
|
812
888
|
var(--neba-secondary-solid-hover) var(--neba-fill-alpha),
|
|
813
|
-
|
|
889
|
+
var(--neba-backing)
|
|
814
890
|
);
|
|
815
891
|
--neba-secondary-fill-active: color-mix(
|
|
816
892
|
in srgb,
|
|
817
893
|
var(--neba-secondary-solid-active) var(--neba-fill-alpha),
|
|
818
|
-
|
|
894
|
+
var(--neba-backing)
|
|
819
895
|
);
|
|
820
896
|
--neba-secondary-soft: color-mix(in srgb, var(--neba-secondary-accent) 10%, transparent);
|
|
821
897
|
--neba-secondary-soft-hover: color-mix(in srgb, var(--neba-secondary-accent) 17%, transparent);
|
|
@@ -843,17 +919,17 @@
|
|
|
843
919
|
--neba-success-fill: color-mix(
|
|
844
920
|
in srgb,
|
|
845
921
|
var(--neba-success-solid) var(--neba-fill-alpha),
|
|
846
|
-
|
|
922
|
+
var(--neba-backing)
|
|
847
923
|
);
|
|
848
924
|
--neba-success-fill-hover: color-mix(
|
|
849
925
|
in srgb,
|
|
850
926
|
var(--neba-success-solid-hover) var(--neba-fill-alpha),
|
|
851
|
-
|
|
927
|
+
var(--neba-backing)
|
|
852
928
|
);
|
|
853
929
|
--neba-success-fill-active: color-mix(
|
|
854
930
|
in srgb,
|
|
855
931
|
var(--neba-success-solid-active) var(--neba-fill-alpha),
|
|
856
|
-
|
|
932
|
+
var(--neba-backing)
|
|
857
933
|
);
|
|
858
934
|
--neba-success-soft: color-mix(in srgb, var(--neba-success-accent) 10%, transparent);
|
|
859
935
|
--neba-success-soft-hover: color-mix(in srgb, var(--neba-success-accent) 17%, transparent);
|
|
@@ -881,17 +957,17 @@
|
|
|
881
957
|
--neba-warning-fill: color-mix(
|
|
882
958
|
in srgb,
|
|
883
959
|
var(--neba-warning-solid) var(--neba-fill-alpha),
|
|
884
|
-
|
|
960
|
+
var(--neba-backing)
|
|
885
961
|
);
|
|
886
962
|
--neba-warning-fill-hover: color-mix(
|
|
887
963
|
in srgb,
|
|
888
964
|
var(--neba-warning-solid-hover) var(--neba-fill-alpha),
|
|
889
|
-
|
|
965
|
+
var(--neba-backing)
|
|
890
966
|
);
|
|
891
967
|
--neba-warning-fill-active: color-mix(
|
|
892
968
|
in srgb,
|
|
893
969
|
var(--neba-warning-solid-active) var(--neba-fill-alpha),
|
|
894
|
-
|
|
970
|
+
var(--neba-backing)
|
|
895
971
|
);
|
|
896
972
|
--neba-warning-soft: color-mix(in srgb, var(--neba-warning-accent) 12%, transparent);
|
|
897
973
|
--neba-warning-soft-hover: color-mix(in srgb, var(--neba-warning-accent) 20%, transparent);
|
|
@@ -919,17 +995,17 @@
|
|
|
919
995
|
--neba-danger-fill: color-mix(
|
|
920
996
|
in srgb,
|
|
921
997
|
var(--neba-danger-solid) var(--neba-fill-alpha),
|
|
922
|
-
|
|
998
|
+
var(--neba-backing)
|
|
923
999
|
);
|
|
924
1000
|
--neba-danger-fill-hover: color-mix(
|
|
925
1001
|
in srgb,
|
|
926
1002
|
var(--neba-danger-solid-hover) var(--neba-fill-alpha),
|
|
927
|
-
|
|
1003
|
+
var(--neba-backing)
|
|
928
1004
|
);
|
|
929
1005
|
--neba-danger-fill-active: color-mix(
|
|
930
1006
|
in srgb,
|
|
931
1007
|
var(--neba-danger-solid-active) var(--neba-fill-alpha),
|
|
932
|
-
|
|
1008
|
+
var(--neba-backing)
|
|
933
1009
|
);
|
|
934
1010
|
--neba-danger-soft: color-mix(in srgb, var(--neba-danger-accent) 10%, transparent);
|
|
935
1011
|
--neba-danger-soft-hover: color-mix(in srgb, var(--neba-danger-accent) 17%, transparent);
|
|
@@ -954,16 +1030,20 @@
|
|
|
954
1030
|
transparent
|
|
955
1031
|
);
|
|
956
1032
|
|
|
957
|
-
--neba-info-fill: color-mix(
|
|
1033
|
+
--neba-info-fill: color-mix(
|
|
1034
|
+
in srgb,
|
|
1035
|
+
var(--neba-info-solid) var(--neba-fill-alpha),
|
|
1036
|
+
var(--neba-backing)
|
|
1037
|
+
);
|
|
958
1038
|
--neba-info-fill-hover: color-mix(
|
|
959
1039
|
in srgb,
|
|
960
1040
|
var(--neba-info-solid-hover) var(--neba-fill-alpha),
|
|
961
|
-
|
|
1041
|
+
var(--neba-backing)
|
|
962
1042
|
);
|
|
963
1043
|
--neba-info-fill-active: color-mix(
|
|
964
1044
|
in srgb,
|
|
965
1045
|
var(--neba-info-solid-active) var(--neba-fill-alpha),
|
|
966
|
-
|
|
1046
|
+
var(--neba-backing)
|
|
967
1047
|
);
|
|
968
1048
|
--neba-info-soft: color-mix(in srgb, var(--neba-info-accent) 10%, transparent);
|
|
969
1049
|
--neba-info-soft-hover: color-mix(in srgb, var(--neba-info-accent) 17%, transparent);
|
|
@@ -2373,6 +2453,86 @@
|
|
|
2373
2453
|
box-shadow: none;
|
|
2374
2454
|
}
|
|
2375
2455
|
|
|
2456
|
+
/* The frame the tile arrives in. The light's own opacity transition would
|
|
2457
|
+
otherwise fade the stand-in out under the tile as a bloom. */
|
|
2458
|
+
.neba-segmented[data-settling] .neba-segment::before {
|
|
2459
|
+
transition: none;
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
/* ---------------------------------------------------------------------------
|
|
2463
|
+
* A tab bar before its indicator is placed
|
|
2464
|
+
*
|
|
2465
|
+
* The pill or bar under the chosen tab is Base UI's indicator, and Base UI
|
|
2466
|
+
* keeps it `hidden` until it has measured the chosen tab, which only happens
|
|
2467
|
+
* once the page is running. A server-rendered `solid` bar therefore had no
|
|
2468
|
+
* pill under the chosen tab until hydration, and the other two had no line.
|
|
2469
|
+
* Until the indicator is shown, the chosen tab draws the same thing itself,
|
|
2470
|
+
* and hands it over in the frame the indicator appears: both follow the one
|
|
2471
|
+
* `hidden` attribute, so there is no frame with two and no frame with none.
|
|
2472
|
+
*
|
|
2473
|
+
* On `::after` rather than the tab's own background, which has a transition
|
|
2474
|
+
* and would fade out over the indicator. `::after` is the tab's afterglow,
|
|
2475
|
+
* which a tab leaves transparent, so the fade it goes back to shows nothing.
|
|
2476
|
+
* `:has()` is past the browser floor in Firefox 113 to 120, where the whole
|
|
2477
|
+
* rule is dropped and the tab is told apart by its colour until hydration, as
|
|
2478
|
+
* it was before.
|
|
2479
|
+
* ------------------------------------------------------------------------- */
|
|
2480
|
+
|
|
2481
|
+
.neba-tabs-list:has(> .neba-tabs-indicator[hidden]) > [data-active]::after {
|
|
2482
|
+
content: '';
|
|
2483
|
+
position: absolute;
|
|
2484
|
+
z-index: -1;
|
|
2485
|
+
pointer-events: none;
|
|
2486
|
+
opacity: 1;
|
|
2487
|
+
transition: none;
|
|
2488
|
+
}
|
|
2489
|
+
|
|
2490
|
+
/* `solid`: the tile, the same sheet as the indicator's. */
|
|
2491
|
+
.neba-tabs-list[data-indicator='tile']:has(> .neba-tabs-indicator[hidden]) > [data-active]::after {
|
|
2492
|
+
inset: 0;
|
|
2493
|
+
border-radius: inherit;
|
|
2494
|
+
background: var(--n-panel-press);
|
|
2495
|
+
background-image: var(--neba-grain), var(--neba-sheen);
|
|
2496
|
+
background-blend-mode: overlay, normal;
|
|
2497
|
+
box-shadow: var(--neba-shadow-1), var(--neba-plate-glass);
|
|
2498
|
+
backdrop-filter: var(--neba-blur);
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
/* `outline` and `text`: a 2px line on the edge the bar runs along. */
|
|
2502
|
+
.neba-tabs-list[data-indicator='bar']:has(> .neba-tabs-indicator[hidden]) > [data-active]::after {
|
|
2503
|
+
inset: auto 0 0;
|
|
2504
|
+
height: 2px;
|
|
2505
|
+
border-radius: 9999px;
|
|
2506
|
+
background: var(--n-accent);
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
.neba-tabs-list[data-indicator='bar'][data-orientation='vertical']:has(
|
|
2510
|
+
> .neba-tabs-indicator[hidden]
|
|
2511
|
+
)
|
|
2512
|
+
> [data-active]::after {
|
|
2513
|
+
inset-block: 0;
|
|
2514
|
+
inset-inline: auto 0;
|
|
2515
|
+
width: 2px;
|
|
2516
|
+
height: auto;
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
/* A bar that wraps: the line is the tab's own bottom edge, or its end edge. */
|
|
2520
|
+
.neba-tabs-list[data-indicator='underline']:has(> .neba-tabs-indicator[hidden])
|
|
2521
|
+
> [data-active]::after {
|
|
2522
|
+
inset: 0;
|
|
2523
|
+
border-radius: 9999px;
|
|
2524
|
+
border-bottom: 2px solid var(--n-accent);
|
|
2525
|
+
background: transparent;
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
.neba-tabs-list[data-indicator='underline'][data-orientation='vertical']:has(
|
|
2529
|
+
> .neba-tabs-indicator[hidden]
|
|
2530
|
+
)
|
|
2531
|
+
> [data-active]::after {
|
|
2532
|
+
border-bottom: 0;
|
|
2533
|
+
border-inline-end: 2px solid var(--n-accent);
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2376
2536
|
/* ---------------------------------------------------------------------------
|
|
2377
2537
|
* Tree guides
|
|
2378
2538
|
*
|
|
@@ -2648,20 +2808,28 @@
|
|
|
2648
2808
|
*
|
|
2649
2809
|
* `currentColor` rather than a token, because a bubble's ink is white on
|
|
2650
2810
|
* `solid` and the page's own on the other two.
|
|
2811
|
+
*
|
|
2812
|
+
* The colour changes through `opacity` on a solid dot rather than through the
|
|
2813
|
+
* dot's `background-color`. A dot has nothing inside it, so the two draw the
|
|
2814
|
+
* same pixels at every frame — `currentColor` at 28% is `currentColor` at an
|
|
2815
|
+
* alpha of 0.28 — but a background is repainted on the main thread every frame
|
|
2816
|
+
* for as long as somebody is typing, and an opacity is handed to the
|
|
2817
|
+
* compositor.
|
|
2651
2818
|
*/
|
|
2652
2819
|
@keyframes neba-typing {
|
|
2653
2820
|
0%,
|
|
2654
2821
|
60%,
|
|
2655
2822
|
100% {
|
|
2656
|
-
|
|
2823
|
+
opacity: 0.28;
|
|
2657
2824
|
}
|
|
2658
2825
|
30% {
|
|
2659
|
-
|
|
2826
|
+
opacity: 1;
|
|
2660
2827
|
}
|
|
2661
2828
|
}
|
|
2662
2829
|
|
|
2663
2830
|
.neba-typing-dot {
|
|
2664
|
-
background-color:
|
|
2831
|
+
background-color: currentColor;
|
|
2832
|
+
opacity: 0.28;
|
|
2665
2833
|
animation: neba-typing 1.25s var(--neba-ease) infinite;
|
|
2666
2834
|
animation-delay: calc(var(--n-i, 0) * 160ms);
|
|
2667
2835
|
}
|
|
@@ -2698,6 +2866,26 @@
|
|
|
2698
2866
|
animation: neba-skeleton-sweep 1.5s var(--neba-ease) infinite;
|
|
2699
2867
|
}
|
|
2700
2868
|
|
|
2869
|
+
/* Off screen, a sweep holds still. `Skeleton` marks its root once it has
|
|
2870
|
+
scrolled out of view, which is also the root of a stack of lines. */
|
|
2871
|
+
[data-offscreen].neba-skeleton::after,
|
|
2872
|
+
[data-offscreen] .neba-skeleton::after {
|
|
2873
|
+
animation-play-state: paused;
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2876
|
+
/* Where a reader asked for reduced transparency the panel colours are laid on
|
|
2877
|
+
the page's surface, which in the dark theme is darker than the wash a
|
|
2878
|
+
placeholder is drawn in, so the highlight crossed it as a shadow. Screened,
|
|
2879
|
+
it can only ever lighten what it passes over: white over a light placeholder
|
|
2880
|
+
is white as before, and the dark theme's lifts it as its nine per cent of
|
|
2881
|
+
white used to. The pulse that stands in for the sweep under reduced motion
|
|
2882
|
+
is the same layer and is screened with it. */
|
|
2883
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
2884
|
+
.neba-skeleton::after {
|
|
2885
|
+
mix-blend-mode: screen;
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2701
2889
|
/*
|
|
2702
2890
|
* Under RTL the start edge is on the right, so both sweeps travel leftwards.
|
|
2703
2891
|
*
|
|
@@ -2726,14 +2914,16 @@
|
|
|
2726
2914
|
|
|
2727
2915
|
/* The reduced-motion stand-in: the highlight stops travelling and the whole
|
|
2728
2916
|
placeholder breathes instead. Colour, which is the axis every other state in
|
|
2729
|
-
the library already uses
|
|
2917
|
+
the library already uses — drawn as the opacity of a layer that is already
|
|
2918
|
+
that colour, which is the same pixels as a background fading in from
|
|
2919
|
+
transparent, without a repaint on every frame of a loading page. */
|
|
2730
2920
|
@keyframes neba-skeleton-pulse {
|
|
2731
2921
|
0%,
|
|
2732
2922
|
100% {
|
|
2733
|
-
|
|
2923
|
+
opacity: 0;
|
|
2734
2924
|
}
|
|
2735
2925
|
50% {
|
|
2736
|
-
|
|
2926
|
+
opacity: 1;
|
|
2737
2927
|
}
|
|
2738
2928
|
}
|
|
2739
2929
|
|
|
@@ -2889,6 +3079,69 @@
|
|
|
2889
3079
|
animation-name: neba-anim-rotate;
|
|
2890
3080
|
}
|
|
2891
3081
|
|
|
3082
|
+
/*
|
|
3083
|
+
* An entrance waiting to be scrolled into view, drawn where the layout put it.
|
|
3084
|
+
*
|
|
3085
|
+
* Its first frame is somewhere else — a slide a full width to one side, a zoom
|
|
3086
|
+
* shrunk to the middle of a box taller than the screen — and the observer that
|
|
3087
|
+
* decides when it starts measures the box as drawn. A full-width slide moved a
|
|
3088
|
+
* full width sideways, or one moved out of a box with `overflow: hidden`, was
|
|
3089
|
+
* never on the screen at all and never started. So the move is taken away until
|
|
3090
|
+
* it starts, and the observer measures the box the reader is scrolling
|
|
3091
|
+
* towards. A first frame that fades is unseen there anyway. One that does not
|
|
3092
|
+
* fade, marked `shown`, is hidden in place as well, or it would jump to its
|
|
3093
|
+
* first frame as it started — but only where the page is going to wait for a
|
|
3094
|
+
* script, so with less motion asked for, with scripting off, and in a browser
|
|
3095
|
+
* that cannot say, it is drawn as it was. An opacity rather than `visibility`,
|
|
3096
|
+
* so what is inside can still take the focus, and focusing it scrolls it into
|
|
3097
|
+
* view. `!important` because an animation's held frame outranks every ordinary
|
|
3098
|
+
* declaration.
|
|
3099
|
+
*/
|
|
3100
|
+
.neba-anim-slide[data-waiting=''] {
|
|
3101
|
+
translate: none !important;
|
|
3102
|
+
}
|
|
3103
|
+
|
|
3104
|
+
.neba-anim-scale[data-waiting=''] {
|
|
3105
|
+
scale: none !important;
|
|
3106
|
+
}
|
|
3107
|
+
|
|
3108
|
+
.neba-anim-rotate[data-waiting=''] {
|
|
3109
|
+
rotate: none !important;
|
|
3110
|
+
}
|
|
3111
|
+
|
|
3112
|
+
@media (prefers-reduced-motion: no-preference) and (scripting: enabled) {
|
|
3113
|
+
.neba-anim[data-waiting='shown'] {
|
|
3114
|
+
opacity: 0 !important;
|
|
3115
|
+
}
|
|
3116
|
+
|
|
3117
|
+
.neba-anim-slide[data-waiting='shown'] {
|
|
3118
|
+
translate: none !important;
|
|
3119
|
+
}
|
|
3120
|
+
|
|
3121
|
+
.neba-anim-scale[data-waiting='shown'] {
|
|
3122
|
+
scale: none !important;
|
|
3123
|
+
}
|
|
3124
|
+
|
|
3125
|
+
.neba-anim-rotate[data-waiting='shown'] {
|
|
3126
|
+
rotate: none !important;
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
3129
|
+
|
|
3130
|
+
/*
|
|
3131
|
+
* With scripting off, nothing will ever let a waiting effect go, so it is not
|
|
3132
|
+
* held at all. An entrance waiting for `visible`, `hover` or `manual` sat on an
|
|
3133
|
+
* invisible first frame for good; it is drawn as it ends instead, which is what
|
|
3134
|
+
* the reduced-motion block below does for the same element. A browser that
|
|
3135
|
+
* does not know `scripting` skips the block, and only a reader with scripting
|
|
3136
|
+
* off could tell.
|
|
3137
|
+
*/
|
|
3138
|
+
@media (scripting: none) {
|
|
3139
|
+
.neba-anim[data-state='paused'],
|
|
3140
|
+
[data-state='paused'] .neba-anim {
|
|
3141
|
+
animation: none;
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
|
|
2892
3145
|
/* Symmetric on purpose: a blink that ended anywhere but where it started would
|
|
2893
3146
|
leave the element half drawn whenever the count ran out. */
|
|
2894
3147
|
@keyframes neba-anim-blink {
|
|
@@ -2992,24 +3245,28 @@
|
|
|
2992
3245
|
/*
|
|
2993
3246
|
* Lighting: a light travelling around the outside of something.
|
|
2994
3247
|
*
|
|
2995
|
-
* The arc is a conic gradient and what moves is
|
|
2996
|
-
*
|
|
2997
|
-
*
|
|
2998
|
-
*
|
|
3248
|
+
* The arc is a conic gradient on a square, and what moves is the square, on
|
|
3249
|
+
* `rotate`. The ring around it holds it: a box the size of the element plus the
|
|
3250
|
+
* spread, with the element's corners, clipping the square to itself and
|
|
3251
|
+
* blurring what is left. A rotation is the one way to move the light that the
|
|
3252
|
+
* compositor runs without the page — the arc used to travel on the gradient's
|
|
3253
|
+
* `from` angle, a registered custom property, which restyled and repainted a
|
|
3254
|
+
* blurred gradient on the main thread on every frame for as long as the light
|
|
3255
|
+
* was on. Rotating a box the element's own shape instead swings its corners out
|
|
3256
|
+
* past the element on every quarter turn, which is what the ring is for. The
|
|
3257
|
+
* square is as wide as the ring is wide and tall together, which covers the
|
|
3258
|
+
* ring at every angle, and is measured in the ring's own container units.
|
|
2999
3259
|
*
|
|
3000
3260
|
* `z-index: -1` inside an isolated stacking context puts the glow behind the
|
|
3001
3261
|
* content but still inside the component, so it reads as light escaping from
|
|
3002
3262
|
* under a sheet rather than as a border drawn around one.
|
|
3003
3263
|
*/
|
|
3004
|
-
@property --neba-glow-angle {
|
|
3005
|
-
syntax: '<angle>';
|
|
3006
|
-
initial-value: 0deg;
|
|
3007
|
-
inherits: false;
|
|
3008
|
-
}
|
|
3009
|
-
|
|
3010
3264
|
@keyframes neba-anim-lighting {
|
|
3265
|
+
from {
|
|
3266
|
+
rotate: 0deg;
|
|
3267
|
+
}
|
|
3011
3268
|
to {
|
|
3012
|
-
|
|
3269
|
+
rotate: 360deg;
|
|
3013
3270
|
}
|
|
3014
3271
|
}
|
|
3015
3272
|
|
|
@@ -3018,20 +3275,30 @@
|
|
|
3018
3275
|
isolation: isolate;
|
|
3019
3276
|
}
|
|
3020
3277
|
|
|
3021
|
-
.neba-
|
|
3022
|
-
content: '';
|
|
3278
|
+
.neba-lighting-ring {
|
|
3023
3279
|
position: absolute;
|
|
3024
3280
|
z-index: -1;
|
|
3025
3281
|
inset: calc(-1 * var(--n-anim-glow-width, 3px));
|
|
3282
|
+
overflow: hidden;
|
|
3026
3283
|
border-radius: inherit;
|
|
3284
|
+
filter: blur(var(--n-anim-glow-blur, 4px));
|
|
3285
|
+
container-type: size;
|
|
3286
|
+
pointer-events: none;
|
|
3287
|
+
}
|
|
3288
|
+
|
|
3289
|
+
.neba-lighting-beam {
|
|
3290
|
+
position: absolute;
|
|
3291
|
+
top: 50%;
|
|
3292
|
+
left: 50%;
|
|
3293
|
+
width: calc(100cqw + 100cqh);
|
|
3294
|
+
height: calc(100cqw + 100cqh);
|
|
3295
|
+
translate: -50% -50%;
|
|
3027
3296
|
background: conic-gradient(
|
|
3028
|
-
from var(--neba-glow-angle),
|
|
3029
3297
|
transparent 0deg,
|
|
3030
3298
|
var(--n-anim-glow, var(--n-accent)) var(--n-anim-glow-arc, 50deg),
|
|
3031
3299
|
transparent calc(var(--n-anim-glow-arc, 50deg) * 2),
|
|
3032
3300
|
transparent 360deg
|
|
3033
3301
|
);
|
|
3034
|
-
filter: blur(var(--n-anim-glow-blur, 4px));
|
|
3035
3302
|
animation-name: neba-anim-lighting;
|
|
3036
3303
|
animation-duration: var(--n-anim-duration, 3s);
|
|
3037
3304
|
animation-delay: var(--n-anim-delay, 0ms);
|
|
@@ -3180,6 +3447,38 @@
|
|
|
3180
3447
|
animation: neba-anim-caret 1s step-end infinite;
|
|
3181
3448
|
}
|
|
3182
3449
|
|
|
3450
|
+
/*
|
|
3451
|
+
* The text effects without their motion: AnimateTyping, AnimateScramble and
|
|
3452
|
+
* AnimateCounter.
|
|
3453
|
+
*
|
|
3454
|
+
* Each lays out its final text from the first frame, unseen, under the copy
|
|
3455
|
+
* that moves. A reader who has asked for less motion is shown the final text,
|
|
3456
|
+
* but by the script, which is not there in the server's HTML or until the page
|
|
3457
|
+
* hydrates: until then the line was empty, noise, or the `from` number. With
|
|
3458
|
+
* scripting off it stayed that way. So the stylesheet answers both cases, by
|
|
3459
|
+
* drawing the final layer and not the moving one — which is also what the
|
|
3460
|
+
* script draws once it runs, so nothing moves when it does. The moving layer
|
|
3461
|
+
* and a counter's `from` are taken out of the layout as well as out of sight:
|
|
3462
|
+
* the script lets `from` go once the answer is drawn, and a box still as wide
|
|
3463
|
+
* as `1,000` around a `5` closed up the moment it did. A browser that does not
|
|
3464
|
+
* know `scripting` keeps the reduced-motion half.
|
|
3465
|
+
*/
|
|
3466
|
+
@media (prefers-reduced-motion: reduce), (scripting: none) {
|
|
3467
|
+
[data-neba-animation] .neba-text-final,
|
|
3468
|
+
[data-neba-animation] .neba-text-noise {
|
|
3469
|
+
visibility: visible;
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3472
|
+
[data-neba-animation] .neba-text-moving,
|
|
3473
|
+
[data-neba-animation] .neba-text-final ~ [data-sample] {
|
|
3474
|
+
display: none;
|
|
3475
|
+
}
|
|
3476
|
+
|
|
3477
|
+
[data-neba-animation] .neba-text-noise::after {
|
|
3478
|
+
content: none;
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3183
3482
|
/* ---------------------------------------------------------------------------
|
|
3184
3483
|
* Text arriving from somewhere else
|
|
3185
3484
|
*
|
|
@@ -3201,8 +3500,12 @@
|
|
|
3201
3500
|
}
|
|
3202
3501
|
}
|
|
3203
3502
|
|
|
3503
|
+
/* `backwards` rather than `both`: the keyframe ends on the word's own opacity,
|
|
3504
|
+
so holding its last frame draws nothing, and a word whose fade is over is
|
|
3505
|
+
then an element with no animation on it rather than one still holding a
|
|
3506
|
+
finished one, which the browser keeps in its list of effects to restyle. */
|
|
3204
3507
|
.neba-stream-word {
|
|
3205
|
-
animation: neba-stream-word-in var(--neba-duration) var(--neba-ease)
|
|
3508
|
+
animation: neba-stream-word-in var(--neba-duration) var(--neba-ease) backwards;
|
|
3206
3509
|
}
|
|
3207
3510
|
|
|
3208
3511
|
/* The block at the end of a stream. The same caret an `AnimateTyping` draws,
|
|
@@ -3269,6 +3572,7 @@
|
|
|
3269
3572
|
inset-inline-start: 0;
|
|
3270
3573
|
inline-size: 100%;
|
|
3271
3574
|
background-image: none;
|
|
3575
|
+
background-color: var(--n-panel-press);
|
|
3272
3576
|
animation: neba-skeleton-pulse 2.4s var(--neba-ease) infinite;
|
|
3273
3577
|
}
|
|
3274
3578
|
|
|
@@ -3319,9 +3623,12 @@
|
|
|
3319
3623
|
|
|
3320
3624
|
/* The arc stops travelling and becomes an even glow. The same trade the
|
|
3321
3625
|
skeleton makes: the decoration survives, the motion does not. */
|
|
3322
|
-
.neba-
|
|
3626
|
+
.neba-lighting-ring {
|
|
3323
3627
|
background: var(--n-anim-glow, var(--n-accent));
|
|
3324
|
-
|
|
3628
|
+
}
|
|
3629
|
+
|
|
3630
|
+
.neba-lighting-beam {
|
|
3631
|
+
display: none;
|
|
3325
3632
|
}
|
|
3326
3633
|
|
|
3327
3634
|
/* A marquee that cannot move is a row of content, so it is drawn as one:
|