@refrakt-md/skeleton 0.23.0 → 0.24.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/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.23.0",
4
+ "version": "0.24.1",
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.23.0"
32
+ "@refrakt-md/types": "0.24.1"
33
33
  },
34
34
  "scripts": {
35
35
  "build": "tsc"
@@ -17,3 +17,11 @@
17
17
  [data-section="media"][data-guest-posture="presentational"] :is(.rf-tabs__tabs, .rf-codegroup__tabs) {
18
18
  display: none;
19
19
  }
20
+
21
+ /* SPEC-104 — a `backdrop` guest (a live sandbox in the bg layer) is inert at the
22
+ * pointer: decoration behind content, never an interaction target. Unlike
23
+ * `presentational`, the behaviours layer still mounts it (it must run) — this rule
24
+ * only suppresses interaction. */
25
+ [data-guest-posture="backdrop"] {
26
+ pointer-events: none;
27
+ }
@@ -17,6 +17,14 @@
17
17
  object-fit: cover;
18
18
  object-position: var(--bg-position, center);
19
19
  }
20
+ /* SPEC-104 — a live sandbox backdrop fills the bg layer like bg-video, beneath
21
+ * the overlay/scrim appended after it (which stack above by source order). */
22
+ [data-name="bg"] > [data-bg-guest] {
23
+ position: absolute;
24
+ inset: 0;
25
+ width: 100%;
26
+ height: 100%;
27
+ }
20
28
  [data-name="bg-overlay"] {
21
29
  position: absolute;
22
30
  inset: 0;
@@ -1,6 +1,6 @@
1
- /* datatable — structure. The toolbar + pagination flex rows and the full-width
2
- * search input. The table chrome, type, borders, and the table overflow/width
3
- * overrides (which override the table element wrapper by source order) stay skin
1
+ /* datatable — structure. The toolbar + pagination flex rows, the full-width
2
+ * search input, and the table scroll container that lets wide tables overflow
3
+ * horizontally on narrow screens. The table chrome, type, and borders stay skin
4
4
  * (Lumina's styles/runes/datatable.css). */
5
5
 
6
6
  .rf-datatable__toolbar {
@@ -9,6 +9,12 @@
9
9
  .rf-datatable__input {
10
10
  width: 100%;
11
11
  }
12
+ /* Scroll wrapper around the table — toolbar/pagination sit outside this so they
13
+ * stay anchored to the viewport while the table itself scrolls horizontally. */
14
+ .rf-datatable__scroll {
15
+ overflow-x: auto;
16
+ -webkit-overflow-scrolling: touch;
17
+ }
12
18
  .rf-datatable__pagination {
13
19
  display: flex;
14
20
  align-items: center;
@@ -8,6 +8,27 @@
8
8
 
9
9
  .rf-hero { position: relative; }
10
10
 
11
+ /* Hero media zone bleeds: a hero is a section header, not a clip-host like
12
+ * card / bento-cell, so a displaced guest in its media zone should spill past
13
+ * the zone boundary instead of being cropped into a peek. Mirrors the existing
14
+ * `[data-rune="preview"]` / `[data-rune="juxtapose"]` / showcase-displace
15
+ * opt-outs in layouts/split.css — same intent, host-aware scope.
16
+ *
17
+ * Covers both routing paths of `frame-displace`:
18
+ * 1. host-on-media — `frame-displace` on the hero lands `data-displace` on
19
+ * the media-zone wrapper itself (the host's frame target is its media).
20
+ * 2. self on a child — a media-zone child rune carrying its own
21
+ * `frame-displace` ends up with `data-displace` on its root, so we still
22
+ * need `:has(> [data-displace])` for that case. */
23
+ .rf-hero > [data-section="media"]:is([data-displace], :has(> [data-displace])) {
24
+ overflow: visible;
25
+ container-type: normal;
26
+ }
27
+ /* Note: unlike the showcase/preview/juxtapose opt-outs in layouts/split.css,
28
+ * we deliberately keep the default `width: 100%` / `max-height: 100%` on the
29
+ * guest — a codegroup or sandbox in a hero should still fill the hero's
30
+ * width; the unclip is only about letting it overflow vertically. */
31
+
11
32
  .rf-hero__preamble {
12
33
  flex-direction: column;
13
34
  align-items: center;
@@ -43,6 +43,33 @@
43
43
  zoom: calc(var(--mockup-scale, 1) * min(1, tan(atan2(100cqi, var(--mockup-device-width, 100cqi)))));
44
44
  }
45
45
 
46
+ /* Media guest: fill the slot. The slot, not the device, sets the size here, so
47
+ * the device scales (up or down) so its width matches the slot's; the cell's
48
+ * fixed height + overflow then crops any vertical overflow (a tall phone peeks,
49
+ * a wide laptop fits whole).
50
+ *
51
+ * The scale factor is `slotWidth ÷ deviceWidth`, but it is *not* computed here:
52
+ * deriving it from container-query units mis-resolves on iOS WebKit (under
53
+ * `zoom` the device balloons; even under `transform` `cqi` resolves to the wrong
54
+ * size). The `mockup` behavior measures the slot in JS — deterministic across
55
+ * engines — and publishes the factor as `--mockup-fit-scale`; centering and the
56
+ * clip stay here. Without JS the factor defaults to 1 (native size), which
57
+ * degrades gracefully. `transform` (not `zoom`) so it never feeds back into the
58
+ * container's measured size.
59
+ *
60
+ * `left` re-centers the native layout box for any slot/device width (the box is
61
+ * left-aligned at native width; the offset shifts its centre onto the slot's),
62
+ * and `transform-origin: top center` anchors the device's top so the clip eats
63
+ * the bottom. `fit="none"` opts out (its own transform path above); standalone
64
+ * mockups keep the capped base zoom (a phone shouldn't fill a column). */
65
+ [data-section="media"] > .rf-mockup:not([data-fit="none"]) .rf-mockup__frame {
66
+ zoom: normal;
67
+ margin-inline: 0;
68
+ left: calc((100% - var(--mockup-device-width, 100%)) / 2);
69
+ transform: scale(calc(var(--mockup-scale, 1) * var(--mockup-fit-scale, 1)));
70
+ transform-origin: top center;
71
+ }
72
+
46
73
  .rf-mockup__viewport {
47
74
  overflow: auto;
48
75
  }
@@ -38,8 +38,8 @@
38
38
  z-index: 1;
39
39
  }
40
40
  .rf-preview__source-tabs { display: flex; }
41
- @container (max-width: 1280px) {
42
- .rf-preview--in-feature {
43
- margin-inline: calc(-1 * var(--rf-content-gutter, 1.5rem));
44
- }
45
- }
41
+ /* The in-feature breakout (`.rf-preview--in-feature { margin-inline: -gutter }`)
42
+ * is NOT here: it overrides the skin rule `.rf-preview { margin: 2rem 0 }` by
43
+ * specificity, so it must stay in @layer skin — in @layer skeleton it loses to
44
+ * that skin margin (skin beats skeleton regardless of specificity) and the bleed
45
+ * is nullified. It lives in Lumina's preview.css @container block. */
@@ -3,6 +3,13 @@
3
3
  * glyph stay skin (Lumina's styles/runes/sandbox.css). */
4
4
 
5
5
  .rf-sandbox { overflow: hidden; }
6
+ /* `height="fill"` pins the iframe to 100% of its host (SPEC-101) — so the host
7
+ * itself needs to claim 100% of its container's height for the iframe's 100%
8
+ * to mean anything. Without this the iframe collapses to the 150px fallback
9
+ * because the auto-height host has no definite height to fill against. */
10
+ .rf-sandbox[data-height="fill"] {
11
+ height: 100%;
12
+ }
6
13
  .rf-sandbox iframe {
7
14
  display: block;
8
15
  width: 100%;