@refrakt-md/skeleton 0.25.1 → 0.26.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/index.css +2 -0
- package/package.json +2 -2
- package/styles/dimensions/reading.css +18 -0
- package/styles/layouts/split.css +12 -3
- package/styles/runes/carousel.css +98 -0
- package/styles/runes/cast.css +9 -3
- package/styles/runes/feature.css +25 -3
- package/styles/runes/gallery.css +3 -27
- package/styles/runes/preview.css +21 -0
- package/styles/runes/textblock.css +3 -6
package/index.css
CHANGED
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
@import './styles/dimensions/cover.css' layer(skeleton);
|
|
37
37
|
@import './styles/dimensions/metadata.css' layer(skeleton);
|
|
38
38
|
@import './styles/dimensions/sections.css' layer(skeleton);
|
|
39
|
+
@import './styles/dimensions/reading.css' layer(skeleton);
|
|
39
40
|
@import './styles/dimensions/checklist.css' layer(skeleton);
|
|
40
41
|
@import './styles/dimensions/sequence.css' layer(skeleton);
|
|
41
42
|
@import './styles/dimensions/guest-posture.css' layer(skeleton);
|
|
@@ -84,6 +85,7 @@
|
|
|
84
85
|
@import './styles/runes/progress.css' layer(skeleton);
|
|
85
86
|
@import './styles/runes/diagram.css' layer(skeleton);
|
|
86
87
|
@import './styles/runes/gallery.css' layer(skeleton);
|
|
88
|
+
@import './styles/runes/carousel.css' layer(skeleton);
|
|
87
89
|
@import './styles/runes/diff.css' layer(skeleton);
|
|
88
90
|
@import './styles/runes/chart.css' layer(skeleton);
|
|
89
91
|
@import './styles/runes/juxtapose.css' layer(skeleton);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@refrakt-md/skeleton",
|
|
3
3
|
"description": "The structural cascade layer + layer-order contract every refrakt theme builds on — ships `@layer skeleton` and the `@layer skeleton, skin;` order declaration, plus the token-name contract",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.26.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"styles"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@refrakt-md/types": "0.
|
|
32
|
+
"@refrakt-md/types": "0.26.0"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
35
|
"build": "tsc"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* Reading register (SPEC-108) — structural treatment of body text, keyed on the
|
|
2
|
+
* `data-reading` refinement of `data-section="body"`. `prose` caps the line-length
|
|
3
|
+
* measure (distinct from the block's `width`) and sets running-text niceties; the
|
|
4
|
+
* default `ui` is unstyled here. The skin (Lumina) owns type, rhythm, and the
|
|
5
|
+
* drop-cap glyph. */
|
|
6
|
+
[data-reading="prose"] {
|
|
7
|
+
max-width: var(--rf-measure, 66ch);
|
|
8
|
+
text-wrap: pretty;
|
|
9
|
+
}
|
|
10
|
+
[data-reading="prose"] > p {
|
|
11
|
+
hanging-punctuation: first last;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Drop cap — float the opening letter of a prose body. Gated on the prose register
|
|
15
|
+
* (the engine only emits `data-dropcap` there). */
|
|
16
|
+
[data-reading="prose"][data-dropcap] > p:first-child::first-letter {
|
|
17
|
+
float: left;
|
|
18
|
+
}
|
package/styles/layouts/split.css
CHANGED
|
@@ -117,7 +117,16 @@
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
/* ─── Collapse breakpoints — beside layouts drop to one column ─── */
|
|
120
|
-
|
|
120
|
+
/* Container-query driven (WORK-490): the collapse responds to the rune's
|
|
121
|
+
* available width — its nearest query container — rather than the global
|
|
122
|
+
* viewport. That container is `.rf-page-content` on a page (content runes always
|
|
123
|
+
* render inside it; it is `container-type: inline-size`) and the `preview`
|
|
124
|
+
* viewport frame inside a preview, so a beside layout in a narrow column collapses
|
|
125
|
+
* when *that column* is tight, and the flip is faithfully simulable in the
|
|
126
|
+
* preview's viewport selector. The rule structure is unchanged from the prior
|
|
127
|
+
* `@media` form — only the query source moves from viewport to container. Shares
|
|
128
|
+
* the `data-collapse` hook (default sm/640px; `never` opts out). */
|
|
129
|
+
@container (max-width: 640px) {
|
|
121
130
|
:is([data-media-position="start"], [data-media-position="end"])[data-collapse="sm"],
|
|
122
131
|
:is([data-media-position="start"], [data-media-position="end"]):not([data-collapse]) {
|
|
123
132
|
grid-template-columns: 1fr;
|
|
@@ -128,7 +137,7 @@
|
|
|
128
137
|
grid-row: auto;
|
|
129
138
|
}
|
|
130
139
|
}
|
|
131
|
-
@
|
|
140
|
+
@container (max-width: 768px) {
|
|
132
141
|
:is([data-media-position="start"], [data-media-position="end"])[data-collapse="md"] {
|
|
133
142
|
grid-template-columns: 1fr;
|
|
134
143
|
}
|
|
@@ -137,7 +146,7 @@
|
|
|
137
146
|
grid-row: auto;
|
|
138
147
|
}
|
|
139
148
|
}
|
|
140
|
-
@
|
|
149
|
+
@container (max-width: 1024px) {
|
|
141
150
|
:is([data-media-position="start"], [data-media-position="end"])[data-collapse="lg"] {
|
|
142
151
|
grid-template-columns: 1fr;
|
|
143
152
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/* carousel — shared layout-mode structure (SPEC-100). Any rune that emits the
|
|
2
|
+
* carousel contract — host `[data-layout="carousel"]`, track `[data-name="items"]`,
|
|
3
|
+
* items `[data-name="item"]` — gets the scroll-snap track and nav positioning,
|
|
4
|
+
* with zero per-rune CSS. Nav chrome (colour/shape) is skin (Lumina's
|
|
5
|
+
* styles/runes/carousel.css). The block-agnostic behavior injects the
|
|
6
|
+
* `.rf-carousel__nav` buttons. */
|
|
7
|
+
[data-layout="carousel"] [data-name="items"] {
|
|
8
|
+
display: flex;
|
|
9
|
+
overflow-x: auto;
|
|
10
|
+
scroll-snap-type: x mandatory;
|
|
11
|
+
-webkit-overflow-scrolling: touch;
|
|
12
|
+
}
|
|
13
|
+
/* Slides are the track's direct children (whatever the rune names them). A rune
|
|
14
|
+
* may override the per-slide width via `--rf-carousel-slide`. */
|
|
15
|
+
[data-layout="carousel"] [data-name="items"] > * {
|
|
16
|
+
scroll-snap-align: start;
|
|
17
|
+
flex: 0 0 var(--rf-carousel-slide, 80%);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Collapse-to-carousel (SPEC-100, WORK-489): a rune whose collapsed form is
|
|
21
|
+
* `carousel` (`collapse-to="carousel"`) flips its item band from grid/list to a
|
|
22
|
+
* scroll-snap row below the `collapse` breakpoint.
|
|
23
|
+
*
|
|
24
|
+
* Container-query driven: the host is its own query container, so the breakpoint
|
|
25
|
+
* is measured against the rune's OWN width — the space it actually occupies —
|
|
26
|
+
* not the global viewport. A `feature` bled to full width collapses on its full
|
|
27
|
+
* width; one sitting in a narrow column collapses on that column. As a bonus this
|
|
28
|
+
* makes the flip faithful inside the `preview` rune's viewport selector: the
|
|
29
|
+
* previewed host fills the constrained frame, so narrowing the frame shrinks the
|
|
30
|
+
* container and fires the breakpoint with no per-preview wiring.
|
|
31
|
+
*
|
|
32
|
+
* CSS-only — no JS nav on the responsive path — and shares the `data-collapse`
|
|
33
|
+
* hook (default sm/640px; `never` opts out). The `container-type` lands only on
|
|
34
|
+
* hosts that opted into `collapse-to="carousel"`, so the blast radius is narrow. */
|
|
35
|
+
[data-collapse-to="carousel"] {
|
|
36
|
+
container-type: inline-size;
|
|
37
|
+
}
|
|
38
|
+
@container (max-width: 640px) {
|
|
39
|
+
[data-collapse-to="carousel"][data-collapse="sm"] [data-name="items"],
|
|
40
|
+
[data-collapse-to="carousel"]:not([data-collapse]) [data-name="items"] {
|
|
41
|
+
display: flex;
|
|
42
|
+
overflow-x: auto;
|
|
43
|
+
scroll-snap-type: x mandatory;
|
|
44
|
+
-webkit-overflow-scrolling: touch;
|
|
45
|
+
grid-template-columns: none;
|
|
46
|
+
}
|
|
47
|
+
[data-collapse-to="carousel"][data-collapse="sm"] [data-name="items"] > *,
|
|
48
|
+
[data-collapse-to="carousel"]:not([data-collapse]) [data-name="items"] > * {
|
|
49
|
+
scroll-snap-align: start;
|
|
50
|
+
flex: 0 0 var(--rf-carousel-slide, 80%);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
@container (max-width: 768px) {
|
|
54
|
+
[data-collapse-to="carousel"][data-collapse="md"] [data-name="items"] {
|
|
55
|
+
display: flex;
|
|
56
|
+
overflow-x: auto;
|
|
57
|
+
scroll-snap-type: x mandatory;
|
|
58
|
+
-webkit-overflow-scrolling: touch;
|
|
59
|
+
grid-template-columns: none;
|
|
60
|
+
}
|
|
61
|
+
[data-collapse-to="carousel"][data-collapse="md"] [data-name="items"] > * {
|
|
62
|
+
scroll-snap-align: start;
|
|
63
|
+
flex: 0 0 var(--rf-carousel-slide, 80%);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
@container (max-width: 1024px) {
|
|
67
|
+
[data-collapse-to="carousel"][data-collapse="lg"] [data-name="items"] {
|
|
68
|
+
display: flex;
|
|
69
|
+
overflow-x: auto;
|
|
70
|
+
scroll-snap-type: x mandatory;
|
|
71
|
+
-webkit-overflow-scrolling: touch;
|
|
72
|
+
grid-template-columns: none;
|
|
73
|
+
}
|
|
74
|
+
[data-collapse-to="carousel"][data-collapse="lg"] [data-name="items"] > * {
|
|
75
|
+
scroll-snap-align: start;
|
|
76
|
+
flex: 0 0 var(--rf-carousel-slide, 80%);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Nav buttons — positioned relative to the track's container (the behavior
|
|
81
|
+
* ensures it is a positioning context). */
|
|
82
|
+
.rf-carousel__nav {
|
|
83
|
+
position: absolute;
|
|
84
|
+
top: 50%;
|
|
85
|
+
transform: translateY(-50%);
|
|
86
|
+
z-index: 2;
|
|
87
|
+
width: 2.5rem;
|
|
88
|
+
height: 2.5rem;
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
justify-content: center;
|
|
92
|
+
}
|
|
93
|
+
.rf-carousel__nav--prev {
|
|
94
|
+
left: 0.5rem;
|
|
95
|
+
}
|
|
96
|
+
.rf-carousel__nav--next {
|
|
97
|
+
right: 0.5rem;
|
|
98
|
+
}
|
package/styles/runes/cast.css
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
/* cast — structure. The members list reset, grid/list arrangements, name/role
|
|
2
2
|
* block display, empty-body hide, the avatar box (size/crop/display), and the list
|
|
3
3
|
* variant flex. Surface chrome, type, radii, and margins are skin. */
|
|
4
|
-
.rf-
|
|
5
|
-
.rf-cast--grid .rf-
|
|
4
|
+
.rf-cast__items { list-style: none; }
|
|
5
|
+
.rf-cast--grid .rf-cast__items {
|
|
6
6
|
display: grid;
|
|
7
7
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
8
8
|
}
|
|
9
|
-
.rf-cast--list .rf-
|
|
9
|
+
.rf-cast--list .rf-cast__items {
|
|
10
10
|
display: flex;
|
|
11
11
|
flex-direction: column;
|
|
12
12
|
}
|
|
13
|
+
/* SPEC-100: carousel arrangement reuses the shared track (styles/runes/carousel.css,
|
|
14
|
+
* keyed on [data-layout="carousel"] [data-name="items"]); cast only sets its
|
|
15
|
+
* per-slide width. */
|
|
16
|
+
.rf-cast--carousel {
|
|
17
|
+
--rf-carousel-slide: clamp(200px, 40%, 280px);
|
|
18
|
+
}
|
|
13
19
|
.rf-cast-member__name { display: block; }
|
|
14
20
|
.rf-cast-member__role { display: block; }
|
|
15
21
|
.rf-cast-member__body:empty { display: none; }
|
package/styles/runes/feature.css
CHANGED
|
@@ -22,14 +22,36 @@
|
|
|
22
22
|
display: contents;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
/*
|
|
26
|
-
.
|
|
25
|
+
/* Item arrangement is the `layout` axis (SPEC-099): `list` stacks the
|
|
26
|
+
* definitions in a single column, `grid` tiles them. Keyed off `[data-layout]`,
|
|
27
|
+
* decoupled from media placement. */
|
|
28
|
+
.rf-feature[data-layout="list"] .rf-feature__items {
|
|
27
29
|
display: block;
|
|
28
30
|
}
|
|
29
|
-
.rf-feature
|
|
31
|
+
.rf-feature[data-layout="grid"] .rf-feature__items {
|
|
30
32
|
display: grid;
|
|
31
33
|
grid-template-columns: repeat(auto-fit, minmax(max(240px, calc((100% - 3rem) / 3)), 1fr));
|
|
32
34
|
}
|
|
35
|
+
/* Collapse-to-column (SPEC-099 §3): below the `collapse` breakpoint a `grid`
|
|
36
|
+
* arrangement reflows to a single column. CSS-only, sharing the media-split
|
|
37
|
+
* breakpoint hook (`data-collapse`; default sm/640px, mirroring split.css).
|
|
38
|
+
* `collapse="never"` opts out. */
|
|
39
|
+
@media (max-width: 640px) {
|
|
40
|
+
.rf-feature[data-layout="grid"][data-collapse="sm"] .rf-feature__items,
|
|
41
|
+
.rf-feature[data-layout="grid"]:not([data-collapse]) .rf-feature__items {
|
|
42
|
+
grid-template-columns: 1fr;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
@media (max-width: 768px) {
|
|
46
|
+
.rf-feature[data-layout="grid"][data-collapse="md"] .rf-feature__items {
|
|
47
|
+
grid-template-columns: 1fr;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
@media (max-width: 1024px) {
|
|
51
|
+
.rf-feature[data-layout="grid"][data-collapse="lg"] .rf-feature__items {
|
|
52
|
+
grid-template-columns: 1fr;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
33
55
|
|
|
34
56
|
/* Beside layouts: definitions stay stacked inside the content track. */
|
|
35
57
|
.rf-feature[data-media-position="start"] .rf-feature__content,
|
package/styles/runes/gallery.css
CHANGED
|
@@ -25,35 +25,11 @@
|
|
|
25
25
|
right: 0;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
/* Carousel
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
overflow-x: auto;
|
|
32
|
-
scroll-snap-type: x mandatory;
|
|
33
|
-
-webkit-overflow-scrolling: touch;
|
|
34
|
-
}
|
|
28
|
+
/* Carousel — the scroll-snap track mechanics and the nav buttons are the shared
|
|
29
|
+
* carousel layout mode (styles/runes/carousel.css, keyed on the contract);
|
|
30
|
+
* gallery only sets its column-based item width. */
|
|
35
31
|
.rf-gallery[data-layout="carousel"] .rf-gallery__item {
|
|
36
32
|
flex: 0 0 calc(100% / var(--gallery-columns, 3));
|
|
37
|
-
scroll-snap-align: start;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/* Carousel nav buttons */
|
|
41
|
-
.rf-gallery__nav {
|
|
42
|
-
position: absolute;
|
|
43
|
-
top: 50%;
|
|
44
|
-
transform: translateY(-50%);
|
|
45
|
-
z-index: 2;
|
|
46
|
-
width: 2.5rem;
|
|
47
|
-
height: 2.5rem;
|
|
48
|
-
display: flex;
|
|
49
|
-
align-items: center;
|
|
50
|
-
justify-content: center;
|
|
51
|
-
}
|
|
52
|
-
.rf-gallery__nav--prev {
|
|
53
|
-
left: calc(var(--rf-gallery-edge) + 0.5rem);
|
|
54
|
-
}
|
|
55
|
-
.rf-gallery__nav--next {
|
|
56
|
-
right: calc(var(--rf-gallery-edge) + 0.5rem);
|
|
57
33
|
}
|
|
58
34
|
|
|
59
35
|
/* Masonry */
|
package/styles/runes/preview.css
CHANGED
|
@@ -8,10 +8,20 @@
|
|
|
8
8
|
justify-content: space-between;
|
|
9
9
|
min-height: 2rem;
|
|
10
10
|
}
|
|
11
|
+
.rf-preview__toolbar-left {
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
}
|
|
11
15
|
.rf-preview__controls {
|
|
12
16
|
display: flex;
|
|
13
17
|
align-items: center;
|
|
14
18
|
}
|
|
19
|
+
/* Preview-only controls are hidden in code view (the canvas they tune isn't
|
|
20
|
+
* shown). The explicit display:flex above would defeat the [hidden] attribute,
|
|
21
|
+
* so restore display:none for the hidden state. */
|
|
22
|
+
.rf-preview__controls[hidden] {
|
|
23
|
+
display: none;
|
|
24
|
+
}
|
|
15
25
|
.rf-preview__view-toggle { display: flex; }
|
|
16
26
|
.rf-preview__toggle { display: flex; }
|
|
17
27
|
.rf-preview__toggle-btn {
|
|
@@ -22,10 +32,21 @@
|
|
|
22
32
|
height: 1.625rem;
|
|
23
33
|
}
|
|
24
34
|
.rf-preview__canvas { overflow: hidden; }
|
|
35
|
+
/* Clip the source panel to its rounded corners (matching the canvas) — otherwise
|
|
36
|
+
* the code block's square fill bleeds past the rounded border at the bottom. */
|
|
37
|
+
.rf-preview__source { overflow: hidden; }
|
|
25
38
|
.rf-preview__viewport-toggle { display: flex; }
|
|
26
39
|
.rf-preview__viewport-frame {
|
|
27
40
|
position: relative;
|
|
28
41
|
overflow: hidden;
|
|
42
|
+
/* The frame is a query container (WORK-490): container-query-driven layouts
|
|
43
|
+
* inside the preview (e.g. split.css beside→stack, carousel collapse-to)
|
|
44
|
+
* resolve against the constrained frame width, so the viewport selector
|
|
45
|
+
* faithfully drives their breakpoints. Runes that establish a closer container
|
|
46
|
+
* (carousel hosts) keep querying themselves; this only governs content with no
|
|
47
|
+
* nearer container. The preview's own toolbar/canvas chrome sits outside the
|
|
48
|
+
* frame, so its @container rules are unaffected. */
|
|
49
|
+
container-type: inline-size;
|
|
29
50
|
}
|
|
30
51
|
.rf-preview__viewport-frame--constrained {
|
|
31
52
|
margin: 0 auto;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
/* textblock — structure. The body block
|
|
2
|
-
*
|
|
3
|
-
* are skin. */
|
|
1
|
+
/* textblock — structure. The body block and the multi-column counts (+
|
|
2
|
+
* responsive). Drop-cap is the universal SPEC-108 opt-in (dimensions/reading.css);
|
|
3
|
+
* lead type, column gap/rule, and text-align are skin. */
|
|
4
4
|
.rf-textblock__body {
|
|
5
5
|
display: block;
|
|
6
6
|
}
|
|
7
|
-
.rf-textblock--dropcap .rf-textblock__body > p:first-child::first-letter {
|
|
8
|
-
float: left;
|
|
9
|
-
}
|
|
10
7
|
.rf-textblock[data-columns="2"] .rf-textblock__body { column-count: 2; }
|
|
11
8
|
.rf-textblock[data-columns="3"] .rf-textblock__body { column-count: 3; }
|
|
12
9
|
.rf-textblock[data-columns="4"] .rf-textblock__body { column-count: 4; }
|