@brust/create-app 2.0.0-alpha.3 → 2.0.0-alpha.5
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 +1 -1
- package/package.json +5 -1
- package/src/args.ts +11 -3
- package/src/cli.ts +15 -4
- package/src/tailwind.ts +9 -0
- package/templates/blank/README.md.tmpl +4 -4
- package/templates/blank/_gitignore +1 -0
- package/templates/blank/app.css +32 -0
- package/templates/blank/components/Counter.tsx +5 -1
- package/templates/blank/components/Layout.tsx +5 -4
- package/templates/blank/package.json.tmpl +3 -1
- package/templates/blank/pages/HomePage.tsx +29 -5
- package/templates/blank/public/favicon.svg +1 -1
- package/templates/pokedex/README.md.tmpl +3 -3
- package/templates/pokedex/package.json.tmpl +1 -1
- package/templates/blank/public/app.css +0 -14
package/README.md
CHANGED
|
@@ -17,4 +17,4 @@ bun run dev # http://127.0.0.1:1337
|
|
|
17
17
|
|
|
18
18
|
`bun create` rejects `-t` and `-y`; use the long flags (the short ones work with `bunx @brust/create-app`).
|
|
19
19
|
|
|
20
|
-
Full guide: [docs/create-app.md](https://github.com/AssetsArt/brust/blob/
|
|
20
|
+
Full guide: [docs/create-app.md](https://github.com/AssetsArt/brust/blob/main/docs/create-app.md).
|
package/package.json
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brust/create-app",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.5",
|
|
4
4
|
"description": "Scaffold a brust v2 app — bun create @brust/app <name>",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"homepage": "https://brust.dev",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
8
9
|
"url": "git+https://github.com/AssetsArt/brust.git",
|
|
9
10
|
"directory": "packages/create-app"
|
|
10
11
|
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/AssetsArt/brust/issues"
|
|
14
|
+
},
|
|
11
15
|
"type": "module",
|
|
12
16
|
"bin": {
|
|
13
17
|
"create-app": "./bin/create-app.ts"
|
package/src/args.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { isAbsolute, resolve } from 'node:path'
|
|
|
5
5
|
const NAME_RE = /^[a-z0-9][a-z0-9_-]*$/
|
|
6
6
|
const MAX_NAME_LEN = 50
|
|
7
7
|
|
|
8
|
-
export const USAGE = 'usage: bun create @brust/app <name> [--template blank|pokedex] [--dir <path>] [--yes] [--brust-dep <spec>]'
|
|
8
|
+
export const USAGE = 'usage: bun create @brust/app <name> [--template blank|pokedex] [--tailwind] [--dir <path>] [--yes] [--brust-dep <spec>] [--version]'
|
|
9
9
|
|
|
10
10
|
export interface ParsedArgs {
|
|
11
11
|
projectName: string
|
|
@@ -13,7 +13,11 @@ export interface ParsedArgs {
|
|
|
13
13
|
template?: string
|
|
14
14
|
yes: boolean
|
|
15
15
|
brustDep?: string
|
|
16
|
+
/** `--tailwind` (L21): accepted and ignored since L28: the blank template uses Tailwind CSS v4 by default. */
|
|
17
|
+
tailwind: boolean
|
|
16
18
|
help: boolean
|
|
19
|
+
/** `--version` (F131): print the bare version and exit; no short form (see the note above). */
|
|
20
|
+
version: boolean
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
export function parseArgs(args: string[]): ParsedArgs {
|
|
@@ -22,7 +26,9 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
22
26
|
let template: string | undefined
|
|
23
27
|
let brustDep: string | undefined
|
|
24
28
|
let yes = false
|
|
29
|
+
let tailwind = false
|
|
25
30
|
let help = false
|
|
31
|
+
let version = false
|
|
26
32
|
const need = (flag: string, v: string | undefined): string => {
|
|
27
33
|
if (!v) throw new Error(`create-app: ${flag} requires a value`)
|
|
28
34
|
return v
|
|
@@ -32,6 +38,7 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
32
38
|
const a = args[i]!
|
|
33
39
|
if (a === '--') continue
|
|
34
40
|
if (a === '--help' || a === '-h') help = true
|
|
41
|
+
else if (a === '--version') version = true
|
|
35
42
|
else if (a === '--dir') dir = need('--dir', args[++i])
|
|
36
43
|
else if (a.startsWith('--dir=')) dir = need('--dir', a.slice('--dir='.length))
|
|
37
44
|
else if (a === '--template' || a === '-t') template = need('--template', args[++i])
|
|
@@ -39,12 +46,13 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
39
46
|
else if (a === '--brust-dep') brustDep = need('--brust-dep', args[++i])
|
|
40
47
|
else if (a.startsWith('--brust-dep=')) brustDep = need('--brust-dep', a.slice('--brust-dep='.length))
|
|
41
48
|
else if (a === '--yes' || a === '-y') yes = true
|
|
49
|
+
else if (a === '--tailwind') tailwind = true
|
|
42
50
|
else if (a.startsWith('-')) throw new Error(`create-app: unknown flag "${a}"`)
|
|
43
51
|
else if (name === undefined) name = a
|
|
44
52
|
else throw new Error(`create-app: unexpected positional argument "${a}"`)
|
|
45
53
|
}
|
|
46
54
|
|
|
47
|
-
if (help) return { projectName: name ?? '', targetDir: '', template, yes, brustDep, help }
|
|
55
|
+
if (help || version) return { projectName: name ?? '', targetDir: '', template, yes, brustDep, tailwind, help, version }
|
|
48
56
|
if (!name) throw new Error(`create-app: missing project name. ${USAGE}`)
|
|
49
57
|
if (name.length > MAX_NAME_LEN) throw new Error(`create-app: project name too long (max ${MAX_NAME_LEN} chars)`)
|
|
50
58
|
if (!NAME_RE.test(name)) {
|
|
@@ -52,5 +60,5 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
52
60
|
}
|
|
53
61
|
const cwd = process.cwd()
|
|
54
62
|
const targetDir = dir ? (isAbsolute(dir) ? dir : resolve(cwd, dir)) : resolve(cwd, name)
|
|
55
|
-
return { projectName: name, targetDir, template, yes, brustDep, help }
|
|
63
|
+
return { projectName: name, targetDir, template, yes, brustDep, tailwind, help, version }
|
|
56
64
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
// `create-app` main — a port of 0.1.x runNew (runtime/cli/new.ts:221-294) with the v2 dependency resolution.
|
|
2
|
-
import { existsSync } from 'node:fs'
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
3
3
|
import { readdir, rm } from 'node:fs/promises'
|
|
4
4
|
import { copyTemplate } from './copy.ts'
|
|
5
5
|
import { parseArgs, USAGE } from './args.ts'
|
|
6
6
|
import { applyOverrides, monorepoRoot, resolveBrustDep } from './dep.ts'
|
|
7
|
+
import { TAILWIND_DEFAULT_NOTE } from './tailwind.ts'
|
|
7
8
|
import { selectTemplate } from './templates.ts'
|
|
8
9
|
|
|
10
|
+
// F131: read at run time from the package.json that `bun publish` ships, so release-bump.ts stays the only place versions change.
|
|
11
|
+
const ownVersion = (): string => (JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as { version?: string }).version ?? '0.0.0'
|
|
12
|
+
|
|
9
13
|
const fail = (msg: string): never => {
|
|
10
14
|
console.error(msg)
|
|
11
15
|
process.exit(1)
|
|
@@ -19,6 +23,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
19
23
|
console.log(USAGE)
|
|
20
24
|
return
|
|
21
25
|
}
|
|
26
|
+
if (parsed.version) {
|
|
27
|
+
console.log(ownVersion())
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
console.log(`@brust/create-app ${ownVersion()}\n`)
|
|
22
31
|
const { projectName, targetDir } = parsed
|
|
23
32
|
|
|
24
33
|
const targetExisted = existsSync(targetDir)
|
|
@@ -26,6 +35,8 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
26
35
|
|
|
27
36
|
let tmpl: ReturnType<typeof selectTemplate>
|
|
28
37
|
try { tmpl = selectTemplate({ explicit: parsed.template, yes: parsed.yes, isTTY: Boolean(process.stdin.isTTY) }) } catch (e) { return fail(msg(e)) }
|
|
38
|
+
// L28 R29.1: Tailwind is the blank template's default; the flag stays accepted so older instructions still work.
|
|
39
|
+
if (parsed.tailwind) console.log(TAILWIND_DEFAULT_NOTE)
|
|
29
40
|
const dep = resolveBrustDep({ explicit: parsed.brustDep, targetDir })
|
|
30
41
|
|
|
31
42
|
try {
|
|
@@ -44,13 +55,13 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
44
55
|
if (!targetExisted) await rm(targetDir, { recursive: true, force: true }).catch(() => {})
|
|
45
56
|
return fail(`create-app: failed to scaffold (${msg(e)})`)
|
|
46
57
|
}
|
|
47
|
-
printNextSteps(projectName, targetDir, tmpl.name, dep.kind === 'workspace')
|
|
58
|
+
printNextSteps(projectName, targetDir, tmpl.name, dep.spec, dep.kind === 'workspace')
|
|
48
59
|
}
|
|
49
60
|
|
|
50
|
-
function printNextSteps(name: string, targetDir: string, template: string, workspace: boolean): void {
|
|
61
|
+
function printNextSteps(name: string, targetDir: string, template: string, spec: string, workspace: boolean): void {
|
|
51
62
|
const cwd = process.cwd()
|
|
52
63
|
const displayPath = targetDir.startsWith(`${cwd}/`) ? `./${targetDir.slice(cwd.length + 1)}` : targetDir
|
|
53
|
-
console.log(`Created ${name} at ${targetDir} (template: ${template})\n`)
|
|
64
|
+
console.log(`Created ${name} at ${targetDir} (template: ${template}, @brust/core ${spec})\n`)
|
|
54
65
|
console.log('Next:')
|
|
55
66
|
console.log(` cd ${displayPath}`)
|
|
56
67
|
console.log(workspace ? ' bun install # run it at the brust repo root: this app is a workspace member' : ' bun install')
|
package/src/tailwind.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Tailwind CSS v4 in the blank template (gaps round L21, made the default by L28 R29.1): the template ships `app.css`
|
|
2
|
+
// (`@import "tailwindcss"` + `@theme` tokens), the layout imports it (brust builds it and links it in <head>, L19), and
|
|
3
|
+
// the two pinned dev dependencies below are in its package.json (R21.1: the app's own). `--tailwind` no longer changes
|
|
4
|
+
// anything; it prints TAILWIND_DEFAULT_NOTE.
|
|
5
|
+
|
|
6
|
+
/** The exact versions brust's own tests build with (the blank template's package.json pins the same). */
|
|
7
|
+
export const TAILWIND_DEV_DEPS = { 'bun-plugin-tailwind': '0.1.2', tailwindcss: '4.3.3' }
|
|
8
|
+
|
|
9
|
+
export const TAILWIND_DEFAULT_NOTE = 'create-app: Tailwind CSS v4 is the default; the --tailwind flag does nothing'
|
|
@@ -6,10 +6,10 @@ A [brust](https://github.com/AssetsArt/brust) app: React components compiled ahe
|
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
bun install
|
|
9
|
-
bun run dev # brust
|
|
9
|
+
bun run dev # brust dev routes.tsx (hot reload) -> http://127.0.0.1:1337
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
Scripts: `dev` (
|
|
12
|
+
Scripts: `dev` (`brust dev`, with hot reload), `build`, `start`, `typecheck`, `dev:cf` (build for Cloudflare Workers and run `wrangler dev`), `deploy:cf` (build and `wrangler deploy`).
|
|
13
13
|
|
|
14
14
|
## Layout
|
|
15
15
|
|
|
@@ -39,5 +39,5 @@ const { data } = await api.hello.get({ query: { name: 'ash' } })
|
|
|
39
39
|
|
|
40
40
|
## Docs
|
|
41
41
|
|
|
42
|
-
- Actions: https://github.com/AssetsArt/brust/blob/
|
|
43
|
-
- The unified store: https://github.com/AssetsArt/brust/blob/
|
|
42
|
+
- Actions: https://github.com/AssetsArt/brust/blob/main/docs/actions.md
|
|
43
|
+
- The unified store: https://github.com/AssetsArt/brust/blob/main/docs/store.md
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
|
|
3
|
+
/* Tailwind CSS v4, CSS-first: no tailwind.config. The tokens below are the brust docs palette; each one becomes a
|
|
4
|
+
utility (bg-paper, text-ink, border-rule, ...). A *.module.css that uses @apply starts with
|
|
5
|
+
@reference "../app.css"; (see brust docs/css.md). */
|
|
6
|
+
@theme {
|
|
7
|
+
--color-paper: oklch(94% 0.035 78);
|
|
8
|
+
--color-sheet: oklch(97% 0.02 82);
|
|
9
|
+
--color-ink: oklch(18% 0.035 82);
|
|
10
|
+
--color-ink-2: oklch(36% 0.045 80);
|
|
11
|
+
--color-rule: oklch(76% 0.05 77);
|
|
12
|
+
--color-amber: oklch(68% 0.145 74);
|
|
13
|
+
--color-amber-ink: oklch(46% 0.12 62);
|
|
14
|
+
--font-sans: ui-rounded, "SF Pro Rounded", system-ui, sans-serif;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* Dark mode follows the system: the same tokens, darker values, so every utility switches with them. */
|
|
18
|
+
@media (prefers-color-scheme: dark) {
|
|
19
|
+
:root {
|
|
20
|
+
--color-paper: oklch(20% 0.028 185);
|
|
21
|
+
--color-sheet: oklch(24% 0.032 182);
|
|
22
|
+
--color-ink: oklch(91% 0.02 82);
|
|
23
|
+
--color-ink-2: oklch(77% 0.03 82);
|
|
24
|
+
--color-rule: oklch(36% 0.032 180);
|
|
25
|
+
--color-amber: oklch(74% 0.12 78);
|
|
26
|
+
--color-amber-ink: oklch(81% 0.11 80);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
:root {
|
|
31
|
+
color-scheme: light dark;
|
|
32
|
+
}
|
|
@@ -4,7 +4,11 @@ import { useState } from 'react'
|
|
|
4
4
|
export default function Counter() {
|
|
5
5
|
const [count, setCount] = useState(0)
|
|
6
6
|
return (
|
|
7
|
-
<button
|
|
7
|
+
<button
|
|
8
|
+
type="button"
|
|
9
|
+
className="cursor-pointer rounded-[0.6rem] border border-amber-ink bg-amber px-[1.1rem] py-2 font-semibold text-[oklch(18%_0.035_82)] hover:brightness-106 focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-amber-ink"
|
|
10
|
+
onClick={() => setCount(count + 1)}
|
|
11
|
+
>
|
|
8
12
|
count is {count}
|
|
9
13
|
</button>
|
|
10
14
|
)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
// The document root: a plain <html> with <Outlet/> for the page.
|
|
1
|
+
// The document root: a plain <html> with <Outlet/> for the page. app.css (Tailwind CSS v4) is imported here; brust
|
|
2
|
+
// builds it into one hashed file and links it in <head>. Static files are served from /public.
|
|
2
3
|
import { Outlet } from '@brust/core/routes'
|
|
4
|
+
import '../app.css'
|
|
3
5
|
|
|
4
6
|
export default function Layout() {
|
|
5
7
|
return (
|
|
@@ -9,10 +11,9 @@ export default function Layout() {
|
|
|
9
11
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
10
12
|
<title>brust app</title>
|
|
11
13
|
<link rel="icon" href="/public/favicon.svg" />
|
|
12
|
-
<link rel="stylesheet" href="/public/app.css" />
|
|
13
14
|
</head>
|
|
14
|
-
<body>
|
|
15
|
-
<main>
|
|
15
|
+
<body className="bg-paper font-sans text-ink leading-[1.55]">
|
|
16
|
+
<main className="mx-auto box-border max-w-2xl px-4 py-16">
|
|
16
17
|
<Outlet />
|
|
17
18
|
</main>
|
|
18
19
|
</body>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"dev": "brust
|
|
7
|
+
"dev": "brust dev routes.tsx",
|
|
8
8
|
"build": "brust build routes.tsx",
|
|
9
9
|
"start": "brust start",
|
|
10
10
|
"typecheck": "bun check",
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/bun": "^1.4.0",
|
|
23
23
|
"@types/react": "^19.2.0",
|
|
24
|
+
"bun-plugin-tailwind": "0.1.2",
|
|
25
|
+
"tailwindcss": "4.3.3",
|
|
24
26
|
"typescript": "^7.0.2",
|
|
25
27
|
"wrangler": "^4.149.0"
|
|
26
28
|
}
|
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import Counter from '../components/Counter'
|
|
2
2
|
|
|
3
|
+
const link = 'font-semibold text-amber-ink underline underline-offset-[0.2em] hover:decoration-2 focus-visible:rounded focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-amber-ink'
|
|
4
|
+
|
|
3
5
|
export default function HomePage() {
|
|
4
6
|
return (
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
<>
|
|
8
|
+
<header className="flex items-center gap-[0.9rem]">
|
|
9
|
+
<svg className="flex-none" viewBox="0 0 32 32" width="44" height="44" aria-hidden="true">
|
|
10
|
+
<rect width="32" height="32" rx="8" fill="#062323" />
|
|
11
|
+
<path d="M7 19a9 9 0 0 1 18 0z" fill="#f2a516" />
|
|
12
|
+
<rect x="5" y="20.5" width="22" height="2.2" rx="1.1" fill="#f2a516" />
|
|
13
|
+
<rect x="10" y="24.6" width="12" height="2" rx="1" fill="#f2a516" opacity=".55" />
|
|
14
|
+
</svg>
|
|
15
|
+
<h1 className="m-0 text-4xl leading-[1.1] font-bold tracking-[-0.01em]">brust app</h1>
|
|
16
|
+
</header>
|
|
17
|
+
<p className="mt-4 mb-8 text-lg text-ink-2">Edit pages/HomePage.tsx and save. The page reloads.</p>
|
|
18
|
+
<section className="rounded-2xl border border-rule bg-sheet p-6">
|
|
19
|
+
<Counter />
|
|
20
|
+
<p className="mt-4 mb-0 text-[0.9375rem] text-ink-2">useState only, so this button is native: a signal in the browser, no React shipped.</p>
|
|
21
|
+
</section>
|
|
22
|
+
<nav className="mt-8 flex flex-wrap gap-x-6 gap-y-2" aria-label="Learn more">
|
|
23
|
+
<a className={link} href="https://brust.dev">
|
|
24
|
+
Docs
|
|
25
|
+
</a>
|
|
26
|
+
<a className={link} href="https://brust.dev/docs/routing">
|
|
27
|
+
Routes
|
|
28
|
+
</a>
|
|
29
|
+
<a className={link} href="https://brust.dev/docs/actions">
|
|
30
|
+
Actions
|
|
31
|
+
</a>
|
|
32
|
+
</nav>
|
|
33
|
+
</>
|
|
10
34
|
)
|
|
11
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="8" fill="#062323"/><path d="M7 19a9 9 0 0 1 18 0z" fill="#f2a516"/><rect x="5" y="20.5" width="22" height="2.2" rx="1.1" fill="#f2a516"/><rect x="10" y="24.6" width="12" height="2" rx="1" fill="#f2a516" opacity=".55"/></svg>
|
|
@@ -7,7 +7,7 @@ React islands, and a persistent team built with Elysia actions + SQLite and one
|
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
9
|
bun install
|
|
10
|
-
bun run dev # brust
|
|
10
|
+
bun run dev # brust dev routes.tsx (hot reload) -> http://127.0.0.1:1337
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Scripts: `dev` (build then start), `build`, `start`, `typecheck`, `snapshot` (needs network; rewrites `data/pokedex.json`).
|
|
@@ -55,5 +55,5 @@ bunx @tailwindcss/cli@4 -i styles/app.css -o public/app.css --minify
|
|
|
55
55
|
|
|
56
56
|
## Docs
|
|
57
57
|
|
|
58
|
-
- Actions: https://github.com/AssetsArt/brust/blob/
|
|
59
|
-
- The unified store: https://github.com/AssetsArt/brust/blob/
|
|
58
|
+
- Actions: https://github.com/AssetsArt/brust/blob/main/docs/actions.md
|
|
59
|
+
- The unified store: https://github.com/AssetsArt/brust/blob/main/docs/store.md
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"dev": "brust
|
|
7
|
+
"dev": "brust dev routes.tsx",
|
|
8
8
|
"build": "brust build routes.tsx",
|
|
9
9
|
"dev:cf": "wrangler d1 migrations apply TEAM_DB --local --persist-to .wrangler/state && brust dev routes.tsx --target cloudflare",
|
|
10
10
|
"deploy:cf": "brust build routes.tsx --target cloudflare && wrangler deploy -c dist/cf/wrangler.jsonc",
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
:root { color-scheme: light dark; font-family: system-ui, sans-serif; }
|
|
2
|
-
body { margin: 0; }
|
|
3
|
-
main { max-width: 40rem; margin: 4rem auto; padding: 0 1.5rem; line-height: 1.5; }
|
|
4
|
-
h1 { font-size: 2rem; margin: 0 0 0.5rem; }
|
|
5
|
-
button {
|
|
6
|
-
cursor: pointer;
|
|
7
|
-
font: inherit;
|
|
8
|
-
padding: 0.5rem 1rem;
|
|
9
|
-
border: 1px solid currentColor;
|
|
10
|
-
border-radius: 0.5rem;
|
|
11
|
-
background: transparent;
|
|
12
|
-
color: inherit;
|
|
13
|
-
}
|
|
14
|
-
button:hover { opacity: 0.8; }
|