awesome-galaxy-orbit-carousel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +348 -0
- package/dist/assets/index-BsEGzit1.css +1 -0
- package/dist/assets/index-EEJeq21F.js +49 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.js +469 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.html +17 -0
- package/dist/style.css +61 -0
- package/dist/types/App.d.ts +2 -0
- package/dist/types/App.d.ts.map +1 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/AwesomeGalaxyOrbitCarousel.d.ts +3 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/AwesomeGalaxyOrbitCarousel.d.ts.map +1 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/GalaxyCore.d.ts +12 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/GalaxyCore.d.ts.map +1 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/OrbitRing.d.ts +18 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/OrbitRing.d.ts.map +1 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/index.d.ts +3 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/index.d.ts.map +1 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/orbitalMath.d.ts +52 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/orbitalMath.d.ts.map +1 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/types.d.ts +37 -0
- package/dist/types/components/AwesomeGalaxyOrbitCarousel/types.d.ts.map +1 -0
- package/dist/types/hooks/useAutoplay.d.ts +15 -0
- package/dist/types/hooks/useAutoplay.d.ts.map +1 -0
- package/dist/types/hooks/useDragRotation.d.ts +13 -0
- package/dist/types/hooks/useDragRotation.d.ts.map +1 -0
- package/dist/types/hooks/useRotationPhysics.d.ts +20 -0
- package/dist/types/hooks/useRotationPhysics.d.ts.map +1 -0
- package/dist/types/hooks/useSphereLayout.d.ts +7 -0
- package/dist/types/hooks/useSphereLayout.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/main.d.ts +2 -0
- package/dist/types/main.d.ts.map +1 -0
- package/dist/types/math/sphericalCoordinates.d.ts +27 -0
- package/dist/types/math/sphericalCoordinates.d.ts.map +1 -0
- package/dist/types/themes/index.d.ts +20 -0
- package/dist/types/themes/index.d.ts.map +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# awesome-galaxy-orbit-carousel
|
|
2
|
+
|
|
3
|
+
A stunning **galaxy-themed 3D orbital carousel** React component. Slides orbit the central core on tilted elliptical rings with Kepler-inspired depth scaling, gravitational pull focus animations, a pulsing sci-fi core, starfield background, and full keyboard navigation — zero external dependencies beyond React.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Multi-ring elliptical orbits** — slides distributed across 1–4 rings, auto-computed from slide count or fully customisable
|
|
10
|
+
- **Kepler-inspired depth** — slides closer to the viewer scale up and brighten; distant slides fade back
|
|
11
|
+
- **Gravitational pull animation** — clicking or auto-advancing a slide triggers a visual "pull" before focus locks
|
|
12
|
+
- **Animated galaxy core** — pulsing orb at center updates colour to match the focused slide
|
|
13
|
+
- **Orbit path rings** — decorative ellipse outlines with per-ring accent tints
|
|
14
|
+
- **Starfield + nebula background** — 120 blinking stars and radial nebula clouds
|
|
15
|
+
- **Autoplay with configurable interval** — pauses on hover automatically
|
|
16
|
+
- **Keyboard navigation** — `←` / `→` to cycle slides, `Enter` to fire `onClick`
|
|
17
|
+
- **Planet cards** — each slide renders as a card with image, tag badge, title, description, and an Explore CTA on focus
|
|
18
|
+
- **ESM + CJS dual build** — works in Vite, Next.js, CRA, and any modern bundler
|
|
19
|
+
- **Full TypeScript types** included
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install awesome-galaxy-orbit-carousel
|
|
27
|
+
# or
|
|
28
|
+
yarn add awesome-galaxy-orbit-carousel
|
|
29
|
+
# or
|
|
30
|
+
pnpm add awesome-galaxy-orbit-carousel
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
> **Peer dependencies** — React ≥ 17 and ReactDOM ≥ 17 must already be installed.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Importing Styles
|
|
38
|
+
|
|
39
|
+
The component relies on keyframe animations (`pulseGlow`, `coreSpin`, `corePulse`, `ringPulse`, `fadeUp`) and CSS custom properties (`--font-display`, `--font-body`) declared in a separate stylesheet. Import it **once** at your app root:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import 'awesome-galaxy-orbit-carousel/style.css';
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For the best visual result, load these Google Fonts in your `index.html` `<head>`:
|
|
46
|
+
|
|
47
|
+
```html
|
|
48
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
49
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
50
|
+
<link
|
|
51
|
+
href="https://fonts.googleapis.com/css2?family=Syne:wght@700;800;900&family=DM+Sans:wght@300;400;500&display=swap"
|
|
52
|
+
rel="stylesheet"
|
|
53
|
+
/>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> The component still renders correctly without the fonts — it falls back to `sans-serif`.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Quick Start
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
import { AwesomeGalaxyOrbitCarousel } from 'awesome-galaxy-orbit-carousel';
|
|
64
|
+
import 'awesome-galaxy-orbit-carousel/style.css';
|
|
65
|
+
|
|
66
|
+
const slides = [
|
|
67
|
+
{ title: 'Aurora', description: 'Northern lights over the tundra.', color: '#020d2e', tag: 'Nature' },
|
|
68
|
+
{ title: 'Nebula', description: 'Star-forming clouds in deep space.', color: '#120a2e', tag: 'Space' },
|
|
69
|
+
{ title: 'Coral', description: 'Vibrant reef ecosystems underwater.', color: '#0d1f0a', tag: 'Ocean' },
|
|
70
|
+
{ title: 'Volcano', description: 'Raw power erupting from the Earth.', color: '#1a0a0a', tag: 'Earth' },
|
|
71
|
+
{ title: 'Glacier', description: 'Ancient ice slowly carving valleys.', color: '#0a1e2e', tag: 'Arctic' },
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
export default function App() {
|
|
75
|
+
return (
|
|
76
|
+
<div style={{ width: '100vw', height: '100vh' }}>
|
|
77
|
+
<AwesomeGalaxyOrbitCarousel data={slides} />
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Props
|
|
86
|
+
|
|
87
|
+
| Prop | Type | Default | Description |
|
|
88
|
+
|---|---|---|---|
|
|
89
|
+
| `data` | `OrbitSlide[]` | **required** | Array of slide objects. See `OrbitSlide` below. Minimum 2 slides recommended. |
|
|
90
|
+
| `rings` | `OrbitRingConfig[]` | auto | Ring layout config. Auto-computed from slide count if omitted. |
|
|
91
|
+
| `intervalSeconds` | `number` | `4` | Seconds between auto-focus advances. |
|
|
92
|
+
| `autoRotate` | `boolean` | `true` | Whether slides auto-advance and the rings continuously rotate. |
|
|
93
|
+
| `onFocusChange` | `(index: number) => void` | — | Fired after each focus transition completes with the new 0-based index. |
|
|
94
|
+
| `width` | `number \| string` | `'100%'` | CSS width of the component container. |
|
|
95
|
+
| `height` | `number \| string` | `'100%'` | CSS height of the component container. |
|
|
96
|
+
| `className` | `string` | — | Optional CSS class applied to the root container. |
|
|
97
|
+
|
|
98
|
+
### `OrbitSlide` object
|
|
99
|
+
|
|
100
|
+
| Field | Type | Required | Description |
|
|
101
|
+
|---|---|---|---|
|
|
102
|
+
| `title` | `string` | ✅ | Main heading on the planet card. Also used as the two-letter placeholder when no image is provided. |
|
|
103
|
+
| `description` | `string` | ➖ | Short body text shown on the card. |
|
|
104
|
+
| `image` | `string` | ➖ | URL of a cover image displayed at the top of the card. |
|
|
105
|
+
| `tag` | `string` | ➖ | Small badge shown top-right of the card image area. |
|
|
106
|
+
| `color` | `string` | ➖ | Hex background colour of the card (e.g. `'#020d2e'`). Maps to a vibrant accent used for glows and borders. |
|
|
107
|
+
| `onClick` | `() => void` | ➖ | Fired when the focused card's **Explore →** button is clicked, or when `Enter` is pressed while the slide is focused. |
|
|
108
|
+
|
|
109
|
+
### `OrbitRingConfig` object
|
|
110
|
+
|
|
111
|
+
Only needed if you want to override the automatic ring layout.
|
|
112
|
+
|
|
113
|
+
| Field | Type | Required | Description |
|
|
114
|
+
|---|---|---|---|
|
|
115
|
+
| `count` | `number` | ✅ | Number of slides to place on this ring. |
|
|
116
|
+
| `radiusX` | `number` | ✅ | Semi-major axis in px (horizontal spread). |
|
|
117
|
+
| `radiusY` | `number` | ✅ | Semi-minor axis in px (vertical spread — smaller = more elliptical). |
|
|
118
|
+
| `period` | `number` | ✅ | Orbital period in seconds. Negative value reverses direction. |
|
|
119
|
+
| `phaseOffset` | `number` | ➖ | Starting angle offset in radians. Staggers ring start positions. |
|
|
120
|
+
| `tilt` | `number` | ➖ | Tilt of the orbital plane in degrees — creates the 3D inclined look. |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Examples
|
|
125
|
+
|
|
126
|
+
### Example 1 — Minimal, no images
|
|
127
|
+
|
|
128
|
+
```jsx
|
|
129
|
+
import { AwesomeGalaxyOrbitCarousel } from 'awesome-galaxy-orbit-carousel';
|
|
130
|
+
import 'awesome-galaxy-orbit-carousel/style.css';
|
|
131
|
+
|
|
132
|
+
var slides = [
|
|
133
|
+
{ title: 'Mercury', description: 'Closest planet to the Sun.', color: '#1a1a1a', tag: 'Planet' },
|
|
134
|
+
{ title: 'Venus', description: 'Hottest planet in the solar system.', color: '#1a1200', tag: 'Planet' },
|
|
135
|
+
{ title: 'Earth', description: 'Our pale blue dot.', color: '#0a1628', tag: 'Planet' },
|
|
136
|
+
{ title: 'Mars', description: 'The red, dusty frontier.', color: '#1a0a0a', tag: 'Planet' },
|
|
137
|
+
{ title: 'Jupiter', description: 'King of the gas giants.', color: '#120f0a', tag: 'Planet' },
|
|
138
|
+
{ title: 'Saturn', description: 'Famous for its ring system.', color: '#141008', tag: 'Planet' },
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
export default function PlanetsDemo() {
|
|
142
|
+
return (
|
|
143
|
+
<div style={{ width: '100vw', height: '100vh' }}>
|
|
144
|
+
<AwesomeGalaxyOrbitCarousel data={slides} />
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### Example 2 — Full featured with images, callbacks, and custom size
|
|
153
|
+
|
|
154
|
+
```jsx
|
|
155
|
+
import { useState } from 'react';
|
|
156
|
+
import { AwesomeGalaxyOrbitCarousel } from 'awesome-galaxy-orbit-carousel';
|
|
157
|
+
import 'awesome-galaxy-orbit-carousel/style.css';
|
|
158
|
+
|
|
159
|
+
var slides = [
|
|
160
|
+
{
|
|
161
|
+
title: 'Arctic',
|
|
162
|
+
description: 'Vast frozen tundra lit only by the polar glow.',
|
|
163
|
+
tag: 'Explore',
|
|
164
|
+
color: '#020d2e',
|
|
165
|
+
image: 'https://images.unsplash.com/photo-1517411032315-54ef2cb783bb?w=600',
|
|
166
|
+
onClick: function() { window.open('https://example.com/arctic', '_blank'); },
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
title: 'Desert',
|
|
170
|
+
description: 'Golden sand sculpted by the wind into endless dunes.',
|
|
171
|
+
tag: 'Journey',
|
|
172
|
+
color: '#1a0f00',
|
|
173
|
+
image: 'https://images.unsplash.com/photo-1509316785289-025f5b846b35?w=600',
|
|
174
|
+
onClick: function() { window.open('https://example.com/desert', '_blank'); },
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
title: 'Jungle',
|
|
178
|
+
description: 'A cathedral of ancient trees alive with unseen creatures.',
|
|
179
|
+
tag: 'Wildlife',
|
|
180
|
+
color: '#0d1f0a',
|
|
181
|
+
image: 'https://images.unsplash.com/photo-1448375240586-882707db888b?w=600',
|
|
182
|
+
onClick: function() { window.open('https://example.com/jungle', '_blank'); },
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
title: 'Abyss',
|
|
186
|
+
description: "The deep ocean floor — Earth's last frontier.",
|
|
187
|
+
tag: 'Discovery',
|
|
188
|
+
color: '#001820',
|
|
189
|
+
image: 'https://images.unsplash.com/photo-1518020382113-a7e8fc38eac9?w=600',
|
|
190
|
+
onClick: function() { window.open('https://example.com/abyss', '_blank'); },
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
title: 'Summit',
|
|
194
|
+
description: 'Where the air thins and the world lies below.',
|
|
195
|
+
tag: 'Adventure',
|
|
196
|
+
color: '#0f0f18',
|
|
197
|
+
image: 'https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=600',
|
|
198
|
+
onClick: function() { window.open('https://example.com/summit', '_blank'); },
|
|
199
|
+
},
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
export default function FullFeaturedDemo() {
|
|
203
|
+
var [activeIndex, setActiveIndex] = useState(0);
|
|
204
|
+
|
|
205
|
+
return (
|
|
206
|
+
<div style={{ position: 'relative', width: '100vw', height: '100vh' }}>
|
|
207
|
+
|
|
208
|
+
{/* Slide counter overlay */}
|
|
209
|
+
<div style={{
|
|
210
|
+
position: 'absolute', top: 20, right: 24, zIndex: 100,
|
|
211
|
+
color: '#00f5ff', fontFamily: 'monospace', fontSize: '13px',
|
|
212
|
+
background: 'rgba(0,0,0,0.4)', padding: '6px 14px', borderRadius: '20px',
|
|
213
|
+
border: '1px solid rgba(0,245,255,0.2)',
|
|
214
|
+
}}>
|
|
215
|
+
{activeIndex + 1} / {slides.length} — {slides[activeIndex].title}
|
|
216
|
+
</div>
|
|
217
|
+
|
|
218
|
+
<AwesomeGalaxyOrbitCarousel
|
|
219
|
+
data={slides}
|
|
220
|
+
intervalSeconds={5}
|
|
221
|
+
autoRotate={true}
|
|
222
|
+
width="100%"
|
|
223
|
+
height="100%"
|
|
224
|
+
onFocusChange={function(index) { setActiveIndex(index); }}
|
|
225
|
+
/>
|
|
226
|
+
</div>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### Example 3 — Custom ring layout (`autoRotate={false}` + manual rings)
|
|
234
|
+
|
|
235
|
+
Override the automatic ring layout and disable autoplay to drive navigation with your own buttons.
|
|
236
|
+
|
|
237
|
+
```jsx
|
|
238
|
+
import { useState } from 'react';
|
|
239
|
+
import { AwesomeGalaxyOrbitCarousel } from 'awesome-galaxy-orbit-carousel';
|
|
240
|
+
import 'awesome-galaxy-orbit-carousel/style.css';
|
|
241
|
+
|
|
242
|
+
var slides = [
|
|
243
|
+
{ title: 'Hydrogen', description: 'The most abundant element.', color: '#080022', tag: '#1' },
|
|
244
|
+
{ title: 'Helium', description: 'Noble gas, second lightest.', color: '#020d2e', tag: '#2' },
|
|
245
|
+
{ title: 'Carbon', description: 'Basis of all organic life.', color: '#0d1f0a', tag: '#6' },
|
|
246
|
+
{ title: 'Oxygen', description: 'Essential for respiration.', color: '#001820', tag: '#8' },
|
|
247
|
+
{ title: 'Iron', description: 'Core of the Earth itself.', color: '#1a0a0a', tag: '#26' },
|
|
248
|
+
{ title: 'Gold', description: 'Prized across all cultures.', color: '#1a1200', tag: '#79' },
|
|
249
|
+
{ title: 'Uranium', description: 'Heaviest natural element.', color: '#0a1e2e', tag: '#92' },
|
|
250
|
+
];
|
|
251
|
+
|
|
252
|
+
// Two custom rings: 3 slides on inner, 4 on outer
|
|
253
|
+
var customRings = [
|
|
254
|
+
{ count: 3, radiusX: 200, radiusY: 85, period: 10, phaseOffset: 0, tilt: 14 },
|
|
255
|
+
{ count: 4, radiusX: 340, radiusY: 130, period: 18, phaseOffset: Math.PI / 4, tilt: 22 },
|
|
256
|
+
];
|
|
257
|
+
|
|
258
|
+
var btnStyle = {
|
|
259
|
+
padding: '10px 28px',
|
|
260
|
+
background: 'rgba(0,245,255,0.08)',
|
|
261
|
+
border: '1px solid rgba(0,245,255,0.3)',
|
|
262
|
+
color: '#00f5ff',
|
|
263
|
+
borderRadius: '100px',
|
|
264
|
+
cursor: 'pointer',
|
|
265
|
+
fontFamily: 'sans-serif',
|
|
266
|
+
fontSize: '13px',
|
|
267
|
+
letterSpacing: '0.08em',
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export default function CustomRingsDemo() {
|
|
271
|
+
var [focused, setFocused] = useState(0);
|
|
272
|
+
var total = slides.length;
|
|
273
|
+
|
|
274
|
+
function prev() {
|
|
275
|
+
setFocused(function(i) { return (i - 1 + total) % total; });
|
|
276
|
+
}
|
|
277
|
+
function next() {
|
|
278
|
+
setFocused(function(i) { return (i + 1) % total; });
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return (
|
|
282
|
+
<div style={{ position: 'relative', width: '100vw', height: '100vh' }}>
|
|
283
|
+
|
|
284
|
+
<AwesomeGalaxyOrbitCarousel
|
|
285
|
+
key={focused}
|
|
286
|
+
data={slides}
|
|
287
|
+
rings={customRings}
|
|
288
|
+
autoRotate={false}
|
|
289
|
+
width="100%"
|
|
290
|
+
height="100%"
|
|
291
|
+
onFocusChange={setFocused}
|
|
292
|
+
/>
|
|
293
|
+
|
|
294
|
+
{/* Navigation buttons */}
|
|
295
|
+
<div style={{
|
|
296
|
+
position: 'absolute', bottom: 40, left: '50%',
|
|
297
|
+
transform: 'translateX(-50%)',
|
|
298
|
+
display: 'flex', gap: '16px', zIndex: 100,
|
|
299
|
+
}}>
|
|
300
|
+
<button style={btnStyle} onClick={prev}>← Prev</button>
|
|
301
|
+
<button style={btnStyle} onClick={next}>Next →</button>
|
|
302
|
+
</div>
|
|
303
|
+
|
|
304
|
+
{/* Focused slide label */}
|
|
305
|
+
<div style={{
|
|
306
|
+
position: 'absolute', top: 24, left: '50%',
|
|
307
|
+
transform: 'translateX(-50%)',
|
|
308
|
+
color: '#fff', fontFamily: 'sans-serif', fontSize: '14px',
|
|
309
|
+
background: 'rgba(0,0,0,0.5)', padding: '6px 18px', borderRadius: '20px',
|
|
310
|
+
border: '1px solid rgba(255,255,255,0.12)',
|
|
311
|
+
whiteSpace: 'nowrap', zIndex: 100,
|
|
312
|
+
}}>
|
|
313
|
+
Focused: {slides[focused].title}
|
|
314
|
+
</div>
|
|
315
|
+
|
|
316
|
+
</div>
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## CSS Custom Properties
|
|
322
|
+
|
|
323
|
+
Override fonts in your own `:root`:
|
|
324
|
+
|
|
325
|
+
```css
|
|
326
|
+
:root {
|
|
327
|
+
--font-display: 'Your Display Font', sans-serif;
|
|
328
|
+
--font-body: 'Your Body Font', sans-serif;
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Default values are `'Syne'` (display, weights 700–900) and `'DM Sans'` (body, weights 300–500).
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Keyboard Controls
|
|
337
|
+
|
|
338
|
+
| Key | Action |
|
|
339
|
+
|---|---|
|
|
340
|
+
| `→` | Focus next slide |
|
|
341
|
+
| `←` | Focus previous slide |
|
|
342
|
+
| `Enter` | Fire `onClick` of the currently focused slide |
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## License
|
|
347
|
+
|
|
348
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:root{--bg-primary: #030712;--bg-secondary: #0a0f1e;--accent-cyan: #00f5ff;--accent-violet: #7c3aed;--accent-amber: #f59e0b;--text-primary: #f1f5f9;--text-secondary: #94a3b8;--font-display: "Syne", sans-serif;--font-body: "DM Sans", sans-serif}html,body,#root{width:100%;height:100%;overflow:hidden}body{background:var(--bg-primary);color:var(--text-primary);font-family:var(--font-body);-webkit-font-smoothing:antialiased}@keyframes pulseGlow{0%,to{opacity:.3;transform:scale(1)}50%{opacity:.9;transform:scale(1.3)}}@keyframes fadeUp{0%{opacity:0;transform:translate(-50%) translateY(12px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@keyframes coreSpin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes corePulse{0%,to{box-shadow:0 0 30px #00f5ff66,0 0 60px #00f5ff22;transform:scale(1)}50%{box-shadow:0 0 50px #00f5ffaa,0 0 100px #00f5ff44;transform:scale(1.08)}}@keyframes ringPulse{0%,to{opacity:.06;transform:scale(1)}50%{opacity:.18;transform:scale(1.06)}}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{opacity:1;filter:invert(1) brightness(.5)}
|