mnfst 0.5.230 → 0.5.232
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/lib/manifest.appwrite.data.js +1 -1
- package/lib/manifest.components.js +8 -0
- package/lib/manifest.css +343 -408
- package/lib/manifest.d.ts +170 -39
- package/lib/manifest.data.js +1 -1
- package/lib/manifest.defer.js +1 -1
- package/lib/manifest.dropdowns.js +2 -0
- package/lib/manifest.edit.css +89 -146
- package/lib/manifest.edit.js +2409 -1040
- package/lib/manifest.integrity.json +10 -10
- package/lib/manifest.js +119 -25
- package/lib/manifest.min.css +1 -1
- package/lib/{manifest.text.edit.css → manifest.rich.text.css} +62 -70
- package/lib/manifest.rich.text.js +2848 -0
- package/lib/manifest.router.js +8 -0
- package/lib/manifest.sw.js +1 -1
- package/package.json +2 -1
- package/lib/manifest.text.edit.js +0 -2234
package/lib/manifest.css
CHANGED
|
@@ -2922,136 +2922,139 @@
|
|
|
2922
2922
|
|
|
2923
2923
|
@layer base, components, utilities;
|
|
2924
2924
|
|
|
2925
|
-
/*
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
(handles, overlay, live region, toolbar, menu). No class names to collide with. */
|
|
2925
|
+
/* Rules are :where()-wrapped and keyed off data-edit-* attributes, so authors
|
|
2926
|
+
override without specificity battles. Visuals are on for every area;
|
|
2927
|
+
x-edit.bare (data-edit-area="bare") keeps the behaviour and draws none of them. */
|
|
2929
2928
|
|
|
2930
2929
|
@layer utilities {
|
|
2931
2930
|
|
|
2932
|
-
/* ----
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
just as editable — it simply carries no visual cues. */
|
|
2931
|
+
/* ---- Pieces ---- */
|
|
2932
|
+
:where([data-edit-piece]) {
|
|
2933
|
+
cursor: grab;
|
|
2934
|
+
touch-action: none;
|
|
2935
|
+
transition: opacity 0.12s ease, outline-color 0.12s ease;
|
|
2936
|
+
}
|
|
2939
2937
|
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2938
|
+
:where([data-edit-piece]):where(:hover):where(:not([data-edit-area="bare"], [data-edit-area="bare"] *, [data-edit-dragging], [data-edit-ghost], :has([data-edit-dragging]) *)) {
|
|
2939
|
+
outline: 1px solid color-mix(in oklch, var(--edit-accent, var(--color-brand-content)) 45%, transparent);
|
|
2940
|
+
outline-offset: 3px;
|
|
2943
2941
|
}
|
|
2944
2942
|
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2943
|
+
:where([data-edit-piece]):focus-visible:where(:not([data-edit-area="bare"], [data-edit-area="bare"] *)) {
|
|
2944
|
+
outline: 2px solid var(--edit-accent, var(--color-brand-content));
|
|
2945
|
+
outline-offset: 3px;
|
|
2946
|
+
}
|
|
2949
2947
|
|
|
2950
|
-
/*
|
|
2951
|
-
:where([data-edit-
|
|
2948
|
+
/* Grip: drags a text piece; sits at its inline-start edge */
|
|
2949
|
+
:where([data-edit-grip]) {
|
|
2950
|
+
position: fixed;
|
|
2951
|
+
z-index: 1001;
|
|
2952
|
+
width: var(--edit-grip-size, 0.75rem);
|
|
2953
|
+
height: calc(var(--edit-grip-size, 0.75rem) * 1.5);
|
|
2954
|
+
translate: calc(-100% - var(--edit-grip-offset, 0.25rem)) 0;
|
|
2955
|
+
border-radius: 3px;
|
|
2956
|
+
color: var(--edit-accent, var(--color-brand-content));
|
|
2957
|
+
background: radial-gradient(circle, currentColor 1px, transparent 1.5px) center / 6px 6px;
|
|
2958
|
+
opacity: 0.6;
|
|
2952
2959
|
cursor: grab;
|
|
2953
2960
|
touch-action: none;
|
|
2954
|
-
|
|
2961
|
+
user-select: none;
|
|
2962
|
+
|
|
2963
|
+
&:hover {
|
|
2964
|
+
opacity: 1;
|
|
2965
|
+
}
|
|
2955
2966
|
}
|
|
2956
2967
|
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2968
|
+
:where([data-edit-grip]:dir(rtl)) {
|
|
2969
|
+
translate: var(--edit-grip-offset, 0.25rem) 0;
|
|
2970
|
+
}
|
|
2960
2971
|
|
|
2961
|
-
:where([data-edit-
|
|
2962
|
-
|
|
2963
|
-
outline-offset: 3px;
|
|
2972
|
+
:where([data-edit-grip][hidden]) {
|
|
2973
|
+
display: none;
|
|
2964
2974
|
}
|
|
2965
2975
|
|
|
2966
|
-
/* Lifted
|
|
2967
|
-
:where([data-edit-
|
|
2976
|
+
/* Lifted, following the pointer */
|
|
2977
|
+
:where([data-edit-dragging=""]) {
|
|
2968
2978
|
z-index: 1000;
|
|
2969
2979
|
cursor: grabbing;
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
:where([data-edit-dragging=""]):where(:not([data-edit-area="bare"], [data-edit-area="bare"] *)) {
|
|
2970
2983
|
box-shadow: 0 8px 24px rgb(0 0 0 / 0.18);
|
|
2971
2984
|
}
|
|
2972
2985
|
|
|
2973
|
-
/*
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2986
|
+
/* Grabbed from the keyboard */
|
|
2987
|
+
:where([data-edit-dragging="keyboard"]):where(:not([data-edit-area="bare"], [data-edit-area="bare"] *)) {
|
|
2988
|
+
outline: 2px dashed var(--edit-accent, var(--color-brand-content));
|
|
2989
|
+
outline-offset: 3px;
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2992
|
+
/* The stand-in holding the slot the drop would land in */
|
|
2977
2993
|
:where([data-edit-ghost]) {
|
|
2978
2994
|
opacity: var(--edit-ghost-opacity, 0.4);
|
|
2979
2995
|
pointer-events: none;
|
|
2980
2996
|
}
|
|
2981
2997
|
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2998
|
+
:where([data-edit-area="bare"] [data-edit-ghost]) {
|
|
2999
|
+
opacity: 0;
|
|
3000
|
+
}
|
|
3001
|
+
|
|
3002
|
+
/* The container the drop would land in */
|
|
3003
|
+
:where(:has(> [data-edit-ghost])):where(:not([data-edit-area="bare"], [data-edit-area="bare"] *)) {
|
|
2985
3004
|
outline: 1px dashed color-mix(in oklch, var(--edit-accent, var(--color-brand-content)) 55%, transparent);
|
|
2986
3005
|
outline-offset: 4px;
|
|
3006
|
+
}
|
|
3007
|
+
|
|
3008
|
+
/* Other areas a drag can land in; an empty one still has a surface */
|
|
3009
|
+
:where([data-edit-drop-target]):where(:not([data-edit-area="bare"])) {
|
|
3010
|
+
min-height: 2.5rem;
|
|
3011
|
+
outline: 1px dashed color-mix(in oklch, var(--edit-accent, var(--color-brand-content)) 55%, transparent);
|
|
3012
|
+
outline-offset: 4px;
|
|
3013
|
+
}
|
|
3014
|
+
|
|
3015
|
+
/* While dragging: empty containers can be dropped into, nothing else reacts */
|
|
3016
|
+
:where([data-edit-area]:not([data-edit-area="bare"]):has([data-edit-dragging=""])) :where(:empty:not(img, input, br, hr, svg, video, canvas, iframe, textarea, [data-edit-ghost], [data-edit-handle], [data-edit-area="bare"], [data-edit-area="bare"] *)) {
|
|
2987
3017
|
min-height: 2.5rem;
|
|
2988
3018
|
}
|
|
2989
3019
|
|
|
2990
|
-
|
|
2991
|
-
:where([data-edit-dragging-in]) {
|
|
3020
|
+
:where([data-edit-area]:has([data-edit-dragging=""])) {
|
|
2992
3021
|
cursor: grabbing;
|
|
2993
3022
|
user-select: none;
|
|
2994
3023
|
|
|
2995
|
-
& :where([data-edit-
|
|
3024
|
+
& :where([data-edit-piece]:not([data-edit-dragging])) {
|
|
2996
3025
|
cursor: grabbing;
|
|
2997
3026
|
}
|
|
2998
3027
|
}
|
|
2999
3028
|
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
}
|
|
3004
|
-
|
|
3005
|
-
/* ---- Move (positioned children) ---- */
|
|
3006
|
-
:where([data-edit-movable]) {
|
|
3007
|
-
cursor: move;
|
|
3008
|
-
touch-action: none;
|
|
3009
|
-
}
|
|
3010
|
-
|
|
3011
|
-
:where([data-edit-ui] [data-edit-movable], [data-edit-ui][data-edit-movable]):hover {
|
|
3012
|
-
outline: 1px solid var(--edit-accent, var(--color-brand-content));
|
|
3013
|
-
outline-offset: 2px;
|
|
3014
|
-
}
|
|
3015
|
-
|
|
3016
|
-
/* ---- Inline text ----
|
|
3017
|
-
One weight everywhere: hover hints and the focused caret both use the same
|
|
3018
|
-
1px line, so focusing doesn't make the page jump a weight class. */
|
|
3019
|
-
:where([data-edit-ui]) :where([data-edit-armed]) [contenteditable="true"],
|
|
3020
|
-
:where([data-edit-ui])[data-edit-armed] [contenteditable="true"] {
|
|
3029
|
+
/* ---- Inline text ---- */
|
|
3030
|
+
:where([data-edit-area]:not([data-edit-area="bare"])) :where([contenteditable="true"], [data-edit-text]):where(:not([data-edit-area="bare"] *)),
|
|
3031
|
+
:where([data-edit-area]:is([contenteditable="true"], [data-edit-text]):not([data-edit-area="bare"])) {
|
|
3021
3032
|
cursor: text;
|
|
3022
3033
|
outline: 1px solid transparent;
|
|
3023
3034
|
outline-offset: 2px;
|
|
3024
3035
|
border-radius: 3px;
|
|
3025
3036
|
transition: outline-color 0.12s ease;
|
|
3026
|
-
}
|
|
3027
3037
|
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
}
|
|
3038
|
+
&:hover {
|
|
3039
|
+
outline-color: color-mix(in oklch, var(--edit-accent, var(--color-brand-content)) 45%, transparent);
|
|
3040
|
+
}
|
|
3032
3041
|
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3042
|
+
&:focus {
|
|
3043
|
+
outline-color: var(--edit-accent, var(--color-brand-content));
|
|
3044
|
+
}
|
|
3036
3045
|
}
|
|
3037
3046
|
|
|
3038
|
-
/* ---- Size handles ----
|
|
3039
|
-
|
|
3040
|
-
:focus still fire and its body stays interactive. */
|
|
3041
|
-
:where([data-edit-sizable]) {
|
|
3047
|
+
/* ---- Size handles ---- */
|
|
3048
|
+
:where(:has(> [data-edit-handle])) {
|
|
3042
3049
|
position: relative;
|
|
3043
3050
|
}
|
|
3044
3051
|
|
|
3045
|
-
|
|
3046
|
-
The hairline is chrome, so it follows the [data-edit-ui] scope like every
|
|
3047
|
-
other affordance; outside the scope the handles still work (hit areas and
|
|
3048
|
-
resize cursors stay), they just draw nothing. */
|
|
3049
|
-
:where([data-edit-sizable]) :where([data-edit-handle])::before {
|
|
3052
|
+
:where([data-edit-handle])::before {
|
|
3050
3053
|
opacity: 0;
|
|
3051
3054
|
transition: opacity 0.12s ease, background-color 0.15s ease;
|
|
3052
3055
|
}
|
|
3053
3056
|
|
|
3054
|
-
:where([data-edit-
|
|
3057
|
+
:where(:has(> [data-edit-handle])):is(:hover, :focus-within):where(:not([data-edit-area="bare"], [data-edit-area="bare"] *)) > :where([data-edit-handle])::before {
|
|
3055
3058
|
opacity: 1;
|
|
3056
3059
|
}
|
|
3057
3060
|
|
|
@@ -3059,9 +3062,9 @@
|
|
|
3059
3062
|
position: absolute;
|
|
3060
3063
|
z-index: 100;
|
|
3061
3064
|
background: transparent;
|
|
3065
|
+
touch-action: none;
|
|
3062
3066
|
--h: var(--edit-size-handle, 1rem);
|
|
3063
3067
|
|
|
3064
|
-
/* Hairline, revealed on hover */
|
|
3065
3068
|
&::before {
|
|
3066
3069
|
content: '';
|
|
3067
3070
|
position: absolute;
|
|
@@ -3081,11 +3084,10 @@
|
|
|
3081
3084
|
}
|
|
3082
3085
|
}
|
|
3083
3086
|
|
|
3084
|
-
:where([data-edit-handle]):focus-visible {
|
|
3087
|
+
:where([data-edit-handle]):focus-visible:where(:not([data-edit-area="bare"], [data-edit-area="bare"] *)) {
|
|
3085
3088
|
outline: 2px solid var(--edit-accent, var(--color-brand-content));
|
|
3086
3089
|
}
|
|
3087
3090
|
|
|
3088
|
-
/* Edges span their axis; corners are square. A corner value contains a hyphen. */
|
|
3089
3091
|
:where([data-edit-handle="top"], [data-edit-handle="bottom"]) {
|
|
3090
3092
|
left: 0;
|
|
3091
3093
|
width: 100%;
|
|
@@ -3113,8 +3115,6 @@
|
|
|
3113
3115
|
height: var(--h);
|
|
3114
3116
|
}
|
|
3115
3117
|
|
|
3116
|
-
/* Inset — each handle straddles its edge; a corner matches one rule per axis.
|
|
3117
|
-
inset-inline-* carries the logical start/end values, so they flip for RTL. */
|
|
3118
3118
|
:where([data-edit-handle^="top"]) {
|
|
3119
3119
|
top: calc(var(--h) * -0.5);
|
|
3120
3120
|
}
|
|
@@ -3139,7 +3139,6 @@
|
|
|
3139
3139
|
inset-inline-end: calc(var(--h) * -0.5);
|
|
3140
3140
|
}
|
|
3141
3141
|
|
|
3142
|
-
/* Corner cursors; the logical pair flips with direction. */
|
|
3143
3142
|
:where([data-edit-handle="top-left"], [data-edit-handle="bottom-right"], [data-edit-handle="top-start"], [data-edit-handle="bottom-end"]) {
|
|
3144
3143
|
cursor: nwse-resize;
|
|
3145
3144
|
}
|
|
@@ -3156,12 +3155,12 @@
|
|
|
3156
3155
|
cursor: nwse-resize;
|
|
3157
3156
|
}
|
|
3158
3157
|
|
|
3159
|
-
/*
|
|
3160
|
-
:where([data-edit-
|
|
3161
|
-
|
|
3158
|
+
/* Bare: handles keep their hit areas and cursors, draw nothing */
|
|
3159
|
+
:where([data-edit-area="bare"] [data-edit-handle])::before {
|
|
3160
|
+
content: none;
|
|
3162
3161
|
}
|
|
3163
3162
|
|
|
3164
|
-
/*
|
|
3163
|
+
/* Pointer capture layer during a resize */
|
|
3165
3164
|
:where([data-edit-overlay]) {
|
|
3166
3165
|
position: fixed;
|
|
3167
3166
|
inset: 0;
|
|
@@ -3169,7 +3168,7 @@
|
|
|
3169
3168
|
background: transparent;
|
|
3170
3169
|
}
|
|
3171
3170
|
|
|
3172
|
-
/* Screen-reader announcements
|
|
3171
|
+
/* Screen-reader announcements */
|
|
3173
3172
|
:where([data-edit-live]) {
|
|
3174
3173
|
position: absolute;
|
|
3175
3174
|
width: 1px;
|
|
@@ -3184,69 +3183,13 @@
|
|
|
3184
3183
|
|
|
3185
3184
|
@media (prefers-reduced-motion: reduce) {
|
|
3186
3185
|
|
|
3187
|
-
:where([data-edit-
|
|
3186
|
+
:where([data-edit-piece]),
|
|
3188
3187
|
:where([data-edit-handle])::before {
|
|
3189
3188
|
transition: none;
|
|
3190
3189
|
}
|
|
3191
3190
|
}
|
|
3192
3191
|
}
|
|
3193
3192
|
|
|
3194
|
-
/* ---- Authoring chrome (toolbar + class/scope menu) ---- */
|
|
3195
|
-
@layer components {
|
|
3196
|
-
|
|
3197
|
-
/* Presence is script's business — it knows which route is on screen. Whether it
|
|
3198
|
-
is seen is not, so the toolbar is styled and revealed here. */
|
|
3199
|
-
:where([data-edit-toolbar]) {
|
|
3200
|
-
display: none;
|
|
3201
|
-
position: fixed;
|
|
3202
|
-
inset-block-end: 1rem;
|
|
3203
|
-
inset-inline-end: 1rem;
|
|
3204
|
-
z-index: 9999;
|
|
3205
|
-
gap: 0.5rem;
|
|
3206
|
-
align-items: center;
|
|
3207
|
-
|
|
3208
|
-
& button[disabled] {
|
|
3209
|
-
opacity: 0.35;
|
|
3210
|
-
pointer-events: none;
|
|
3211
|
-
}
|
|
3212
|
-
}
|
|
3213
|
-
|
|
3214
|
-
/* --edit-toolbar: none (any scope up to :root) suppresses it — e.g. a site
|
|
3215
|
-
that demos .authoring regions but has its own publish flow. */
|
|
3216
|
-
:root[data-edit-active] :where([data-edit-toolbar]) {
|
|
3217
|
-
display: var(--edit-toolbar, flex);
|
|
3218
|
-
}
|
|
3219
|
-
|
|
3220
|
-
/* A popover: the top layer sits above every stacking context, so no handle,
|
|
3221
|
-
overlay or z-index anywhere on the page can paint over it. */
|
|
3222
|
-
:where([data-edit-menu]) {
|
|
3223
|
-
position: fixed;
|
|
3224
|
-
margin: 0;
|
|
3225
|
-
width: 16rem;
|
|
3226
|
-
padding: 0.6rem;
|
|
3227
|
-
display: flex;
|
|
3228
|
-
flex-direction: column;
|
|
3229
|
-
gap: 0.4rem;
|
|
3230
|
-
background: var(--color-surface-1);
|
|
3231
|
-
border: 1px solid var(--color-line);
|
|
3232
|
-
border-radius: var(--radius);
|
|
3233
|
-
box-shadow: 0 8px 30px rgb(0 0 0 / 0.2);
|
|
3234
|
-
|
|
3235
|
-
& input {
|
|
3236
|
-
width: 100%;
|
|
3237
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
3238
|
-
font-size: 0.75rem;
|
|
3239
|
-
}
|
|
3240
|
-
|
|
3241
|
-
& small {
|
|
3242
|
-
font-size: 0.7rem;
|
|
3243
|
-
text-transform: uppercase;
|
|
3244
|
-
letter-spacing: 0.05em;
|
|
3245
|
-
color: var(--color-content-subtle);
|
|
3246
|
-
}
|
|
3247
|
-
}
|
|
3248
|
-
}
|
|
3249
|
-
|
|
3250
3193
|
/* Manifest Forms */
|
|
3251
3194
|
|
|
3252
3195
|
@layer base, components, utilities;
|
|
@@ -3911,6 +3854,260 @@
|
|
|
3911
3854
|
}
|
|
3912
3855
|
}
|
|
3913
3856
|
|
|
3857
|
+
/* Manifest Rich Text */
|
|
3858
|
+
|
|
3859
|
+
@layer base, components, utilities;
|
|
3860
|
+
|
|
3861
|
+
@layer components {
|
|
3862
|
+
|
|
3863
|
+
:where([data-rich-text]:not([data-edit-text])) {
|
|
3864
|
+
position: relative;
|
|
3865
|
+
overflow-y: auto;
|
|
3866
|
+
max-height: var(--rich-text-max-height, none);
|
|
3867
|
+
outline: none;
|
|
3868
|
+
|
|
3869
|
+
/* Document-wide styles (.all controls, $rich.all) */
|
|
3870
|
+
font-family: var(--rich-text-font, inherit);
|
|
3871
|
+
font-size: var(--rich-text-size, inherit);
|
|
3872
|
+
line-height: var(--rich-text-leading, inherit);
|
|
3873
|
+
text-align: var(--rich-text-align, start);
|
|
3874
|
+
color: var(--rich-text-color, inherit);
|
|
3875
|
+
|
|
3876
|
+
/* Placeholder overlays the first line */
|
|
3877
|
+
&[data-rich-text-empty]::before {
|
|
3878
|
+
content: attr(placeholder);
|
|
3879
|
+
position: absolute;
|
|
3880
|
+
inset-block-start: var(--rich-text-padding, 0.75rem);
|
|
3881
|
+
inset-inline: var(--rich-text-padding, 0.75rem);
|
|
3882
|
+
color: var(--color-content-subtle);
|
|
3883
|
+
pointer-events: none;
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
|
|
3887
|
+
/* .all background on an unstyled area */
|
|
3888
|
+
:where([data-rich-text].unstyle[style*="--rich-text-background"]) {
|
|
3889
|
+
background: var(--rich-text-background);
|
|
3890
|
+
}
|
|
3891
|
+
|
|
3892
|
+
/* Unstyled: placeholder hugs the line */
|
|
3893
|
+
:where([data-rich-text].unstyle)[data-rich-text-empty]::before {
|
|
3894
|
+
inset-block-start: 0;
|
|
3895
|
+
inset-inline: 0;
|
|
3896
|
+
}
|
|
3897
|
+
|
|
3898
|
+
/* Field look; .unstyle drops it */
|
|
3899
|
+
:where([data-rich-text]:not(.unstyle, [data-edit-text])) {
|
|
3900
|
+
min-height: var(--rich-text-min-height, 8rem);
|
|
3901
|
+
padding: var(--rich-text-padding, 0.75rem);
|
|
3902
|
+
background: var(--rich-text-background, var(--color-surface-1));
|
|
3903
|
+
border: 1px solid var(--color-line);
|
|
3904
|
+
border-radius: var(--radius);
|
|
3905
|
+
|
|
3906
|
+
/* Held while a focus-taking control acts on the area */
|
|
3907
|
+
&:focus,
|
|
3908
|
+
&[data-rich-text-focused] {
|
|
3909
|
+
border-color: var(--color-content-subtle);
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
|
|
3913
|
+
/* Single-line (.inline) */
|
|
3914
|
+
:where([data-rich-text-inline]:not(.unstyle, [data-edit-text])) {
|
|
3915
|
+
min-height: var(--rich-text-min-height, auto);
|
|
3916
|
+
}
|
|
3917
|
+
|
|
3918
|
+
/* ---- Selection menu (x-rich-text-menu) ---- */
|
|
3919
|
+
:where([data-rich-text-menu]) {
|
|
3920
|
+
position: fixed;
|
|
3921
|
+
margin: 0;
|
|
3922
|
+
inset: auto;
|
|
3923
|
+
left: var(--rich-text-selection-center);
|
|
3924
|
+
top: var(--rich-text-selection-y);
|
|
3925
|
+
transform: translate(-50%, calc(-100% - 0.5rem));
|
|
3926
|
+
gap: 0.25rem;
|
|
3927
|
+
align-items: center;
|
|
3928
|
+
padding: 0.25rem;
|
|
3929
|
+
background: var(--color-surface-1);
|
|
3930
|
+
border: 1px solid var(--color-line);
|
|
3931
|
+
border-radius: var(--radius);
|
|
3932
|
+
box-shadow: 0 8px 30px rgb(0 0 0 / 0.2);
|
|
3933
|
+
}
|
|
3934
|
+
|
|
3935
|
+
/* Display only while open */
|
|
3936
|
+
:where([data-rich-text-menu]:popover-open) {
|
|
3937
|
+
display: flex;
|
|
3938
|
+
}
|
|
3939
|
+
|
|
3940
|
+
/* No Popover API: hidden */
|
|
3941
|
+
@supports not selector(:popover-open) {
|
|
3942
|
+
:where([data-rich-text-menu]) {
|
|
3943
|
+
display: none;
|
|
3944
|
+
}
|
|
3945
|
+
}
|
|
3946
|
+
|
|
3947
|
+
/* ---- Controls ---- */
|
|
3948
|
+
:where([data-rich-text-control]) {
|
|
3949
|
+
&[data-rich-text-active] {
|
|
3950
|
+
background: color-mix(in oklch, var(--color-content-stark) 10%, transparent);
|
|
3951
|
+
color: var(--color-content-stark);
|
|
3952
|
+
}
|
|
3953
|
+
|
|
3954
|
+
& > svg {
|
|
3955
|
+
width: 1rem;
|
|
3956
|
+
height: 1rem;
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
|
|
3960
|
+
/* Icon-only buttons */
|
|
3961
|
+
:where(button[data-rich-text-control]:has(> svg:only-child)) {
|
|
3962
|
+
padding: 0.35rem;
|
|
3963
|
+
line-height: 0;
|
|
3964
|
+
}
|
|
3965
|
+
|
|
3966
|
+
/* Disabled controls still catch the click, so the area keeps focus */
|
|
3967
|
+
:where([data-rich-text-control][aria-disabled=true]) {
|
|
3968
|
+
pointer-events: auto;
|
|
3969
|
+
}
|
|
3970
|
+
|
|
3971
|
+
/* ---- Editable content ---- */
|
|
3972
|
+
:where([data-rich-text]:not([data-edit-text])) {
|
|
3973
|
+
|
|
3974
|
+
& > * + * {
|
|
3975
|
+
margin-block-start: 0.75em;
|
|
3976
|
+
}
|
|
3977
|
+
|
|
3978
|
+
& :where(h1, h2, h3, h4, h5, h6) {
|
|
3979
|
+
font-weight: 600;
|
|
3980
|
+
line-height: 1.25;
|
|
3981
|
+
}
|
|
3982
|
+
|
|
3983
|
+
& h1 { font-size: 1.6em }
|
|
3984
|
+
& h2 { font-size: 1.35em }
|
|
3985
|
+
& h3 { font-size: 1.15em }
|
|
3986
|
+
|
|
3987
|
+
& :where(ul, ol) {
|
|
3988
|
+
padding-inline-start: 1.5em;
|
|
3989
|
+
}
|
|
3990
|
+
|
|
3991
|
+
& li {
|
|
3992
|
+
list-style: revert;
|
|
3993
|
+
}
|
|
3994
|
+
|
|
3995
|
+
& blockquote {
|
|
3996
|
+
padding-inline-start: 0.85em;
|
|
3997
|
+
border-inline-start: 2px solid var(--color-line);
|
|
3998
|
+
color: var(--color-content-neutral);
|
|
3999
|
+
}
|
|
4000
|
+
|
|
4001
|
+
& code {
|
|
4002
|
+
padding: 0.1em 0.3em;
|
|
4003
|
+
border-radius: 4px;
|
|
4004
|
+
font-size: 0.9em;
|
|
4005
|
+
background: color-mix(in oklch, var(--color-content-stark) 8%, transparent);
|
|
4006
|
+
}
|
|
4007
|
+
|
|
4008
|
+
& pre {
|
|
4009
|
+
padding: 0.75em;
|
|
4010
|
+
border-radius: var(--radius);
|
|
4011
|
+
overflow-x: auto;
|
|
4012
|
+
background: color-mix(in oklch, var(--color-content-stark) 8%, transparent);
|
|
4013
|
+
|
|
4014
|
+
& code {
|
|
4015
|
+
padding: 0;
|
|
4016
|
+
background: none;
|
|
4017
|
+
}
|
|
4018
|
+
}
|
|
4019
|
+
|
|
4020
|
+
& a {
|
|
4021
|
+
color: var(--color-brand-content);
|
|
4022
|
+
text-decoration: underline;
|
|
4023
|
+
}
|
|
4024
|
+
|
|
4025
|
+
& hr {
|
|
4026
|
+
margin-block: 1em;
|
|
4027
|
+
}
|
|
4028
|
+
|
|
4029
|
+
& img {
|
|
4030
|
+
max-width: 100%;
|
|
4031
|
+
}
|
|
4032
|
+
|
|
4033
|
+
& table {
|
|
4034
|
+
width: 100%;
|
|
4035
|
+
table-layout: fixed;
|
|
4036
|
+
|
|
4037
|
+
& :where(td, th) {
|
|
4038
|
+
padding: 0.35em 0.5em;
|
|
4039
|
+
border: 1px solid var(--color-line);
|
|
4040
|
+
vertical-align: top;
|
|
4041
|
+
}
|
|
4042
|
+
|
|
4043
|
+
& th {
|
|
4044
|
+
font-weight: 600;
|
|
4045
|
+
text-align: start;
|
|
4046
|
+
background: var(--color-surface-2);
|
|
4047
|
+
}
|
|
4048
|
+
}
|
|
4049
|
+
|
|
4050
|
+
/* Cell block selection */
|
|
4051
|
+
& :where(td, th)[data-rich-text-cell] {
|
|
4052
|
+
background: color-mix(in oklch, var(--color-brand-content) 18%, transparent);
|
|
4053
|
+
}
|
|
4054
|
+
|
|
4055
|
+
/* Table border resizing */
|
|
4056
|
+
&[data-rich-text-border="x"] { cursor: col-resize }
|
|
4057
|
+
&[data-rich-text-border="y"] { cursor: row-resize }
|
|
4058
|
+
&[data-rich-text-resizing] { user-select: none }
|
|
4059
|
+
&[data-rich-text-resizing="x"] { cursor: col-resize }
|
|
4060
|
+
&[data-rich-text-resizing="y"] { cursor: row-resize }
|
|
4061
|
+
|
|
4062
|
+
/* Task lists */
|
|
4063
|
+
& :where(ul[data-checklist]) {
|
|
4064
|
+
padding-inline-start: 0.25em;
|
|
4065
|
+
list-style: none;
|
|
4066
|
+
|
|
4067
|
+
& li {
|
|
4068
|
+
display: flex;
|
|
4069
|
+
align-items: baseline;
|
|
4070
|
+
gap: 0.5em;
|
|
4071
|
+
list-style: none;
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
4074
|
+
|
|
4075
|
+
& :where(dt) {
|
|
4076
|
+
font-weight: 600;
|
|
4077
|
+
}
|
|
4078
|
+
|
|
4079
|
+
& :where(dd) {
|
|
4080
|
+
margin-inline-start: 1.5em;
|
|
4081
|
+
}
|
|
4082
|
+
|
|
4083
|
+
& :where(kbd) {
|
|
4084
|
+
padding: 0.1em 0.35em;
|
|
4085
|
+
border: 1px solid var(--color-line);
|
|
4086
|
+
border-radius: 4px;
|
|
4087
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
4088
|
+
font-size: 0.85em;
|
|
4089
|
+
}
|
|
4090
|
+
|
|
4091
|
+
& :where(mark) {
|
|
4092
|
+
background: color-mix(in oklch, var(--color-brand-content) 25%, transparent);
|
|
4093
|
+
color: inherit;
|
|
4094
|
+
}
|
|
4095
|
+
|
|
4096
|
+
& :where(small) {
|
|
4097
|
+
font-size: 0.8em;
|
|
4098
|
+
}
|
|
4099
|
+
|
|
4100
|
+
& :where(figcaption) {
|
|
4101
|
+
font-size: 0.8em;
|
|
4102
|
+
color: var(--color-content-neutral);
|
|
4103
|
+
}
|
|
4104
|
+
|
|
4105
|
+
& :where(abbr, dfn) {
|
|
4106
|
+
text-decoration: underline dotted;
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
4109
|
+
}
|
|
4110
|
+
|
|
3914
4111
|
/* Manifest Sidebars */
|
|
3915
4112
|
|
|
3916
4113
|
@layer base, components, utilities;
|
|
@@ -4207,268 +4404,6 @@
|
|
|
4207
4404
|
}
|
|
4208
4405
|
}
|
|
4209
4406
|
|
|
4210
|
-
/* Manifest Text Edit */
|
|
4211
|
-
|
|
4212
|
-
@layer base, components, utilities;
|
|
4213
|
-
|
|
4214
|
-
/* Self-contained. The editable area is a field first — it borrows the tokens inputs
|
|
4215
|
-
and textareas use, so it sits in a form without looking bolted on. Controls are
|
|
4216
|
-
styled where they are, not by where they sit, because they can be anywhere. */
|
|
4217
|
-
|
|
4218
|
-
@layer components {
|
|
4219
|
-
|
|
4220
|
-
:where([data-text-edit]) {
|
|
4221
|
-
position: relative;
|
|
4222
|
-
overflow-y: auto;
|
|
4223
|
-
max-height: var(--text-edit-max-height, none);
|
|
4224
|
-
outline: none;
|
|
4225
|
-
|
|
4226
|
-
/* Page-level styling — set by .page controls, read back by $text.page.
|
|
4227
|
-
Presentation, so it lives here rather than inside the stored markup. */
|
|
4228
|
-
font-family: var(--text-edit-font, inherit);
|
|
4229
|
-
font-size: var(--text-edit-size, inherit);
|
|
4230
|
-
line-height: var(--text-edit-leading, inherit);
|
|
4231
|
-
text-align: var(--text-edit-align, start);
|
|
4232
|
-
color: var(--text-edit-color, inherit);
|
|
4233
|
-
|
|
4234
|
-
/* Flagged from script: :empty never matches the <br> a contenteditable
|
|
4235
|
-
keeps, and the tag holding it is not predictable after a wipe. The
|
|
4236
|
-
placeholder OVERLAYS the first line (it is not a line of its own), so
|
|
4237
|
-
the caret sits on top of it and nothing jumps when typing starts. */
|
|
4238
|
-
&[data-text-edit-empty]::before {
|
|
4239
|
-
content: attr(placeholder);
|
|
4240
|
-
position: absolute;
|
|
4241
|
-
inset-block-start: var(--text-edit-padding, 0.75rem);
|
|
4242
|
-
inset-inline: var(--text-edit-padding, 0.75rem);
|
|
4243
|
-
color: var(--color-content-subtle);
|
|
4244
|
-
pointer-events: none;
|
|
4245
|
-
}
|
|
4246
|
-
}
|
|
4247
|
-
|
|
4248
|
-
/* An unstyled area has no field padding, so its placeholder hugs the line. */
|
|
4249
|
-
:where([data-text-edit].unstyle)[data-text-edit-empty]::before {
|
|
4250
|
-
inset-block-start: 0;
|
|
4251
|
-
inset-inline: 0;
|
|
4252
|
-
}
|
|
4253
|
-
|
|
4254
|
-
/* The FIELD look. `.unstyle` drops it so an area can sit seamlessly in a
|
|
4255
|
-
page — a WYSIWYG document inherits its element's own type and colours;
|
|
4256
|
-
everything above (caret custody, placeholder, commands) still works. */
|
|
4257
|
-
:where([data-text-edit]:not(.unstyle)) {
|
|
4258
|
-
min-height: var(--text-edit-min-height, 8rem);
|
|
4259
|
-
padding: var(--text-edit-padding, 0.75rem);
|
|
4260
|
-
background: var(--text-edit-background, var(--color-surface-1));
|
|
4261
|
-
border: 1px solid var(--color-line);
|
|
4262
|
-
border-radius: var(--radius);
|
|
4263
|
-
|
|
4264
|
-
/* Held while the area owns the editing session — a <select> or colour
|
|
4265
|
-
control takes NATIVE focus by design, and the ring must not flicker
|
|
4266
|
-
off while the writer is mid-command. */
|
|
4267
|
-
&:focus,
|
|
4268
|
-
&[data-text-edit-focused] {
|
|
4269
|
-
border-color: var(--color-content-subtle);
|
|
4270
|
-
}
|
|
4271
|
-
}
|
|
4272
|
-
|
|
4273
|
-
/* ---- Selection menu (x-text-edit-menu) ----
|
|
4274
|
-
Positioned by the --text-edit-selection-* variables the plugin writes to
|
|
4275
|
-
:root, so the default needs no script; restyle or reposition freely. */
|
|
4276
|
-
:where([data-text-edit-menu]) {
|
|
4277
|
-
position: fixed;
|
|
4278
|
-
margin: 0;
|
|
4279
|
-
inset: auto;
|
|
4280
|
-
left: var(--text-edit-selection-center);
|
|
4281
|
-
top: var(--text-edit-selection-y);
|
|
4282
|
-
transform: translate(-50%, calc(-100% - 0.5rem));
|
|
4283
|
-
gap: 0.25rem;
|
|
4284
|
-
align-items: center;
|
|
4285
|
-
padding: 0.25rem;
|
|
4286
|
-
background: var(--color-surface-1);
|
|
4287
|
-
border: 1px solid var(--color-line);
|
|
4288
|
-
border-radius: var(--radius);
|
|
4289
|
-
box-shadow: 0 8px 30px rgb(0 0 0 / 0.2);
|
|
4290
|
-
}
|
|
4291
|
-
|
|
4292
|
-
/* display only while OPEN: an author display on the base rule would beat
|
|
4293
|
-
the UA's closed-popover display:none, leaving the menu floating fixed
|
|
4294
|
-
over the page before any selection exists. */
|
|
4295
|
-
:where([data-text-edit-menu]:popover-open) {
|
|
4296
|
-
display: flex;
|
|
4297
|
-
}
|
|
4298
|
-
|
|
4299
|
-
/* Without the Popover API the attribute is inert and the menu would render
|
|
4300
|
-
permanently fixed on the page — hide it there; the bubble is progressive
|
|
4301
|
-
enhancement. (In supporting browsers a closed popover is hidden natively.) */
|
|
4302
|
-
@supports not selector(:popover-open) {
|
|
4303
|
-
:where([data-text-edit-menu]) {
|
|
4304
|
-
display: none;
|
|
4305
|
-
}
|
|
4306
|
-
}
|
|
4307
|
-
|
|
4308
|
-
/* ---- Controls ----
|
|
4309
|
-
A control is marked wherever it lives, so a toolbar is optional markup and
|
|
4310
|
-
never a requirement. The reset already dims [aria-disabled=true]. */
|
|
4311
|
-
:where([data-text-edit-control]) {
|
|
4312
|
-
&[data-text-edit-active] {
|
|
4313
|
-
background: color-mix(in oklch, var(--color-content-stark) 10%, transparent);
|
|
4314
|
-
color: var(--color-content-stark);
|
|
4315
|
-
}
|
|
4316
|
-
|
|
4317
|
-
& > svg {
|
|
4318
|
-
width: 1rem;
|
|
4319
|
-
height: 1rem;
|
|
4320
|
-
}
|
|
4321
|
-
}
|
|
4322
|
-
|
|
4323
|
-
:where(button[data-text-edit-control]) {
|
|
4324
|
-
padding: 0.35rem;
|
|
4325
|
-
line-height: 0;
|
|
4326
|
-
}
|
|
4327
|
-
|
|
4328
|
-
/* ---- Editable content ----
|
|
4329
|
-
The editor authors real block elements, so style them as elements. Deliberately
|
|
4330
|
-
lighter than the .prose class, which sets a reading measure this field can't use. */
|
|
4331
|
-
:where([data-text-edit]) {
|
|
4332
|
-
|
|
4333
|
-
& > * + * {
|
|
4334
|
-
margin-block-start: 0.75em;
|
|
4335
|
-
}
|
|
4336
|
-
|
|
4337
|
-
& :where(h1, h2, h3, h4, h5, h6) {
|
|
4338
|
-
font-weight: 600;
|
|
4339
|
-
line-height: 1.25;
|
|
4340
|
-
}
|
|
4341
|
-
|
|
4342
|
-
& h1 { font-size: 1.6em }
|
|
4343
|
-
& h2 { font-size: 1.35em }
|
|
4344
|
-
& h3 { font-size: 1.15em }
|
|
4345
|
-
|
|
4346
|
-
& :where(ul, ol) {
|
|
4347
|
-
padding-inline-start: 1.5em;
|
|
4348
|
-
}
|
|
4349
|
-
|
|
4350
|
-
& li {
|
|
4351
|
-
list-style: revert;
|
|
4352
|
-
}
|
|
4353
|
-
|
|
4354
|
-
& blockquote {
|
|
4355
|
-
padding-inline-start: 0.85em;
|
|
4356
|
-
border-inline-start: 2px solid var(--color-line);
|
|
4357
|
-
color: var(--color-content-neutral);
|
|
4358
|
-
}
|
|
4359
|
-
|
|
4360
|
-
& code {
|
|
4361
|
-
padding: 0.1em 0.3em;
|
|
4362
|
-
border-radius: 4px;
|
|
4363
|
-
font-size: 0.9em;
|
|
4364
|
-
background: color-mix(in oklch, var(--color-content-stark) 8%, transparent);
|
|
4365
|
-
}
|
|
4366
|
-
|
|
4367
|
-
& pre {
|
|
4368
|
-
padding: 0.75em;
|
|
4369
|
-
border-radius: var(--radius);
|
|
4370
|
-
overflow-x: auto;
|
|
4371
|
-
background: color-mix(in oklch, var(--color-content-stark) 8%, transparent);
|
|
4372
|
-
|
|
4373
|
-
& code {
|
|
4374
|
-
padding: 0;
|
|
4375
|
-
background: none;
|
|
4376
|
-
}
|
|
4377
|
-
}
|
|
4378
|
-
|
|
4379
|
-
& a {
|
|
4380
|
-
color: var(--color-brand-content);
|
|
4381
|
-
text-decoration: underline;
|
|
4382
|
-
}
|
|
4383
|
-
|
|
4384
|
-
& hr {
|
|
4385
|
-
margin-block: 1em;
|
|
4386
|
-
}
|
|
4387
|
-
|
|
4388
|
-
& img {
|
|
4389
|
-
max-width: 100%;
|
|
4390
|
-
}
|
|
4391
|
-
|
|
4392
|
-
& table {
|
|
4393
|
-
width: 100%;
|
|
4394
|
-
table-layout: fixed;
|
|
4395
|
-
|
|
4396
|
-
& :where(td, th) {
|
|
4397
|
-
padding: 0.35em 0.5em;
|
|
4398
|
-
border: 1px solid var(--color-line);
|
|
4399
|
-
vertical-align: top;
|
|
4400
|
-
}
|
|
4401
|
-
|
|
4402
|
-
& th {
|
|
4403
|
-
font-weight: 600;
|
|
4404
|
-
text-align: start;
|
|
4405
|
-
background: var(--color-surface-2);
|
|
4406
|
-
}
|
|
4407
|
-
}
|
|
4408
|
-
|
|
4409
|
-
/* A block selection across cells. The browser can only highlight text, so an
|
|
4410
|
-
empty cell shows nothing — this is what makes a spreadsheet-style
|
|
4411
|
-
selection visible. */
|
|
4412
|
-
& :where(td, th)[data-text-edit-cell] {
|
|
4413
|
-
background: color-mix(in oklch, var(--color-brand-content) 18%, transparent);
|
|
4414
|
-
}
|
|
4415
|
-
|
|
4416
|
-
/* Borders read as grabbable only when the pointer is on one */
|
|
4417
|
-
&[data-text-edit-border="x"] { cursor: col-resize }
|
|
4418
|
-
&[data-text-edit-border="y"] { cursor: row-resize }
|
|
4419
|
-
&[data-text-edit-resizing] { user-select: none }
|
|
4420
|
-
&[data-text-edit-resizing="x"] { cursor: col-resize }
|
|
4421
|
-
&[data-text-edit-resizing="y"] { cursor: row-resize }
|
|
4422
|
-
|
|
4423
|
-
/* Task lists — the checkbox replaces the marker */
|
|
4424
|
-
& :where(ul[data-checklist]) {
|
|
4425
|
-
padding-inline-start: 0.25em;
|
|
4426
|
-
list-style: none;
|
|
4427
|
-
|
|
4428
|
-
& li {
|
|
4429
|
-
display: flex;
|
|
4430
|
-
align-items: baseline;
|
|
4431
|
-
gap: 0.5em;
|
|
4432
|
-
list-style: none;
|
|
4433
|
-
}
|
|
4434
|
-
}
|
|
4435
|
-
|
|
4436
|
-
& :where(dt) {
|
|
4437
|
-
font-weight: 600;
|
|
4438
|
-
}
|
|
4439
|
-
|
|
4440
|
-
& :where(dd) {
|
|
4441
|
-
margin-inline-start: 1.5em;
|
|
4442
|
-
}
|
|
4443
|
-
|
|
4444
|
-
& :where(kbd) {
|
|
4445
|
-
padding: 0.1em 0.35em;
|
|
4446
|
-
border: 1px solid var(--color-line);
|
|
4447
|
-
border-radius: 4px;
|
|
4448
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
4449
|
-
font-size: 0.85em;
|
|
4450
|
-
}
|
|
4451
|
-
|
|
4452
|
-
& :where(mark) {
|
|
4453
|
-
background: color-mix(in oklch, var(--color-brand-content) 25%, transparent);
|
|
4454
|
-
color: inherit;
|
|
4455
|
-
}
|
|
4456
|
-
|
|
4457
|
-
& :where(small) {
|
|
4458
|
-
font-size: 0.8em;
|
|
4459
|
-
}
|
|
4460
|
-
|
|
4461
|
-
& :where(figcaption) {
|
|
4462
|
-
font-size: 0.8em;
|
|
4463
|
-
color: var(--color-content-neutral);
|
|
4464
|
-
}
|
|
4465
|
-
|
|
4466
|
-
& :where(abbr, dfn) {
|
|
4467
|
-
text-decoration: underline dotted;
|
|
4468
|
-
}
|
|
4469
|
-
}
|
|
4470
|
-
}
|
|
4471
|
-
|
|
4472
4407
|
/* ManifestToasts */
|
|
4473
4408
|
|
|
4474
4409
|
@layer base, components, utilities;
|