create-playcanvas 0.2.6 → 0.3.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/README.md +39 -47
- package/dist/index.mjs +48 -47
- package/package.json +53 -49
- package/templates/index.ts +15 -57
- package/templates/react-ts/README.md +32 -59
- package/templates/react-ts/eslint.config.mjs +14 -0
- package/templates/react-ts/index.html +10 -10
- package/templates/react-ts/package.json +34 -27
- package/templates/react-ts/prettier.config.mjs +1 -0
- package/templates/react-ts/src/App.css +37 -49
- package/templates/react-ts/src/App.tsx +38 -41
- package/templates/react-ts/src/Scene.tsx +50 -50
- package/templates/react-ts/src/index.css +30 -52
- package/templates/react-ts/src/main.tsx +9 -8
- package/templates/react-ts/src/vite-env.d.ts +12 -0
- package/templates/react-ts/tsconfig.json +24 -5
- package/templates/react-ts/vite.config.ts +4 -4
- package/templates/vanilla-ts/README.md +31 -91
- package/templates/vanilla-ts/eslint.config.mjs +3 -0
- package/templates/vanilla-ts/index.html +10 -10
- package/templates/vanilla-ts/package.json +28 -21
- package/templates/vanilla-ts/prettier.config.mjs +1 -0
- package/templates/vanilla-ts/src/App.ts +149 -151
- package/templates/vanilla-ts/src/main.ts +7 -7
- package/templates/vanilla-ts/src/style.css +60 -93
- package/templates/vanilla-ts/src/utils.ts +9 -8
- package/templates/vanilla-ts/src/vite-env.d.ts +12 -0
- package/templates/vanilla-ts/tsconfig.json +22 -22
- package/index.js +0 -3
- package/templates/react-ts/scripts/ensure-node-version.cjs +0 -12
- package/templates/react-ts/tsconfig.app.json +0 -27
- package/templates/react-ts/tsconfig.node.json +0 -25
- package/templates/vanilla-ts/scripts/ensure-node-version.cjs +0 -12
|
@@ -1,82 +1,55 @@
|
|
|
1
|
-
#
|
|
1
|
+
# PlayCanvas React + TypeScript Starter
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A Vite-powered `@playcanvas/react` project with TypeScript, hot module replacement, ESLint and Prettier.
|
|
4
4
|
|
|
5
5
|
## Prerequisites
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Node.js 22.23.2 or later.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
nvm install 22 # or 20.19+
|
|
11
|
-
nvm use 22
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## Getting Started
|
|
17
|
-
|
|
18
|
-
Scaffold and install dependencies:
|
|
9
|
+
## Getting started
|
|
19
10
|
|
|
20
11
|
```bash
|
|
21
|
-
npm create playcanvas@latest -
|
|
12
|
+
npm create playcanvas@latest playcanvas-project -- --template react-ts
|
|
22
13
|
cd playcanvas-project
|
|
23
14
|
npm install
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Start the dev server with hot-module reload:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
15
|
npm run dev
|
|
30
16
|
```
|
|
31
17
|
|
|
32
|
-
Open <http://localhost:5173
|
|
33
|
-
|
|
34
|
-
---
|
|
18
|
+
Open <http://localhost:5173>. Edit `src/Scene.tsx` to test hot module replacement.
|
|
35
19
|
|
|
36
20
|
## Scripts
|
|
37
21
|
|
|
38
|
-
| Command
|
|
39
|
-
|
|
40
|
-
| `npm run dev`
|
|
41
|
-
| `npm run build`
|
|
42
|
-
| `npm run
|
|
43
|
-
| `npm run lint`
|
|
22
|
+
| Command | Description |
|
|
23
|
+
| ------------------- | --------------------------------- |
|
|
24
|
+
| `npm run dev` | Start the Vite development server |
|
|
25
|
+
| `npm run build` | Build for production |
|
|
26
|
+
| `npm run start` | Preview the production build |
|
|
27
|
+
| `npm run lint` | Run ESLint |
|
|
28
|
+
| `npm run fmt` | Check formatting |
|
|
29
|
+
| `npm run typecheck` | Run TypeScript checks |
|
|
44
30
|
|
|
45
|
-
|
|
31
|
+
## Project structure
|
|
46
32
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```
|
|
33
|
+
```text
|
|
50
34
|
.
|
|
51
|
-
├── public/
|
|
35
|
+
├── public/
|
|
36
|
+
│ └── environment-map.png
|
|
52
37
|
├── src/
|
|
53
|
-
│ ├──
|
|
54
|
-
│ ├── App.tsx
|
|
55
|
-
│
|
|
56
|
-
|
|
57
|
-
|
|
38
|
+
│ ├── assets/
|
|
39
|
+
│ ├── App.tsx
|
|
40
|
+
│ ├── Scene.tsx
|
|
41
|
+
│ └── main.tsx
|
|
42
|
+
├── eslint.config.mjs
|
|
43
|
+
├── index.html
|
|
44
|
+
├── tsconfig.json
|
|
45
|
+
└── vite.config.ts
|
|
58
46
|
```
|
|
59
47
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
ESLint is pre-configured with TypeScript, React hooks, React Refresh, and global browser/node globals. Adjust `eslint.config.js` as your codebase grows.
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## Deployment
|
|
67
|
-
|
|
68
|
-
Run `npm run build` to generate a static production bundle in `dist/`. Deploy the contents of that folder to any static hosting provider (Netlify, Vercel, GitHub Pages, Cloudflare Pages, etc.).
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
## Further Reading
|
|
73
|
-
|
|
74
|
-
* [PlayCanvas Engine Docs](https://developer.playcanvas.com)
|
|
75
|
-
* [PlayCanvas React Docs](https://developer.playcanvas.com/user-manual/react/)
|
|
76
|
-
* [React Docs](https://react.dev/)
|
|
77
|
-
* [Vite Docs](https://vitejs.dev/)
|
|
78
|
-
* [TypeScript Handbook](https://www.typescriptlang.org/docs/)
|
|
48
|
+
Run `npm run build` to generate a deployable static site in `dist/`.
|
|
79
49
|
|
|
80
|
-
|
|
50
|
+
## Further reading
|
|
81
51
|
|
|
82
|
-
|
|
52
|
+
- [PlayCanvas React manual](https://developer.playcanvas.com/user-manual/react/)
|
|
53
|
+
- [React documentation](https://react.dev/)
|
|
54
|
+
- [Vite documentation](https://vite.dev/)
|
|
55
|
+
- [TypeScript documentation](https://www.typescriptlang.org/docs/)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import reactConfig from '@playcanvas/eslint-config/react';
|
|
2
|
+
import typescriptConfig from '@playcanvas/eslint-config/typescript';
|
|
3
|
+
|
|
4
|
+
export default [
|
|
5
|
+
...typescriptConfig,
|
|
6
|
+
...reactConfig,
|
|
7
|
+
{
|
|
8
|
+
rules: {
|
|
9
|
+
'react/jsx-uses-react': 'off',
|
|
10
|
+
'react/prop-types': 'off',
|
|
11
|
+
'react/react-in-jsx-scope': 'off'
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
];
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/png" href="/src/assets/playcanvas.png" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>PlayCanvas + React + TS</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
+
</body>
|
|
13
13
|
</html>
|
|
@@ -1,29 +1,36 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
2
|
+
"name": "playcanvas-project",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "A PlayCanvas React project",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"dev": "vite",
|
|
10
|
+
"fmt": "prettier --check .",
|
|
11
|
+
"fmt:fix": "prettier --write .",
|
|
12
|
+
"lint": "eslint .",
|
|
13
|
+
"lint:fix": "eslint . --fix",
|
|
14
|
+
"start": "vite preview",
|
|
15
|
+
"typecheck": "tsc --noEmit"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@playcanvas/react": "^0.11.5",
|
|
19
|
+
"playcanvas": "^2.21.3",
|
|
20
|
+
"react": "^19.2.8",
|
|
21
|
+
"react-dom": "^19.2.8"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@playcanvas/eslint-config": "3.0.0-beta.8",
|
|
25
|
+
"@types/react": "^19.2.18",
|
|
26
|
+
"@types/react-dom": "^19.2.4",
|
|
27
|
+
"@vitejs/plugin-react": "^6.0.5",
|
|
28
|
+
"eslint": "^9.39.5",
|
|
29
|
+
"prettier": "^3.9.6",
|
|
30
|
+
"typescript": "~6.0.3",
|
|
31
|
+
"vite": "^8.2.0"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=22.23.2"
|
|
35
|
+
}
|
|
29
36
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@playcanvas/eslint-config/prettier';
|
|
@@ -1,87 +1,75 @@
|
|
|
1
1
|
#root {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
height: 100vh;
|
|
5
|
+
width: 100vw;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
header {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: row;
|
|
11
|
+
align-items: center;
|
|
12
|
+
padding: 2rem;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
.absolute {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
position: absolute;
|
|
17
|
+
top: 0;
|
|
18
|
+
left: 0;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
.full-bleed {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
width: 100vw;
|
|
23
|
+
height: 100vh;
|
|
24
|
+
overflow: hidden;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
.logo {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
height: 2em;
|
|
29
|
+
padding: 0.5em;
|
|
30
|
+
will-change: filter;
|
|
31
|
+
transition: filter 300ms;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
.playcanvas-logo {
|
|
35
|
-
|
|
35
|
+
border-radius: 100%;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
.logo:hover {
|
|
39
|
-
|
|
39
|
+
filter: drop-shadow(0 0 2em #646cffaa);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
.logo.react:hover {
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.card {
|
|
47
|
-
padding: 2em;
|
|
43
|
+
filter: drop-shadow(0 0 2em #61dafbaa);
|
|
48
44
|
}
|
|
49
45
|
|
|
50
46
|
.read-the-docs {
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.container{
|
|
55
|
-
position: absolute;
|
|
56
|
-
top: 0;
|
|
57
|
-
left: 0;
|
|
58
|
-
display: flex;
|
|
47
|
+
color: #888;
|
|
59
48
|
}
|
|
60
49
|
|
|
61
50
|
.overlay {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
51
|
+
margin: 0 auto;
|
|
52
|
+
text-align: center;
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
align-items: center;
|
|
56
|
+
justify-content: stretch;
|
|
57
|
+
width: 100vw;
|
|
58
|
+
height: 100vh;
|
|
59
|
+
pointer-events: none;
|
|
71
60
|
}
|
|
72
61
|
|
|
73
62
|
.overlay a {
|
|
74
|
-
|
|
63
|
+
pointer-events: auto;
|
|
75
64
|
}
|
|
76
65
|
|
|
77
66
|
.overlay > .grow {
|
|
78
|
-
|
|
67
|
+
flex-grow: 1;
|
|
79
68
|
}
|
|
80
69
|
|
|
81
70
|
.pill {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
71
|
+
background-color: #000;
|
|
72
|
+
color: #fff;
|
|
73
|
+
padding: 0.5rem 1rem;
|
|
74
|
+
border-radius: 0.5rem;
|
|
86
75
|
}
|
|
87
|
-
|
|
@@ -1,46 +1,43 @@
|
|
|
1
|
-
import { Application } from
|
|
2
|
-
import { useState } from 'react'
|
|
3
|
-
|
|
4
|
-
import playcanvasLogo from './assets/playcanvas.png'
|
|
5
|
-
import './
|
|
6
|
-
import
|
|
1
|
+
import { Application } from '@playcanvas/react';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
|
|
4
|
+
import playcanvasLogo from './assets/playcanvas.png';
|
|
5
|
+
import reactLogo from './assets/react.svg';
|
|
6
|
+
import './App.css';
|
|
7
|
+
import Scene from './Scene';
|
|
7
8
|
|
|
8
9
|
function App() {
|
|
9
|
-
|
|
10
|
+
const [count, setCount] = useState(0);
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
</p>
|
|
41
|
-
</div>
|
|
42
|
-
</>
|
|
43
|
-
)
|
|
12
|
+
return (
|
|
13
|
+
<>
|
|
14
|
+
<div className="full-bleed">
|
|
15
|
+
<Application className="playcanvas-app">
|
|
16
|
+
<Scene onClick={() => setCount((count) => count + 1)} />
|
|
17
|
+
</Application>
|
|
18
|
+
</div>
|
|
19
|
+
<div className="absolute overlay">
|
|
20
|
+
<div className="grow">
|
|
21
|
+
<header>
|
|
22
|
+
<h1>PlayCanvas + React</h1>
|
|
23
|
+
<a href="https://developer.playcanvas.com/user-manual/react/" target="_blank" rel="noreferrer">
|
|
24
|
+
<img src={playcanvasLogo} className="playcanvas-logo logo" alt="PlayCanvas logo" />
|
|
25
|
+
</a>
|
|
26
|
+
<a href="https://react.dev" target="_blank" rel="noreferrer">
|
|
27
|
+
<img src={reactLogo} className="logo react" alt="React logo" />
|
|
28
|
+
</a>
|
|
29
|
+
</header>
|
|
30
|
+
</div>
|
|
31
|
+
<div>
|
|
32
|
+
<span className="pill">Click Count: {count}</span>
|
|
33
|
+
<p>
|
|
34
|
+
Edit <code>src/Scene.tsx</code> and save to test HMR
|
|
35
|
+
</p>
|
|
36
|
+
</div>
|
|
37
|
+
<p className="read-the-docs">Click on the PlayCanvas and React logos to learn more</p>
|
|
38
|
+
</div>
|
|
39
|
+
</>
|
|
40
|
+
);
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
export default App
|
|
43
|
+
export default App;
|
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { useEnvAtlas, useMaterial } from "@playcanvas/react/hooks";
|
|
8
|
-
import { Camera, Environment, Render, Script } from "@playcanvas/react/components";
|
|
1
|
+
import { Entity } from '@playcanvas/react';
|
|
2
|
+
import { Camera, Environment, Render, Script } from '@playcanvas/react/components';
|
|
3
|
+
import { useEnvAtlas, useMaterial } from '@playcanvas/react/hooks';
|
|
4
|
+
import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs';
|
|
5
|
+
import { Grid } from 'playcanvas/scripts/esm/grid.mjs';
|
|
6
|
+
import { useEffect, useState } from 'react';
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
9
|
* The Scene renders a sphere with a grid and camera controls
|
|
12
10
|
*/
|
|
13
11
|
function Scene({ onClick }: SceneProps) {
|
|
12
|
+
// Track the hover state and set the color based on the hover state
|
|
13
|
+
const [hovering, setHovering] = useState(false);
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// Set a material color based on the hover state
|
|
16
|
+
const diffuse = hovering ? 'orange' : 'lightgrey';
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
// Create a material for the sphere
|
|
19
|
+
const material = useMaterial({ diffuse });
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
// Load the environment map
|
|
22
|
+
const { asset: envMap } = useEnvAtlas('/environment-map.png');
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
// change the mouse cursor based on the hover state
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
document.body.style.cursor = hovering ? 'pointer' : 'default';
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
return () => {
|
|
29
|
+
document.body.style.cursor = '';
|
|
30
|
+
};
|
|
31
|
+
}, [hovering]);
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
// Don't render until the environment map is loaded
|
|
34
|
+
if (!envMap) return null;
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
return (
|
|
37
|
+
<>
|
|
38
|
+
{/* Render some environment lighting using the environment map */}
|
|
39
|
+
<Environment envAtlas={envMap} showSkybox={false} />
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
{/* Render a background grid */}
|
|
42
|
+
<Entity scale={[1000, 1000, 1000]}>
|
|
43
|
+
<Script script={Grid} />
|
|
44
|
+
</Entity>
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
{/* Create a camera entity with camera controls */}
|
|
47
|
+
<Entity name="camera" position={[4, 1, 4]}>
|
|
48
|
+
<Camera clearColor="#171717" />
|
|
49
|
+
<Script script={CameraControls} />
|
|
50
|
+
</Entity>
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
)
|
|
52
|
+
{/* Create and position entity with pointer events */}
|
|
53
|
+
<Entity
|
|
54
|
+
position={[0, 0.5, 0]}
|
|
55
|
+
onClick={onClick}
|
|
56
|
+
onPointerOver={() => setHovering(true)}
|
|
57
|
+
onPointerOut={() => setHovering(false)}
|
|
58
|
+
>
|
|
59
|
+
{/* Render a sphere with the material */}
|
|
60
|
+
<Render type="sphere" material={material} />
|
|
61
|
+
</Entity>
|
|
62
|
+
</>
|
|
63
|
+
);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
type SceneProps = {
|
|
67
|
-
|
|
68
|
-
}
|
|
67
|
+
onClick: () => void;
|
|
68
|
+
};
|
|
69
69
|
|
|
70
70
|
export default Scene;
|
|
@@ -1,73 +1,51 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
+
line-height: 1.5;
|
|
4
|
+
font-weight: 400;
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
color: rgba(255, 255, 255, 0.87);
|
|
8
|
+
background-color: #242424;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
font-synthesis: none;
|
|
11
|
+
text-rendering: optimizeLegibility;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
a {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
font-weight: 500;
|
|
18
|
+
color: #646cff;
|
|
19
|
+
text-decoration: inherit;
|
|
20
20
|
}
|
|
21
21
|
a:hover {
|
|
22
|
-
|
|
22
|
+
color: #535bf2;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
a > img {
|
|
26
|
-
|
|
26
|
+
vertical-align: middle;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
body {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
margin: 0;
|
|
31
|
+
display: flex;
|
|
32
|
+
place-items: center;
|
|
33
|
+
min-width: 320px;
|
|
34
|
+
min-height: 100vh;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
h1 {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
button {
|
|
44
|
-
border-radius: 8px;
|
|
45
|
-
border: 1px solid transparent;
|
|
46
|
-
padding: 0.6em 1.2em;
|
|
47
|
-
font-size: 1em;
|
|
48
|
-
font-weight: 500;
|
|
49
|
-
font-family: inherit;
|
|
50
|
-
background-color: #1a1a1a;
|
|
51
|
-
cursor: pointer;
|
|
52
|
-
transition: border-color 0.25s;
|
|
53
|
-
}
|
|
54
|
-
button:hover {
|
|
55
|
-
border-color: #646cff;
|
|
56
|
-
}
|
|
57
|
-
button:focus,
|
|
58
|
-
button:focus-visible {
|
|
59
|
-
outline: 4px auto -webkit-focus-ring-color;
|
|
38
|
+
font-size: 2.4em;
|
|
39
|
+
line-height: 1.1;
|
|
40
|
+
opacity: 0.85;
|
|
60
41
|
}
|
|
61
42
|
|
|
62
43
|
@media (prefers-color-scheme: light) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
button {
|
|
71
|
-
background-color: #f9f9f9;
|
|
72
|
-
}
|
|
44
|
+
:root {
|
|
45
|
+
color: #213547;
|
|
46
|
+
background-color: #ffffff;
|
|
47
|
+
}
|
|
48
|
+
a:hover {
|
|
49
|
+
color: #747bff;
|
|
50
|
+
}
|
|
73
51
|
}
|