@refrakt-md/skeleton 0.22.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.
Files changed (107) hide show
  1. package/README.md +41 -0
  2. package/dist/index.d.ts +24 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +23 -0
  5. package/dist/index.js.map +1 -0
  6. package/index.css +145 -0
  7. package/package.json +37 -0
  8. package/styles/dimensions/checklist.css +43 -0
  9. package/styles/dimensions/cover.css +91 -0
  10. package/styles/dimensions/guest-posture.css +19 -0
  11. package/styles/dimensions/media.css +38 -0
  12. package/styles/dimensions/metadata.css +66 -0
  13. package/styles/dimensions/sections.css +22 -0
  14. package/styles/dimensions/sequence.css +109 -0
  15. package/styles/dimensions/state.css +28 -0
  16. package/styles/global.css +37 -0
  17. package/styles/layouts/blog.css +38 -0
  18. package/styles/layouts/default.css +51 -0
  19. package/styles/layouts/docs.css +82 -0
  20. package/styles/layouts/mobile.css +39 -0
  21. package/styles/layouts/on-this-page.css +4 -0
  22. package/styles/layouts/plan.css +103 -0
  23. package/styles/layouts/search.css +80 -0
  24. package/styles/layouts/split.css +127 -0
  25. package/styles/layouts/theme-toggle.css +26 -0
  26. package/styles/layouts/version-switcher.css +10 -0
  27. package/styles/runes/accordion.css +55 -0
  28. package/styles/runes/aggregate.css +13 -0
  29. package/styles/runes/annotate.css +55 -0
  30. package/styles/runes/audio.css +70 -0
  31. package/styles/runes/bento.css +118 -0
  32. package/styles/runes/bg.css +29 -0
  33. package/styles/runes/blog.css +13 -0
  34. package/styles/runes/bond.css +36 -0
  35. package/styles/runes/breadcrumb.css +16 -0
  36. package/styles/runes/budget.css +42 -0
  37. package/styles/runes/card.css +37 -0
  38. package/styles/runes/cast.css +33 -0
  39. package/styles/runes/changelog.css +9 -0
  40. package/styles/runes/character.css +22 -0
  41. package/styles/runes/chart.css +32 -0
  42. package/styles/runes/codegroup.css +25 -0
  43. package/styles/runes/collection.css +51 -0
  44. package/styles/runes/compare.css +19 -0
  45. package/styles/runes/comparison.css +54 -0
  46. package/styles/runes/conversation.css +29 -0
  47. package/styles/runes/cta.css +46 -0
  48. package/styles/runes/datatable.css +16 -0
  49. package/styles/runes/design-context.css +6 -0
  50. package/styles/runes/details.css +19 -0
  51. package/styles/runes/diagram.css +17 -0
  52. package/styles/runes/diff.css +40 -0
  53. package/styles/runes/drawer.css +118 -0
  54. package/styles/runes/embed.css +20 -0
  55. package/styles/runes/event.css +5 -0
  56. package/styles/runes/expand.css +7 -0
  57. package/styles/runes/faction.css +13 -0
  58. package/styles/runes/feature.css +56 -0
  59. package/styles/runes/figure.css +23 -0
  60. package/styles/runes/file-ref.css +2 -0
  61. package/styles/runes/form.css +55 -0
  62. package/styles/runes/gallery.css +128 -0
  63. package/styles/runes/grid.css +62 -0
  64. package/styles/runes/hero.css +130 -0
  65. package/styles/runes/hint.css +28 -0
  66. package/styles/runes/howto.css +35 -0
  67. package/styles/runes/itinerary.css +41 -0
  68. package/styles/runes/juxtapose.css +61 -0
  69. package/styles/runes/lore.css +12 -0
  70. package/styles/runes/map.css +45 -0
  71. package/styles/runes/mediatext.css +37 -0
  72. package/styles/runes/milestone.css +31 -0
  73. package/styles/runes/mockup.css +144 -0
  74. package/styles/runes/nav.css +258 -0
  75. package/styles/runes/organization.css +6 -0
  76. package/styles/runes/page-section.css +12 -0
  77. package/styles/runes/pagination.css +39 -0
  78. package/styles/runes/palette.css +33 -0
  79. package/styles/runes/placeholder.css +7 -0
  80. package/styles/runes/plan-history.css +38 -0
  81. package/styles/runes/plan-progress.css +10 -0
  82. package/styles/runes/playlist.css +61 -0
  83. package/styles/runes/plot.css +23 -0
  84. package/styles/runes/preview.css +45 -0
  85. package/styles/runes/pricing.css +40 -0
  86. package/styles/runes/progress.css +22 -0
  87. package/styles/runes/pullquote.css +39 -0
  88. package/styles/runes/realm.css +14 -0
  89. package/styles/runes/recipe.css +40 -0
  90. package/styles/runes/relationships.css +49 -0
  91. package/styles/runes/reveal.css +29 -0
  92. package/styles/runes/sandbox.css +30 -0
  93. package/styles/runes/section.css +36 -0
  94. package/styles/runes/showcase.css +12 -0
  95. package/styles/runes/spacing.css +45 -0
  96. package/styles/runes/steps.css +65 -0
  97. package/styles/runes/storyboard.css +22 -0
  98. package/styles/runes/swatch.css +12 -0
  99. package/styles/runes/symbol.css +8 -0
  100. package/styles/runes/tabs.css +28 -0
  101. package/styles/runes/testimonial.css +13 -0
  102. package/styles/runes/textblock.css +25 -0
  103. package/styles/runes/timeline.css +31 -0
  104. package/styles/runes/toc.css +10 -0
  105. package/styles/runes/track.css +55 -0
  106. package/styles/runes/typography.css +33 -0
  107. package/styles/runes/xref.css +5 -0
@@ -0,0 +1,127 @@
1
+ /* split — structure. The shared media|content layout used by card, recipe, hero,
2
+ * feature, step, realm, faction, playlist (the `splitLayoutAttributes` preset):
3
+ * the start/end two-column grid, the top/bottom stack, the 3-section grid
4
+ * placement, the media-zone fill/clip mechanism, and the responsive collapse.
5
+ *
6
+ * Mutually exclusive with cover (media-position=cover). The media radius tier, the
7
+ * beside-image depth shadow, and the codegroup radius alignment are skin (Lumina's
8
+ * layouts/split.css). Zone rhythm (sections.css margins) is skin too, so a rune's
9
+ * zone overrides still resolve by source order against it. */
10
+
11
+ /* ─── Beside layouts (start / end): two-column grid ─── */
12
+ [data-media-position="start"],
13
+ [data-media-position="end"] {
14
+ display: grid;
15
+ grid-template-columns: var(--media-share, 50%) 1fr;
16
+ align-items: var(--split-valign, start);
17
+ }
18
+ /* "end" flips the grid so media lands in column 2 (source order is media-first). */
19
+ [data-media-position="end"] {
20
+ grid-template-columns: 1fr var(--media-share, 50%);
21
+ }
22
+ [data-media-position="end"] > [data-section="media"],
23
+ [data-media-position="end"] > [data-name="media"] { grid-column: 2; }
24
+ [data-media-position="end"] > [data-name="content"] { grid-column: 1; }
25
+
26
+ /* `media-ratio` → media's share of the row width. */
27
+ [data-media-ratio="1/3"] { --media-share: 33.333%; }
28
+ [data-media-ratio="2/5"] { --media-share: 40%; }
29
+ [data-media-ratio="1/2"] { --media-share: 50%; }
30
+ [data-media-ratio="3/5"] { --media-share: 60%; }
31
+ [data-media-ratio="2/3"] { --media-share: 66.667%; }
32
+
33
+ /* Grid so children can use justify-self/align-self (default: stretch). */
34
+ [data-media-position="start"] > [data-name="media"],
35
+ [data-media-position="end"] > [data-name="media"],
36
+ [data-media-position="start"] > [data-section="media"],
37
+ [data-media-position="end"] > [data-section="media"] {
38
+ display: grid;
39
+ }
40
+
41
+ /* ─── Stacked layouts (top / bottom) ─── */
42
+ /* "bottom" puts content on top, media at the bottom; column-reverse flips the
43
+ * media-first source order visually without changing the DOM. */
44
+ [data-media-position="bottom"] {
45
+ display: flex;
46
+ flex-direction: column-reverse;
47
+ }
48
+
49
+ /* ─── 3-section grid placement (header + content + media) ─── */
50
+ [data-media-position="start"]:has(> [data-section="header"]) > [data-section="header"] { grid-column: 1; grid-row: 1; }
51
+ [data-media-position="start"]:has(> [data-section="header"]) > [data-name="content"] { grid-column: 1; grid-row: 2; }
52
+ [data-media-position="start"]:has(> [data-section="header"]) > [data-section="media"] { grid-column: 2; grid-row: 1 / 3; }
53
+
54
+ [data-media-position="end"]:has(> [data-section="header"]) > [data-section="header"] { grid-column: 2; grid-row: 1; }
55
+ [data-media-position="end"]:has(> [data-section="header"]) > [data-name="content"] { grid-column: 2; grid-row: 2; }
56
+ [data-media-position="end"]:has(> [data-section="header"]) > [data-section="media"] { grid-column: 1; grid-row: 1 / 3; }
57
+
58
+ [data-media-position="start"]:has(> [data-section="header"]) > [data-section="media"],
59
+ [data-media-position="end"]:has(> [data-section="header"]) > [data-section="media"] {
60
+ margin: 0;
61
+ }
62
+
63
+ /* ─── Media zone base — fill + clip + container-query context ─── */
64
+ [data-section="media"] {
65
+ container-type: inline-size;
66
+ overflow: hidden;
67
+ }
68
+ [data-section="media"] > * {
69
+ display: block;
70
+ width: 100%;
71
+ max-height: 100%;
72
+ margin: 0;
73
+ }
74
+ [data-section="media"] > :is(img, video) {
75
+ height: 100%;
76
+ object-fit: cover;
77
+ }
78
+ /* Guests that manage their own bleed / interactive chrome opt out of the clip. */
79
+ [data-section="media"]:is(
80
+ :has(> [data-rune="preview"]),
81
+ :has(> [data-rune="juxtapose"]),
82
+ :has(> .rf-showcase[data-displace]:not(.rf-showcase--in-bento-cell))
83
+ ) {
84
+ overflow: visible;
85
+ container-type: normal;
86
+ }
87
+ /* …and keep their intrinsic width/sizing (the generic width:100% would defeat a
88
+ * negative-margin breakout). */
89
+ [data-section="media"]:is(
90
+ :has(> [data-rune="preview"]),
91
+ :has(> [data-rune="juxtapose"]),
92
+ :has(> .rf-showcase[data-displace]:not(.rf-showcase--in-bento-cell))
93
+ ) > * {
94
+ width: auto;
95
+ max-height: none;
96
+ }
97
+
98
+ /* ─── Collapse breakpoints — beside layouts drop to one column ─── */
99
+ @media (max-width: 640px) {
100
+ :is([data-media-position="start"], [data-media-position="end"])[data-collapse="sm"],
101
+ :is([data-media-position="start"], [data-media-position="end"]):not([data-collapse]) {
102
+ grid-template-columns: 1fr;
103
+ }
104
+ :is([data-media-position="start"], [data-media-position="end"])[data-collapse="sm"] > *,
105
+ :is([data-media-position="start"], [data-media-position="end"]):not([data-collapse]) > * {
106
+ grid-column: auto;
107
+ grid-row: auto;
108
+ }
109
+ }
110
+ @media (max-width: 768px) {
111
+ :is([data-media-position="start"], [data-media-position="end"])[data-collapse="md"] {
112
+ grid-template-columns: 1fr;
113
+ }
114
+ :is([data-media-position="start"], [data-media-position="end"])[data-collapse="md"] > * {
115
+ grid-column: auto;
116
+ grid-row: auto;
117
+ }
118
+ }
119
+ @media (max-width: 1024px) {
120
+ :is([data-media-position="start"], [data-media-position="end"])[data-collapse="lg"] {
121
+ grid-template-columns: 1fr;
122
+ }
123
+ :is([data-media-position="start"], [data-media-position="end"])[data-collapse="lg"] > * {
124
+ grid-column: auto;
125
+ grid-row: auto;
126
+ }
127
+ }
@@ -0,0 +1,26 @@
1
+ /* theme-toggle — structure. The button box (inline-flex centring + size), the
2
+ * header order, the tint-lock hide, and the icon mask box. Borders, radii, colours,
3
+ * and the glyph masks are skin. */
4
+ .rf-theme-toggle {
5
+ display: inline-flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ width: 2rem;
9
+ height: 2rem;
10
+ }
11
+ .rf-header__inner .rf-theme-toggle,
12
+ .rf-docs-header__inner .rf-theme-toggle,
13
+ .rf-blog-header__inner .rf-theme-toggle {
14
+ order: 2;
15
+ }
16
+ html[data-tint-lock="true"] .rf-theme-toggle {
17
+ display: none;
18
+ }
19
+ .rf-theme-toggle__icon {
20
+ display: inline-block;
21
+ width: 1rem;
22
+ height: 1rem;
23
+ mask-size: contain;
24
+ mask-repeat: no-repeat;
25
+ mask-position: center;
26
+ }
@@ -0,0 +1,10 @@
1
+ /* version-switcher — structure. The inline-flex row and the native-appearance reset
2
+ * on the select. Spacing, type, borders, the arrow glyph, and focus chrome are skin. */
3
+ .rf-version-switcher {
4
+ display: inline-flex;
5
+ align-items: center;
6
+ }
7
+ .rf-version-switcher__select {
8
+ appearance: none;
9
+ -webkit-appearance: none;
10
+ }
@@ -0,0 +1,55 @@
1
+ /* accordion — structure. The eyebrow stretched-link, the items passthrough, the
2
+ * item-header flex + native-marker hide + chevron box/glyph/open-rotate mechanism,
3
+ * the title/count flex, and the ::details-content collapse mechanism. Type,
4
+ * borders, spacing, the chevron tint, transitions, and prose are skin (Lumina's
5
+ * styles/runes/accordion.css). The chevron glyph is the registry mask
6
+ * --rf-icon-accordion-chevron (SPEC-094 §8 / WORK-437). */
7
+
8
+ .rf-accordion__eyebrow:has(a) {
9
+ display: inline-block;
10
+ position: relative;
11
+ }
12
+ .rf-accordion__eyebrow:has(a) a::before {
13
+ content: '';
14
+ position: absolute;
15
+ inset: 0;
16
+ }
17
+ .rf-accordion__items { display: contents; }
18
+
19
+ .rf-accordion-item__header {
20
+ display: flex;
21
+ align-items: center;
22
+ list-style: none;
23
+ }
24
+ .rf-accordion-item__header::-webkit-details-marker { display: none; }
25
+ .rf-accordion-item__header::marker { display: none; content: ''; }
26
+ .rf-accordion-item__header::before {
27
+ content: '';
28
+ flex-shrink: 0;
29
+ width: 0.75rem;
30
+ height: 0.75rem;
31
+ mask-size: contain;
32
+ mask-repeat: no-repeat;
33
+ mask-position: center;
34
+ -webkit-mask-image: var(--rf-icon-accordion-chevron);
35
+ mask-image: var(--rf-icon-accordion-chevron);
36
+ }
37
+ .rf-accordion-item[open] .rf-accordion-item__header::before {
38
+ transform: rotate(90deg);
39
+ }
40
+ .rf-accordion-item__title { flex: 1; min-width: 0; }
41
+ .rf-accordion-item__count { flex-shrink: 0; }
42
+
43
+ /* Collapse / expand mechanism. */
44
+ .rf-accordion-item { interpolate-size: allow-keywords; }
45
+ .rf-accordion-item::details-content {
46
+ block-size: 0;
47
+ overflow: hidden;
48
+ }
49
+ .rf-accordion-item[open]::details-content { block-size: auto; }
50
+
51
+ /* Block-content panels switch to a flex column (gap is skin). */
52
+ .rf-accordion-item__body:has([data-block]) {
53
+ display: flex;
54
+ flex-direction: column;
55
+ }
@@ -0,0 +1,13 @@
1
+ /* aggregate — structure. The items stack / grouped wrap-row and the group min-width.
2
+ * Margins, the inline-count type, and the empty state are skin. */
3
+ .rf-aggregate__items {
4
+ display: flex;
5
+ flex-direction: column;
6
+ }
7
+ .rf-aggregate__items:has(.rf-aggregate__group) {
8
+ flex-direction: row;
9
+ flex-wrap: wrap;
10
+ }
11
+ .rf-aggregate__group {
12
+ min-width: 0;
13
+ }
@@ -0,0 +1,55 @@
1
+ /* annotate — structure. The body passthrough, the margin-note float, the inline /
2
+ * tooltip note display + the tooltip positioning + hover reveal, and the metadata
3
+ * hide. Type, colour, borders, spacing, and the `?` glyph stay skin (Lumina's
4
+ * styles/runes/annotate.css). */
5
+
6
+ .rf-annotate__body { display: contents; }
7
+
8
+ /* Margin style — float the note into the margin. */
9
+ .rf-annotate--margin .rf-annotate-note {
10
+ float: right;
11
+ clear: right;
12
+ width: 40%;
13
+ }
14
+
15
+ /* Inline style */
16
+ .rf-annotate--inline p { display: inline; }
17
+ .rf-annotate--inline .rf-annotate-note {
18
+ display: inline-block;
19
+ vertical-align: baseline;
20
+ }
21
+
22
+ /* Tooltip style */
23
+ .rf-annotate--tooltip .rf-annotate-note {
24
+ display: inline-block;
25
+ position: relative;
26
+ vertical-align: super;
27
+ }
28
+ .rf-annotate--tooltip .rf-annotate-note::before {
29
+ display: inline-flex;
30
+ align-items: center;
31
+ justify-content: center;
32
+ width: 1rem;
33
+ height: 1rem;
34
+ }
35
+ .rf-annotate--tooltip .rf-annotate-note__body {
36
+ display: none;
37
+ position: absolute;
38
+ bottom: 100%;
39
+ left: 50%;
40
+ transform: translateX(-50%);
41
+ width: 16rem;
42
+ z-index: 10;
43
+ }
44
+ .rf-annotate--tooltip .rf-annotate-note:hover .rf-annotate-note__body {
45
+ display: block;
46
+ }
47
+ .rf-annotate-note__body > span[property],
48
+ .rf-annotate-note__body > meta { display: none; }
49
+
50
+ @media (max-width: 768px) {
51
+ .rf-annotate--margin .rf-annotate-note {
52
+ float: none;
53
+ width: 100%;
54
+ }
55
+ }
@@ -0,0 +1,70 @@
1
+ /* audio — structure. The web-component block, the player flex column, the info/
2
+ * controls flex, the name ellipsis clip, the play-button box (size + centring), the
3
+ * play-icon size, the time min-width, the progress track box + bar fill, the
4
+ * waveform box, the waveform-mode progress hide, the chapters list reset, and the
5
+ * chapter row flex. Surface, colours, radii, borders, type, and focus chrome are
6
+ * skin. */
7
+ .rf-audio rf-audio { display: block; }
8
+ .rf-audio-player {
9
+ display: flex;
10
+ flex-direction: column;
11
+ }
12
+ .rf-audio-player__info {
13
+ display: flex;
14
+ flex-direction: column;
15
+ }
16
+ .rf-audio-player__name {
17
+ overflow: hidden;
18
+ }
19
+ .rf-audio-player__controls {
20
+ display: flex;
21
+ align-items: center;
22
+ }
23
+ .rf-audio-player__play {
24
+ flex-shrink: 0;
25
+ width: 2.25rem;
26
+ height: 2.25rem;
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: center;
30
+ }
31
+ .rf-audio-player__play svg {
32
+ width: 1rem;
33
+ height: 1rem;
34
+ }
35
+ .rf-audio-player__time {
36
+ min-width: 2.5rem;
37
+ }
38
+ .rf-audio-player__progress {
39
+ flex: 1;
40
+ height: 6px;
41
+ position: relative;
42
+ overflow: hidden;
43
+ }
44
+ .rf-audio-player__progress-bar {
45
+ height: 100%;
46
+ width: 0%;
47
+ pointer-events: none;
48
+ }
49
+ .rf-audio-player__waveform {
50
+ width: 100%;
51
+ min-height: 48px;
52
+ overflow: hidden;
53
+ }
54
+ .rf-audio[data-waveform="true"] .rf-audio-player__controls .rf-audio-player__progress {
55
+ display: none;
56
+ }
57
+ .rf-audio-player__chapters {
58
+ list-style: none;
59
+ }
60
+ .rf-audio-player__chapter {
61
+ display: flex;
62
+ width: 100%;
63
+ align-items: center;
64
+ }
65
+ .rf-audio-player__chapter-name {
66
+ flex: 1;
67
+ }
68
+ .rf-audio-player__chapter-time {
69
+ flex-shrink: 0;
70
+ }
@@ -0,0 +1,118 @@
1
+ /* bento — structure. The container-query grid system: the grid track + cell
2
+ * spans, the cell flex layout + media placement, the row/content sizing knobs,
3
+ * the collapse queries, the stretched link, and metadata hiding. The cell surface
4
+ * chrome, spacing vars (padding/edge/gap), type, and the media-well chrome stay
5
+ * skin (Lumina's styles/runes/bento.css). bento-cell is a hand-rolled surface
6
+ * outside the data-elevation axis, so its padding has no surfaces competitor. */
7
+
8
+ .rf-bento {
9
+ container-type: inline-size;
10
+ container-name: rf-bento;
11
+ }
12
+
13
+ .rf-bento__grid {
14
+ --bento-cols-effective: var(--bento-columns, 6);
15
+ display: grid;
16
+ grid-template-columns: repeat(var(--bento-cols-effective), 1fr);
17
+ grid-auto-rows: var(--bento-row-track, var(--bento-row-height, var(--rf-bento-row-height, 24rem)));
18
+ }
19
+
20
+ /* Author row-height presets — the uniform grid row track height (grid mode). */
21
+ .rf-bento[data-row-height="sm"] { --bento-row-height: 16rem; }
22
+ .rf-bento[data-row-height="md"] { --bento-row-height: 24rem; }
23
+ .rf-bento[data-row-height="lg"] { --bento-row-height: 32rem; }
24
+ .rf-bento[data-row-height="xl"] { --bento-row-height: 40rem; }
25
+
26
+ /* content-height / media-ratio — perpendicular text-zone sizing knobs. */
27
+ .rf-bento[data-content-height="sm"], .rf-bento-cell[data-content-height="sm"] { --cell-content-height: 6rem; --cell-content-overflow: hidden; }
28
+ .rf-bento[data-content-height="md"], .rf-bento-cell[data-content-height="md"] { --cell-content-height: 10rem; --cell-content-overflow: hidden; }
29
+ .rf-bento[data-content-height="lg"], .rf-bento-cell[data-content-height="lg"] { --cell-content-height: 14rem; --cell-content-overflow: hidden; }
30
+ .rf-bento[data-content-height="xl"], .rf-bento-cell[data-content-height="xl"] { --cell-content-height: 18rem; --cell-content-overflow: hidden; }
31
+
32
+ .rf-bento[data-media-ratio="1/3"], .rf-bento-cell[data-media-ratio="1/3"] { --cell-media-ratio: 33.333%; }
33
+ .rf-bento[data-media-ratio="2/5"], .rf-bento-cell[data-media-ratio="2/5"] { --cell-media-ratio: 40%; }
34
+ .rf-bento[data-media-ratio="1/2"], .rf-bento-cell[data-media-ratio="1/2"] { --cell-media-ratio: 50%; }
35
+ .rf-bento[data-media-ratio="3/5"], .rf-bento-cell[data-media-ratio="3/5"] { --cell-media-ratio: 60%; }
36
+ .rf-bento[data-media-ratio="2/3"], .rf-bento-cell[data-media-ratio="2/3"] { --cell-media-ratio: 66.667%; }
37
+
38
+ .rf-bento-cell[data-media-position="top"] > .rf-bento-cell__content,
39
+ .rf-bento-cell[data-media-position="bottom"] > .rf-bento-cell__content {
40
+ flex-basis: var(--cell-content-height, auto);
41
+ overflow: var(--cell-content-overflow, visible);
42
+ }
43
+
44
+ /* Cell footprint: resolved cols/rows spans, auto-capped to the effective columns. */
45
+ .rf-bento-cell {
46
+ grid-column: span min(var(--cell-cols, 1), var(--bento-cols-effective, 6));
47
+ grid-row: span var(--cell-rows, 1);
48
+ min-width: 0;
49
+ }
50
+
51
+ /* The cell flex container (surface chrome + spacing are skin). */
52
+ .rf-bento-cell {
53
+ overflow: hidden;
54
+ position: relative; /* anchor for the stretched link */
55
+ display: flex;
56
+ flex-direction: column;
57
+ min-height: 0;
58
+ }
59
+
60
+ /* Media placement (data-media-position). */
61
+ .rf-bento-cell[data-media-position="bottom"] { flex-direction: column-reverse; }
62
+ .rf-bento-cell[data-media-position="start"] { flex-direction: row; align-items: stretch; }
63
+ .rf-bento-cell[data-media-position="end"] { flex-direction: row-reverse; align-items: stretch; }
64
+ .rf-bento-cell[data-media-position="start"] > .rf-bento-cell__media,
65
+ .rf-bento-cell[data-media-position="end"] > .rf-bento-cell__media {
66
+ flex: 0 0 var(--cell-media-ratio, 42%);
67
+ align-self: stretch;
68
+ }
69
+ .rf-bento-cell[data-media-position="start"] > .rf-bento-cell__content,
70
+ .rf-bento-cell[data-media-position="end"] > .rf-bento-cell__content { flex: 1; min-width: 0; }
71
+
72
+ .rf-bento-cell__content {
73
+ display: flex;
74
+ flex-direction: column;
75
+ min-height: 0;
76
+ flex: 0 0 auto;
77
+ }
78
+ .rf-bento-cell[data-media-position="top"] > .rf-bento-cell__media,
79
+ .rf-bento-cell[data-media-position="bottom"] > .rf-bento-cell__media {
80
+ flex: 1 1 auto;
81
+ min-height: 0;
82
+ aspect-ratio: var(--bento-media-aspect, 16 / 9);
83
+ }
84
+ .rf-bento-cell__media > :is(img, video) { object-position: var(--bento-media-anchor, center); }
85
+ .rf-bento-cell__media[style*="--frame-aspect"] { --bento-media-aspect: var(--frame-aspect); }
86
+ .rf-bento-cell__media[style*="--frame-anchor"] { --bento-media-anchor: var(--frame-anchor); }
87
+ .rf-bento-cell__body { min-height: 0; }
88
+ .rf-bento-cell__body > span[property],
89
+ .rf-bento-cell__body > meta { display: none; }
90
+ .rf-bento-cell__footer { margin-top: auto; }
91
+ .rf-bento-cell__body img { width: 100%; height: auto; }
92
+
93
+ /* Whole-cell link — stretched overlay; nested links stay clickable. */
94
+ .rf-bento-cell__link { position: absolute; inset: 0; z-index: 0; }
95
+ .rf-bento-cell a:not(.rf-bento-cell__link) { position: relative; z-index: 1; }
96
+
97
+ /* ─── Binary collapse — single stacked column with auto rows below breakpoint. ─── */
98
+ @container rf-bento (max-width: 640px) {
99
+ :is(.rf-bento[data-collapse="sm"], .rf-bento[data-collapse=""]) .rf-bento__grid { --bento-cols-effective: 1; --bento-row-track: auto; }
100
+ :is(.rf-bento[data-collapse="sm"], .rf-bento[data-collapse=""]) .rf-bento-cell[data-media-position="start"],
101
+ :is(.rf-bento[data-collapse="sm"], .rf-bento[data-collapse=""]) .rf-bento-cell[data-media-position="end"] { flex-direction: column; }
102
+ :is(.rf-bento[data-collapse="sm"], .rf-bento[data-collapse=""]) .rf-bento-cell[data-media-position] > .rf-bento-cell__media { flex: 0 0 auto; aspect-ratio: var(--bento-media-aspect, 16 / 9); }
103
+ :is(.rf-bento[data-collapse="sm"], .rf-bento[data-collapse=""]) .rf-bento-cell[data-media-position] > .rf-bento-cell__content { flex: 0 0 auto; }
104
+ }
105
+ @container rf-bento (max-width: 768px) {
106
+ .rf-bento[data-collapse="md"] .rf-bento__grid { --bento-cols-effective: 1; --bento-row-track: auto; }
107
+ .rf-bento[data-collapse="md"] .rf-bento-cell[data-media-position="start"],
108
+ .rf-bento[data-collapse="md"] .rf-bento-cell[data-media-position="end"] { flex-direction: column; }
109
+ .rf-bento[data-collapse="md"] .rf-bento-cell[data-media-position] > .rf-bento-cell__media { flex: 0 0 auto; aspect-ratio: var(--bento-media-aspect, 16 / 9); }
110
+ .rf-bento[data-collapse="md"] .rf-bento-cell[data-media-position] > .rf-bento-cell__content { flex: 0 0 auto; }
111
+ }
112
+ @container rf-bento (max-width: 1024px) {
113
+ .rf-bento[data-collapse="lg"] .rf-bento__grid { --bento-cols-effective: 1; --bento-row-track: auto; }
114
+ .rf-bento[data-collapse="lg"] .rf-bento-cell[data-media-position="start"],
115
+ .rf-bento[data-collapse="lg"] .rf-bento-cell[data-media-position="end"] { flex-direction: column; }
116
+ .rf-bento[data-collapse="lg"] .rf-bento-cell[data-media-position] > .rf-bento-cell__media { flex: 0 0 auto; aspect-ratio: var(--bento-media-aspect, 16 / 9); }
117
+ .rf-bento[data-collapse="lg"] .rf-bento-cell[data-media-position] > .rf-bento-cell__content { flex: 0 0 auto; }
118
+ }
@@ -0,0 +1,29 @@
1
+ /* bg — structure. The background/overlay/scrim layer placement (absolute fill +
2
+ * z-index + clip), the content-above-bg stacking, and the video fill. The images,
3
+ * gradients, blur/opacity, overlay tints, and scrim paint are skin. */
4
+ [data-name="bg"] {
5
+ position: absolute;
6
+ inset: 0;
7
+ z-index: 0;
8
+ overflow: hidden;
9
+ }
10
+ [data-bg] > :not([data-name="bg"]) {
11
+ position: relative;
12
+ z-index: 1;
13
+ }
14
+ [data-name="bg-video"] {
15
+ width: 100%;
16
+ height: 100%;
17
+ object-fit: cover;
18
+ object-position: var(--bg-position, center);
19
+ }
20
+ [data-name="bg-overlay"] {
21
+ position: absolute;
22
+ inset: 0;
23
+ }
24
+ [data-name="scrim"] {
25
+ position: absolute;
26
+ inset: 0;
27
+ pointer-events: none;
28
+ z-index: 1;
29
+ }
@@ -0,0 +1,13 @@
1
+ /* blog — structure. The posts flex stack, the date block, and the grid layout. The
2
+ * post surface chrome, type, and gaps are skin. */
3
+ .rf-blog__posts {
4
+ display: flex;
5
+ flex-direction: column;
6
+ }
7
+ .rf-blog__post time {
8
+ display: inline-block;
9
+ }
10
+ .rf-blog--grid .rf-blog__posts {
11
+ display: grid;
12
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
13
+ }
@@ -0,0 +1,36 @@
1
+ /* bond — structure. The flex row, the connector flex, the arrow rail box (display +
2
+ * size + relative), and the arrowhead pseudo positioning (both directions). The
3
+ * rail/arrowhead colours (drawn via borders), status tints, and type are skin. */
4
+ .rf-bond {
5
+ display: flex;
6
+ flex-wrap: wrap;
7
+ align-items: center;
8
+ }
9
+ .rf-bond__connector {
10
+ display: flex;
11
+ align-items: center;
12
+ flex-shrink: 0;
13
+ }
14
+ .rf-bond__arrow {
15
+ display: inline-block;
16
+ width: 2rem;
17
+ height: 2px;
18
+ position: relative;
19
+ }
20
+ .rf-bond__arrow::after {
21
+ content: '';
22
+ position: absolute;
23
+ right: -1px;
24
+ top: 50%;
25
+ transform: translateY(-50%);
26
+ }
27
+ .rf-bond[data-bidirectional="true"] .rf-bond__arrow::before {
28
+ content: '';
29
+ position: absolute;
30
+ left: -1px;
31
+ top: 50%;
32
+ transform: translateY(-50%);
33
+ }
34
+ .rf-bond__body {
35
+ width: 100%;
36
+ }
@@ -0,0 +1,16 @@
1
+ /* breadcrumb — structure. The items/item display:contents passthroughs and the
2
+ * flex trail (the ol row + each li). Type, colour, gaps, and the separator glyph
3
+ * are skin (Lumina's styles/runes/breadcrumb.css). */
4
+
5
+ .rf-breadcrumb__items { display: contents; }
6
+ .rf-breadcrumb-item { display: contents; }
7
+ .rf-breadcrumb ol {
8
+ display: flex;
9
+ align-items: center;
10
+ flex-wrap: wrap;
11
+ list-style: none;
12
+ }
13
+ .rf-breadcrumb li {
14
+ display: flex;
15
+ align-items: center;
16
+ }
@@ -0,0 +1,42 @@
1
+ /* budget — structure. The categories stack, the category/line-item/total/per-day
2
+ * flex rows, the line-items list reset, description/per-day-label flex sizing, and
3
+ * the summary line-item hide. Type, borders, the est. badge, and spacing are skin. */
4
+ .rf-budget__categories {
5
+ display: flex;
6
+ flex-direction: column;
7
+ }
8
+ .rf-budget-category__header {
9
+ display: flex;
10
+ justify-content: space-between;
11
+ align-items: center;
12
+ }
13
+ .rf-budget-category__line-items { list-style: none; }
14
+ .rf-budget-line-item {
15
+ display: flex;
16
+ justify-content: space-between;
17
+ align-items: baseline;
18
+ }
19
+ .rf-budget-line-item__description {
20
+ flex: 1;
21
+ min-width: 0;
22
+ }
23
+ .rf-budget__footer {
24
+ display: flex;
25
+ flex-direction: column;
26
+ }
27
+ .rf-budget__total {
28
+ display: flex;
29
+ justify-content: space-between;
30
+ align-items: baseline;
31
+ }
32
+ .rf-budget__per-day {
33
+ display: flex;
34
+ justify-content: space-between;
35
+ align-items: baseline;
36
+ }
37
+ .rf-budget__per-day-label {
38
+ min-width: 0;
39
+ }
40
+ [data-variant="summary"] .rf-budget-category__line-items {
41
+ display: none;
42
+ }
@@ -0,0 +1,37 @@
1
+ /* card — structure (SPEC-070). Pure layout only: the stretched-link positioning,
2
+ * the clip, the split vertical-align, the collection-grid height filling, and the
3
+ * intrinsic-height scale. ALL spacing stays skin in Lumina's card.css — the root
4
+ * `padding` overrides the surface-elevation padding (skin) by source order, and
5
+ * the split gaps + zone-reset margins are same-layer rhythm contests. */
6
+
7
+ .rf-card {
8
+ position: relative; /* anchor for the stretched link */
9
+ overflow: hidden; /* clip non-media layers to the rounded box */
10
+ }
11
+
12
+ /* Split layout: stretch the media zone to the content height (the gaps are skin). */
13
+ .rf-card[data-media-position="start"],
14
+ .rf-card[data-media-position="end"] {
15
+ align-items: stretch;
16
+ }
17
+
18
+ /* Collection grid: a stacked card becomes a column and its body grows so footers
19
+ * drop to a common baseline across the row. */
20
+ .rf-collection[data-layout='grid'] .rf-card[data-layout='stacked'] {
21
+ display: flex;
22
+ flex-direction: column;
23
+ height: 100%;
24
+ }
25
+ .rf-collection[data-layout='grid'] .rf-card[data-layout='stacked'] > .rf-card__content { flex: 1; }
26
+ .rf-collection[data-layout='grid'] .rf-card[data-layout='stacked'] .rf-card__content { display: flex; flex-direction: column; }
27
+ .rf-collection[data-layout='grid'] .rf-card[data-layout='stacked'] .rf-card__body { flex: 1; }
28
+
29
+ /* Intrinsic-height scale (SPEC-089) — poster shape for cover / bg-only cards. */
30
+ .rf-card[data-height="sm"] { min-height: 12rem; }
31
+ .rf-card[data-height="md"] { min-height: 18rem; }
32
+ .rf-card[data-height="lg"] { min-height: 26rem; }
33
+ .rf-card[data-height="xl"] { min-height: 34rem; }
34
+
35
+ /* Whole-card stretched link; real links in body/footer sit above it. */
36
+ .rf-card__link { position: absolute; inset: 0; z-index: 0; }
37
+ .rf-card a:not(.rf-card__link) { position: relative; z-index: 1; }