@toybreaker/fiko 0.4.0 → 0.5.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024–2025 Toybreaker
3
+ Copyright (c) 2024–2026 Toybreaker
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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 six cascade layers and imports all `omg/` sheets in the correct order.
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
- | `theme` | Semantic aliases + element defaults |
108
- | `layout` | Body, container, grid, nav |
109
- | `components` | Buttons, inputs, links |
110
- | `utilities` | Atomic helpers: `.hide`, `.flex`, `.center`, etc. |
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:
@@ -166,4 +184,4 @@ fiko was designed to pair with Astro scoped styles:
166
184
 
167
185
  ## License
168
186
 
169
- MIT — Copyright (c) 2024–2025 Toybreaker
187
+ MIT — Copyright (c) 2024–2026 Toybreaker
package/index.css CHANGED
@@ -50,3 +50,5 @@
50
50
  @import url(omg/utils/aspect.css) layer(utilities);
51
51
  @import url(omg/utils/gradients.css) layer(utilities);
52
52
  @import url(omg/utils/misc.css) layer(utilities);
53
+
54
+ @import url(omg/utils/fiko.css) layer(utilities);
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
- .bento > :first-child { grid-column: 1 / -1; }
107
+ /* Featured first child: 2×2 */
108
+ .bento > :first-child { grid-column: span 2; grid-row: span 2; }
89
109
 
90
- .bento > :nth-child(7n + 1):not(:first-child) { grid-column: 1 / -1; }
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
- @container main-container (min-width: 480px) {
93
- .bento { grid-template-columns: 1fr 1fr; }
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: 640px) {
97
- .bento { grid-template-columns: 1fr 1fr 1fr; }
98
- .bento > :first-child { grid-column: 1 / 3; grid-row: 1 / 3; }
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
  }
@@ -144,7 +144,7 @@ svg:not(:root) {
144
144
  margin-right: var(--maximise);
145
145
  }
146
146
 
147
- .clipped-circle {
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,10 +1,10 @@
1
1
  {
2
2
  "name": "@toybreaker/fiko",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
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>",
7
- "homepage": "https://junglesta.github.io/fiko/demo/",
7
+ "homepage": "https://fiko.junglestar.org",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "git+https://github.com/junglesta/fiko.git"
@@ -22,7 +22,9 @@
22
22
  "modern-css"
23
23
  ],
24
24
  "scripts": {
25
- "build": "node scripts/build-demo.mjs"
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
- /*! 🐉 404.css | MIT License */
2
- /* branding/3client_theme.css — brand-specific overrides
1
+ /*! fiko | MIT License */
2
+ /* branding/overrides.css — brand-specific overrides
3
3
  *
4
- * .h1–.h6, .dim, .underline, .typewriter, .dots, .maximise,
5
- * .clipped-circle, .cat, .bento, [lang] switching are in fiko core.
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
- /*! 🐉 404.css | MIT License */
2
- /* branding/1client_vars.css — brand palette tokens
1
+ /*! fiko | MIT License */
2
+ /* branding/palette.css — raw brand color tokens
3
3
  *
4
- * Neutrals (--dark, --light and alpha variants) are defined in
5
- * omg/1vars.css — override here only if your brand uses a tinted surface.
4
+ * Injected into the `tokens` layer:
5
+ * @import url(./branding/palette.css) layer(tokens);
6
6
  *
7
- * Add brand-specific tokens: --brand, --nobori, --surface_*, gradients, etc.
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
- /*! 🐉 404.css | MIT License */
2
- /* 000/2client_datatheme.css — semantic theme aliases
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