@toybreaker/fiko 0.6.4 → 0.7.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.
@@ -1,67 +1,123 @@
1
1
  /*! fiko | MIT License */
2
2
  /* utils/fiko.css — FIKO signature utilities
3
3
  *
4
- * .fiko_orbital warm animated orb glow (needs dimensions; override --fiko_orb_a / --fiko_orb_b)
4
+ * .fiko_glow ambient blurred orb glow; slow drift (no orbit)
5
+ * Override: --fiko_orb_a / --fiko_orb_b
6
+ *
7
+ * .fiko_orbital — true elliptical orbit via CSS Motion Path
8
+ * Same tokens; super-slow so it reads as ambient, not busy
9
+ *
5
10
  * .fiko — one-shot vertical shake on page load (no JS)
6
11
  * .fiko_hover — vertical shake on :hover
7
12
  * .fiko_loop — continuous vertical shake
8
- * Override: style="--shake_distance: 12px; --shake_duration: 0.4s"
13
+ * Override: --shake_distance / --shake_duration
14
+ *
15
+ * Both glow utilities: element needs dimensions (height / min-height).
16
+ * Pseudo-elements carry the orbs; direct children stay above via z-index.
9
17
  */
10
18
 
11
- .fiko_orbital {
12
- --fiko_orb_a: oklch(0.65 0.22 40); /* warm orange */
13
- --fiko_orb_b: oklch(0.72 0.20 65); /* amber */
14
- position: relative;
15
- overflow: hidden;
16
- background: var(--dark, oklch(0.12 0.01 265));
17
- }
18
-
19
+ /* ── shared orb pseudo-element base ────────────────────── */
20
+ .fiko_glow::before,
21
+ .fiko_glow::after,
19
22
  .fiko_orbital::before,
20
23
  .fiko_orbital::after {
21
- content: '';
22
- position: absolute;
23
- border-radius: 50%;
24
- pointer-events: none;
25
- z-index: 0;
24
+ content: '';
25
+ position: absolute;
26
+ border-radius: 50%;
27
+ pointer-events: none;
28
+ z-index: 0;
29
+ }
30
+
31
+ /* ── .fiko_glow — ambient drift ────────────────────────── */
32
+
33
+ .fiko_glow {
34
+ --fiko_orb_a: oklch(0.65 0.22 40); /* warm orange */
35
+ --fiko_orb_b: oklch(0.72 0.20 65); /* amber */
36
+ position: relative;
37
+ overflow: hidden;
38
+ background: var(--surface, oklch(0.12 0.01 265));
26
39
  }
27
40
 
28
41
  /* primary orb — top-right */
29
- .fiko_orbital::before {
30
- width: 60%;
31
- aspect-ratio: 1;
32
- background: var(--fiko_orb_a);
33
- filter: blur(80px);
34
- opacity: 0.22;
35
- top: -20%;
36
- right: -10%;
37
- animation: fiko_orb_drift 9s ease-in-out infinite;
42
+ .fiko_glow::before {
43
+ width: 60%;
44
+ aspect-ratio: 1;
45
+ background: var(--fiko_orb_a);
46
+ filter: blur(80px);
47
+ opacity: 0.22;
48
+ top: -20%;
49
+ right: -10%;
50
+ animation: fiko_orb_drift 9s ease-in-out infinite;
38
51
  }
39
52
 
40
53
  /* secondary orb — bottom-right */
54
+ .fiko_glow::after {
55
+ width: 40%;
56
+ aspect-ratio: 1;
57
+ background: var(--fiko_orb_b);
58
+ filter: blur(60px);
59
+ opacity: 0.15;
60
+ bottom: -10%;
61
+ right: 25%;
62
+ animation: fiko_orb_drift 13s ease-in-out infinite reverse;
63
+ }
64
+
65
+ .fiko_glow > * { position: relative; z-index: 1; }
66
+
67
+ @keyframes fiko_orb_drift {
68
+ 0% { transform: translate(0, 0) scale(1); }
69
+ 33% { transform: translate(30px, -20px) scale(1.05); }
70
+ 66% { transform: translate(-20px, 15px) scale(0.96); }
71
+ 100% { transform: translate(0, 0) scale(1); }
72
+ }
73
+
74
+ /* ── .fiko_orbital — true elliptical orbit ─────────────── */
75
+ /* CSS Motion Path (offset-path). Super slow — ambient, not busy. */
76
+ /* Two orbs on slightly different ellipses, opposite directions. */
77
+
78
+ .fiko_orbital {
79
+ --fiko_orb_a: oklch(0.65 0.22 40); /* warm orange */
80
+ --fiko_orb_b: oklch(0.72 0.20 65); /* amber */
81
+ position: relative;
82
+ overflow: hidden;
83
+ background: var(--surface, oklch(0.12 0.01 265));
84
+ }
85
+
86
+ .fiko_orbital::before {
87
+ width: 55%;
88
+ aspect-ratio: 1;
89
+ background: var(--fiko_orb_a);
90
+ filter: blur(70px);
91
+ opacity: 0.20;
92
+ offset-path: ellipse(30% 18% at 50% 50%);
93
+ offset-distance: 0%;
94
+ animation: fiko_orbit 38s linear infinite;
95
+ }
96
+
41
97
  .fiko_orbital::after {
42
- width: 40%;
43
- aspect-ratio: 1;
44
- background: var(--fiko_orb_b);
45
- filter: blur(60px);
46
- opacity: 0.15;
47
- bottom: -10%;
48
- right: 25%;
49
- animation: fiko_orb_drift 13s ease-in-out infinite reverse;
98
+ width: 40%;
99
+ aspect-ratio: 1;
100
+ background: var(--fiko_orb_b);
101
+ filter: blur(55px);
102
+ opacity: 0.14;
103
+ offset-path: ellipse(36% 22% at 50% 50%);
104
+ offset-distance: 50%;
105
+ animation: fiko_orbit 54s linear infinite reverse;
50
106
  }
51
107
 
52
- /* keep children above orbs */
53
108
  .fiko_orbital > * { position: relative; z-index: 1; }
54
109
 
55
- @keyframes fiko_orb_drift {
56
- 0% { transform: translate(0, 0) scale(1); }
57
- 33% { transform: translate(30px, -20px) scale(1.05); }
58
- 66% { transform: translate(-20px, 15px) scale(0.96); }
59
- 100% { transform: translate(0, 0) scale(1); }
110
+ @keyframes fiko_orbit {
111
+ from { offset-distance: 0%; }
112
+ to { offset-distance: 100%; }
60
113
  }
61
114
 
115
+ /* ── motion safety ──────────────────────────────────────── */
62
116
  @media (prefers-reduced-motion: reduce) {
63
- .fiko_orbital::before,
64
- .fiko_orbital::after { animation: none; }
117
+ .fiko_glow::before,
118
+ .fiko_glow::after,
119
+ .fiko_orbital::before,
120
+ .fiko_orbital::after { animation: none; }
65
121
  }
66
122
 
67
123
  /* ─── .fiko shake utility ───────────────────────────────────────────────────
@@ -76,40 +132,33 @@
76
132
  */
77
133
 
78
134
  .fiko,
79
- .fiko_hover,
80
- .fiko_loop {
81
- --shake_distance: 18px;
82
- --shake_duration: 0.6s;
135
+ .fiko_hover {
136
+ --shake_distance: 18px;
137
+ --shake_duration: 0.6s;
83
138
  }
84
139
 
85
140
  /* default: one-shot on load */
86
141
  .fiko {
87
- animation: fiko_shake var(--shake_duration) ease-out both;
142
+ animation: fiko_shake var(--shake_duration) ease-out both;
88
143
  }
89
144
 
90
145
  /* hover: re-triggers each time cursor enters */
91
146
  .fiko_hover:hover {
92
- animation: fiko_shake var(--shake_duration) ease-out both;
93
- }
94
-
95
- /* loop: runs continuously */
96
- .fiko_loop {
97
- animation: fiko_shake var(--shake_duration) ease-out infinite;
147
+ animation: fiko_shake var(--shake_duration) ease-out both;
98
148
  }
99
149
 
100
150
  @keyframes fiko_shake {
101
- 0% { transform: translateY(0); }
102
- 10% { transform: translateY(calc(var(--shake_distance) * -1)); }
103
- 22% { transform: translateY(calc(var(--shake_distance) * 0.78)); }
104
- 36% { transform: translateY(calc(var(--shake_distance) * -0.56)); }
105
- 50% { transform: translateY(calc(var(--shake_distance) * 0.44)); }
106
- 64% { transform: translateY(calc(var(--shake_distance) * -0.22)); }
107
- 78% { transform: translateY(calc(var(--shake_distance) * 0.11)); }
108
- 100% { transform: translateY(0); }
151
+ 0% { transform: translateY(0); }
152
+ 10% { transform: translateY(calc(var(--shake_distance) * -1)); }
153
+ 22% { transform: translateY(calc(var(--shake_distance) * 0.78)); }
154
+ 36% { transform: translateY(calc(var(--shake_distance) * -0.56)); }
155
+ 50% { transform: translateY(calc(var(--shake_distance) * 0.44)); }
156
+ 64% { transform: translateY(calc(var(--shake_distance) * -0.22)); }
157
+ 78% { transform: translateY(calc(var(--shake_distance) * 0.11)); }
158
+ 100% { transform: translateY(0); }
109
159
  }
110
160
 
111
161
  @media (prefers-reduced-motion: reduce) {
112
- .fiko,
113
- .fiko_hover:hover,
114
- .fiko_loop { animation: none; }
162
+ .fiko,
163
+ .fiko_hover:hover { animation: none; }
115
164
  }
@@ -1,27 +1,165 @@
1
1
  /*! 🐉 404.css | MIT License */
2
- /* utils/layout.css — flex, positioning, writing mode */
2
+ /* utils/layout.css — flex, grid, container, bento, positioning, writing mode */
3
+
4
+ /* ── FLEX ───────────────────────────────────────── */
3
5
 
4
6
  .flex {
5
- display: flex;
7
+ display: flex;
6
8
  }
7
9
 
8
10
  .flex_col {
9
- flex-direction: column;
11
+ flex-direction: column;
12
+ }
13
+
14
+ .flex_wrap {
15
+ flex-wrap: wrap;
10
16
  }
11
17
 
18
+ .flex_1 {
19
+ flex: 1;
20
+ }
21
+
22
+ .fill {
23
+ flex: 1;
24
+ min-width: 0;
25
+ }
26
+
27
+ .w_full {
28
+ width: 100%;
29
+ }
30
+
31
+ /* ── ALIGN ──────────────────────────────────────── */
32
+
33
+ .align_start { align-items: flex-start; }
34
+ .align_center { align-items: center; }
35
+ .align_end { align-items: flex-end; }
36
+ .align_stretch { align-items: stretch; }
37
+ .align_baseline { align-items: baseline; }
38
+
39
+ /* ── JUSTIFY ────────────────────────────────────── */
40
+
41
+ .justify_start { justify-content: flex-start; }
42
+ .justify_center { justify-content: center; }
43
+ .justify_end { justify-content: flex-end; }
44
+ .justify_between { justify-content: space-between; }
45
+ .justify_around { justify-content: space-around; }
46
+
47
+ /* ── POSITIONING ────────────────────────────────── */
48
+
12
49
  .sticky {
13
- position: sticky;
14
- top: 0;
50
+ position: sticky;
51
+ top: 0;
15
52
  }
16
53
 
54
+ /* ── WRITING MODE ───────────────────────────────── */
55
+
17
56
  .vertical {
18
- display: block;
19
- writing-mode: vertical-rl;
20
- transform: rotate(180deg);
21
- text-transform: uppercase;
22
- position: relative;
23
- top: -10px;
24
- .active & {
25
- font-size: 200%;
26
- }
57
+ display: block;
58
+ writing-mode: vertical-rl;
59
+ transform: rotate(180deg);
60
+ text-transform: uppercase;
61
+ position: relative;
62
+ top: -10px;
63
+ .active & {
64
+ font-size: 200%;
65
+ }
66
+ }
67
+
68
+ /* ── CONTAINER ──────────────────────────────────── */
69
+ /* Container query setup — wraps sections for responsive children */
70
+
71
+ .container {
72
+ container-type: inline-size;
73
+ container-name: main-container;
74
+ width: min(100% - (var(--breath) * 2), var(--container_xl));
75
+ margin-inline: auto;
76
+ }
77
+
78
+ /* ── GRID ───────────────────────────────────────── */
79
+
80
+ .grid {
81
+ display: grid;
82
+ grid-template-columns: repeat(var(--grid_cols, 1), 1fr);
83
+ gap: var(--breath);
84
+ }
85
+
86
+ @container main-container (min-width: var(--bp_sm)) {
87
+ .grid {
88
+ --grid_cols: 2;
89
+ }
90
+ }
91
+
92
+ @container main-container (min-width: var(--bp_md)) {
93
+ .grid {
94
+ --grid_cols: 3;
95
+ }
96
+ }
97
+
98
+ @container main-container (min-width: var(--bp_lg)) {
99
+ .grid {
100
+ --grid_cols: 4;
101
+ }
102
+ }
103
+
104
+ /* ── BENTO BOX ──────────────────────────────────── */
105
+ /* Mosaic product grid. Wrap cards in <div class="bento">
106
+ *
107
+ * Token-driven: adjust --bento_cols / --bento_rows at any level.
108
+ * aspect-ratio keeps cells proportional automatically.
109
+ * grid-auto-flow: dense fills gaps — add items in any order.
110
+ *
111
+ * Quick override examples:
112
+ * style="--bento_cols:4; --bento_rows:2" → 4×2 landscape
113
+ * style="--bento_cols:2; --bento_rows:4" → 2×4 portrait
114
+ *
115
+ * Span modifiers on children:
116
+ * .bento_col_2 / .bento_col_3 → span N columns
117
+ * .bento_row_2 / .bento_row_3 → span N rows
118
+ * .bento_full → full width
119
+ */
120
+
121
+ .bento {
122
+ --bento_cols: 3;
123
+ --bento_rows: 3;
124
+ display: grid;
125
+ grid-template-columns: repeat(var(--bento_cols), 1fr);
126
+ grid-template-rows: repeat(var(--bento_rows), 1fr);
127
+ grid-auto-flow: dense;
128
+ gap: calc(var(--spaceV) * 0.5) calc(var(--spaceH) * 0.5);
129
+ width: 100%;
130
+ aspect-ratio: var(--bento_cols) / var(--bento_rows);
131
+ }
132
+
133
+ /* Featured first child: 2×2 */
134
+ .bento > :first-child { grid-column: span 2; grid-row: span 2; }
135
+
136
+ /* ── Span modifiers ─────────────────────────────── */
137
+ .bento > .bento_col_2 { grid-column: span 2; }
138
+ .bento > .bento_col_3 { grid-column: span 3; }
139
+ .bento > .bento_full { grid-column: 1 / -1; }
140
+ .bento > .bento_row_2 { grid-row: span 2; }
141
+ .bento > .bento_row_3 { grid-row: span 3; }
142
+
143
+ /* ── Responsive defaults ────────────────────────── */
144
+ @container main-container (max-width: 479px) {
145
+ .bento { --bento_cols: 1; --bento_rows: 6; }
146
+ .bento > :first-child { grid-column: span 1; grid-row: span 1; }
147
+ }
148
+
149
+ @container main-container (min-width: 480px) and (max-width: 639px) {
150
+ .bento { --bento_cols: 2; --bento_rows: 4; }
151
+ .bento > :first-child { grid-column: span 2; grid-row: span 2; }
152
+ }
153
+
154
+ /* ── BREAKOUT ───────────────────────────────────── */
155
+ /* Pull an element outside the container margins */
156
+
157
+ .maximise {
158
+ margin-inline: var(--maximise);
159
+ }
160
+
161
+ /* ── CLIP ───────────────────────────────────────── */
162
+
163
+ .clipped_circle {
164
+ clip-path: circle(50px at center);
27
165
  }
@@ -1,9 +1,2 @@
1
1
  /*! 🐉 404.css | MIT License */
2
- /* utils/misc.css — one-off component state overrides */
3
-
4
- .adv {
5
- opacity: 0.5;
6
- #icn_whatsapp {
7
- filter: grayscale(88%);
8
- }
9
- }
2
+ /* utils/misc.css — one-off utility overrides */
@@ -16,19 +16,19 @@
16
16
  .pad_block_xl { padding-block: calc(var(--spaceV) * 9); }
17
17
  .pad_block_xxl { padding-block: calc(var(--spaceV) * 12); }
18
18
 
19
- .pad_top_sm { padding-top: calc(var(--spaceV) * 1.5); }
20
- .pad_top_md { padding-top: calc(var(--spaceV) * 3); }
21
- .pad_top_lg { padding-top: calc(var(--spaceV) * 6); }
22
- .pad_top_xl { padding-top: calc(var(--spaceV) * 9); }
23
- .pad_top_xxl { padding-top: calc(var(--spaceV) * 12); }
24
-
25
- .pad_bottom_sm { padding-bottom: calc(var(--spaceV) * 1.5); }
26
- .pad_bottom_md { padding-bottom: calc(var(--spaceV) * 3); }
27
- .pad_bottom_lg { padding-bottom: calc(var(--spaceV) * 6); }
28
- .pad_bottom_xl { padding-bottom: calc(var(--spaceV) * 9); }
29
- .pad_bottom_xxl { padding-bottom: calc(var(--spaceV) * 12); }
30
-
31
- .top_padding { padding-top: var(--spaceV); }
19
+ .pad_top_sm { padding-block-start: calc(var(--spaceV) * 1.5); }
20
+ .pad_top_md { padding-block-start: calc(var(--spaceV) * 3); }
21
+ .pad_top_lg { padding-block-start: calc(var(--spaceV) * 6); }
22
+ .pad_top_xl { padding-block-start: calc(var(--spaceV) * 9); }
23
+ .pad_top_xxl { padding-block-start: calc(var(--spaceV) * 12); }
24
+
25
+ .pad_bottom_sm { padding-block-end: calc(var(--spaceV) * 1.5); }
26
+ .pad_bottom_md { padding-block-end: calc(var(--spaceV) * 3); }
27
+ .pad_bottom_lg { padding-block-end: calc(var(--spaceV) * 6); }
28
+ .pad_bottom_xl { padding-block-end: calc(var(--spaceV) * 9); }
29
+ .pad_bottom_xxl { padding-block-end: calc(var(--spaceV) * 12); }
30
+
31
+ .top_padding { padding-block-start: var(--spaceV); }
32
32
 
33
33
  /* ── SPACER BLOCKS ───────────────────────────────── */
34
34
 
@@ -1,31 +1,119 @@
1
1
  /*! 🐉 404.css | MIT License */
2
- /* utils/text.css — text alignment, transform, wrap */
2
+ /* utils/text.css — text utilities */
3
+
4
+ /* ── ALIGNMENT & TRANSFORM ──────────────────────── */
3
5
 
4
6
  .center,
5
7
  .centre,
6
8
  .centered {
7
- text-align: center;
9
+ text-align: center;
8
10
  }
9
11
 
10
12
  .uppercase,
11
13
  .uppercase > * {
12
- text-transform: uppercase !important;
14
+ text-transform: uppercase !important;
13
15
  }
14
16
 
15
17
  .capitalize,
16
18
  .capitalise,
17
19
  .titlecase {
18
- text-transform: capitalize;
20
+ text-transform: capitalize;
19
21
  }
20
22
 
21
23
  .strikethrough {
22
- text-decoration: line-through;
24
+ text-decoration: line-through;
23
25
  }
24
26
 
25
27
  .pretty {
26
- text-wrap: pretty;
28
+ text-wrap: pretty;
27
29
  }
28
30
 
31
+ /* ── FONT FAMILY ────────────────────────────────── */
32
+
29
33
  .mono {
30
- font-family: ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace;
34
+ font-family: ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace;
35
+ }
36
+
37
+ .typewriter {
38
+ font-family: var(--font_serif);
39
+ }
40
+
41
+ /* ── DECORATION ─────────────────────────────────── */
42
+
43
+ .underline {
44
+ text-decoration: underline;
45
+ text-underline-offset: 3px;
46
+ }
47
+
48
+ /* ── WEIGHT ─────────────────────────────────────── */
49
+
50
+ .weight_thin { font-weight: var(--weight_thin); }
51
+ .weight_light { font-weight: var(--weight_light); }
52
+ .weight_regular { font-weight: var(--weight_regular); }
53
+ .weight_medium { font-weight: var(--weight_medium); }
54
+ .weight_bold { font-weight: var(--weight_bold); }
55
+
56
+ /* numeric scale */
57
+ .weight_100 { font-weight: var(--weight_100); }
58
+ .weight_200 { font-weight: var(--weight_200); }
59
+ .weight_300 { font-weight: var(--weight_300); }
60
+ .weight_400 { font-weight: var(--weight_400); }
61
+ .weight_500 { font-weight: var(--weight_500); }
62
+ .weight_600 { font-weight: var(--weight_600); }
63
+ .weight_700 { font-weight: var(--weight_700); }
64
+ .weight_800 { font-weight: var(--weight_800); }
65
+
66
+ /* ── SIZE & WEIGHT ──────────────────────────────── */
67
+
68
+ .dim {
69
+ color: var(--text);
70
+ font-size: calc(var(--font_size) * 0.95);
71
+ }
72
+
73
+ /* ── PROSE ──────────────────────────────────────── */
74
+
75
+ .prose {
76
+ max-width: 66ch;
77
+ margin-inline: auto;
78
+ }
79
+
80
+ /* ── CAT ────────────────────────────────────────── */
81
+
82
+ .cat {
83
+ text-transform: capitalize;
84
+ }
85
+
86
+ /* ── HEADING SCALE ──────────────────────────────── */
87
+ /* Apply heading styles to any element, decoupled from heading semantics.
88
+ * Usage: <p class="h2">Display heading</p>
89
+ */
90
+
91
+ .h1,
92
+ .h2,
93
+ .h3,
94
+ .h4,
95
+ .h5,
96
+ .h6 {
97
+ user-select: none !important;
98
+ line-height: 1.2 !important;
99
+ font-family: var(--font_family) !important;
100
+ }
101
+ .h1 { font-size: calc(var(--font_size) * 2.5) !important; font-weight: var(--weight_light) !important; }
102
+ .h2 { font-size: calc(var(--font_size) * 2) !important; font-weight: var(--weight_light) !important; }
103
+ .h3 { font-size: calc(var(--font_size) * 1.75) !important; font-weight: var(--weight_thin) !important; }
104
+ .h4 { font-size: calc(var(--font_size) * 1.5) !important; font-weight: var(--weight_thin) !important; }
105
+ .h5 { font-size: calc(var(--font_size) * 1.25) !important; font-weight: var(--weight_thin) !important; }
106
+ .h6 { font-size: calc(var(--font_size) * 1) !important; font-weight: var(--weight_light) !important; }
107
+
108
+ /* ── DOT LEADER ─────────────────────────────────── */
109
+ /* Usage: <span class="dots"> between label and value in menus/TOC */
110
+
111
+ .dots {
112
+ flex: 8;
113
+ border-bottom: max(2px, var(--borderpx)) dotted currentColor;
114
+ margin: 0 0 0 8px;
115
+ height: var(--borderpx);
116
+ position: relative;
117
+ top: 0;
118
+ opacity: 0.25;
31
119
  }
@@ -0,0 +1,22 @@
1
+ /*! 🐉 404.css | MIT License */
2
+ /* utils/transitions.css — View Transitions API helpers */
3
+
4
+ /* ── VIEW TRANSITIONS ── */
5
+ /* Assign view-transition-name to elements that should animate between pages/states.
6
+ * Usage: <img class="vt_hero"> on both pages — browser morphs between them.
7
+ * Names must be unique per page. Use inline style="--vt_name: my-name" for dynamic names.
8
+ */
9
+
10
+ .vt_hero { view-transition-name: hero; }
11
+ .vt_header { view-transition-name: header; }
12
+ .vt_image { view-transition-name: image; }
13
+ .vt_title { view-transition-name: title; }
14
+ .vt_card { view-transition-name: card; }
15
+
16
+ /* token-driven — override with inline style="--vt_name: my-name" */
17
+ .vt_custom { view-transition-name: var(--vt_name, none); }
18
+
19
+ /* opt in to cross-fade for the whole page */
20
+ .vt_page {
21
+ view-transition-name: root;
22
+ }
@@ -23,6 +23,32 @@
23
23
  display: none;
24
24
  }
25
25
 
26
+ /* ── SKIP TO CONTENT ────────────────────────────── */
27
+ /* Usage: <a class="skip_to_content" href="#main">Skip to content</a>
28
+ * Place as the very first element inside <body>.
29
+ * Invisible until focused — keyboard users can jump past nav.
30
+ */
31
+
32
+ .skip_to_content {
33
+ position: absolute;
34
+ inset-block-start: var(--spaceV);
35
+ inset-inline-start: var(--spaceH);
36
+ z-index: 9999;
37
+ padding: var(--spaceV) var(--spaceH);
38
+ background: var(--surface);
39
+ border: var(--borderpx) solid var(--border_color);
40
+ border-radius: var(--radius);
41
+ font-weight: var(--weight_bold);
42
+ translate: 0 -200%;
43
+ transition: translate var(--transition);
44
+ }
45
+
46
+ .skip_to_content:focus-visible {
47
+ translate: 0 0;
48
+ outline: 2px solid var(--primary);
49
+ outline-offset: 2px;
50
+ }
51
+
26
52
  /* visually hidden but accessible to screen readers */
27
53
  .visually_hidden,
28
54
  .sr_only {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toybreaker/fiko",
3
- "version": "0.6.4",
3
+ "version": "0.7.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,7 @@
22
22
  "modern-css"
23
23
  ],
24
24
  "scripts": {
25
- "dev": "serve . & sleep 1 && open http://localhost:3000/demo/",
25
+ "dev": "serve . -p 5555 & sleep 1 && open http://localhost:5555/",
26
26
  "build": "node scripts/build-demo.mjs",
27
27
  "deploy": "node scripts/build-demo.mjs && netlify deploy --prod --dir=dist --site=922d0a52-64e0-4eda-9fd9-742aa8619a87"
28
28
  },