@snowztech/ui-css 0.2.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/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@snowztech/ui-css",
3
+ "version": "0.2.0",
4
+ "description": "Terminal-minimal CSS design system. Tokens, resets, and component classes. Framework-agnostic.",
5
+ "license": "MIT",
6
+ "author": {
7
+ "name": "Lucas Neves Pereira",
8
+ "email": "lnevespereira@proton.me",
9
+ "url": "https://github.com/lucasnevespereira"
10
+ },
11
+ "homepage": "https://github.com/snowztech/ui#readme",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/snowztech/ui.git",
15
+ "directory": "packages/ui-css"
16
+ },
17
+ "bugs": {
18
+ "url": "https://github.com/snowztech/ui/issues"
19
+ },
20
+ "keywords": [
21
+ "design-system",
22
+ "css",
23
+ "tokens",
24
+ "snowztech",
25
+ "terminal",
26
+ "minimal"
27
+ ],
28
+ "files": [
29
+ "dist",
30
+ "src",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
34
+ "exports": {
35
+ ".": "./dist/snowztech-ui.css",
36
+ "./min": "./dist/snowztech-ui.min.css",
37
+ "./tokens": "./dist/tokens.css",
38
+ "./tokens.css": "./dist/tokens.css",
39
+ "./base": "./dist/base.css",
40
+ "./base.css": "./dist/base.css",
41
+ "./styles.css": "./dist/snowztech-ui.css",
42
+ "./components/*": "./dist/components/*.css",
43
+ "./package.json": "./package.json"
44
+ },
45
+ "devDependencies": {
46
+ "esbuild": "^0.27.7"
47
+ },
48
+ "engines": {
49
+ "node": ">=18"
50
+ },
51
+ "publishConfig": {
52
+ "access": "public"
53
+ },
54
+ "sideEffects": [
55
+ "*.css"
56
+ ],
57
+ "scripts": {
58
+ "build": "node build.mjs",
59
+ "dev": "node build.mjs --watch"
60
+ }
61
+ }
package/src/base.css ADDED
@@ -0,0 +1,23 @@
1
+ /* Resets and global defaults. Optional. Import tokens.css alone to skip these. */
2
+
3
+ *, *::before, *::after { box-sizing: border-box; }
4
+ html, body { margin: 0; padding: 0; }
5
+ html, body { height: 100%; }
6
+
7
+ body {
8
+ font-family: var(--sn-font-mono);
9
+ font-size: var(--sn-text-sm);
10
+ line-height: var(--sn-leading-normal);
11
+ color: var(--sn-fg);
12
+ background: var(--sn-bg);
13
+ -webkit-font-smoothing: antialiased;
14
+ }
15
+
16
+ ::selection { background: var(--sn-accent-soft); color: var(--sn-fg); }
17
+
18
+ a { color: var(--sn-accent); text-decoration: none; }
19
+ a:hover { color: var(--sn-accent-hover); }
20
+
21
+ @keyframes sn-spin { to { transform: rotate(360deg); } }
22
+ @keyframes sn-pulse { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } }
23
+ @keyframes sn-blink { 50% { opacity: 0; } }
@@ -0,0 +1,35 @@
1
+ .sn-avatar {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ width: var(--sn-avatar-size, 32px);
6
+ height: var(--sn-avatar-size, 32px);
7
+ border-radius: 50%;
8
+ background: var(--sn-bg-elev-1);
9
+ color: var(--sn-fg-muted);
10
+ font-family: var(--sn-font-mono);
11
+ font-size: max(10px, calc(var(--sn-avatar-size, 32px) * 0.38));
12
+ font-weight: 500;
13
+ overflow: hidden;
14
+ flex-shrink: 0;
15
+ vertical-align: middle;
16
+ }
17
+
18
+ .sn-avatar--square { border-radius: var(--sn-r-xs); }
19
+ .sn-avatar--ring { box-shadow: 0 0 0 1px var(--sn-border-strong); }
20
+
21
+ .sn-avatar--xs { --sn-avatar-size: 20px; }
22
+ .sn-avatar--sm { --sn-avatar-size: 28px; }
23
+ .sn-avatar--md { --sn-avatar-size: 32px; }
24
+ .sn-avatar--lg { --sn-avatar-size: 48px; }
25
+ .sn-avatar--xl { --sn-avatar-size: 64px; }
26
+
27
+ .sn-avatar > img {
28
+ width: 100%;
29
+ height: 100%;
30
+ object-fit: cover;
31
+ display: block;
32
+ }
33
+
34
+ .sn-avatar-stack { display: inline-flex; }
35
+ .sn-avatar-stack > * + * { margin-left: var(--sn-avatar-overlap, -8px); }
@@ -0,0 +1,18 @@
1
+ .sn-badge {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: 4px;
5
+ font-family: var(--sn-font-mono);
6
+ font-size: var(--sn-text-2xs);
7
+ font-weight: 400;
8
+ padding: 2px 6px;
9
+ border-radius: var(--sn-r-xs);
10
+ border: 1px solid var(--sn-border);
11
+ color: var(--sn-fg-muted);
12
+ height: 18px;
13
+ text-transform: lowercase;
14
+ }
15
+ .sn-badge--accent { color: var(--sn-accent); border-color: var(--sn-accent-border); }
16
+ .sn-badge--success { color: var(--sn-success); border-color: rgba(127, 199, 127, 0.30); }
17
+ .sn-badge--warning { color: var(--sn-warning); border-color: rgba(212, 168, 87, 0.30); }
18
+ .sn-badge--danger { color: var(--sn-danger); border-color: rgba(215, 112, 112, 0.30); }
@@ -0,0 +1,53 @@
1
+ .sn-btn {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ gap: 8px;
6
+ font-family: var(--sn-font-mono);
7
+ font-size: var(--sn-text-sm);
8
+ font-weight: 500;
9
+ line-height: 1;
10
+ border-radius: var(--sn-r-xs);
11
+ padding: 0 14px;
12
+ height: 30px;
13
+ border: 1px solid transparent;
14
+ cursor: pointer;
15
+ transition: background var(--sn-fast) var(--sn-ease),
16
+ border-color var(--sn-fast) var(--sn-ease),
17
+ color var(--sn-fast) var(--sn-ease);
18
+ white-space: nowrap;
19
+ user-select: none;
20
+ background: transparent;
21
+ color: var(--sn-fg);
22
+ }
23
+ .sn-btn:focus-visible { outline: 1px solid var(--sn-accent); outline-offset: 1px; }
24
+ .sn-btn[disabled] { opacity: 0.4; cursor: not-allowed; }
25
+ .sn-btn--sm { height: 24px; font-size: var(--sn-text-xs); padding: 0 10px; }
26
+ .sn-btn--lg { height: 36px; font-size: var(--sn-text-sm); padding: 0 18px; }
27
+
28
+ .sn-btn--primary {
29
+ background: var(--sn-fg);
30
+ color: var(--sn-fg-inverse);
31
+ border-color: var(--sn-fg);
32
+ }
33
+ .sn-btn--primary:hover { background: var(--sn-fg-muted); border-color: var(--sn-fg-muted); }
34
+
35
+ .sn-btn--secondary {
36
+ background: transparent;
37
+ color: var(--sn-fg);
38
+ border-color: var(--sn-border-strong);
39
+ }
40
+ .sn-btn--secondary:hover { border-color: var(--sn-fg-muted); }
41
+
42
+ .sn-btn--ghost { background: transparent; color: var(--sn-fg-muted); }
43
+ .sn-btn--ghost:hover { color: var(--sn-fg); }
44
+
45
+ .sn-btn--accent {
46
+ background: var(--sn-accent);
47
+ color: var(--sn-accent-fg);
48
+ border-color: var(--sn-accent);
49
+ }
50
+ .sn-btn--accent:hover { background: var(--sn-accent-hover); border-color: var(--sn-accent-hover); }
51
+
52
+ .sn-btn--danger { background: transparent; color: var(--sn-danger); border-color: var(--sn-border-strong); }
53
+ .sn-btn--danger:hover { border-color: var(--sn-danger); }
@@ -0,0 +1,12 @@
1
+ .sn-card {
2
+ background: transparent;
3
+ border: 1px solid var(--sn-border);
4
+ border-radius: var(--sn-r-xs);
5
+ padding: var(--sn-s-5);
6
+ }
7
+ .sn-card--rounded { border-radius: var(--sn-r-lg); }
8
+ .sn-card--accent {
9
+ border-color: var(--sn-accent-border);
10
+ background: var(--sn-accent-soft);
11
+ }
12
+ .sn-card--inset { background: var(--sn-bg-inset); }
@@ -0,0 +1,25 @@
1
+ .sn-copy-btn {
2
+ appearance: none;
3
+ border: 1px solid transparent;
4
+ background: transparent;
5
+ color: var(--sn-fg-muted);
6
+ padding: 6px;
7
+ cursor: pointer;
8
+ display: inline-flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+ border-radius: var(--sn-r-xs);
12
+ transition: color var(--sn-fast) var(--sn-ease),
13
+ border-color var(--sn-fast) var(--sn-ease);
14
+ }
15
+ .sn-copy-btn:hover { color: var(--sn-fg); }
16
+ .sn-copy-btn:focus-visible { outline: 1px solid var(--sn-accent); outline-offset: 1px; }
17
+ .sn-copy-btn[data-copied="true"],
18
+ .sn-copy-btn[data-copied="true"]:hover {
19
+ color: var(--sn-success);
20
+ }
21
+
22
+ /* Hide the "copied" icon until the data attribute flips. */
23
+ .sn-copy-btn .sn-copy-btn__copied { display: none; }
24
+ .sn-copy-btn[data-copied="true"] .sn-copy-btn__copied { display: inline-flex; }
25
+ .sn-copy-btn[data-copied="true"] .sn-copy-btn__idle { display: none; }
@@ -0,0 +1,6 @@
1
+ .sn-divider {
2
+ height: 1px;
3
+ background: var(--sn-border);
4
+ border: 0;
5
+ margin: 0;
6
+ }
@@ -0,0 +1,6 @@
1
+ .sn-icon {
2
+ display: inline-block;
3
+ vertical-align: middle;
4
+ flex-shrink: 0;
5
+ color: currentColor;
6
+ }
@@ -0,0 +1,15 @@
1
+ .sn-input {
2
+ font-family: var(--sn-font-mono);
3
+ font-size: var(--sn-text-sm);
4
+ color: var(--sn-fg);
5
+ background: transparent;
6
+ border: 1px solid var(--sn-border-strong);
7
+ border-radius: var(--sn-r-xs);
8
+ padding: 0 10px;
9
+ height: 30px;
10
+ width: 100%;
11
+ transition: border-color var(--sn-fast) var(--sn-ease);
12
+ }
13
+ .sn-input::placeholder { color: var(--sn-fg-faint); }
14
+ .sn-input:hover { border-color: var(--sn-fg-muted); }
15
+ .sn-input:focus { outline: none; border-color: var(--sn-accent); }
@@ -0,0 +1,8 @@
1
+ .sn-kbd {
2
+ font-family: var(--sn-font-mono);
3
+ font-size: var(--sn-text-2xs);
4
+ border: 1px solid var(--sn-border-strong);
5
+ border-radius: var(--sn-r-xs);
6
+ padding: 1px 5px;
7
+ color: var(--sn-fg-muted);
8
+ }
@@ -0,0 +1,31 @@
1
+ /* Wrapper for mark SVGs. The SVG itself owns its art via `currentColor`,
2
+ the class controls layout, sizing, and color hand-off. */
3
+
4
+ .sn-mark {
5
+ display: inline-block;
6
+ vertical-align: middle;
7
+ flex-shrink: 0;
8
+ color: currentColor;
9
+ width: var(--sn-mark-size, 32px);
10
+ height: var(--sn-mark-size, 32px);
11
+ }
12
+
13
+ .sn-mark--xs { --sn-mark-size: 16px; }
14
+ .sn-mark--sm { --sn-mark-size: 24px; }
15
+ .sn-mark--md { --sn-mark-size: 32px; }
16
+ .sn-mark--lg { --sn-mark-size: 48px; }
17
+ .sn-mark--xl { --sn-mark-size: 64px; }
18
+
19
+ .sn-mark--accent { color: var(--sn-accent); }
20
+ .sn-mark--muted { color: var(--sn-fg-muted); }
21
+
22
+ /* Wordmark */
23
+ .sn-wordmark {
24
+ font-family: var(--sn-font-mono);
25
+ font-size: var(--sn-wordmark-size, 18px);
26
+ font-weight: 700;
27
+ letter-spacing: -0.01em;
28
+ color: currentColor;
29
+ line-height: 1;
30
+ }
31
+ .sn-wordmark__dot { color: var(--sn-accent); }
@@ -0,0 +1,13 @@
1
+ .sn-meta {
2
+ font-family: var(--sn-font-mono);
3
+ font-size: var(--sn-text-2xs);
4
+ letter-spacing: 0.04em;
5
+ text-transform: uppercase;
6
+ color: var(--sn-fg-faint);
7
+ }
8
+
9
+ .sn-prompt {
10
+ color: var(--sn-fg-faint);
11
+ user-select: none;
12
+ }
13
+ .sn-prompt::before { content: "› "; }
@@ -0,0 +1,21 @@
1
+ .sn-monogram {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ flex-shrink: 0;
6
+ background: var(--sn-monogram-bg, var(--sn-bg));
7
+ color: var(--sn-monogram-fg, var(--sn-fg));
8
+ width: var(--sn-monogram-size, 64px);
9
+ height: var(--sn-monogram-size, 64px);
10
+ border-radius: var(--sn-monogram-radius, var(--sn-r-md));
11
+ }
12
+
13
+ .sn-monogram--xs { --sn-monogram-size: 32px; --sn-monogram-radius: var(--sn-r-xs); }
14
+ .sn-monogram--sm { --sn-monogram-size: 48px; --sn-monogram-radius: var(--sn-r-sm); }
15
+ .sn-monogram--md { --sn-monogram-size: 64px; --sn-monogram-radius: var(--sn-r-md); }
16
+ .sn-monogram--lg { --sn-monogram-size: 96px; --sn-monogram-radius: var(--sn-r-lg); }
17
+
18
+ .sn-monogram--inverse {
19
+ --sn-monogram-bg: var(--sn-fg);
20
+ --sn-monogram-fg: var(--sn-bg);
21
+ }
@@ -0,0 +1,34 @@
1
+ .sn-pulse {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: var(--sn-s-2);
5
+ color: var(--sn-fg-muted);
6
+ font-size: var(--sn-text-sm);
7
+ }
8
+
9
+ .sn-pulse__dot {
10
+ position: relative;
11
+ display: inline-flex;
12
+ width: var(--sn-pulse-size, 8px);
13
+ height: var(--sn-pulse-size, 8px);
14
+ flex-shrink: 0;
15
+ }
16
+
17
+ .sn-pulse__dot::before,
18
+ .sn-pulse__dot::after {
19
+ content: "";
20
+ position: absolute;
21
+ inset: 0;
22
+ border-radius: 50%;
23
+ background: var(--sn-pulse-color, var(--sn-success));
24
+ }
25
+
26
+ .sn-pulse__dot::before {
27
+ opacity: 0.6;
28
+ animation: sn-pulse 2s ease-in-out infinite;
29
+ }
30
+
31
+ .sn-pulse--success { --sn-pulse-color: var(--sn-success); }
32
+ .sn-pulse--warning { --sn-pulse-color: var(--sn-warning); }
33
+ .sn-pulse--danger { --sn-pulse-color: var(--sn-danger); }
34
+ .sn-pulse--accent { --sn-pulse-color: var(--sn-accent); }
@@ -0,0 +1,23 @@
1
+ .sn-theme-toggle {
2
+ appearance: none;
3
+ border: none;
4
+ background: transparent;
5
+ padding: 6px;
6
+ cursor: pointer;
7
+ display: inline-flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ transition: opacity var(--sn-base);
11
+ }
12
+ .sn-theme-toggle:focus-visible { outline: 1px solid var(--sn-accent); outline-offset: 1px; }
13
+
14
+ .sn-theme-toggle__indicator {
15
+ display: inline-block;
16
+ width: var(--sn-theme-toggle-size, 12px);
17
+ height: var(--sn-theme-toggle-size, 12px);
18
+ border-radius: 50%;
19
+ border: 1px solid var(--sn-fg-muted);
20
+ background: var(--sn-fg);
21
+ transition: background var(--sn-base) var(--sn-ease);
22
+ }
23
+ [data-theme="light"] .sn-theme-toggle__indicator { background: transparent; }
package/src/index.css ADDED
@@ -0,0 +1,17 @@
1
+ @import "./tokens.css";
2
+ @import "./base.css";
3
+
4
+ @import "./components/btn.css";
5
+ @import "./components/input.css";
6
+ @import "./components/card.css";
7
+ @import "./components/badge.css";
8
+ @import "./components/kbd.css";
9
+ @import "./components/divider.css";
10
+ @import "./components/meta.css";
11
+ @import "./components/icon.css";
12
+ @import "./components/mark.css";
13
+ @import "./components/monogram.css";
14
+ @import "./components/avatar.css";
15
+ @import "./components/pulse.css";
16
+ @import "./components/copy-button.css";
17
+ @import "./components/theme-toggle.css";
package/src/tokens.css ADDED
@@ -0,0 +1,96 @@
1
+ /* snowztech / design tokens
2
+ Pure CSS custom properties. Safe to import alone (no resets, no components). */
3
+
4
+ :root {
5
+ --sn-font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
6
+ --sn-font-sans: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
7
+
8
+ --sn-text-2xs: 11px;
9
+ --sn-text-xs: 12px;
10
+ --sn-text-sm: 13px;
11
+ --sn-text-base: 14px;
12
+ --sn-text-md: 15px;
13
+ --sn-text-lg: 17px;
14
+ --sn-text-xl: 20px;
15
+ --sn-text-2xl: 24px;
16
+ --sn-text-3xl: 28px;
17
+ --sn-text-4xl: 36px;
18
+
19
+ --sn-leading-tight: 1.2;
20
+ --sn-leading-normal: 1.55;
21
+ --sn-leading-relaxed: 1.75;
22
+
23
+ --sn-s-1: 4px; --sn-s-2: 8px; --sn-s-3: 12px;
24
+ --sn-s-4: 16px; --sn-s-5: 20px; --sn-s-6: 24px;
25
+ --sn-s-7: 32px; --sn-s-8: 40px; --sn-s-9: 48px;
26
+ --sn-s-10: 64px; --sn-s-11: 80px; --sn-s-12: 96px;
27
+
28
+ --sn-r-none: 0;
29
+ --sn-r-xs: 2px;
30
+ --sn-r-sm: 4px;
31
+ --sn-r-md: 6px;
32
+ --sn-r-lg: 8px;
33
+
34
+ --sn-fast: 100ms;
35
+ --sn-base: 160ms;
36
+ --sn-ease: cubic-bezier(0.2, 0, 0, 1);
37
+
38
+ /* dark, default */
39
+ --sn-bg: #0a0a0a;
40
+ --sn-bg-elev-1: #111111;
41
+ --sn-bg-elev-2: #181818;
42
+ --sn-bg-inset: #050505;
43
+
44
+ --sn-border: #1f1f1f;
45
+ --sn-border-strong: #2a2a2a;
46
+ --sn-border-subtle: #161616;
47
+
48
+ --sn-fg: #e8e8e8;
49
+ --sn-fg-muted: #888888;
50
+ --sn-fg-subtle: #666666;
51
+ --sn-fg-faint: #444444;
52
+ --sn-fg-inverse: #0a0a0a;
53
+
54
+ --sn-accent: #8ab4f8;
55
+ --sn-accent-hover: #a8c7fa;
56
+ --sn-accent-active: #6c9eed;
57
+ --sn-accent-fg: #0a0a0a;
58
+ --sn-accent-soft: rgba(138, 180, 248, 0.10);
59
+ --sn-accent-border: rgba(138, 180, 248, 0.24);
60
+
61
+ --sn-success: #7fc77f;
62
+ --sn-warning: #d4a857;
63
+ --sn-danger: #d77070;
64
+
65
+ --sn-success-soft: rgba(127, 199, 127, 0.10);
66
+ --sn-warning-soft: rgba(212, 168, 87, 0.10);
67
+ --sn-danger-soft: rgba(215, 112, 112, 0.10);
68
+
69
+ --sn-shadow-sm: none;
70
+ --sn-shadow-md: 0 0 0 1px var(--sn-border);
71
+ --sn-shadow-lg: 0 0 0 1px var(--sn-border-strong);
72
+ }
73
+
74
+ [data-theme="light"] {
75
+ --sn-bg: #f7f7f5;
76
+ --sn-bg-elev-1: #ffffff;
77
+ --sn-bg-elev-2: #ffffff;
78
+ --sn-bg-inset: #efefec;
79
+
80
+ --sn-border: #e2e2dd;
81
+ --sn-border-strong: #c8c8c2;
82
+ --sn-border-subtle: #ececea;
83
+
84
+ --sn-fg: #161616;
85
+ --sn-fg-muted: #6a6a6a;
86
+ --sn-fg-subtle: #888888;
87
+ --sn-fg-faint: #b0b0ad;
88
+ --sn-fg-inverse: #ffffff;
89
+
90
+ --sn-accent: #2a64d6;
91
+ --sn-accent-hover: #1f56c2;
92
+ --sn-accent-active: #194ba8;
93
+ --sn-accent-fg: #ffffff;
94
+ --sn-accent-soft: rgba(42, 100, 214, 0.08);
95
+ --sn-accent-border: rgba(42, 100, 214, 0.24);
96
+ }