@toybreaker/fiko 0.4.0 → 0.5.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 +30 -12
- package/index.css +2 -0
- package/omg/4layout.css +36 -14
- package/omg/5components.css +35 -1
- package/omg/utils/fiko.css +66 -0
- package/package.json +8 -3
- package/template/branding/overrides.css +7 -4
- package/template/branding/palette.css +8 -5
- package/template/branding/roles.css +7 -4
package/README.md
CHANGED
|
@@ -21,8 +21,6 @@ fiko takes a third path: a minimal, layered foundation you override by design, n
|
|
|
21
21
|
## Install
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
npm install @toybreaker/fiko
|
|
25
|
-
# or
|
|
26
24
|
pnpm add @toybreaker/fiko
|
|
27
25
|
```
|
|
28
26
|
|
|
@@ -37,7 +35,7 @@ pnpm add @toybreaker/fiko
|
|
|
37
35
|
@import "@toybreaker/fiko";
|
|
38
36
|
```
|
|
39
37
|
|
|
40
|
-
This imports `omg/` — the brand-agnostic framework. It declares
|
|
38
|
+
This imports `omg/` — the brand-agnostic framework. It declares seven cascade layers and imports all `omg/` sheets in the correct order.
|
|
41
39
|
|
|
42
40
|
### 2. Add your brand (copy the template)
|
|
43
41
|
|
|
@@ -97,20 +95,23 @@ fiko/
|
|
|
97
95
|
## Cascade Layers
|
|
98
96
|
|
|
99
97
|
```css
|
|
100
|
-
@layer reset, tokens, theme, layout, components, utilities;
|
|
98
|
+
@layer reset, tokens, base, theme, layout, components, utilities;
|
|
101
99
|
```
|
|
102
100
|
|
|
103
|
-
| Layer | Purpose |
|
|
104
|
-
|
|
105
|
-
| `reset` | Margin/padding zero, box-sizing, smooth scroll |
|
|
106
|
-
| `tokens` | CSS custom properties: spacing, type, color |
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
101
|
+
| Layer | Purpose | Your files |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| `reset` | Margin/padding zero, box-sizing, smooth scroll | — |
|
|
104
|
+
| `tokens` | CSS custom properties: spacing, type, color | `branding/palette.css` |
|
|
105
|
+
| `base` | Element defaults (h1–h6, p, blockquote) | — |
|
|
106
|
+
| `theme` | Semantic aliases + brand overrides | `branding/roles.css`, `branding/overrides.css` |
|
|
107
|
+
| `layout` | Body, container, grid, nav | — |
|
|
108
|
+
| `components` | Buttons, inputs, links | — |
|
|
109
|
+
| `utilities` | Atomic helpers: `.hide`, `.flex`, `.center`, etc. | — |
|
|
111
110
|
|
|
112
111
|
`@layer` makes specificity predictable. A utility class in `utilities` always beats a component in `components` — no `!important` wars.
|
|
113
112
|
|
|
113
|
+
**Why `theme` after `base`?** `base` sets sensible element defaults (e.g. `h1` size). Your `overrides.css` in `theme` always wins over them — no high-specificity selectors needed.
|
|
114
|
+
|
|
114
115
|
---
|
|
115
116
|
|
|
116
117
|
## OKLCH Colors
|
|
@@ -154,6 +155,23 @@ All color tokens use OKLCH:
|
|
|
154
155
|
|
|
155
156
|
---
|
|
156
157
|
|
|
158
|
+
## Local Development
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# dev server — opens http://localhost:3000/demo/ automatically
|
|
162
|
+
pnpm dev
|
|
163
|
+
|
|
164
|
+
# build demo into dist/
|
|
165
|
+
pnpm build
|
|
166
|
+
|
|
167
|
+
# build + deploy to Netlify
|
|
168
|
+
pnpm deploy
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
`pnpm dev` serves the repo root (so `demo/index.html` can load `../index.css`) and opens the browser automatically. Edit any file in `omg/` or `demo/` and reload — no build step needed during development.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
157
175
|
## Pairing with Astro
|
|
158
176
|
|
|
159
177
|
fiko was designed to pair with Astro scoped styles:
|
package/index.css
CHANGED
package/omg/4layout.css
CHANGED
|
@@ -76,29 +76,51 @@ nav li {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/* ── BENTO BOX ──────────────────────────────────── */
|
|
79
|
-
/* Mosaic product grid. Wrap cards in <div class="bento">
|
|
79
|
+
/* Mosaic product grid. Wrap cards in <div class="bento">
|
|
80
|
+
*
|
|
81
|
+
* Token-driven: adjust --bento_cols / --bento_rows at any level.
|
|
82
|
+
* aspect-ratio keeps cells proportional automatically.
|
|
83
|
+
* grid-auto-flow: dense fills gaps — add items in any order.
|
|
84
|
+
*
|
|
85
|
+
* Quick override examples:
|
|
86
|
+
* style="--bento_cols:4; --bento_rows:2" → 4×2 landscape
|
|
87
|
+
* style="--bento_cols:2; --bento_rows:4" → 2×4 portrait
|
|
88
|
+
*
|
|
89
|
+
* Span modifiers on children:
|
|
90
|
+
* .bento_col_2 / .bento_col_3 → span N columns
|
|
91
|
+
* .bento_row_2 / .bento_row_3 → span N rows
|
|
92
|
+
* .bento_full → full width
|
|
93
|
+
*/
|
|
80
94
|
|
|
81
95
|
.bento {
|
|
96
|
+
--bento_cols: 3;
|
|
97
|
+
--bento_rows: 3;
|
|
82
98
|
display: grid;
|
|
83
|
-
grid-template-columns: 1fr;
|
|
99
|
+
grid-template-columns: repeat(var(--bento_cols), 1fr);
|
|
100
|
+
grid-template-rows: repeat(var(--bento_rows), 1fr);
|
|
101
|
+
grid-auto-flow: dense;
|
|
84
102
|
gap: calc(var(--spaceV) * 0.5) calc(var(--spaceH) * 0.5);
|
|
85
103
|
width: 100%;
|
|
104
|
+
aspect-ratio: var(--bento_cols) / var(--bento_rows);
|
|
86
105
|
}
|
|
87
106
|
|
|
88
|
-
|
|
107
|
+
/* Featured first child: 2×2 */
|
|
108
|
+
.bento > :first-child { grid-column: span 2; grid-row: span 2; }
|
|
89
109
|
|
|
90
|
-
|
|
110
|
+
/* ── Span modifiers ─────────────────────────────── */
|
|
111
|
+
.bento > .bento_col_2 { grid-column: span 2; }
|
|
112
|
+
.bento > .bento_col_3 { grid-column: span 3; }
|
|
113
|
+
.bento > .bento_full { grid-column: 1 / -1; }
|
|
114
|
+
.bento > .bento_row_2 { grid-row: span 2; }
|
|
115
|
+
.bento > .bento_row_3 { grid-row: span 3; }
|
|
91
116
|
|
|
92
|
-
|
|
93
|
-
|
|
117
|
+
/* ── Responsive defaults ────────────────────────── */
|
|
118
|
+
@container main-container (max-width: 479px) {
|
|
119
|
+
.bento { --bento_cols: 1; --bento_rows: 6; }
|
|
120
|
+
.bento > :first-child { grid-column: span 1; grid-row: span 1; }
|
|
94
121
|
}
|
|
95
122
|
|
|
96
|
-
@container main-container (min-width:
|
|
97
|
-
.bento {
|
|
98
|
-
.bento > :first-child { grid-column:
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
@container main-container (min-width: 960px) {
|
|
102
|
-
.bento { grid-template-columns: repeat(4, 1fr); }
|
|
103
|
-
.bento > :first-child { grid-column: 1 / 3; grid-row: 1 / 3; }
|
|
123
|
+
@container main-container (min-width: 480px) and (max-width: 639px) {
|
|
124
|
+
.bento { --bento_cols: 2; --bento_rows: 4; }
|
|
125
|
+
.bento > :first-child { grid-column: span 2; grid-row: span 2; }
|
|
104
126
|
}
|
package/omg/5components.css
CHANGED
|
@@ -144,7 +144,7 @@ svg:not(:root) {
|
|
|
144
144
|
margin-right: var(--maximise);
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
.
|
|
147
|
+
.clipped_circle {
|
|
148
148
|
clip-path: circle(50px at center);
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -206,6 +206,40 @@ details.accordion > :not(summary) {
|
|
|
206
206
|
padding: var(--spaceV) var(--spaceH);
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
/* ── ACCORDION CHEVRON — SVG arrow marker ────────── */
|
|
210
|
+
/* Modifier: <details class="accordion accordion_chevron">
|
|
211
|
+
* Replaces +/× text with an animated SVG chevron via mask-image.
|
|
212
|
+
* Closed: → pointing right. Open: rotated 90° pointing down.
|
|
213
|
+
* Composable: stack with other modifiers for full editorial style.
|
|
214
|
+
* Color inherits --cta; override with: style="--cta: var(--brand)"
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
details.accordion.accordion_chevron > summary::after,
|
|
218
|
+
details.accordion.accordion_chevron[open] > summary::after {
|
|
219
|
+
content: '';
|
|
220
|
+
display: block;
|
|
221
|
+
width: 1.25em;
|
|
222
|
+
height: 1.25em;
|
|
223
|
+
flex-shrink: 0;
|
|
224
|
+
background-color: var(--cta);
|
|
225
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9 6L15 12L9 18'/%3E%3C/svg%3E");
|
|
226
|
+
-webkit-mask-size: contain;
|
|
227
|
+
-webkit-mask-repeat: no-repeat;
|
|
228
|
+
-webkit-mask-position: center;
|
|
229
|
+
mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9 6L15 12L9 18'/%3E%3C/svg%3E");
|
|
230
|
+
mask-size: contain;
|
|
231
|
+
mask-repeat: no-repeat;
|
|
232
|
+
mask-position: center;
|
|
233
|
+
transform: rotate(0deg);
|
|
234
|
+
transition: transform 200ms ease, background-color var(--transition);
|
|
235
|
+
line-height: 1;
|
|
236
|
+
font-size: 1em;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
details.accordion.accordion_chevron[open] > summary::after {
|
|
240
|
+
transform: rotate(90deg);
|
|
241
|
+
}
|
|
242
|
+
|
|
209
243
|
/* ── DOT LEADER ─────────────────────────────────── */
|
|
210
244
|
/* Usage: <span class="dots"> between label and value in menus/TOC */
|
|
211
245
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*! fiko | MIT License */
|
|
2
|
+
/* utils/fiko.css — .fiko signature class
|
|
3
|
+
*
|
|
4
|
+
* Adds the warm animated orb glow to any element.
|
|
5
|
+
* Usage: <section class="fiko"> … </section>
|
|
6
|
+
*
|
|
7
|
+
* Requirements: the element needs dimensions (height/min-height).
|
|
8
|
+
* Pseudo-elements carry the orbs; direct children stay above via z-index.
|
|
9
|
+
* Override orb colors with --fiko_orb_a / --fiko_orb_b.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
.fiko {
|
|
13
|
+
--fiko_orb_a: oklch(0.65 0.22 40); /* warm orange */
|
|
14
|
+
--fiko_orb_b: oklch(0.72 0.20 65); /* amber */
|
|
15
|
+
position: relative;
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
background: var(--dark, oklch(0.12 0.01 265));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.fiko::before,
|
|
21
|
+
.fiko::after {
|
|
22
|
+
content: '';
|
|
23
|
+
position: absolute;
|
|
24
|
+
border-radius: 50%;
|
|
25
|
+
pointer-events: none;
|
|
26
|
+
z-index: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* primary orb — top-right */
|
|
30
|
+
.fiko::before {
|
|
31
|
+
width: 60%;
|
|
32
|
+
aspect-ratio: 1;
|
|
33
|
+
background: var(--fiko_orb_a);
|
|
34
|
+
filter: blur(80px);
|
|
35
|
+
opacity: 0.22;
|
|
36
|
+
top: -20%;
|
|
37
|
+
right: -10%;
|
|
38
|
+
animation: fiko_orb_drift 9s ease-in-out infinite;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* secondary orb — bottom-right */
|
|
42
|
+
.fiko::after {
|
|
43
|
+
width: 40%;
|
|
44
|
+
aspect-ratio: 1;
|
|
45
|
+
background: var(--fiko_orb_b);
|
|
46
|
+
filter: blur(60px);
|
|
47
|
+
opacity: 0.15;
|
|
48
|
+
bottom: -10%;
|
|
49
|
+
right: 25%;
|
|
50
|
+
animation: fiko_orb_drift 13s ease-in-out infinite reverse;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* keep children above orbs */
|
|
54
|
+
.fiko > * { position: relative; z-index: 1; }
|
|
55
|
+
|
|
56
|
+
@keyframes fiko_orb_drift {
|
|
57
|
+
0% { transform: translate(0, 0) scale(1); }
|
|
58
|
+
33% { transform: translate(30px, -20px) scale(1.05); }
|
|
59
|
+
66% { transform: translate(-20px, 15px) scale(0.96); }
|
|
60
|
+
100% { transform: translate(0, 0) scale(1); }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@media (prefers-reduced-motion: reduce) {
|
|
64
|
+
.fiko::before,
|
|
65
|
+
.fiko::after { animation: none; }
|
|
66
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toybreaker/fiko",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "LOOK GOOD OR DIE! — cascade layers, OKLCH colors, design tokens. Zero specificity wars. Smiling DX.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Toybreaker <hello@junglestar.co>",
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
"modern-css"
|
|
23
23
|
],
|
|
24
24
|
"scripts": {
|
|
25
|
-
"
|
|
25
|
+
"dev": "serve . & sleep 1 && open http://localhost:3000/demo/",
|
|
26
|
+
"build": "node scripts/build-demo.mjs",
|
|
27
|
+
"deploy": "node scripts/build-demo.mjs && netlify deploy --prod --dir=dist"
|
|
26
28
|
},
|
|
27
29
|
"main": "index.css",
|
|
28
30
|
"style": "index.css",
|
|
@@ -35,5 +37,8 @@
|
|
|
35
37
|
"index.css",
|
|
36
38
|
"omg/",
|
|
37
39
|
"template/"
|
|
38
|
-
]
|
|
40
|
+
],
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"serve": "^14.2.6"
|
|
43
|
+
}
|
|
39
44
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
/* branding/
|
|
1
|
+
/*! fiko | MIT License */
|
|
2
|
+
/* branding/overrides.css — brand-specific overrides
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* .
|
|
4
|
+
* Injected into the `theme` layer:
|
|
5
|
+
* @import url(./branding/overrides.css) layer(theme);
|
|
6
|
+
*
|
|
7
|
+
* .h1–.h6, .dim, .underline, .typewriter, .prose, .dots, .maximise,
|
|
8
|
+
* .cat, .bento, .accordion, [lang] switching are in fiko core (omg/).
|
|
6
9
|
* Add brand/client-specific rules here only.
|
|
7
10
|
*/
|
|
8
11
|
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
/* branding/
|
|
1
|
+
/*! fiko | MIT License */
|
|
2
|
+
/* branding/palette.css — raw brand color tokens
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Injected into the `tokens` layer:
|
|
5
|
+
* @import url(./branding/palette.css) layer(tokens);
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Neutrals (--dark, --light and alpha variants) are defined in omg/1vars.css.
|
|
8
|
+
* Override here only if your brand uses a tinted surface.
|
|
9
|
+
*
|
|
10
|
+
* Add brand-specific tokens: --brand, --surface_*, gradients, etc.
|
|
8
11
|
*/
|
|
9
12
|
|
|
10
13
|
:root {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
/*
|
|
1
|
+
/*! fiko | MIT License */
|
|
2
|
+
/* branding/roles.css — semantic theme aliases
|
|
3
|
+
*
|
|
4
|
+
* Maps raw palette tokens (from palette.css) to semantic roles.
|
|
5
|
+
*
|
|
6
|
+
* Injected into the `theme` layer:
|
|
7
|
+
* @import url(./branding/roles.css) layer(theme);
|
|
3
8
|
*
|
|
4
|
-
* Maps raw palette tokens (from 1client_vars.css) to semantic roles.
|
|
5
|
-
* This file loads in the `theme` layer.
|
|
6
9
|
* Permanent light mode — dark mode intentionally excluded.
|
|
7
10
|
*/
|
|
8
11
|
|