@refrakt-md/lumina 0.20.0 → 0.20.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 +4 -4
- package/styles/dimensions/cover.css +17 -4
- package/styles/dimensions/frame.css +70 -20
- package/styles/dimensions/substrate.css +14 -7
- package/styles/dimensions/surfaces.css +33 -0
- package/styles/layouts/split.css +10 -0
- package/styles/runes/bg.css +14 -3
- package/styles/runes/card.css +7 -0
- package/styles/runes/figure.css +14 -0
- package/styles/runes/map.css +29 -0
- package/styles/runes/preview.css +5 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@refrakt-md/lumina",
|
|
3
3
|
"description": "Lumina theme for refrakt.md — design tokens, CSS, identity transform, and layout configs",
|
|
4
|
-
"version": "0.20.
|
|
4
|
+
"version": "0.20.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -83,9 +83,9 @@
|
|
|
83
83
|
"build": "tsc"
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@refrakt-md/runes": "0.20.
|
|
87
|
-
"@refrakt-md/transform": "0.20.
|
|
88
|
-
"@refrakt-md/types": "0.20.
|
|
86
|
+
"@refrakt-md/runes": "0.20.1",
|
|
87
|
+
"@refrakt-md/transform": "0.20.1",
|
|
88
|
+
"@refrakt-md/types": "0.20.1"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"postcss": "^8.4.0"
|
|
@@ -103,14 +103,27 @@
|
|
|
103
103
|
position: absolute;
|
|
104
104
|
inset: 0;
|
|
105
105
|
pointer-events: none;
|
|
106
|
-
|
|
106
|
+
/* `inherit` matches the media zone's `--rf-radius-media`, so a frost scrim's
|
|
107
|
+
* `backdrop-filter` region clips at the same rounded corners — `overflow:
|
|
108
|
+
* hidden` on the media zone doesn't reliably clip backdrop-filter past the
|
|
109
|
+
* rounded edge in WebKit, so the pseudo carries its own radius. (The
|
|
110
|
+
* gradient variant doesn't strictly need this, but it's harmless and keeps
|
|
111
|
+
* the two scrim variants visually congruent.) */
|
|
112
|
+
border-radius: inherit;
|
|
113
|
+
/* The scrim shape is `--cover-scrim-image` (custom property override) when
|
|
114
|
+
* the engine emits one — for `content-place="center …"` it emits a radial
|
|
115
|
+
* ellipse so the dark falls under the centred overlay. For the directional
|
|
116
|
+
* cases (`start`/`end` block-axis) the engine sets `--cover-scrim-dir` and
|
|
117
|
+
* the linear fallback resolves to the right edge. */
|
|
118
|
+
background-image: var(--cover-scrim-image, linear-gradient(var(--cover-scrim-dir, to top), rgb(0 0 0 / 0.55), transparent 62%));
|
|
107
119
|
}
|
|
108
120
|
|
|
109
121
|
/* Frost treatment (`scrim-type="frost"`) — a frosted-glass blur over the media
|
|
110
122
|
* instead of a gradient. `scrim-blur` (named scale) sets the blur radius; the
|
|
111
123
|
* tint follows the cover scheme (a dark scheme → a dark frost for light text).
|
|
112
124
|
* The frost is masked to the content edge (following `--cover-scrim-dir`, default
|
|
113
|
-
* bottom) so it reads as a band behind the text, not a blur over the whole
|
|
125
|
+
* bottom) so it reads as a band behind the text, not a blur over the whole
|
|
126
|
+
* image. `--cover-scrim-mask` is the radial equivalent for centred content. */
|
|
114
127
|
[data-media-position="cover"][data-scrim-blur="none"] { --cover-scrim-blur: 0px; }
|
|
115
128
|
[data-media-position="cover"][data-scrim-blur="sm"] { --cover-scrim-blur: 4px; }
|
|
116
129
|
[data-media-position="cover"][data-scrim-blur="md"] { --cover-scrim-blur: 8px; }
|
|
@@ -120,8 +133,8 @@
|
|
|
120
133
|
background-color: rgb(0 0 0 / 0.18);
|
|
121
134
|
-webkit-backdrop-filter: blur(var(--cover-scrim-blur, 8px));
|
|
122
135
|
backdrop-filter: blur(var(--cover-scrim-blur, 8px));
|
|
123
|
-
-webkit-mask-image: linear-gradient(var(--cover-scrim-dir, to top), #000 30%, transparent 72%);
|
|
124
|
-
mask-image: linear-gradient(var(--cover-scrim-dir, to top), #000 30%, transparent 72%);
|
|
136
|
+
-webkit-mask-image: var(--cover-scrim-mask, linear-gradient(var(--cover-scrim-dir, to top), #000 30%, transparent 72%));
|
|
137
|
+
mask-image: var(--cover-scrim-mask, linear-gradient(var(--cover-scrim-dir, to top), #000 30%, transparent 72%));
|
|
125
138
|
}
|
|
126
139
|
[data-media-position="cover"][data-scrim-type="frost"][data-color-scheme="light"]:not([data-scrim="none"]) [data-section="media"]::after {
|
|
127
140
|
background-color: rgb(255 255 255 / 0.25);
|
|
@@ -20,11 +20,31 @@
|
|
|
20
20
|
* `frame-shadow` (drop-shadow silhouette here) never collide — different property,
|
|
21
21
|
* different surface. */
|
|
22
22
|
|
|
23
|
-
/* ── Silhouette drop-shadow ────────────────────────────────────────────
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
/* ── Silhouette drop-shadow ────────────────────────────────────────────
|
|
24
|
+
* Same media-target / self-target split as `frame-displace`. Media-target
|
|
25
|
+
* frames land `data-frame-shadow` on the media zone wrapper, but the shadow
|
|
26
|
+
* should ride the inner guest so it (a) shifts with `frame-displace` and
|
|
27
|
+
* (b) actually casts onto exposed slot interior when the guest is inset
|
|
28
|
+
* from the wrapper. Self-target frames (showcase, figure) keep the filter
|
|
29
|
+
* on the root itself, where it traces the rune's own painted silhouette. */
|
|
30
|
+
[data-frame-shadow="none"] { --frame-shadow: none; }
|
|
31
|
+
[data-frame-shadow="sm"] { --frame-shadow: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.10)); }
|
|
32
|
+
[data-frame-shadow="md"] { --frame-shadow: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.25)); }
|
|
33
|
+
[data-frame-shadow="lg"] { --frame-shadow: drop-shadow(0 12px 40px rgba(0, 0, 0, 0.20)); }
|
|
34
|
+
|
|
35
|
+
/* Self-target — figure, showcase, anything else where the rune root is the
|
|
36
|
+
* frame target. The filter applies to the painted root. */
|
|
37
|
+
[data-frame-shadow]:not([data-section="media"]) {
|
|
38
|
+
filter: var(--frame-shadow);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* Media-target — card, bento-cell, recipe, etc. The filter rides the inner
|
|
42
|
+
* guest so a displaced image's shadow falls into the slot's exposed
|
|
43
|
+
* interior (clipped at the slot's `overflow: hidden` boundary like any
|
|
44
|
+
* other in-slot content). */
|
|
45
|
+
[data-section="media"][data-frame-shadow] > :is(img, video, [data-rune]) {
|
|
46
|
+
filter: var(--frame-shadow);
|
|
47
|
+
}
|
|
28
48
|
|
|
29
49
|
/* ── Aspect ratio ────────────────────────────────────────────────────── */
|
|
30
50
|
[style*="--frame-aspect"] { aspect-ratio: var(--frame-aspect); }
|
|
@@ -36,19 +56,49 @@
|
|
|
36
56
|
[style*="--frame-place-x"] { justify-self: var(--frame-place-x, auto); align-self: var(--frame-place-y, auto); }
|
|
37
57
|
|
|
38
58
|
/* ── Oversize — guest exceeds its slot (clipping hosts crop it) ──────── */
|
|
39
|
-
[
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
/* `[data-rune]` extends the rule to nested rune guests (codegroup, mockup,
|
|
60
|
+
* chart, etc.), so frame chrome stays guest-agnostic — the same selector
|
|
61
|
+
* pattern the displace rule uses. */
|
|
62
|
+
[style*="--frame-oversize"] > :is(img, video, [data-rune]) { width: calc(100% * var(--frame-oversize, 1)); max-width: none; }
|
|
63
|
+
|
|
64
|
+
/* ── Displacement (peek / spill) — move the guest toward an edge/corner.
|
|
65
|
+
* The host decides whether the guest is cropped or spills; this only moves it.
|
|
66
|
+
* Two cases, distinguished by where the engine landed `data-displace`:
|
|
67
|
+
*
|
|
68
|
+
* 1. Media-target frame (`frameTarget: 'media'`, e.g. card / bento-cell /
|
|
69
|
+
* figure media well). `data-displace` lands on the media zone wrapper
|
|
70
|
+
* (`[data-section="media"]`), but the wrapper itself is the *host* and
|
|
71
|
+
* already has `overflow: hidden`. We translate the inner guest with
|
|
72
|
+
* `transform: translate(...)` so the zone clips the peek at its own edge,
|
|
73
|
+
* not at the outer card/cell edge. The wrapper stays put — the card's
|
|
74
|
+
* layout is unchanged.
|
|
75
|
+
*
|
|
76
|
+
* 2. Self-target frame (`frameTarget: 'self'`, e.g. showcase, where the rune
|
|
77
|
+
* root is the host). `data-displace` lands on the root, and the root's
|
|
78
|
+
* parent (a page section, the page itself) is the clip-or-spill decider.
|
|
79
|
+
* We push the root with negative margins so it can spill past its
|
|
80
|
+
* parent's edge for a true breakout. */
|
|
81
|
+
|
|
82
|
+
/* — Case 1: media-zone displace → translate the inner guest, zone clips. */
|
|
83
|
+
[data-section="media"][data-displace] > :is(img, video, [data-rune]) {
|
|
84
|
+
transform: translate(var(--displace-x, 0), var(--displace-y, 0));
|
|
54
85
|
}
|
|
86
|
+
[data-section="media"][data-displace="top"] { --displace-y: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
|
|
87
|
+
[data-section="media"][data-displace="bottom"] { --displace-y: var(--frame-offset, var(--rf-spacing-lg)); }
|
|
88
|
+
[data-section="media"][data-displace="end"] { --displace-x: var(--frame-offset, var(--rf-spacing-lg)); }
|
|
89
|
+
[data-section="media"][data-displace="top-end"] { --displace-x: var(--frame-offset, var(--rf-spacing-lg)); --displace-y: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
|
|
90
|
+
[data-section="media"][data-displace="bottom-end"] { --displace-x: var(--frame-offset, var(--rf-spacing-lg)); --displace-y: var(--frame-offset, var(--rf-spacing-lg)); }
|
|
91
|
+
|
|
92
|
+
/* — Case 2: self-target (showcase, etc.) → root moves; parent decides. */
|
|
93
|
+
[data-displace]:not([data-section="media"]) { position: relative; z-index: 1; }
|
|
94
|
+
[data-displace="top"]:not([data-section="media"]) { margin-top: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
|
|
95
|
+
[data-displace="bottom"]:not([data-section="media"]) { margin-bottom: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
|
|
96
|
+
[data-displace="both"]:not([data-section="media"]) { margin-block: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
|
|
97
|
+
[data-displace="end"]:not([data-section="media"]) { margin-inline-end: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
|
|
98
|
+
[data-displace="bottom-end"]:not([data-section="media"]) { margin-bottom: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); margin-inline-end: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
|
|
99
|
+
[data-displace="top-end"]:not([data-section="media"]) { margin-top: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); margin-inline-end: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
|
|
100
|
+
|
|
101
|
+
/* Displacement carries across breakpoints. For media-target the guest is
|
|
102
|
+
* clipped by the zone's `overflow: hidden` regardless of width, so the peek
|
|
103
|
+
* reads consistently from desktop to mobile. For self-target (showcase) the
|
|
104
|
+
* negative-margin spill stays on too — that's the intended breakout. */
|
|
@@ -55,16 +55,23 @@
|
|
|
55
55
|
--substrate-tile: auto;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
/* cross — plus marks
|
|
58
|
+
/* cross — plus marks at the centre of each cell, drawn as two perpendicular
|
|
59
|
+
* thin ellipses (no `mask` — an element-level `mask` would clip the rune's
|
|
60
|
+
* own text content along with the pattern, which is what we don't want). A
|
|
61
|
+
* small plus reads fainter than a 1px line at the same ink opacity, so the
|
|
62
|
+
* pattern carries its own ink boost — same idea as dots.
|
|
63
|
+
*
|
|
64
|
+
* The stop syntax mirrors dots: `ink <r>, transparent 0` produces a sharp-
|
|
65
|
+
* edged shape filled with ink (the explicit length on ink, plus `0` after
|
|
66
|
+
* transparent for a zero-length transition, beats the `ink 100%, transparent
|
|
67
|
+
* 100%` form which some renderers collapse to nothing). Ellipse radii at
|
|
68
|
+
* 1px (rather than sub-pixel 0.5px) so the stroke survives DPR rounding. */
|
|
59
69
|
[data-substrate="cross"] {
|
|
60
70
|
--substrate-image:
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
radial-gradient(ellipse 3px 1px at center, var(--substrate-ink) 100%, transparent 0),
|
|
72
|
+
radial-gradient(ellipse 1px 3px at center, var(--substrate-ink) 100%, transparent 0);
|
|
63
73
|
--substrate-pos: center;
|
|
64
|
-
-
|
|
65
|
-
-webkit-mask-size: var(--substrate-cell) var(--substrate-cell);
|
|
66
|
-
mask-image: radial-gradient(circle at center, #000 0 2px, transparent 2px);
|
|
67
|
-
mask-size: var(--substrate-cell) var(--substrate-cell);
|
|
74
|
+
--substrate-boost: 1.6;
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
/* checker — alternating filled cells */
|
|
@@ -103,6 +103,17 @@
|
|
|
103
103
|
padding: var(--rune-padding, var(--rf-spacing-md));
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
/* ─── Media slot inherits the surface border ─────────────────────────
|
|
107
|
+
* When a surface-bearing rune wraps a `[data-section="media"]` slot, the slot
|
|
108
|
+
* shares the surface's 1px border so the framed media reads as part of the
|
|
109
|
+
* same surface rather than a separate inner box. Scoped via `:where()` for
|
|
110
|
+
* zero specificity — per-rune CSS can still override if a particular surface
|
|
111
|
+
* wants a different chrome (e.g. character's circular portrait avoids this
|
|
112
|
+
* because it's not a `[data-section="media"]` slot). */
|
|
113
|
+
:where(.rf-card, .rf-bento-cell, .rf-recipe, .rf-realm, .rf-faction, .rf-playlist) [data-section="media"] {
|
|
114
|
+
border: 1px solid var(--rf-color-border);
|
|
115
|
+
}
|
|
116
|
+
|
|
106
117
|
/* ─── Inset surface (SPEC-087) — tint-tracking recessed fill ──────────
|
|
107
118
|
* Derived at use-site via relative-color (lower L, keep C+H) so it recomputes from a tinted
|
|
108
119
|
* `--rf-color-surface` automatically (a static inset-colour token would
|
|
@@ -116,6 +127,28 @@
|
|
|
116
127
|
background: oklch(from var(--rf-color-surface) calc(l - var(--rf-surface-inset-shift)) c h);
|
|
117
128
|
}
|
|
118
129
|
|
|
130
|
+
/* …but when they're a media-zone guest the slot already provides the recessed
|
|
131
|
+
* surface (border, radius, inset fill), so the inner chrome would just stack
|
|
132
|
+
* as double-chrome. Drop it; keep padding so axis labels / SVG keep breathing
|
|
133
|
+
* room. */
|
|
134
|
+
[data-section="media"] > :is(.rf-chart, .rf-diagram) {
|
|
135
|
+
background: transparent;
|
|
136
|
+
border: 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* Same treatment for `juxtapose` as a media guest — its `__panels` container
|
|
140
|
+
* has its own border + background + rounded corners (juxtapose stands alone
|
|
141
|
+
* outside a card), but inside a card slot they double up with the slot's own
|
|
142
|
+
* chrome. Drop the inner chrome; round to match the slot's media radius so the
|
|
143
|
+
* comparison reads as part of the card surface. The slot's overflow:visible
|
|
144
|
+
* and container-type:normal still come from `split.css` (juxtapose manages
|
|
145
|
+
* its own clip inside `__panels`). */
|
|
146
|
+
[data-section="media"] > .rf-juxtapose .rf-juxtapose__panels {
|
|
147
|
+
background: transparent;
|
|
148
|
+
border: 0;
|
|
149
|
+
border-radius: var(--rf-radius-media);
|
|
150
|
+
}
|
|
151
|
+
|
|
119
152
|
/* Media wells of media-bearing runes: a recessed sub-surface that tracks the
|
|
120
153
|
* (possibly tinted) container colour — invisible under a full-bleed guest,
|
|
121
154
|
* visible in the gaps (transparent, displaced, or absent guest). */
|
package/styles/layouts/split.css
CHANGED
|
@@ -106,6 +106,16 @@
|
|
|
106
106
|
) {
|
|
107
107
|
overflow: visible;
|
|
108
108
|
container-type: normal;
|
|
109
|
+
}
|
|
110
|
+
/* `preview` (negative-margin breakout) and a displaced `showcase` (peek
|
|
111
|
+
* spill) want the slot fully de-chromed so the bleed reads as edge-to-edge.
|
|
112
|
+
* Juxtapose just opted out of the clip — it still wants to read as part of
|
|
113
|
+
* the card surface, so it keeps the slot's rounded corners (juxtapose's
|
|
114
|
+
* own `__panels` chrome is dropped instead; see surfaces.css). */
|
|
115
|
+
[data-section="media"]:is(
|
|
116
|
+
:has(> [data-rune="preview"]),
|
|
117
|
+
:has(> .rf-showcase[data-displace]:not(.rf-showcase--in-bento-cell))
|
|
118
|
+
) {
|
|
109
119
|
border-radius: 0;
|
|
110
120
|
}
|
|
111
121
|
/* …and let those self-managing guests keep their intrinsic width/sizing: the
|
package/styles/runes/bg.css
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/* Background — Directive rune for background images, video, overlays, blur */
|
|
2
2
|
|
|
3
|
-
/* Background layer — absolute positioned behind content
|
|
3
|
+
/* Background layer — absolute positioned behind content. `border-radius:
|
|
4
|
+
* inherit` rounds the gradient/image to whatever shape the parent surface has,
|
|
5
|
+
* so a card / bento-cell / any rounded host clips the bg to its own corners
|
|
6
|
+
* without needing `overflow: hidden` (though hosts with thin-edge padding
|
|
7
|
+
* still need it so the bg can't poke past the rounded outer edge). */
|
|
4
8
|
[data-name="bg"] {
|
|
5
9
|
position: absolute;
|
|
6
10
|
inset: 0;
|
|
7
11
|
z-index: 0;
|
|
8
12
|
overflow: hidden;
|
|
13
|
+
border-radius: inherit;
|
|
9
14
|
background-image: var(--bg-image);
|
|
10
15
|
background-size: var(--bg-fit, cover);
|
|
11
16
|
background-position: var(--bg-position, center);
|
|
@@ -22,8 +27,14 @@
|
|
|
22
27
|
[data-name="bg"][data-bg-fixed] {
|
|
23
28
|
background-attachment: fixed;
|
|
24
29
|
}
|
|
25
|
-
/* Content above background — any sibling of bg layer gets z-index
|
|
26
|
-
|
|
30
|
+
/* Content above background — any sibling of the bg layer gets `z-index: 1`
|
|
31
|
+
* so it stacks over the `data-name="bg"` layer (which sits at `z-index: 0`).
|
|
32
|
+
* Keyed off the `data-bg` attribute the engine emits on the bg-owning rune
|
|
33
|
+
* (`engine.ts` → `bgDataAttrs['data-bg'] = ''`), not the per-block BEM
|
|
34
|
+
* modifier class `rf-<block>--has-bg` — the attribute is rune-agnostic so
|
|
35
|
+
* one rule covers card, bento-cell, hero, feature, and anything else that
|
|
36
|
+
* raises a bg layer. */
|
|
37
|
+
[data-bg] > :not([data-name="bg"]) {
|
|
27
38
|
position: relative;
|
|
28
39
|
z-index: 1;
|
|
29
40
|
}
|
package/styles/runes/card.css
CHANGED
|
@@ -27,6 +27,13 @@
|
|
|
27
27
|
border-radius: var(--rf-radius-container);
|
|
28
28
|
border: 1px solid var(--rf-color-border);
|
|
29
29
|
background: var(--rf-color-surface);
|
|
30
|
+
/* Clip non-media content (substrate patterns, bg gradient/image layers) to
|
|
31
|
+
* the card's rounded outer corners. The displaced-peek case is unaffected:
|
|
32
|
+
* `frame-displace` translates the guest *inside* the media zone, which has
|
|
33
|
+
* its own `overflow: hidden`, so no peek ever crosses this boundary.
|
|
34
|
+
* `box-shadow` from `elevation` paints outside the element box and is
|
|
35
|
+
* unaffected by `overflow`. */
|
|
36
|
+
overflow: hidden;
|
|
30
37
|
}
|
|
31
38
|
|
|
32
39
|
/* Content zone fills the remaining inset so total text padding still equals
|
package/styles/runes/figure.css
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
/* Figure */
|
|
2
2
|
.rf-figure img {
|
|
3
|
+
display: block;
|
|
3
4
|
max-width: 100%;
|
|
4
5
|
height: auto;
|
|
6
|
+
margin-inline: auto;
|
|
5
7
|
border-radius: var(--rf-radius-media);
|
|
6
8
|
}
|
|
9
|
+
|
|
10
|
+
/* When `frame-aspect` sets an explicit surface shape, the image fills the
|
|
11
|
+
* shape rather than sitting at its natural size with whitespace on the
|
|
12
|
+
* inline-end. `object-fit: cover` crops only if the natural aspect doesn't
|
|
13
|
+
* match — and `frame-anchor` already picks the focal point of that crop
|
|
14
|
+
* (the same contract as a card's media slot). */
|
|
15
|
+
.rf-figure[style*="--frame-aspect"] img {
|
|
16
|
+
width: 100%;
|
|
17
|
+
height: 100%;
|
|
18
|
+
object-fit: cover;
|
|
19
|
+
margin: 0;
|
|
20
|
+
}
|
|
7
21
|
.rf-figure figcaption {
|
|
8
22
|
margin-top: 0.625rem;
|
|
9
23
|
font-size: 0.825rem;
|
package/styles/runes/map.css
CHANGED
|
@@ -22,6 +22,13 @@
|
|
|
22
22
|
width: 100%;
|
|
23
23
|
position: relative;
|
|
24
24
|
background: var(--rf-color-surface, #f8f9fa);
|
|
25
|
+
/* Establish a stacking context so Leaflet's internal pane z-indices
|
|
26
|
+
* (tile-pane 200, overlay-pane 400, marker-pane 600, popup-pane 700,
|
|
27
|
+
* etc.) stay contained instead of escaping past siblings — otherwise
|
|
28
|
+
* a map dropped into a cover card's media slot punches through the
|
|
29
|
+
* cover scrim (z-index auto) and overlaid content (z-index 1).
|
|
30
|
+
* `position: relative` alone is not enough; `isolation: isolate` is. */
|
|
31
|
+
isolation: isolate;
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
/* Fallback list shown while Leaflet loads */
|
|
@@ -80,6 +87,28 @@
|
|
|
80
87
|
display: none;
|
|
81
88
|
}
|
|
82
89
|
|
|
90
|
+
/* ── Map as a media guest ──
|
|
91
|
+
* When dropped into a `[data-section="media"]` slot (e.g. a card or
|
|
92
|
+
* bento-cell in cover mode), the map yields its standalone presentation to
|
|
93
|
+
* the slot: no outer margin or padding (map is in the Banner surface group
|
|
94
|
+
* which gives it vertical `--rune-padding`; see `surfaces.css`), no rounding
|
|
95
|
+
* (the slot already clips), and the Leaflet container stretches to fill the
|
|
96
|
+
* slot height instead of capping at the per-size pixel height. The fallback
|
|
97
|
+
* list (rendered before Leaflet hydrates) drops its outer padding too so it
|
|
98
|
+
* doesn't bleed past the slot edge during the brief flash before tiles load. */
|
|
99
|
+
[data-section="media"] > .rf-map {
|
|
100
|
+
margin: 0;
|
|
101
|
+
padding: 0;
|
|
102
|
+
height: 100%;
|
|
103
|
+
border-radius: inherit;
|
|
104
|
+
}
|
|
105
|
+
[data-section="media"] > .rf-map > .rf-map__container {
|
|
106
|
+
height: 100%;
|
|
107
|
+
}
|
|
108
|
+
[data-section="media"] .rf-map__fallback {
|
|
109
|
+
padding: 0.75rem 1rem;
|
|
110
|
+
}
|
|
111
|
+
|
|
83
112
|
/* Leaflet popup overrides to match theme */
|
|
84
113
|
.rf-map .leaflet-popup-content-wrapper {
|
|
85
114
|
border-radius: var(--rf-radius-md, 0.5rem);
|
package/styles/runes/preview.css
CHANGED
|
@@ -75,7 +75,11 @@
|
|
|
75
75
|
border-radius: var(--rf-radius-lg);
|
|
76
76
|
overflow: hidden;
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
/* Centre a standalone mockup whose `data-fit="none"` makes it inline-block —
|
|
79
|
+
* margin-inline auto can't centre an inline-block, only its parent's text
|
|
80
|
+
* alignment can. Scoped to a *direct-child* mockup so a card or bento cell
|
|
81
|
+
* that happens to hold a mockup doesn't get its body text centred too. */
|
|
82
|
+
.rf-preview__canvas:has(> .rf-mockup) {
|
|
79
83
|
text-align: center;
|
|
80
84
|
}
|
|
81
85
|
.rf-preview__canvas > *:first-child {
|