@seliseblocks/mailcraft 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCS.md +557 -0
- package/LICENSE +21 -0
- package/README.md +126 -0
- package/dist/mailcraft-editor.bundle.js +519 -0
- package/dist/mailcraft-editor.bundle.js.map +7 -0
- package/examples/templates/activate-your-account.html +54 -0
- package/examples/templates/back-in-stock.html +63 -0
- package/examples/templates/cart-left-behind.html +74 -0
- package/examples/templates/community-giveaway.html +81 -0
- package/examples/templates/frontend-futures-invite.html +69 -0
- package/examples/templates/give-25-get-25.html +69 -0
- package/examples/templates/invoice-paid.html +77 -0
- package/examples/templates/meet-nova-launch.html +69 -0
- package/examples/templates/mega-weekend-sale.html +57 -0
- package/examples/templates/order-confirmed.html +80 -0
- package/examples/templates/rate-your-headphones.html +71 -0
- package/examples/templates/reset-your-password.html +54 -0
- package/examples/templates/thankyou-promo-code.html +68 -0
- package/examples/templates/the-sunday-brief.html +47 -0
- package/examples/templates/welcome-to-your-workspace.html +62 -0
- package/examples/templates/your-order-shipped.html +74 -0
- package/examples/templates/your-password-was-changed.html +58 -0
- package/examples/templates/your-signin-code.html +58 -0
- package/examples/vanilla.html +1574 -0
- package/package.json +66 -0
- package/src/core/accent.js +194 -0
- package/src/core/assets.js +15 -0
- package/src/core/binder.js +119 -0
- package/src/core/blocks.js +256 -0
- package/src/core/css-cascade.js +117 -0
- package/src/core/editor-core.js +1492 -0
- package/src/core/export.js +58 -0
- package/src/core/footer.js +73 -0
- package/src/core/i18n/ar.js +177 -0
- package/src/core/i18n/bg.js +152 -0
- package/src/core/i18n/bn.js +176 -0
- package/src/core/i18n/ca.js +152 -0
- package/src/core/i18n/cs.js +152 -0
- package/src/core/i18n/da.js +152 -0
- package/src/core/i18n/de-CH.js +152 -0
- package/src/core/i18n/de.js +152 -0
- package/src/core/i18n/dz.js +179 -0
- package/src/core/i18n/el.js +152 -0
- package/src/core/i18n/en.js +269 -0
- package/src/core/i18n/es.js +152 -0
- package/src/core/i18n/et.js +152 -0
- package/src/core/i18n/fi.js +152 -0
- package/src/core/i18n/fr.js +152 -0
- package/src/core/i18n/hr.js +152 -0
- package/src/core/i18n/hu.js +152 -0
- package/src/core/i18n/index.js +83 -0
- package/src/core/i18n/it.js +152 -0
- package/src/core/i18n/lt.js +152 -0
- package/src/core/i18n/lv.js +152 -0
- package/src/core/i18n/nb.js +152 -0
- package/src/core/i18n/nl.js +152 -0
- package/src/core/i18n/pl.js +152 -0
- package/src/core/i18n/pt.js +152 -0
- package/src/core/i18n/ro.js +152 -0
- package/src/core/i18n/ru.js +152 -0
- package/src/core/i18n/sk.js +152 -0
- package/src/core/i18n/sl.js +152 -0
- package/src/core/i18n/sv.js +152 -0
- package/src/core/i18n/tables.js +50 -0
- package/src/core/i18n/tr.js +152 -0
- package/src/core/i18n/uk.js +152 -0
- package/src/core/icons.js +235 -0
- package/src/core/ids.js +1 -0
- package/src/core/import-html.js +959 -0
- package/src/core/layout-style.js +115 -0
- package/src/core/parse.js +10 -0
- package/src/core/placeholder.js +15 -0
- package/src/core/sanitize.js +141 -0
- package/src/core/storage-limits.js +184 -0
- package/src/core/storage.js +85 -0
- package/src/core/theme.js +1 -0
- package/src/core/toolbar.js +67 -0
- package/src/core/variables.js +11 -0
- package/src/create-editor.js +109 -0
- package/src/index.js +9 -0
- package/src/mailcraft-editor.js +1862 -0
- package/src/render/block-body.js +295 -0
- package/src/render/canvas.js +284 -0
- package/src/render/fields.js +609 -0
- package/src/render/focus-preserve.js +158 -0
- package/src/render/rte.js +212 -0
- package/src/render/screenshot.js +132 -0
- package/src/render/story.js +415 -0
- package/src/render/style.js +452 -0
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The editor's chrome stylesheet -- the only CSS that can't be expressed as
|
|
3
|
+
* an inline `style` attribute: the two chrome palettes (light/dark), the RTE's
|
|
4
|
+
* own token set, shared component classes (segmented controls, tooltips, the
|
|
5
|
+
* sheet-wrap/workspace framing), keyframes, and scrollbars. Selectors kept
|
|
6
|
+
* scoped to `#mc` / `#mc[data-chrome="dark"]` since the Shadow DOM gives them
|
|
7
|
+
* their own namespace. `#mc`'s own height is `100%` here instead of `100vh`,
|
|
8
|
+
* since a Web Component sizes to its host element, not the viewport.
|
|
9
|
+
*/
|
|
10
|
+
export const STYLE = `
|
|
11
|
+
@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap');
|
|
12
|
+
:host { display: block; height: 100%; }
|
|
13
|
+
#mc, #mc *, #mc *::before, #mc *::after { box-sizing: border-box; }
|
|
14
|
+
#mc {
|
|
15
|
+
--ed-font: 'Manrope', 'Segoe UI Variable', 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
|
16
|
+
--ed-bg: #f5f7fa; --ed-panel: #ffffff; --ed-panel-2: #f8fafc; --ed-work: #f1f4f8;
|
|
17
|
+
--ed-line: rgba(15,23,42,0.09); --ed-line-2: rgba(15,23,42,0.16);
|
|
18
|
+
--ed-text: #172033; --ed-muted: #667085; --ed-faint: #98a2b3;
|
|
19
|
+
--ed-panel-label: #344054; --ed-panel-value: #475467; --ed-panel-meta: #7b8799;
|
|
20
|
+
--ed-panel-label-size: 12px; --ed-panel-value-size: 11.5px; --ed-panel-meta-size: 9.5px;
|
|
21
|
+
--ed-accent: #0065b3; --ed-accent-strong: #00538f; --ed-accent-ink: #ffffff; --ed-soft: rgba(0,101,179,0.09);
|
|
22
|
+
--ed-accent-tint: #33a3e8; --ed-glow: rgba(0,101,179,0.28); --ed-select: rgba(0,101,179,0.22);
|
|
23
|
+
/* The accent as it must read on the email sheet, which is a white page in
|
|
24
|
+
both themes -- so this family does NOT flip with the chrome (see the dark
|
|
25
|
+
palette below, where it is deliberately not overridden). */
|
|
26
|
+
--ed-accent-sheet: #0065b3; --ed-accent-sheet-strong: #004f8c; --ed-accent-sheet-ink: #ffffff;
|
|
27
|
+
--ed-accent-sheet-line: rgba(0,101,179,0.5);
|
|
28
|
+
--ed-grid: rgba(71,85,105,0.10);
|
|
29
|
+
--ed-danger: #dc4c53; --ed-danger-soft: rgba(220,76,83,0.12);
|
|
30
|
+
--ed-success: #1a9f6b; --ed-success-soft: rgba(26,159,107,0.12);
|
|
31
|
+
--ed-radius: 10px; --ed-radius-sm: 6px;
|
|
32
|
+
--ed-shadow-sm: 0 1px 2px rgba(15,23,42,0.06);
|
|
33
|
+
--ed-shadow-md: 0 8px 24px rgba(15,23,42,0.12);
|
|
34
|
+
--ed-shadow-lg: 0 20px 48px rgba(15,23,42,0.16);
|
|
35
|
+
--rte-bg: #ffffff; --rte-panel: #f8fafc; --rte-input: #f1f5f9;
|
|
36
|
+
--rte-border: rgba(15,23,42,0.12); --rte-text: #172033; --rte-muted: #64748b;
|
|
37
|
+
--rte-shadow: 0 16px 42px rgba(15,23,42,0.18); --rte-tip-bg: #172033; --rte-tip-text: #ffffff;
|
|
38
|
+
}
|
|
39
|
+
#mc[data-chrome="dark"] {
|
|
40
|
+
--ed-bg: #0b1120; --ed-panel: #111827; --ed-panel-2: #182235; --ed-work: #0d1524;
|
|
41
|
+
--ed-line: rgba(226,232,240,0.10); --ed-line-2: rgba(226,232,240,0.18);
|
|
42
|
+
--ed-text: #f1f5f9; --ed-muted: #a8b3c4; --ed-faint: #718096;
|
|
43
|
+
--ed-panel-label: #e2e8f0; --ed-panel-value: #c0cad8; --ed-panel-meta: #8d9aae;
|
|
44
|
+
--ed-accent: #58a8e3; --ed-accent-strong: #8fc4ec; --ed-accent-ink: #08111f; --ed-soft: rgba(88,168,227,0.13);
|
|
45
|
+
--ed-accent-tint: #8fcdf2; --ed-glow: rgba(88,168,227,0.28); --ed-select: rgba(88,168,227,0.3);
|
|
46
|
+
--ed-grid: rgba(148,163,184,0.08);
|
|
47
|
+
--ed-danger: #f2777c; --ed-danger-soft: rgba(242,119,124,0.14);
|
|
48
|
+
--ed-success: #4ade95; --ed-success-soft: rgba(74,222,149,0.14);
|
|
49
|
+
--ed-shadow-sm: 0 1px 2px rgba(0,0,0,0.24);
|
|
50
|
+
--ed-shadow-md: 0 8px 24px rgba(0,0,0,0.34);
|
|
51
|
+
--ed-shadow-lg: 0 20px 48px rgba(0,0,0,0.46);
|
|
52
|
+
--rte-bg: #111827; --rte-panel: #182235; --rte-input: #1e293b;
|
|
53
|
+
--rte-border: rgba(226,232,240,0.14); --rte-text: #f8fafc; --rte-muted: #a8b3c4;
|
|
54
|
+
--rte-shadow: 0 18px 46px rgba(0,0,0,0.44); --rte-tip-bg: #e2e8f0; --rte-tip-text: #111827;
|
|
55
|
+
}
|
|
56
|
+
#mc button, #mc input, #mc select, #mc textarea { border-radius: 8px; }
|
|
57
|
+
#mc button { font-family: var(--ed-font); -webkit-tap-highlight-color: transparent; }
|
|
58
|
+
#mc button:not(:disabled) { transition-duration: 150ms !important; transition-timing-function: ease !important; }
|
|
59
|
+
#mc button:disabled { cursor: default !important; opacity: 0.45; }
|
|
60
|
+
#mc input, #mc select, #mc textarea { transition: border-color 150ms ease, background-color 150ms ease, box-shadow 150ms ease; }
|
|
61
|
+
/* Custom stepper buttons already cover increment/decrement -- the browser's
|
|
62
|
+
own spinner arrows are redundant chrome-on-chrome and look inconsistent
|
|
63
|
+
across browsers, so they're hidden everywhere a number input appears. */
|
|
64
|
+
#mc input[type="number"] { -moz-appearance: textfield; }
|
|
65
|
+
#mc input[type="number"]::-webkit-inner-spin-button,
|
|
66
|
+
#mc input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
|
|
67
|
+
/* Native <select> chrome (system font, OS-drawn arrow) doesn't match the rest
|
|
68
|
+
of the UI -- swap in a plain custom arrow and let everything else (font,
|
|
69
|
+
color, border, radius) keep flowing from the same inline styles as every
|
|
70
|
+
other field. */
|
|
71
|
+
/* !important is load-bearing here, not decorative: every select's inline
|
|
72
|
+
style sets background: var(--ed-panel-2) (a shorthand), and the CSS
|
|
73
|
+
background shorthand implicitly resets background-image to none even
|
|
74
|
+
when the declaration never mentions an image -- so without !important
|
|
75
|
+
the inline color wins and silently erases this chevron. */
|
|
76
|
+
#mc select {
|
|
77
|
+
appearance: none; -webkit-appearance: none; -moz-appearance: none;
|
|
78
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") !important;
|
|
79
|
+
background-repeat: no-repeat !important; background-position: right 7px center !important; background-size: 11px !important;
|
|
80
|
+
padding-right: 26px !important;
|
|
81
|
+
}
|
|
82
|
+
#mc[data-chrome="dark"] select {
|
|
83
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a8b3c4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") !important;
|
|
84
|
+
}
|
|
85
|
+
#mc input[type="color"] { border-radius: var(--ed-radius-sm); overflow: hidden; }
|
|
86
|
+
#mc input[type="color"]::-webkit-color-swatch { border: 0; }
|
|
87
|
+
#mc input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
|
|
88
|
+
#mc ::-webkit-scrollbar { width: 9px; height: 9px; }
|
|
89
|
+
#mc ::-webkit-scrollbar-thumb { background: var(--ed-line-2); border-radius: 999px; }
|
|
90
|
+
#mc ::-webkit-scrollbar-track { background: transparent; }
|
|
91
|
+
#mc :focus-visible { outline: 2px solid var(--ed-accent); outline-offset: 2px; }
|
|
92
|
+
#mc ::selection { background: var(--ed-select); }
|
|
93
|
+
#mc a { color: var(--ed-accent); }
|
|
94
|
+
#mc a:hover { color: var(--ed-accent); opacity: 0.72; }
|
|
95
|
+
@keyframes mcIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
|
|
96
|
+
@keyframes mcFade { from { opacity: 0; } to { opacity: 1; } }
|
|
97
|
+
@keyframes mcPulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }
|
|
98
|
+
@keyframes mcStoryShimmer { from { background-position: 140% 0; } to { background-position: -40% 0; } }
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
* Hover/selection outlines on canvas rows and blocks. Re-rendering on every
|
|
102
|
+
* mouseover to toggle these would rebuild the whole canvas on every pixel of
|
|
103
|
+
* mouse movement, which is what made drag/hover feel un-smooth -- these are
|
|
104
|
+
* real CSS instead, same visual result, zero JS.
|
|
105
|
+
*/
|
|
106
|
+
.mc-row-el { outline: 1px solid transparent; transition: outline-color 0.12s; }
|
|
107
|
+
.mc-row-el.is-selected { outline: 2px solid var(--ed-accent-sheet); }
|
|
108
|
+
.mc-row-el:not(.is-selected):hover { outline: 1px dashed var(--ed-faint); }
|
|
109
|
+
.mc-block-el { outline: 1px solid transparent; outline-offset: 1px; transition: outline-color 0.12s; }
|
|
110
|
+
.mc-block-el.is-selected { outline: 2px solid var(--ed-accent-sheet); }
|
|
111
|
+
.mc-block-el:not(.is-selected):hover { outline: 1px dashed var(--ed-accent-sheet); }
|
|
112
|
+
/*
|
|
113
|
+
* The grab strip runs the row's whole left edge (see render/canvas.js); the
|
|
114
|
+
* visible part is a round badge straddling the selection border. It takes
|
|
115
|
+
* --ed-accent-sheet, not --ed-accent, for the same reason as the canvas
|
|
116
|
+
* toolbars: the email sheet stays a light page in both chrome themes, so the
|
|
117
|
+
* accent here is the one fitted against white (core/accent.js).
|
|
118
|
+
*/
|
|
119
|
+
.mc-row-grip { display: none; }
|
|
120
|
+
.mc-row-el:hover .mc-row-grip, .mc-row-el.is-selected .mc-row-grip { display: flex; }
|
|
121
|
+
/* The badge's fill lives here, not inline on the element: an inline
|
|
122
|
+
background would outrank the hover rule below and the badge would never
|
|
123
|
+
light up under the cursor. */
|
|
124
|
+
.mc-row-grip-handle { background: var(--ed-accent-sheet); color: var(--ed-accent-sheet-ink); box-shadow: 0 2px 6px rgba(15,23,42,0.3); transition: background 0.14s ease; }
|
|
125
|
+
.mc-row-grip:hover .mc-row-grip-handle { background: var(--ed-accent-sheet-strong); }
|
|
126
|
+
/* The drag slider (render/fields.js isSlider). The track's filled/empty
|
|
127
|
+
split is painted inline as a gradient that follows the thumb; only the
|
|
128
|
+
chrome that CSS pseudo-elements own lives here. */
|
|
129
|
+
.mc-slider { -webkit-appearance: none; appearance: none; height: 4px; border-radius: 2px; background: var(--ed-line-2); outline: none; cursor: pointer; }
|
|
130
|
+
.mc-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 16px; height: 16px; border-radius: 50%; background: var(--ed-accent); border: 0; box-shadow: 0 1px 4px rgba(15,23,42,0.3); cursor: grab; }
|
|
131
|
+
.mc-slider::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: var(--ed-accent); border: 0; box-shadow: 0 1px 4px rgba(15,23,42,0.3); cursor: grab; }
|
|
132
|
+
.mc-slider:focus-visible { box-shadow: 0 0 0 3px var(--ed-soft); }
|
|
133
|
+
#mc .mc-slider-field { padding-bottom: 8px; }
|
|
134
|
+
/* A section bar that opens a tab sits flush under the tabbar's own
|
|
135
|
+
border-bottom -- its border-top would double that hairline. */
|
|
136
|
+
.mc-section-bar:first-child { border-top: 0; }
|
|
137
|
+
.mc-rte { overflow: visible; }
|
|
138
|
+
|
|
139
|
+
/* Attribution strip (mailcraft-editor.js buildFooter). Sits on the panel-2
|
|
140
|
+
surface with the panel's own hairline above it, so it reads as chrome
|
|
141
|
+
rather than as content; the link only takes the accent on hover, since a
|
|
142
|
+
permanently colored line would compete with the canvas. */
|
|
143
|
+
.mc-footer-link { cursor: pointer; transition: color 0.14s ease; }
|
|
144
|
+
.mc-footer-link:hover { color: var(--ed-accent); text-decoration: underline; }
|
|
145
|
+
|
|
146
|
+
/* Brand mark -- the small gradient envelope glyph in the header. */
|
|
147
|
+
.mc-brand-mark {
|
|
148
|
+
display: flex; align-items: center; justify-content: center; flex: none;
|
|
149
|
+
width: 26px; height: 26px; border-radius: 8px;
|
|
150
|
+
background: linear-gradient(145deg, var(--ed-accent-tint), var(--ed-accent) 55%, var(--ed-accent-strong));
|
|
151
|
+
box-shadow: 0 5px 14px var(--ed-glow);
|
|
152
|
+
color: #ffffff;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/*
|
|
156
|
+
* Shared segmented-control shell -- one bordered/backed track that owns the
|
|
157
|
+
* only visible border, with borderless children floating inside it. Avoids
|
|
158
|
+
* ever doubling a border: each button gets its own smaller inner radius, the
|
|
159
|
+
* wrapper's outer radius is larger, and the gap/padding reveal the track
|
|
160
|
+
* background between items instead of adjoining per-button borders.
|
|
161
|
+
*/
|
|
162
|
+
.mc-segment { display: flex; align-items: center; gap: 3px; padding: 3px; border: 1px solid var(--ed-line); border-radius: var(--ed-radius); background: var(--ed-panel); }
|
|
163
|
+
.mc-segment button { border: 0; border-radius: 7px; cursor: pointer; transition: background 0.16s, color 0.16s; }
|
|
164
|
+
.mc-segment button:hover:not(:disabled):not([aria-pressed="true"]) { background: var(--ed-soft) !important; color: var(--ed-accent) !important; }
|
|
165
|
+
.mc-segment button[aria-pressed="true"]:hover { background: var(--ed-accent-strong) !important; color: var(--ed-accent-ink) !important; }
|
|
166
|
+
.mc-segment button:disabled { cursor: default; opacity: 0.42; }
|
|
167
|
+
|
|
168
|
+
/*
|
|
169
|
+
* Shared CSS-only tooltip -- a small bubble shown on hover/focus-visible of
|
|
170
|
+
* the positioned parent that owns it, no JS involved in showing/hiding it.
|
|
171
|
+
* dir="down" (below the control, e.g. tabs/segments) or dir="up" (above,
|
|
172
|
+
* e.g. the RTE toolbar) controls which side it renders on.
|
|
173
|
+
*/
|
|
174
|
+
.mc-tooltip {
|
|
175
|
+
position: absolute; left: 50%; transform: translate(-50%, -2px); z-index: 100;
|
|
176
|
+
padding: 6px 8px; border-radius: 7px; background: var(--rte-tip-bg); color: var(--rte-tip-text);
|
|
177
|
+
font: 500 10.5px/1.2 var(--ed-font); white-space: nowrap;
|
|
178
|
+
opacity: 0; visibility: hidden; pointer-events: none;
|
|
179
|
+
box-shadow: 0 7px 20px rgba(15,23,42,0.22);
|
|
180
|
+
transition: opacity 0.12s ease, transform 0.12s ease, visibility 0s linear 0.12s;
|
|
181
|
+
}
|
|
182
|
+
.mc-tooltip-down { top: calc(100% + 7px); }
|
|
183
|
+
.mc-tooltip-down::before { content: ''; position: absolute; left: 50%; top: -4px; width: 8px; height: 8px; background: var(--rte-tip-bg); transform: translateX(-50%) rotate(45deg); }
|
|
184
|
+
.mc-tooltip-up { bottom: calc(100% + 7px); }
|
|
185
|
+
.mc-tooltip-up::before { content: ''; position: absolute; left: 50%; bottom: -4px; width: 8px; height: 8px; background: var(--rte-tip-bg); transform: translateX(-50%) rotate(45deg); }
|
|
186
|
+
[data-tip]:hover > .mc-tooltip, [data-tip]:focus-visible > .mc-tooltip {
|
|
187
|
+
opacity: 1; visibility: visible; transform: translate(-50%, 0); transition-delay: 0s;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@media (prefers-reduced-motion: reduce) {
|
|
191
|
+
#mc *, #mc *::before, #mc *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* Dotted-grid workspace background, shared by the canvas and the preview body. */
|
|
195
|
+
.mc-workspace, .mc-preview-body {
|
|
196
|
+
background-color: var(--ed-work);
|
|
197
|
+
background-image: radial-gradient(circle, var(--ed-grid) 1px, transparent 1.2px);
|
|
198
|
+
background-size: 22px 22px;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/*
|
|
202
|
+
* The email sheet gets exactly one visible frame. .mc-sheet-wrap is a pure
|
|
203
|
+
* positioning element (zero padding/border/background/box-shadow) whose only
|
|
204
|
+
* contribution is a drop-shadow filter that hugs the sheet's own silhouette
|
|
205
|
+
* rather than boxing it a second time; the sheet itself ([data-mc-sheet])
|
|
206
|
+
* carries the one real border/radius/shadow, scoped per context since the
|
|
207
|
+
* canvas and the preview modal want slightly different treatments.
|
|
208
|
+
*/
|
|
209
|
+
/* No 'filter' here: a filter on the wrap forces the browser to re-rasterize
|
|
210
|
+
the whole email document (and re-run the blur) on every repaint inside it --
|
|
211
|
+
selection, hover and typing all stutter on long templates. The sheet's own
|
|
212
|
+
box-shadow below provides the depth at per-element paint cost. */
|
|
213
|
+
.mc-sheet-wrap { padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
|
|
214
|
+
.mc-workspace [data-mc-sheet="1"] { border: 1px solid var(--ed-line); border-radius: 6px; box-shadow: 0 2px 5px rgba(15,23,42,0.05), 0 14px 38px rgba(15,23,42,0.10); }
|
|
215
|
+
#mc[data-chrome="dark"] .mc-workspace [data-mc-sheet="1"] { border-color: rgba(148,163,184,0.4); box-shadow: 0 0 0 1px rgba(15,23,42,0.4), 0 22px 58px rgba(0,0,0,0.36); }
|
|
216
|
+
.mc-preview-body [data-mc-sheet="1"] { border: 1px solid var(--ed-line-2); border-radius: 8px; box-shadow: 0 18px 50px rgba(15,23,42,0.13); }
|
|
217
|
+
#mc[data-chrome="dark"] .mc-preview-body [data-mc-sheet="1"] { border-color: rgba(148,163,184,0.4); box-shadow: 0 22px 58px rgba(0,0,0,0.4); }
|
|
218
|
+
|
|
219
|
+
/* Final component polish mirrored from the approved standalone editor. */
|
|
220
|
+
#mc { --ed-success: #20a779; --ed-danger: #e05766; }
|
|
221
|
+
#mc ::-webkit-scrollbar { width: 8px; height: 8px; }
|
|
222
|
+
#mc :focus-visible { outline: 3px solid var(--ed-soft); outline-offset: 1px; }
|
|
223
|
+
#mc button, #mc input, #mc textarea, #mc select { border-radius: 8px !important; }
|
|
224
|
+
#mc button { transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease, background .18s ease, color .18s ease, filter .18s ease !important; }
|
|
225
|
+
#mc button:not(:disabled):active { transform: translateY(1px); }
|
|
226
|
+
#mc button:disabled { opacity: .42; cursor: not-allowed !important; }
|
|
227
|
+
#mc input, #mc textarea, #mc select { box-shadow: inset 0 0 0 1px transparent; transition: border-color .18s ease, box-shadow .18s ease, background .18s ease !important; }
|
|
228
|
+
#mc input:focus, #mc textarea:focus, #mc select:focus { border-color: var(--ed-accent) !important; box-shadow: 0 0 0 3px var(--ed-soft); outline: none; }
|
|
229
|
+
/* The stepper's value input is a bare number inside the pill -- the generic
|
|
230
|
+
focus ring above drew a floating box around the digits mid-control; the
|
|
231
|
+
pill itself carries the focus treatment instead (render/fields.js). */
|
|
232
|
+
#mc .mc-stepper-input:focus { border-color: transparent !important; box-shadow: none; }
|
|
233
|
+
#mc [data-rte-control="1"] { position: relative; overflow: visible !important; border-radius: 5px !important; transition: background .14s ease, color .14s ease, transform .14s ease !important; }
|
|
234
|
+
#mc [data-rte-control="1"][data-active="false"]:hover { background: var(--ed-soft) !important; color: var(--ed-accent) !important; }
|
|
235
|
+
#mc [data-rte-control="1"]:active { transform: translateY(1px); }
|
|
236
|
+
#mc [data-rte-picker="1"] { transition: box-shadow .14s ease, background .14s ease; }
|
|
237
|
+
#mc [data-rte-picker="1"]:hover { box-shadow: inset 0 0 0 1px var(--ed-accent), 0 0 0 3px var(--ed-soft) !important; }
|
|
238
|
+
#mc .mc-rte-tooltip { position: absolute; left: 50%; bottom: calc(100% + 7px); transform: translate(-50%, 3px); z-index: 120; padding: 5px 7px; border-radius: 5px; background: var(--rte-tip-bg); color: var(--rte-tip-text); font: 500 10px/1.2 var(--ed-font); letter-spacing: 0; white-space: nowrap; opacity: 0; visibility: hidden; pointer-events: none; box-shadow: 0 7px 18px rgba(15,23,42,.20); transition: opacity .12s ease, transform .12s ease, visibility 0s linear .12s; }
|
|
239
|
+
#mc .mc-rte-tooltip::after { content: ''; position: absolute; left: 50%; bottom: -3px; width: 7px; height: 7px; background: var(--rte-tip-bg); transform: translateX(-50%) rotate(45deg); }
|
|
240
|
+
#mc [data-rte-control="1"]:hover .mc-rte-tooltip, #mc [data-rte-control="1"]:focus-visible .mc-rte-tooltip, #mc [data-rte-picker="1"]:hover .mc-rte-tooltip, #mc [data-rte-picker="1"]:focus-within .mc-rte-tooltip { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition-delay: 0s; }
|
|
241
|
+
#mc [data-rte-picker="1"], #mc [data-rte-select="1"] { border-radius: 5px !important; }
|
|
242
|
+
#mc [data-rte-root="1"] button, #mc [data-rte-root="1"] input, #mc [data-rte-root="1"] select { border-radius: 5px !important; }
|
|
243
|
+
#mc [data-rte-select="1"] select:hover, #mc [data-rte-select="1"]:focus-within select { border-color: var(--ed-accent) !important; box-shadow: 0 0 0 3px var(--ed-soft); }
|
|
244
|
+
#mc [data-rte-select="1"] select { background-image: none !important; padding-right: 24px !important; }
|
|
245
|
+
#mc .mc-shell { border-color: var(--ed-line) !important; border-radius: 14px; grid-template-rows: 62px 1fr !important; box-shadow: 0 1px 2px rgba(15,23,42,.04), 0 16px 44px rgba(15,23,42,.10) !important; }
|
|
246
|
+
|
|
247
|
+
/* The header row is pinned above with !important, so a shell built without a
|
|
248
|
+
header has to say so here too -- otherwise the canvas lands in a 62px track
|
|
249
|
+
and the editor renders into a sliver. */
|
|
250
|
+
#mc .mc-shell.mc-no-header { grid-template-rows: 1fr !important; }
|
|
251
|
+
/* Opaque, no backdrop-filter: the header sits over the scrolling canvas, so a
|
|
252
|
+
backdrop blur re-composites every scroll frame -- visible scroll jank. */
|
|
253
|
+
#mc .mc-header { padding: 0 18px !important; background: var(--ed-panel) !important; }
|
|
254
|
+
#mc .mc-brand-mark { width: 30px !important; height: 30px !important; border-radius: 9px; background: linear-gradient(145deg, var(--ed-accent-tint), var(--ed-accent) 56%, var(--ed-accent-strong)) !important; box-shadow: 0 7px 18px var(--ed-glow); }
|
|
255
|
+
#mc .mc-brand-mark svg { width: 20px; height: 20px; display: block; color: #fff; }
|
|
256
|
+
#mc .mc-brand-name { font-family: var(--ed-font) !important; font-size: 17px !important; letter-spacing: -.03em !important; }
|
|
257
|
+
#mc .mc-header button { font-family: var(--ed-font) !important; font-size: 10.5px !important; font-weight: 600; letter-spacing: .015em !important; text-transform: none !important; }
|
|
258
|
+
#mc .mc-header > div { border-radius: 10px; }
|
|
259
|
+
#mc .mc-segment { gap: 3px !important; padding: 3px !important; border: 0 !important; border-radius: 10px; background: var(--ed-panel-2) !important; }
|
|
260
|
+
#mc .mc-segment button { min-width: 62px; height: 26px; padding: 0 10px !important; border: 0 !important; border-radius: 7px !important; font-family: var(--ed-font) !important; font-size: 10px !important; font-weight: 600; letter-spacing: .01em !important; text-transform: none !important; }
|
|
261
|
+
#mc .mc-field-segment { width: 100%; box-shadow: none; }
|
|
262
|
+
#mc .mc-field-segment button { min-width: 0; flex: 1; height: 28px; }
|
|
263
|
+
#mc .mc-device-segment { position: relative; z-index: 40; overflow: visible !important; }
|
|
264
|
+
#mc .mc-device-segment button { position: relative; min-width: 38px; width: 38px; padding: 0 !important; display: flex; align-items: center; justify-content: center; overflow: visible !important; }
|
|
265
|
+
#mc .mc-device-segment button:hover, #mc .mc-device-segment button:focus-visible { z-index: 50; }
|
|
266
|
+
#mc .mc-device-segment button svg { width: 15px; height: 15px; display: block; }
|
|
267
|
+
#mc .mc-layout { grid-template-columns: minmax(0,1fr) 360px !important; }
|
|
268
|
+
#mc .mc-canvas-stage { padding: 28px 40px 150px !important; }
|
|
269
|
+
#mc .mc-workspace [data-mc-sheet="1"] { border: 1px solid rgba(15,23,42,.10); border-radius: 4px; background: #ffffff; box-shadow: 0 2px 5px rgba(15,23,42,.05), 0 14px 38px rgba(15,23,42,.10) !important; }
|
|
270
|
+
#mc[data-chrome="dark"] .mc-workspace [data-mc-sheet="1"] { border-color: rgba(148,163,184,.46); box-shadow: 0 0 0 1px rgba(15,23,42,.48), 0 22px 58px rgba(0,0,0,.38) !important; }
|
|
271
|
+
#mc .mc-preview-body [data-mc-sheet="1"] { border: 1px solid rgba(15,23,42,.12); border-radius: 10px; background: #ffffff; box-shadow: 0 18px 50px rgba(15,23,42,.13) !important; }
|
|
272
|
+
#mc[data-chrome="dark"] .mc-preview-body [data-mc-sheet="1"] { border-color: rgba(203,213,225,.42); box-shadow: 0 0 0 1px rgba(15,23,42,.65), 0 24px 65px rgba(0,0,0,.40) !important; }
|
|
273
|
+
#mc .mc-inspector { box-shadow: -10px 0 30px rgba(42,47,77,.04); color: var(--ed-panel-label); }
|
|
274
|
+
#mc .mc-tabbar { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); padding: 7px 8px 0; gap: 3px; border-bottom: 0 !important; background: var(--ed-panel) !important; overflow: visible; position: relative; z-index: 12; }
|
|
275
|
+
#mc .mc-tabbar button { position: relative; min-width: 0; height: 39px; border-radius: 8px 8px 0 0 !important; padding: 0 !important; display: flex; align-items: center; justify-content: center; font-family: var(--ed-font) !important; }
|
|
276
|
+
#mc .mc-tabbar button svg { width: 16px; height: 16px; display: block; }
|
|
277
|
+
#mc .mc-tab-surface { width: 100%; min-width: 0; background: var(--ed-panel); color: var(--ed-text); }
|
|
278
|
+
#mc .mc-inspector .mc-section-label {
|
|
279
|
+
font-size: 10px !important; line-height: 1.2 !important; font-weight: 700 !important;
|
|
280
|
+
letter-spacing: .07em !important; color: var(--ed-muted) !important;
|
|
281
|
+
}
|
|
282
|
+
#mc .mc-inspector .mc-section-body { padding: 12px 14px 16px !important; }
|
|
283
|
+
#mc .mc-inspector .mc-section-body > :first-child { margin-top: 0 !important; }
|
|
284
|
+
#mc .mc-field-list { display: grid; align-content: start; gap: 12px; }
|
|
285
|
+
#mc .mc-field-list .mc-field { min-width: 0; }
|
|
286
|
+
#mc .mc-field-list .mc-field-row {
|
|
287
|
+
display: grid !important; grid-template-columns: minmax(0, 1fr) 168px;
|
|
288
|
+
align-items: center; column-gap: 14px; min-height: 32px;
|
|
289
|
+
}
|
|
290
|
+
#mc .mc-field-list .mc-field-row > .mc-field-label { min-width: 0; }
|
|
291
|
+
#mc .mc-field-list .mc-field-row > .mc-field-control {
|
|
292
|
+
width: 100% !important; min-width: 0; box-sizing: border-box;
|
|
293
|
+
}
|
|
294
|
+
#mc .mc-field-list .mc-field-row > .mc-switch { justify-self: end; }
|
|
295
|
+
#mc .mc-field-list .mc-color-control .mc-stepper-input { width: auto !important; flex: 1; min-width: 0; }
|
|
296
|
+
#mc .mc-field-list .mc-field-label {
|
|
297
|
+
font-family: var(--ed-font) !important; font-size: var(--ed-panel-label-size) !important;
|
|
298
|
+
line-height: 1.4 !important; font-weight: 500 !important; color: var(--ed-panel-label) !important;
|
|
299
|
+
}
|
|
300
|
+
#mc .mc-field-list input:not([type="range"]):not([type="color"]),
|
|
301
|
+
#mc .mc-field-list textarea, #mc .mc-field-list select,
|
|
302
|
+
#mc .mc-field-list .mc-field-segment button {
|
|
303
|
+
font-size: var(--ed-panel-value-size) !important; line-height: 1.4 !important;
|
|
304
|
+
}
|
|
305
|
+
#mc .mc-field-list input:not([type="range"]):not([type="color"]),
|
|
306
|
+
#mc .mc-field-list textarea, #mc .mc-field-list select,
|
|
307
|
+
#mc .mc-field-list .mc-field-segment button[aria-pressed="false"] {
|
|
308
|
+
color: var(--ed-panel-value) !important;
|
|
309
|
+
}
|
|
310
|
+
#mc .mc-field-list .mc-stepper span {
|
|
311
|
+
font-size: var(--ed-panel-value-size) !important; color: var(--ed-panel-value) !important;
|
|
312
|
+
}
|
|
313
|
+
#mc .mc-field-list input:not([type="range"]):not([type="color"]):not(.mc-stepper-input),
|
|
314
|
+
#mc .mc-field-list select { min-height: 32px; }
|
|
315
|
+
#mc .mc-layer-tree { align-content: start; padding-top: 10px !important; }
|
|
316
|
+
#mc .mc-tree-section { min-width: 0; border-bottom: 1px solid var(--ed-line); padding-bottom: 13px !important; }
|
|
317
|
+
#mc .mc-tree-section.is-selected { box-shadow: none; }
|
|
318
|
+
#mc .mc-tree-section + .mc-tree-section { padding-top: 13px !important; }
|
|
319
|
+
#mc .mc-tree-section:last-child { border-bottom: 0; padding-bottom: 0 !important; }
|
|
320
|
+
#mc .mc-tree-section-node { min-height: 34px; padding: 5px 6px !important; }
|
|
321
|
+
#mc .mc-tree-column-node { min-height: 32px !important; padding-block: 4px !important; }
|
|
322
|
+
#mc .mc-tree-block-node { min-height: 32px; padding-block: 4px !important; }
|
|
323
|
+
#mc .mc-tree-children {
|
|
324
|
+
position: relative; display: grid; gap: 2px; margin-inline-start: 18px;
|
|
325
|
+
padding-inline-start: 18px;
|
|
326
|
+
}
|
|
327
|
+
#mc .mc-tree-columns { margin-top: 5px; }
|
|
328
|
+
#mc .mc-tree-blocks { margin-top: 2px; margin-bottom: 5px; }
|
|
329
|
+
#mc .mc-tree-branch, #mc .mc-tree-children > .mc-tree-node { position: relative; min-width: 0; }
|
|
330
|
+
#mc .mc-tree-branch::before, #mc .mc-tree-children > .mc-tree-node::before {
|
|
331
|
+
content: ''; position: absolute; inset-inline-start: -18px; top: 16px;
|
|
332
|
+
width: 17px; border-top: 1px solid var(--ed-line-2);
|
|
333
|
+
}
|
|
334
|
+
#mc .mc-tree-branch::after, #mc .mc-tree-children > .mc-tree-node::after {
|
|
335
|
+
content: ''; position: absolute; inset-inline-start: -18px; top: -3px; bottom: -3px;
|
|
336
|
+
border-inline-start: 1px solid var(--ed-line-2);
|
|
337
|
+
}
|
|
338
|
+
#mc .mc-tree-branch:last-child::after, #mc .mc-tree-children > .mc-tree-node:last-child::after {
|
|
339
|
+
bottom: auto; height: 19px;
|
|
340
|
+
}
|
|
341
|
+
#mc .mc-tree-node { isolation: isolate; }
|
|
342
|
+
#mc .mc-tree-block-node > span:nth-child(2) { min-width: 0; }
|
|
343
|
+
#mc .mc-layer-tree .mc-tree-title {
|
|
344
|
+
font-size: var(--ed-panel-label-size) !important; line-height: 1.35 !important;
|
|
345
|
+
font-weight: 500 !important; color: var(--ed-panel-label) !important;
|
|
346
|
+
}
|
|
347
|
+
#mc .mc-layer-tree .mc-tree-section-node .mc-tree-title { font-weight: 600 !important; }
|
|
348
|
+
#mc .mc-layer-tree .mc-tree-column-node .mc-tree-title {
|
|
349
|
+
font-size: var(--ed-panel-value-size) !important; color: var(--ed-panel-value) !important;
|
|
350
|
+
}
|
|
351
|
+
#mc .mc-layer-tree .mc-tree-count,
|
|
352
|
+
#mc .mc-layer-tree .mc-tree-type,
|
|
353
|
+
#mc .mc-layer-tree .mc-tree-index {
|
|
354
|
+
font-size: var(--ed-panel-meta-size) !important; line-height: 1.3 !important;
|
|
355
|
+
font-weight: 600 !important; color: var(--ed-panel-meta) !important;
|
|
356
|
+
}
|
|
357
|
+
#mc .mc-layer-tree .mc-tree-type { letter-spacing: .035em !important; }
|
|
358
|
+
#mc .mc-layer-tree .mc-tree-section.is-selected .mc-tree-index {
|
|
359
|
+
color: var(--ed-accent-ink) !important;
|
|
360
|
+
}
|
|
361
|
+
#mc .mc-tab-tooltip { position: absolute; top: calc(100% + 7px); left: 50%; transform: translate(-50%, -2px); z-index: 100; padding: 6px 8px; border-radius: 7px; background: #172033; color: #ffffff; font: 500 10.5px/1.2 var(--ed-font); letter-spacing: 0; text-transform: none; white-space: nowrap; opacity: 0; visibility: hidden; pointer-events: none; box-shadow: 0 7px 20px rgba(15,23,42,.22); transition: opacity .12s ease, transform .12s ease, visibility 0s linear .12s; }
|
|
362
|
+
#mc .mc-tab-tooltip::before { content: ''; position: absolute; left: 50%; top: -4px; width: 8px; height: 8px; background: #172033; transform: translateX(-50%) rotate(45deg); }
|
|
363
|
+
#mc [data-tip]:hover .mc-tab-tooltip, #mc [data-tip]:focus-visible .mc-tab-tooltip { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition-delay: 0s; }
|
|
364
|
+
#mc[data-chrome="dark"] .mc-tab-tooltip, #mc[data-chrome="dark"] .mc-tab-tooltip::before { background: #e2e8f0; color: #111827; }
|
|
365
|
+
/* End-aligned tooltip for controls hugging a right edge: hidden tooltips are
|
|
366
|
+
still laid out (visibility, not display), so a centered bubble poking past
|
|
367
|
+
the inspector's edge grew a horizontal scrollbar under the panel. */
|
|
368
|
+
#mc .mc-tooltip-end { left: auto; right: 0; transform: translate(0, -2px); }
|
|
369
|
+
#mc .mc-tooltip-end::before { left: auto; right: 11px; transform: rotate(45deg); }
|
|
370
|
+
#mc [data-tip]:hover > .mc-tooltip-end, #mc [data-tip]:focus-visible > .mc-tooltip-end { transform: translate(0, 0); }
|
|
371
|
+
/* No backdrop-filter: the dock floats over the scrolling canvas (every frame
|
|
372
|
+
would re-blur) and its background is opaque anyway, so the blur never shows. */
|
|
373
|
+
#mc .mc-zoom { border-color: var(--ed-line) !important; border-radius: 12px; box-shadow: 0 10px 30px rgba(36,41,70,.15) !important; }
|
|
374
|
+
#mc .mc-inspector [draggable="true"] { border-radius: 12px; overflow: hidden; }
|
|
375
|
+
#mc .mc-shortcuts { border: 0 !important; border-radius: 12px; padding: 14px !important; background: var(--ed-panel-2); box-shadow: inset 0 0 0 1px var(--ed-line); }
|
|
376
|
+
/* Dim only, no backdrop blur: blurring the whole editor behind a modal is the
|
|
377
|
+
single most expensive paint the chrome can ask for on weak GPUs. */
|
|
378
|
+
#mc .mc-modal-backdrop { background: rgba(14,16,27,.62) !important; }
|
|
379
|
+
#mc .mc-modal { border-color: var(--ed-line) !important; border-radius: 18px; overflow: hidden; box-shadow: 0 28px 80px rgba(10,13,28,.30) !important; }
|
|
380
|
+
#mc .mc-fullscreen-panel { border-radius: 14px; overflow: hidden; }
|
|
381
|
+
#mc .mc-modal button, #mc .mc-fullscreen-panel button { font-family: var(--ed-font) !important; font-size: 10.5px !important; font-weight: 600 !important; letter-spacing: .01em !important; text-transform: none !important; }
|
|
382
|
+
#mc .mc-icon-label { display: inline-flex !important; align-items: center; justify-content: center; gap: 6px; }
|
|
383
|
+
#mc .mc-icon-label svg, #mc .mc-icon-button svg { width: 14px; height: 14px; display: block; flex: none; }
|
|
384
|
+
#mc .mc-icon-button { display: inline-flex !important; align-items: center; justify-content: center; }
|
|
385
|
+
#mc .mc-code-panel { grid-template-rows: 58px minmax(0,1fr) auto !important; background: var(--ed-work) !important; }
|
|
386
|
+
#mc .mc-code-toolbar, #mc .mc-preview-toolbar { position: relative; z-index: 45; overflow: visible !important; padding: 0 16px !important; background: var(--ed-panel) !important; box-shadow: 0 1px 0 var(--ed-line); }
|
|
387
|
+
#mc .mc-code-badge { width: 32px; height: 32px; border-radius: 9px; display: flex !important; align-items: center; justify-content: center; color: var(--ed-accent); background: var(--ed-soft); }
|
|
388
|
+
#mc .mc-code-heading { font-family: var(--ed-font) !important; font-size: 14px !important; font-weight: 600 !important; letter-spacing: -.01em !important; }
|
|
389
|
+
#mc .mc-code-kicker, #mc .mc-preview-kicker { font-family: var(--ed-font) !important; font-size: 9.5px !important; font-weight: 500; letter-spacing: .025em !important; text-transform: none !important; }
|
|
390
|
+
#mc .mc-code-split { gap: 12px; padding: 12px; background: var(--ed-work); }
|
|
391
|
+
#mc .mc-code-source, #mc .mc-code-preview { border: 1px solid var(--ed-line) !important; border-radius: 12px; overflow: hidden; background: var(--ed-panel) !important; }
|
|
392
|
+
#mc .mc-pane-label { padding: 8px 13px !important; background: var(--ed-panel-2) !important; font-size: 9.5px !important; letter-spacing: .025em !important; text-transform: none !important; }
|
|
393
|
+
#mc .mc-code-preview-body { padding: 14px !important; background: var(--ed-work); }
|
|
394
|
+
#mc .mc-code-frame { border: 0 !important; border-radius: 9px; box-shadow: 0 5px 20px rgba(15,23,42,.10) !important; }
|
|
395
|
+
#mc .mc-code-footer { padding: 8px 16px !important; background: var(--ed-panel); font-family: var(--ed-font) !important; font-size: 9.5px !important; letter-spacing: 0 !important; }
|
|
396
|
+
#mc .mc-preview-panel { grid-template-rows: 58px minmax(0,1fr) !important; }
|
|
397
|
+
#mc .mc-preview-title { font-family: var(--ed-font); font-size: 12px !important; font-weight: 600; }
|
|
398
|
+
#mc .mc-preview-body { padding: 32px 24px !important; background-color: var(--ed-work); background-image: radial-gradient(circle, var(--ed-grid) 1px, transparent 1.2px); background-size: 22px 22px; }
|
|
399
|
+
#mc .mc-toast { border-radius: 10px; box-shadow: 0 12px 34px rgba(16,19,36,.28) !important; }
|
|
400
|
+
#mc[data-chrome="dark"] .mc-shell { box-shadow: 0 24px 70px rgba(0,0,0,.44) !important; }
|
|
401
|
+
#mc[data-chrome="dark"] .mc-header { background: rgba(25,28,41,.88) !important; }
|
|
402
|
+
@media (max-width: 1240px) { #mc .mc-layout { grid-template-columns: minmax(0,1fr) 330px !important; } }
|
|
403
|
+
|
|
404
|
+
/*
|
|
405
|
+
* Inspector switch -- the on/off control in the properties panel. Everything
|
|
406
|
+
* visual hangs off the button's own aria-checked, so there is no second
|
|
407
|
+
* source of truth for "is it on": a pill track that fills with the accent
|
|
408
|
+
* color, and a knob that slides (transform, not left, so the motion stays on
|
|
409
|
+
* the compositor). Lives at the very end of the sheet, after the polish
|
|
410
|
+
* block, because that block's blanket "#mc button ... border-radius: 8px
|
|
411
|
+
* !important" beats plain specificity -- hence the !important here too.
|
|
412
|
+
* (No backticks anywhere in this file's CSS: the whole stylesheet is one
|
|
413
|
+
* template literal, so a backtick inside it ends the string.)
|
|
414
|
+
*/
|
|
415
|
+
#mc .mc-switch {
|
|
416
|
+
position: relative; flex: none; width: 38px; height: 22px; padding: 0;
|
|
417
|
+
border: 0; border-radius: 999px !important; cursor: pointer;
|
|
418
|
+
background: var(--ed-line-2); box-shadow: inset 0 0 0 1px var(--ed-line);
|
|
419
|
+
}
|
|
420
|
+
#mc .mc-switch-knob {
|
|
421
|
+
position: absolute; top: 3px; left: 3px; width: 16px; height: 16px;
|
|
422
|
+
border-radius: 50%; background: #ffffff; pointer-events: none;
|
|
423
|
+
box-shadow: 0 1px 2px rgba(15,23,42,0.30), 0 2px 5px rgba(15,23,42,0.14);
|
|
424
|
+
transition: transform 0.18s cubic-bezier(0.22,0.61,0.36,1);
|
|
425
|
+
}
|
|
426
|
+
#mc .mc-switch[aria-checked="true"] { background: var(--ed-accent); box-shadow: inset 0 0 0 1px var(--ed-accent); }
|
|
427
|
+
#mc .mc-switch[aria-checked="true"] .mc-switch-knob { transform: translateX(16px); }
|
|
428
|
+
#mc .mc-switch-row:hover .mc-switch { background: color-mix(in srgb, var(--ed-faint) 52%, transparent); }
|
|
429
|
+
#mc .mc-switch-row:hover .mc-switch[aria-checked="true"] { background: var(--ed-accent-strong); box-shadow: inset 0 0 0 1px var(--ed-accent-strong); }
|
|
430
|
+
#mc .mc-switch-row:hover label { color: var(--ed-text); }
|
|
431
|
+
#mc[data-chrome="dark"] .mc-switch-knob { background: #e2e8f0; box-shadow: 0 1px 2px rgba(0,0,0,0.44), 0 2px 5px rgba(0,0,0,0.28); }
|
|
432
|
+
/*
|
|
433
|
+
* One-shot slide for the switch the user just clicked. A prop change rebuilds
|
|
434
|
+
* the panel, so the switch that comes back is a brand new node already in its
|
|
435
|
+
* final state -- nothing for a transition to interpolate. render/fields.js tags
|
|
436
|
+
* just that one node with .mc-switch-anim, and these keyframes replay the move
|
|
437
|
+
* from where the old node stood. Panels that merely open keep painting their
|
|
438
|
+
* switches in place, with no animation.
|
|
439
|
+
*/
|
|
440
|
+
#mc .mc-switch-anim[aria-checked="true"] { animation: mcSwitchOn 0.18s cubic-bezier(0.22,0.61,0.36,1); }
|
|
441
|
+
#mc .mc-switch-anim[aria-checked="false"] { animation: mcSwitchOff 0.18s cubic-bezier(0.22,0.61,0.36,1); }
|
|
442
|
+
#mc .mc-switch-anim[aria-checked="true"] .mc-switch-knob { animation: mcKnobOn 0.18s cubic-bezier(0.22,0.61,0.36,1); }
|
|
443
|
+
#mc .mc-switch-anim[aria-checked="false"] .mc-switch-knob { animation: mcKnobOff 0.18s cubic-bezier(0.22,0.61,0.36,1); }
|
|
444
|
+
@keyframes mcSwitchOn { from { background: var(--ed-line-2); } }
|
|
445
|
+
@keyframes mcSwitchOff { from { background: var(--ed-accent); } }
|
|
446
|
+
@keyframes mcKnobOn { from { transform: translateX(0); } }
|
|
447
|
+
@keyframes mcKnobOff { from { transform: translateX(16px); } }
|
|
448
|
+
|
|
449
|
+
/* The inspector inherits the active chrome palette. Keeping theme ownership
|
|
450
|
+
at #mc makes the header, menus, every panel and every field switch together
|
|
451
|
+
when light/dark changes, instead of leaving the side panel permanently dark. */
|
|
452
|
+
`;
|