@refrakt-md/lumina 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/base.css CHANGED
@@ -40,3 +40,8 @@
40
40
  * loader before base.css), so it has no skin remainder to import here (WORK-438). */
41
41
  @import './styles/dimensions/checklist.css';
42
42
  @import './styles/dimensions/sequence.css';
43
+ /* Motion is a universal dimension (keys on [data-reveal]/[data-animate], not a
44
+ * rune block), so it must live in this no-runes base entry — the one the
45
+ * production loader imports. In index.css only, motion ships in dev (full
46
+ * barrel) but vanishes from builds (base.css + tree-shaken rune blocks). */
47
+ @import './styles/dimensions/motion.css';
@@ -868,6 +868,18 @@
868
868
  "stacked": {
869
869
  "source": "meta",
870
870
  "dataAttribute": "data-stacked"
871
+ },
872
+ "tick-count": {
873
+ "source": "meta",
874
+ "dataAttribute": "data-tick-count"
875
+ },
876
+ "tick-step": {
877
+ "source": "meta",
878
+ "dataAttribute": "data-tick-step"
879
+ },
880
+ "label-angle": {
881
+ "source": "meta",
882
+ "dataAttribute": "data-label-angle"
871
883
  }
872
884
  }
873
885
  },
@@ -3827,6 +3839,531 @@
3827
3839
  "childOrder": [
3828
3840
  "{content}"
3829
3841
  ]
3842
+ },
3843
+ "Spec": {
3844
+ "block": "spec",
3845
+ "root": ".rf-spec",
3846
+ "dataRune": "spec",
3847
+ "childOrder": [
3848
+ "eyebrow",
3849
+ "title",
3850
+ "blurb",
3851
+ "metadata",
3852
+ "tags",
3853
+ "body",
3854
+ "{content}"
3855
+ ],
3856
+ "modifiers": {
3857
+ "id": {
3858
+ "source": "meta",
3859
+ "classPattern": ".rf-spec--{value}",
3860
+ "dataAttribute": "data-id"
3861
+ },
3862
+ "status": {
3863
+ "source": "meta",
3864
+ "default": "draft",
3865
+ "classPattern": ".rf-spec--{value}",
3866
+ "dataAttribute": "data-status"
3867
+ },
3868
+ "version": {
3869
+ "source": "meta",
3870
+ "classPattern": ".rf-spec--{value}",
3871
+ "dataAttribute": "data-version"
3872
+ },
3873
+ "supersedes": {
3874
+ "source": "meta",
3875
+ "classPattern": ".rf-spec--{value}",
3876
+ "dataAttribute": "data-supersedes"
3877
+ },
3878
+ "tags": {
3879
+ "source": "meta",
3880
+ "dataAttribute": "data-tags"
3881
+ },
3882
+ "created": {
3883
+ "source": "meta",
3884
+ "dataAttribute": "data-created"
3885
+ },
3886
+ "modified": {
3887
+ "source": "meta",
3888
+ "dataAttribute": "data-modified"
3889
+ }
3890
+ },
3891
+ "elements": {
3892
+ "eyebrow": {
3893
+ "tag": "div",
3894
+ "selector": ".rf-spec__eyebrow",
3895
+ "source": "block",
3896
+ "layout": "bar",
3897
+ "fields": [
3898
+ "id",
3899
+ "status"
3900
+ ]
3901
+ },
3902
+ "metadata": {
3903
+ "tag": "dl",
3904
+ "selector": ".rf-spec__metadata",
3905
+ "source": "block",
3906
+ "layout": "definition-list",
3907
+ "fields": [
3908
+ "version",
3909
+ "supersedes",
3910
+ "created",
3911
+ "modified"
3912
+ ]
3913
+ },
3914
+ "tags": {
3915
+ "tag": "div",
3916
+ "selector": ".rf-spec__tags",
3917
+ "source": "block",
3918
+ "layout": "bar",
3919
+ "fields": [
3920
+ "tags"
3921
+ ]
3922
+ }
3923
+ }
3924
+ },
3925
+ "Work": {
3926
+ "block": "work",
3927
+ "root": ".rf-work",
3928
+ "dataRune": "work",
3929
+ "childOrder": [
3930
+ "eyebrow",
3931
+ "title",
3932
+ "blurb",
3933
+ "metadata",
3934
+ "tags",
3935
+ "body",
3936
+ "{content}"
3937
+ ],
3938
+ "modifiers": {
3939
+ "id": {
3940
+ "source": "meta",
3941
+ "classPattern": ".rf-work--{value}",
3942
+ "dataAttribute": "data-id"
3943
+ },
3944
+ "status": {
3945
+ "source": "meta",
3946
+ "default": "draft",
3947
+ "classPattern": ".rf-work--{value}",
3948
+ "dataAttribute": "data-status"
3949
+ },
3950
+ "priority": {
3951
+ "source": "meta",
3952
+ "default": "medium",
3953
+ "classPattern": ".rf-work--{value}",
3954
+ "dataAttribute": "data-priority"
3955
+ },
3956
+ "complexity": {
3957
+ "source": "meta",
3958
+ "default": "unknown",
3959
+ "classPattern": ".rf-work--{value}",
3960
+ "dataAttribute": "data-complexity"
3961
+ },
3962
+ "assignee": {
3963
+ "source": "meta",
3964
+ "dataAttribute": "data-assignee"
3965
+ },
3966
+ "milestone": {
3967
+ "source": "meta",
3968
+ "dataAttribute": "data-milestone"
3969
+ },
3970
+ "source": {
3971
+ "source": "meta",
3972
+ "dataAttribute": "data-source"
3973
+ },
3974
+ "tags": {
3975
+ "source": "meta",
3976
+ "dataAttribute": "data-tags"
3977
+ },
3978
+ "created": {
3979
+ "source": "meta",
3980
+ "dataAttribute": "data-created"
3981
+ },
3982
+ "modified": {
3983
+ "source": "meta",
3984
+ "dataAttribute": "data-modified"
3985
+ }
3986
+ },
3987
+ "elements": {
3988
+ "eyebrow": {
3989
+ "tag": "div",
3990
+ "selector": ".rf-work__eyebrow",
3991
+ "source": "block",
3992
+ "layout": "bar",
3993
+ "fields": [
3994
+ "id",
3995
+ "status"
3996
+ ]
3997
+ },
3998
+ "metadata": {
3999
+ "tag": "dl",
4000
+ "selector": ".rf-work__metadata",
4001
+ "source": "block",
4002
+ "layout": "definition-list",
4003
+ "fields": [
4004
+ "priority",
4005
+ "complexity",
4006
+ "assignee",
4007
+ "milestone",
4008
+ "source",
4009
+ "created",
4010
+ "modified"
4011
+ ]
4012
+ },
4013
+ "tags": {
4014
+ "tag": "div",
4015
+ "selector": ".rf-work__tags",
4016
+ "source": "block",
4017
+ "layout": "bar",
4018
+ "fields": [
4019
+ "tags"
4020
+ ]
4021
+ }
4022
+ }
4023
+ },
4024
+ "Bug": {
4025
+ "block": "bug",
4026
+ "root": ".rf-bug",
4027
+ "dataRune": "bug",
4028
+ "childOrder": [
4029
+ "eyebrow",
4030
+ "title",
4031
+ "blurb",
4032
+ "metadata",
4033
+ "tags",
4034
+ "body",
4035
+ "{content}"
4036
+ ],
4037
+ "modifiers": {
4038
+ "id": {
4039
+ "source": "meta",
4040
+ "classPattern": ".rf-bug--{value}",
4041
+ "dataAttribute": "data-id"
4042
+ },
4043
+ "status": {
4044
+ "source": "meta",
4045
+ "default": "reported",
4046
+ "classPattern": ".rf-bug--{value}",
4047
+ "dataAttribute": "data-status"
4048
+ },
4049
+ "severity": {
4050
+ "source": "meta",
4051
+ "default": "major",
4052
+ "classPattern": ".rf-bug--{value}",
4053
+ "dataAttribute": "data-severity"
4054
+ },
4055
+ "assignee": {
4056
+ "source": "meta",
4057
+ "dataAttribute": "data-assignee"
4058
+ },
4059
+ "milestone": {
4060
+ "source": "meta",
4061
+ "dataAttribute": "data-milestone"
4062
+ },
4063
+ "source": {
4064
+ "source": "meta",
4065
+ "dataAttribute": "data-source"
4066
+ },
4067
+ "tags": {
4068
+ "source": "meta",
4069
+ "dataAttribute": "data-tags"
4070
+ },
4071
+ "created": {
4072
+ "source": "meta",
4073
+ "dataAttribute": "data-created"
4074
+ },
4075
+ "modified": {
4076
+ "source": "meta",
4077
+ "dataAttribute": "data-modified"
4078
+ }
4079
+ },
4080
+ "elements": {
4081
+ "eyebrow": {
4082
+ "tag": "div",
4083
+ "selector": ".rf-bug__eyebrow",
4084
+ "source": "block",
4085
+ "layout": "bar",
4086
+ "fields": [
4087
+ "id",
4088
+ "status"
4089
+ ]
4090
+ },
4091
+ "metadata": {
4092
+ "tag": "dl",
4093
+ "selector": ".rf-bug__metadata",
4094
+ "source": "block",
4095
+ "layout": "definition-list",
4096
+ "fields": [
4097
+ "severity",
4098
+ "assignee",
4099
+ "milestone",
4100
+ "source",
4101
+ "created",
4102
+ "modified"
4103
+ ]
4104
+ },
4105
+ "tags": {
4106
+ "tag": "div",
4107
+ "selector": ".rf-bug__tags",
4108
+ "source": "block",
4109
+ "layout": "bar",
4110
+ "fields": [
4111
+ "tags"
4112
+ ]
4113
+ }
4114
+ }
4115
+ },
4116
+ "Decision": {
4117
+ "block": "decision",
4118
+ "root": ".rf-decision",
4119
+ "dataRune": "decision",
4120
+ "childOrder": [
4121
+ "eyebrow",
4122
+ "title",
4123
+ "blurb",
4124
+ "metadata",
4125
+ "tags",
4126
+ "body",
4127
+ "{content}"
4128
+ ],
4129
+ "modifiers": {
4130
+ "id": {
4131
+ "source": "meta",
4132
+ "classPattern": ".rf-decision--{value}",
4133
+ "dataAttribute": "data-id"
4134
+ },
4135
+ "status": {
4136
+ "source": "meta",
4137
+ "default": "proposed",
4138
+ "classPattern": ".rf-decision--{value}",
4139
+ "dataAttribute": "data-status"
4140
+ },
4141
+ "date": {
4142
+ "source": "meta",
4143
+ "dataAttribute": "data-date"
4144
+ },
4145
+ "supersedes": {
4146
+ "source": "meta",
4147
+ "dataAttribute": "data-supersedes"
4148
+ },
4149
+ "source": {
4150
+ "source": "meta",
4151
+ "dataAttribute": "data-source"
4152
+ },
4153
+ "tags": {
4154
+ "source": "meta",
4155
+ "dataAttribute": "data-tags"
4156
+ },
4157
+ "created": {
4158
+ "source": "meta",
4159
+ "dataAttribute": "data-created"
4160
+ },
4161
+ "modified": {
4162
+ "source": "meta",
4163
+ "dataAttribute": "data-modified"
4164
+ }
4165
+ },
4166
+ "elements": {
4167
+ "eyebrow": {
4168
+ "tag": "div",
4169
+ "selector": ".rf-decision__eyebrow",
4170
+ "source": "block",
4171
+ "layout": "bar",
4172
+ "fields": [
4173
+ "id",
4174
+ "status"
4175
+ ]
4176
+ },
4177
+ "metadata": {
4178
+ "tag": "dl",
4179
+ "selector": ".rf-decision__metadata",
4180
+ "source": "block",
4181
+ "layout": "definition-list",
4182
+ "fields": [
4183
+ "date",
4184
+ "supersedes",
4185
+ "source",
4186
+ "created",
4187
+ "modified"
4188
+ ]
4189
+ },
4190
+ "tags": {
4191
+ "tag": "div",
4192
+ "selector": ".rf-decision__tags",
4193
+ "source": "block",
4194
+ "layout": "bar",
4195
+ "fields": [
4196
+ "tags"
4197
+ ]
4198
+ }
4199
+ }
4200
+ },
4201
+ "Milestone": {
4202
+ "block": "milestone",
4203
+ "root": ".rf-milestone",
4204
+ "dataRune": "milestone",
4205
+ "childOrder": [
4206
+ "eyebrow",
4207
+ "title",
4208
+ "blurb",
4209
+ "metadata",
4210
+ "body",
4211
+ "{content}"
4212
+ ],
4213
+ "modifiers": {
4214
+ "name": {
4215
+ "source": "meta",
4216
+ "classPattern": ".rf-milestone--{value}",
4217
+ "dataAttribute": "data-name"
4218
+ },
4219
+ "status": {
4220
+ "source": "meta",
4221
+ "default": "planning",
4222
+ "classPattern": ".rf-milestone--{value}",
4223
+ "dataAttribute": "data-status"
4224
+ },
4225
+ "target": {
4226
+ "source": "meta",
4227
+ "dataAttribute": "data-target"
4228
+ },
4229
+ "created": {
4230
+ "source": "meta",
4231
+ "dataAttribute": "data-created"
4232
+ },
4233
+ "modified": {
4234
+ "source": "meta",
4235
+ "dataAttribute": "data-modified"
4236
+ }
4237
+ },
4238
+ "elements": {
4239
+ "eyebrow": {
4240
+ "tag": "div",
4241
+ "selector": ".rf-milestone__eyebrow",
4242
+ "source": "block",
4243
+ "layout": "bar",
4244
+ "fields": [
4245
+ "name",
4246
+ "status"
4247
+ ]
4248
+ },
4249
+ "metadata": {
4250
+ "tag": "dl",
4251
+ "selector": ".rf-milestone__metadata",
4252
+ "source": "block",
4253
+ "layout": "definition-list",
4254
+ "fields": [
4255
+ "target",
4256
+ "created",
4257
+ "modified"
4258
+ ]
4259
+ }
4260
+ }
4261
+ },
4262
+ "Backlog": {
4263
+ "block": "backlog",
4264
+ "root": ".rf-backlog",
4265
+ "dataRune": "backlog",
4266
+ "childOrder": [
4267
+ "{content}"
4268
+ ],
4269
+ "modifiers": {
4270
+ "filter": {
4271
+ "source": "meta",
4272
+ "dataAttribute": "data-filter"
4273
+ },
4274
+ "sort": {
4275
+ "source": "meta",
4276
+ "dataAttribute": "data-sort"
4277
+ },
4278
+ "group": {
4279
+ "source": "meta",
4280
+ "dataAttribute": "data-group"
4281
+ },
4282
+ "show": {
4283
+ "source": "meta",
4284
+ "dataAttribute": "data-show"
4285
+ }
4286
+ },
4287
+ "childDensity": "minimal"
4288
+ },
4289
+ "DecisionLog": {
4290
+ "block": "decision-log",
4291
+ "root": ".rf-decision-log",
4292
+ "dataRune": "decision-log",
4293
+ "childOrder": [
4294
+ "{content}"
4295
+ ],
4296
+ "modifiers": {
4297
+ "filter": {
4298
+ "source": "meta",
4299
+ "dataAttribute": "data-filter"
4300
+ },
4301
+ "sort": {
4302
+ "source": "meta",
4303
+ "dataAttribute": "data-sort"
4304
+ }
4305
+ },
4306
+ "childDensity": "minimal"
4307
+ },
4308
+ "PlanProgress": {
4309
+ "block": "plan-progress",
4310
+ "root": ".rf-plan-progress",
4311
+ "dataRune": "plan-progress",
4312
+ "childOrder": [
4313
+ "{content}"
4314
+ ]
4315
+ },
4316
+ "PlanActivity": {
4317
+ "block": "plan-activity",
4318
+ "root": ".rf-plan-activity",
4319
+ "dataRune": "plan-activity",
4320
+ "childOrder": [
4321
+ "{content}"
4322
+ ],
4323
+ "modifiers": {
4324
+ "limit": {
4325
+ "source": "meta",
4326
+ "dataAttribute": "data-limit"
4327
+ }
4328
+ }
4329
+ },
4330
+ "PlanHistory": {
4331
+ "block": "plan-history",
4332
+ "root": ".rf-plan-history",
4333
+ "dataRune": "plan-history",
4334
+ "childOrder": [
4335
+ "{content}"
4336
+ ],
4337
+ "modifiers": {
4338
+ "id": {
4339
+ "source": "meta",
4340
+ "dataAttribute": "data-id"
4341
+ },
4342
+ "limit": {
4343
+ "source": "meta",
4344
+ "dataAttribute": "data-limit"
4345
+ },
4346
+ "type": {
4347
+ "source": "meta",
4348
+ "dataAttribute": "data-type"
4349
+ },
4350
+ "since": {
4351
+ "source": "meta",
4352
+ "dataAttribute": "data-since"
4353
+ },
4354
+ "group": {
4355
+ "source": "meta",
4356
+ "dataAttribute": "data-group"
4357
+ }
4358
+ }
4359
+ },
4360
+ "PlanEntityTabs": {
4361
+ "block": "plan-entity-tabs",
4362
+ "root": ".rf-plan-entity-tabs",
4363
+ "dataRune": "plan-entity-tabs",
4364
+ "childOrder": [
4365
+ "{content}"
4366
+ ]
3830
4367
  }
3831
4368
  }
3832
4369
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,YAAY,EAAE,iBAoO1B,CAAC"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,YAAY,EAAE,iBAgP1B,CAAC"}
package/dist/tokens.js CHANGED
@@ -153,6 +153,17 @@ export const luminaTokens = {
153
153
  punctuation: '#6b6661', // tonal — same as color.muted
154
154
  variable: '#1c1a17', // tonal — same as color.text
155
155
  },
156
+ // SPEC-105 — scroll-reveal motion physics. The single source of truth for the
157
+ // `--rf-reveal-*` tokens `dimensions/motion.css` reads; a site retunes the feel
158
+ // via `refrakt.config.json` `theme.tokens.reveal.*`. A gentle, unhurried default.
159
+ reveal: {
160
+ duration: '1.3s',
161
+ easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
162
+ distance: '2rem',
163
+ 'scale-start': '0.94',
164
+ blur: '8px',
165
+ stagger: '220ms',
166
+ },
156
167
  modes: {
157
168
  dark: {
158
169
  color: {
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
package/index.css CHANGED
@@ -49,6 +49,7 @@
49
49
  * tabs/codegroup structure it depends on (WORK-438). */
50
50
  @import './styles/dimensions/checklist.css';
51
51
  @import './styles/dimensions/sequence.css';
52
+ @import './styles/dimensions/motion.css';
52
53
 
53
54
  /* Runes */
54
55
  @import './styles/runes/accordion.css';
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.23.0",
4
+ "version": "0.24.1",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -84,10 +84,10 @@
84
84
  "generate-tokens": "node scripts/generate-tokens.mjs"
85
85
  },
86
86
  "dependencies": {
87
- "@refrakt-md/runes": "0.23.0",
88
- "@refrakt-md/skeleton": "0.23.0",
89
- "@refrakt-md/transform": "0.23.0",
90
- "@refrakt-md/types": "0.23.0"
87
+ "@refrakt-md/runes": "0.24.1",
88
+ "@refrakt-md/skeleton": "0.24.1",
89
+ "@refrakt-md/transform": "0.24.1",
90
+ "@refrakt-md/types": "0.24.1"
91
91
  },
92
92
  "devDependencies": {
93
93
  "postcss": "^8.4.0"
@@ -80,8 +80,10 @@
80
80
  * We push the root with negative margins so it can spill past its
81
81
  * parent's edge for a true breakout. */
82
82
 
83
- /* — Case 1: media-zone displace → translate the inner guest, zone clips. */
84
- [data-section="media"][data-displace] > :is(img, video, .rf-placeholder, [data-rune]) {
83
+ /* — Case 1a: media-zone displace, default `peek` mode → translate the inner
84
+ * guest inside the slot. The zone's `overflow: hidden` clips the displaced
85
+ * guest into a peek (card / bento-cell behaviour). */
86
+ [data-section="media"][data-displace]:not([data-displace-mode="bleed"]) > :is(img, video, .rf-placeholder, [data-rune]) {
85
87
  transform: translate(var(--displace-x, 0), var(--displace-y, 0));
86
88
  }
87
89
  [data-section="media"][data-displace="top"] { --displace-y: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
@@ -90,6 +92,18 @@
90
92
  [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))); }
91
93
  [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)); }
92
94
 
95
+ /* — Case 1b: media-zone displace, `bleed` mode → negative margin on the media
96
+ * zone itself, so following layout pulls up and the guest extends past the
97
+ * host's edge (hero / cta behaviour). The guest renders at its natural
98
+ * position inside the zone — no translate, no artificial gap above. The
99
+ * margin needs to exceed the host's padding for the guest to clear the host
100
+ * edge; the offset scale tops out at `3xl` (6rem) for this. */
101
+ [data-section="media"][data-displace="top"][data-displace-mode="bleed"] { margin-top: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
102
+ [data-section="media"][data-displace="bottom"][data-displace-mode="bleed"] { margin-bottom: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
103
+ [data-section="media"][data-displace="end"][data-displace-mode="bleed"] { margin-inline-end: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
104
+ [data-section="media"][data-displace="top-end"][data-displace-mode="bleed"] { margin-top: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); margin-inline-end: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
105
+ [data-section="media"][data-displace="bottom-end"][data-displace-mode="bleed"] { margin-bottom: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); margin-inline-end: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
106
+
93
107
  /* — Case 2: self-target (showcase, etc.) → root moves; parent decides. */
94
108
  [data-displace]:not([data-section="media"]) { position: relative; z-index: 1; }
95
109
  [data-displace="top"]:not([data-section="media"]) { margin-top: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
@@ -0,0 +1,102 @@
1
+ /* ─── Motion Dimension — skin (SPEC-105) ───────────────────────────────────
2
+ * Scroll-reveal entrance choreography. The split that keeps motion from leaking
3
+ * author concerns into theme concerns:
4
+ * • Author declares *intent* — `data-reveal` / `data-stagger` (the engine, WORK-431).
5
+ * • The behaviour owns *when* — `data-in-view` + the root `data-animate` gate (WORK-433).
6
+ * • This file owns *how* — the physics, keyed on `data-reveal` × `data-in-view`.
7
+ *
8
+ * It covers every section rune from ONE stylesheet: it keys on the generic
9
+ * attributes + the `--rf-reveal-index` marker, never on a rune's structure, so no
10
+ * rune's own CSS gains a motion block. Motion is theme choreography (skin); the
11
+ * framework structure (@refrakt-md/skeleton) has none — a different theme ships its
12
+ * own motion.css. Retune calm↔punchy purely via the tokens below.
13
+ *
14
+ * Reduced motion is handled by the global reset (WORK-352, global.css), which
15
+ * neutralises transition/animation durations; the behaviour also marks everything
16
+ * in-view immediately. */
17
+
18
+ @layer skin {
19
+ /* Physics tokens (`--rf-reveal-duration` / `-easing` / `-distance` /
20
+ * `-scale-start` / `-blur` / `-stagger`) are part of the theme TokenContract
21
+ * (SPEC-105), defined in `src/tokens.ts` and emitted into `tokens/base.css`.
22
+ * A site retunes the feel via `refrakt.config.json` `theme.tokens.reveal.*`;
23
+ * this file only *consumes* them. The fallbacks below keep motion sensible if a
24
+ * theme ships this stylesheet without the reveal token group. */
25
+
26
+ /* Per-character offsets — set on the `[data-reveal]` container and inherited by
27
+ * staggered children, so the single hidden-state block below covers every
28
+ * character. `none` carries no offsets (it never animates). */
29
+ [data-reveal="fade"] { --reveal-x: 0; --reveal-y: 0; --reveal-scale: 1; --reveal-blur: 0; }
30
+ [data-reveal="slide"] { --reveal-x: 0; --reveal-y: var(--rf-reveal-distance, 1.5rem); --reveal-scale: 1; --reveal-blur: 0; }
31
+ [data-reveal="scale"] { --reveal-x: 0; --reveal-y: 0; --reveal-scale: var(--rf-reveal-scale-start, 0.95); --reveal-blur: 0; }
32
+ /* `blur` is focus-led; it animates `filter` (not compositor-cheap), so a theme
33
+ * or low-power path may downgrade it to `fade` by zeroing the blur token. */
34
+ [data-reveal="blur"] { --reveal-x: 0; --reveal-y: 0; --reveal-scale: 1; --reveal-blur: var(--rf-reveal-blur, 8px); }
35
+
36
+ /* The animated unit:
37
+ * • non-staggered → the `[data-reveal]` element itself,
38
+ * • staggered → its indexed children (`[style*="--rf-reveal-index"]`).
39
+ * Everything is gated under the root `[data-animate]` flag the behaviour sets on
40
+ * boot — no JS → no flag → fully visible, nothing hidden (SSR-complete).
41
+ *
42
+ * CRITICAL: reveal animates the INDIVIDUAL `translate`/`scale` properties, never
43
+ * the `transform` shorthand, so it composes with the rune transforms Lumina
44
+ * already uses (hover-lifts on card/cta/feature, frame displacement, drawer/nav
45
+ * slides) instead of clobbering them. */
46
+ [data-animate] :where(
47
+ [data-reveal]:not([data-reveal="none"]):not([data-stagger]),
48
+ [data-stagger]:not([data-reveal="none"]) [style*="--rf-reveal-index"]
49
+ ) {
50
+ transition:
51
+ opacity var(--rf-reveal-duration, 0.9s) var(--rf-reveal-easing, ease-out),
52
+ translate var(--rf-reveal-duration, 0.9s) var(--rf-reveal-easing, ease-out),
53
+ scale var(--rf-reveal-duration, 0.9s) var(--rf-reveal-easing, ease-out),
54
+ filter var(--rf-reveal-duration, 0.9s) var(--rf-reveal-easing, ease-out);
55
+ }
56
+
57
+ /* Pre-entrance (hidden) — until the unit's trigger fires. */
58
+ [data-animate] :where(
59
+ [data-reveal]:not([data-reveal="none"]):not([data-stagger]):not([data-in-view]),
60
+ [data-stagger]:not([data-reveal="none"]):not([data-in-view]) [style*="--rf-reveal-index"]
61
+ ) {
62
+ opacity: 0;
63
+ translate: var(--reveal-x) var(--reveal-y);
64
+ scale: var(--reveal-scale);
65
+ filter: blur(var(--reveal-blur));
66
+ }
67
+
68
+ /* Revealed (resting) — explicit IDENTITY values, never the `none` default.
69
+ * This is what makes the entrance interpolate in WebKit: Safari does not
70
+ * transition `translate`/`scale`/`filter` to-or-from `none`, so reverting to
71
+ * the default would snap (no motion on iOS) — only opacity would animate.
72
+ * Transitioning between two explicit values animates everywhere. */
73
+ [data-animate] :where(
74
+ [data-reveal]:not([data-reveal="none"]):not([data-stagger])[data-in-view],
75
+ [data-stagger][data-in-view] [style*="--rf-reveal-index"]
76
+ ) {
77
+ opacity: 1;
78
+ translate: 0 0;
79
+ scale: 1;
80
+ filter: blur(0);
81
+ }
82
+
83
+ /* Stagger — each child's entrance offset from the container's single in-view
84
+ * trigger by its engine-stamped index against the interval token. */
85
+ [data-animate] [data-stagger][data-in-view] [style*="--rf-reveal-index"] {
86
+ transition-delay: calc(var(--rf-reveal-index) * var(--rf-reveal-stagger, 140ms));
87
+ }
88
+
89
+ /* Per-part choreography (opt-in polish, not required): on a non-staggered
90
+ * sliding section, let the media arrive a beat behind the content for a subtle
91
+ * two-part entrance. Demonstrated on the named anatomy the theme already styles;
92
+ * a theme adds or drops this freely. */
93
+ [data-animate] [data-reveal="slide"]:not([data-stagger]):not([data-in-view]) > * > [data-section="media"] {
94
+ translate: 0 calc(var(--rf-reveal-distance, 1.5rem) * 1.5);
95
+ }
96
+ [data-animate] [data-reveal="slide"]:not([data-stagger])[data-in-view] > * > [data-section="media"] {
97
+ translate: 0 0; /* explicit identity end-state — see the WebKit note above */
98
+ }
99
+ [data-animate] [data-reveal="slide"]:not([data-stagger]) > * > [data-section="media"] {
100
+ transition: translate var(--rf-reveal-duration, 0.9s) var(--rf-reveal-easing, ease-out);
101
+ }
102
+ }
@@ -25,7 +25,12 @@
25
25
  Layout-chrome navs (menubar in header, columns in footer) are excluded
26
26
  so they sit flush with the surrounding header/footer container. */
27
27
 
28
- [data-rune]:not([data-rune] [data-rune]):not(:where([data-layout="menubar"], [data-layout="columns"])) {
28
+ /* `:where(...)` zeros the selector specificity so per-rune CSS, the
29
+ * `[data-rune][data-spacing="..."]` attribute rules, and per-instance overrides
30
+ * all win cleanly. Without `:where()` the `:not([data-rune] [data-rune])` clause
31
+ * inflates this default to (0,3,0) — beating the (0,2,0) spacing attribute and
32
+ * masking `spacing="flush"` on top-level runes like hero. */
33
+ :where([data-rune]:not([data-rune] [data-rune]):not([data-layout="menubar"]):not([data-layout="columns"])) {
29
34
  margin: var(--rf-spacing-md) 0;
30
35
  }
31
36
 
@@ -4,7 +4,19 @@
4
4
  * The layout *structure* (start/end grid, top/bottom stack, 3-section placement,
5
5
  * the media-zone fill/clip mechanism, responsive collapse) lives in
6
6
  * @refrakt-md/skeleton (layouts/split.css). What remains here is skin: the media
7
- * radius tier, the beside-image depth shadow, and the codegroup radius alignment. */
7
+ * radius tier, the beside-image depth shadow, the codegroup radius alignment,
8
+ * and the default side-by-side spacing rhythm. */
9
+
10
+ /* Default side-by-side spacing — applies to every rune using the split layout
11
+ * (hero, feature, step, realm, faction, etc.). Contained-chrome runes
12
+ * (card, recipe, bento-cell, playlist) override `column-gap` / `row-gap` with
13
+ * higher-specificity selectors to hug their internal media well; everything
14
+ * else inherits this comfortable default so columns don't sit flush. */
15
+ [data-media-position="start"],
16
+ [data-media-position="end"] {
17
+ column-gap: var(--rf-spacing-lg);
18
+ row-gap: var(--rf-spacing-lg);
19
+ }
8
20
 
9
21
  /* Media guests use the smaller media radius tier so they never read as more
10
22
  * rounded than the (larger-radius) container they sit in. */
@@ -11,24 +11,48 @@
11
11
  --rf-chart-series-5: #a855f7;
12
12
  --rf-chart-series-6: #ec4899;
13
13
  --rf-chart-bar-ratio: 0.75;
14
- --rf-chart-bar-thickness: 48px;
14
+ --rf-chart-bar-thickness: 12px;
15
15
  --rf-chart-bar-gap: 0.15;
16
- --rf-chart-bar-radius: 2px;
16
+ --rf-chart-bar-cluster-gap: 4px;
17
+ --rf-chart-bar-radius: var(--rf-radius-sm);
18
+ --rf-chart-area-opacity: 0.3;
17
19
  --rf-chart-point-radius: 4px;
18
20
  --rf-chart-line-width: 2px;
19
21
  --rf-chart-label-size: 12px;
20
22
  --rf-chart-label-color: var(--rf-color-muted);
21
23
  --rf-chart-grid-color: var(--rf-color-border);
24
+ --rf-chart-grid-dash-color: var(--rf-color-muted);
22
25
  --rf-chart-grid-width: 1px;
26
+ --rf-chart-grid-dash: 3 3;
23
27
  border-radius: var(--rf-radius-lg);
24
28
  padding: 1.5rem;
25
29
  margin: 0;
26
30
  }
27
31
  .rf-chart__axis { stroke: var(--rf-chart-grid-color); stroke-width: var(--rf-chart-grid-width); }
32
+ /* Dotted horizontal grid lines behind the data — text-tier muted colour so the
33
+ * scale is legible at a glance. Opacity still keeps them quieter than the data,
34
+ * which stays the figure-ground emphasis. */
35
+ .rf-chart__grid {
36
+ stroke: var(--rf-chart-grid-dash-color);
37
+ stroke-width: var(--rf-chart-grid-width);
38
+ stroke-dasharray: var(--rf-chart-grid-dash);
39
+ opacity: 0.2;
40
+ }
28
41
  .rf-chart__label { fill: var(--rf-chart-label-color); font-size: var(--rf-chart-label-size); }
42
+ .rf-chart__tick-label { fill: var(--rf-chart-label-color); font-size: var(--rf-chart-label-size); }
29
43
  .rf-chart__bar { rx: var(--rf-chart-bar-radius); fill: var(--rf-chart-series-1); }
30
44
  .rf-chart__point { fill: var(--rf-chart-series-1); }
31
45
  .rf-chart__line { fill: none; stroke: var(--rf-chart-series-1); stroke-width: var(--rf-chart-line-width); }
46
+ /* Area-under-line gradient stops. The `--rf-chart-area-opacity` knob drives the
47
+ * top alpha; the bottom is always 0 so the gradient fades into the chart floor. */
48
+ .rf-chart__area-stop { stop-color: var(--rf-chart-series-1); }
49
+ .rf-chart__area-stop[data-series="1"] { stop-color: var(--rf-chart-series-2); }
50
+ .rf-chart__area-stop[data-series="2"] { stop-color: var(--rf-chart-series-3); }
51
+ .rf-chart__area-stop[data-series="3"] { stop-color: var(--rf-chart-series-4); }
52
+ .rf-chart__area-stop[data-series="4"] { stop-color: var(--rf-chart-series-5); }
53
+ .rf-chart__area-stop[data-series="5"] { stop-color: var(--rf-chart-series-6); }
54
+ .rf-chart__area-stop[data-position="top"] { stop-opacity: var(--rf-chart-area-opacity); }
55
+ .rf-chart__area-stop[data-position="bottom"] { stop-opacity: 0; }
32
56
  .rf-chart__bar[data-series="1"], .rf-chart__point[data-series="1"] { fill: var(--rf-chart-series-2); }
33
57
  .rf-chart__bar[data-series="2"], .rf-chart__point[data-series="2"] { fill: var(--rf-chart-series-3); }
34
58
  .rf-chart__bar[data-series="3"], .rf-chart__point[data-series="3"] { fill: var(--rf-chart-series-4); }
@@ -3,7 +3,7 @@
3
3
  * divider/handle positioning, toggle-bar flex, and meta/label hides live in
4
4
  * @refrakt-md/skeleton (styles/runes/juxtapose.css). */
5
5
  .rf-juxtapose__panels {
6
- border-radius: var(--rf-radius-md);
6
+ border-radius: var(--rf-radius-lg);
7
7
  border: 1px solid var(--rf-color-border);
8
8
  background: var(--rf-color-surface);
9
9
  }
@@ -414,6 +414,18 @@
414
414
  margin: 0;
415
415
  }
416
416
 
417
+ /* ── Mockup as a media guest ──
418
+ * In a card / bento-cell media zone the mockup sits in the recessed well. Its
419
+ * `flush` elevation gives it vertical breathing room (padding-block) but leaves
420
+ * it hugging the well's sides; add matching inline padding so the inset reads
421
+ * even on all four edges. Because `.rf-mockup` is the size container, the inline
422
+ * padding also narrows `100cqi` — and the device, which fills the slot width as
423
+ * a media guest (skeleton's uncapped frame zoom), then fills the padded box, so
424
+ * the gap stays even with the top/bottom margin at any slot width. */
425
+ [data-section="media"] > .rf-mockup {
426
+ padding-inline: var(--rune-padding, var(--rf-spacing-sm));
427
+ }
428
+
417
429
  /* ═══════════════════════════════════════
418
430
  DARK MODE
419
431
  ═══════════════════════════════════════ */
@@ -156,6 +156,13 @@
156
156
  border-left: none;
157
157
  border-right: none;
158
158
  }
159
+ /* Break out of the feature's padding-inline to reach the viewport edges. Stays
160
+ * skin (not skeleton): this overrides the skin rule `.rf-preview { margin: 2rem 0 }`
161
+ * by specificity, and that only wins within the same cascade layer — in
162
+ * @layer skeleton it loses to the skin margin and the bleed is nullified. */
163
+ .rf-preview--in-feature {
164
+ margin-inline: calc(-1 * var(--rf-content-gutter, 1.5rem));
165
+ }
159
166
  .rf-preview--in-feature .rf-preview__toolbar {
160
167
  padding-inline: var(--rf-content-gutter, 1.5rem);
161
168
  }
@@ -1,9 +1,6 @@
1
1
  @layer skin {
2
2
  /* Sandbox — skin. The iframe clip/fill + banner/poster/activate layout live in
3
3
  * @refrakt-md/skeleton (styles/runes/sandbox.css). */
4
- .rf-sandbox {
5
- border-radius: var(--rf-radius-md);
6
- }
7
4
  .rf-sandbox iframe {
8
5
  border: none;
9
6
  }
@@ -14,7 +11,6 @@
14
11
  /* When inside preview, remove sandbox margin */
15
12
  .rf-preview .rf-sandbox {
16
13
  margin: 0;
17
- border-radius: 0;
18
14
  }
19
15
  /* Untrusted-mode affordance. */
20
16
  .rf-sandbox[data-security-mode="untrusted"] {
package/tokens/base.css CHANGED
@@ -90,6 +90,12 @@
90
90
  --rf-syntax-comment: #8a857d;
91
91
  --rf-syntax-punctuation: #6b6661;
92
92
  --rf-syntax-variable: #1c1a17;
93
+ --rf-reveal-duration: 1.3s;
94
+ --rf-reveal-easing: cubic-bezier(0.16, 1, 0.3, 1);
95
+ --rf-reveal-distance: 2rem;
96
+ --rf-reveal-scale-start: 0.94;
97
+ --rf-reveal-blur: 8px;
98
+ --rf-reveal-stagger: 220ms;
93
99
  --rf-syntax-token-keyword: #2a5c63;
94
100
  --rf-syntax-token-tag: #2a5c63;
95
101
  --rf-syntax-token-function: #4a3b6e;