PluginProbe
Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) / 2.0.3
Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) v2.0.3
2.1.3 2.1.2 2.1.1 2.1.0 2.0.4 2.0.3 2.0.2 2.0.1 2.0.0 1.5.5 1.5.4 1.5.3 1.5.2 1.5.1 1.5.0 trunk 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 All 57 releases
darkify / src / assets / css / client_main.css

client_main.css in Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) 2.0.3, at src/assets/css/client_main.css

756 lines 23.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*
2 * The colour rules below set `background-color`, never the `background`
3 * shorthand — and that distinction is load-bearing, not a style preference.
4 *
5 * `background` resets every background property it does not mention, so a rule
6 * of the form `background: <colour> !important` does not just repaint an
7 * element: it sets `background-image: none` on it. Everything a design paints
8 * through that property disappears — a select's dropdown chevron, an icon on a
9 * button, a sprite, a texture, a pattern, a gradient. And because the rule is
10 * `!important`, it outranks even an inline `background-image`, so nothing the
11 * engine writes inline can put the image back.
12 *
13 * The pairing was invisible while every rule also declared `background-color`
14 * on the next line with the same value: the shorthand contributed nothing to
15 * the colour and only did the damage. Dropping it changes no colour anywhere
16 * and lets the design's own imagery survive into dark mode.
17 */
18
19 .darkify_dark_mode_enabled
20 .darkify_style_all:not(
21 .darkify_switch,
22 .darkify_switch *,
23 .darkify_ignore,
24 .darkify_ignore *
25 ) {
26 background-color: var(--darkify_dark_mode_bg) !important;
27 color: var(--darkify_dark_mode_text_color) !important;
28 border-right-color: var(--darkify_dark_mode_border_color) !important;
29 border-left-color: var(--darkify_dark_mode_border_color) !important;
30 border-top-color: var(--darkify_dark_mode_border_color) !important;
31 border-bottom-color: var(--darkify_dark_mode_border_color) !important;
32 }
33 .darkify_dark_mode_enabled
34 .darkify_style_bg_txt:not(
35 .darkify_switch,
36 .darkify_switch *,
37 .darkify_ignore,
38 .darkify_ignore *
39 ) {
40 background-color: var(--darkify_dark_mode_bg) !important;
41 color: var(--darkify_dark_mode_text_color) !important;
42 }
43 .darkify_dark_mode_enabled
44 .darkify_style_bg_border:not(
45 .darkify_switch,
46 .darkify_switch *,
47 .darkify_ignore,
48 .darkify_ignore *
49 ) {
50 background-color: var(--darkify_dark_mode_bg) !important;
51 border-right-color: var(--darkify_dark_mode_border_color) !important;
52 border-left-color: var(--darkify_dark_mode_border_color) !important;
53 border-top-color: var(--darkify_dark_mode_border_color) !important;
54 border-bottom-color: var(--darkify_dark_mode_border_color) !important;
55 }
56 .darkify_dark_mode_enabled
57 .darkify_style_txt_border:not(
58 .darkify_switch,
59 .darkify_switch *,
60 .darkify_ignore,
61 .darkify_ignore *
62 ) {
63 color: var(--darkify_dark_mode_text_color) !important;
64 border-right-color: var(--darkify_dark_mode_border_color) !important;
65 border-left-color: var(--darkify_dark_mode_border_color) !important;
66 border-top-color: var(--darkify_dark_mode_border_color) !important;
67 border-bottom-color: var(--darkify_dark_mode_border_color) !important;
68 }
69 .darkify_dark_mode_enabled
70 .darkify_style_bg:not(
71 .darkify_switch,
72 .darkify_switch *,
73 .darkify_ignore,
74 .darkify_ignore *
75 ) {
76 background-color: var(--darkify_dark_mode_bg) !important;
77 }
78 .darkify_dark_mode_enabled
79 .darkify_style_txt:not(
80 .darkify_switch,
81 .darkify_switch *,
82 .darkify_ignore,
83 .darkify_ignore *
84 ) {
85 color: var(--darkify_dark_mode_text_color) !important;
86 }
87 .darkify_dark_mode_enabled
88 .darkify_style_border:not(
89 .darkify_switch,
90 .darkify_switch *,
91 .darkify_ignore,
92 .darkify_ignore *
93 ) {
94 border-right-color: var(--darkify_dark_mode_border_color) !important;
95 border-left-color: var(--darkify_dark_mode_border_color) !important;
96 border-top-color: var(--darkify_dark_mode_border_color) !important;
97 border-bottom-color: var(--darkify_dark_mode_border_color) !important;
98 }
99 .darkify_dark_mode_enabled
100 .darkify_style_secondary_bg:not(
101 .darkify_switch,
102 .darkify_switch *,
103 .darkify_ignore,
104 .darkify_ignore *
105 ) {
106 background-color: var(--darkify_dark_mode_secondary_bg) !important;
107 }
108
109 /*Handle Link Style*/
110 .darkify_dark_mode_enabled
111 .darkify_style_link:not(
112 .darkify_switch,
113 .darkify_switch *,
114 .darkify_ignore,
115 .darkify_ignore *,
116 .darkify-nav ul li a
117 ) {
118 color: var(--darkify_dark_mode_link_color) !important;
119 }
120 .darkify_dark_mode_enabled
121 .darkify_style_link:not(
122 .darkify_switch,
123 .darkify_switch *,
124 .darkify_ignore,
125 .darkify_ignore *
126 ):hover {
127 color: var(--darkify_dark_mode_link_hover_color) !important;
128 }
129
130 /*Handle Form Element Style*/
131 .darkify_dark_mode_enabled
132 .darkify_style_form_element:not(
133 .darkify_switch,
134 .darkify_switch *,
135 .darkify_ignore,
136 .darkify_ignore *
137 ) {
138 background-color: var(--darkify_dark_mode_input_bg) !important;
139 color: var(--darkify_dark_mode_input_text_color) !important;
140 }
141 .darkify_dark_mode_enabled
142 .darkify_style_form_element:not(
143 .darkify_switch,
144 .darkify_switch *,
145 .darkify_ignore,
146 .darkify_ignore *
147 )::placeholder {
148 color: var(--darkify_dark_mode_input_placeholder_color) !important;
149 }
150
151 /*Handle Button Style*/
152 .darkify_dark_mode_enabled
153 .darkify_style_button:not(
154 .darkify_switch,
155 .darkify_switch *,
156 .darkify_ignore,
157 .darkify_ignore *
158 ) {
159 background-color: var(--darkify_dark_mode_btn_bg) !important;
160 color: var(--darkify_dark_mode_btn_text_color) !important;
161 }
162 /* the hover state */
163 .darkify_dark_mode_enabled
164 .darkify_style_button:not(
165 .darkify_switch,
166 .darkify_switch *,
167 .darkify_ignore,
168 .darkify_ignore *
169 ):hover {
170 background-color: var(--darkify_dark_mode_btn_hover_bg) !important;
171 color: var(--darkify_dark_mode_btn_text_hover_color) !important;
172 }
173
174
175 /* ========================
176 Borders the design does not draw
177 ===========================*/
178 /*
179 * A side marked here had a width in the light design but no colour — the
180 * `border: 8px solid transparent` idiom themes and block grids use for gutters
181 * and alignment. It occupies space and paints nothing.
182 *
183 * The rules above cannot tell those sides apart from real ones: they set all
184 * four border colours at once, because a class cannot carry per-side
185 * information. Painting a gutter turns invisible spacing into a visible line,
186 * and an element ringed by four of them grows a box that the light design never
187 * had — the effect that made WooCommerce product cards appear boxed in dark
188 * mode while looking open in light.
189 *
190 * The classifier stamps these markers on exactly the sides it measured as
191 * transparent, so each one is pinned back to transparent regardless of which
192 * colour rule matched. They repeat the `:not(...)` shape of the rules they
193 * override so the specificity matches, and sit after them so they win the tie.
194 */
195 .darkify_dark_mode_enabled
196 .darkify_border_keep_top:not(
197 .darkify_switch,
198 .darkify_switch *,
199 .darkify_ignore,
200 .darkify_ignore *
201 ) {
202 border-top-color: transparent !important;
203 }
204 .darkify_dark_mode_enabled
205 .darkify_border_keep_right:not(
206 .darkify_switch,
207 .darkify_switch *,
208 .darkify_ignore,
209 .darkify_ignore *
210 ) {
211 border-right-color: transparent !important;
212 }
213 .darkify_dark_mode_enabled
214 .darkify_border_keep_bottom:not(
215 .darkify_switch,
216 .darkify_switch *,
217 .darkify_ignore,
218 .darkify_ignore *
219 ) {
220 border-bottom-color: transparent !important;
221 }
222 .darkify_dark_mode_enabled
223 .darkify_border_keep_left:not(
224 .darkify_switch,
225 .darkify_switch *,
226 .darkify_ignore,
227 .darkify_ignore *
228 ) {
229 border-left-color: transparent !important;
230 }
231
232 /* ========================
233 Pre-paint baseline (FOUC)
234 ===========================*/
235 /*
236 * Dark mode is decided in the <head>, but the colours come from a DOM walk that
237 * cannot start until the DOM exists. Something has to cover that gap.
238 *
239 * It cannot be a colour wash on the elements themselves. The engine derives
240 * each dark colour by *reading* the element's computed light colour, so any
241 * rule that restyles elements beforehand destroys its input — everything reads
242 * back as the wash and nothing can be derived.
243 *
244 * A `brightness()` filter on <html> used to fill the gap. It painted only, so
245 * `getComputedStyle` still reported the design's real colours, but it dimmed
246 * the *whole viewport* — on a slow page that reads as a grey overlay sitting
247 * over the site for the entire load, and it repeats on every navigation. The
248 * filter is gone for that reason.
249 *
250 * What is left is the page backdrop alone: the root paints the configured dark
251 * background from the first frame, so the gap before the walk is a dark page
252 * rather than a white one. Content that has already painted keeps its light
253 * colours for those few frames — a much smaller artefact than dimming the
254 * entire viewport.
255 *
256 * Deliberately temporary: the class comes off the moment the first walk has
257 * assigned real colours.
258 */
259 html.darkify_dark_mode_enabled.darkify_prepaint {
260 background-color: var(--darkify_dark_mode_bg) !important;
261 }
262
263 /* ========================
264 Admin Bar Menu Design
265 ===========================*/
266 .darkify_admin_bar_switch_container {
267 cursor: pointer !important;
268 display: flex;
269 align-items: center;
270 justify-content: center;
271 width: 40px !important;
272 height: 32px !important;
273 }
274 /* On Darkify's own settings/help screens the admin-bar node is always rendered
275 so the React admin can reveal it the instant "Admin Panel Dark Mode" is
276 switched on (see WpAdminBarBridge) rather than only after a reload. It starts
277 hidden whenever the option is off. */
278 .darkify_admin_bar_switch_container.darkify_admin_bar_hidden {
279 display: none !important;
280 }
281 .darkify_admin_bar_switch_container .ab-item {
282 height: 18px !important;
283 cursor: pointer !important;
284 background-color: #ffffff !important;
285 -webkit-mask: url(../../Admin/assets/images/switch_apple_light.svg) no-repeat center;
286 mask: url(../../Admin/assets/images/switch_apple_light.svg) no-repeat center;
287 }
288 .darkify_dark_mode_enabled .darkify_admin_bar_switch_container .ab-item {
289 -webkit-mask: url(../../Admin/assets/images/switch_apple_dark.svg) no-repeat center;
290 mask: url(../../Admin/assets/images/switch_apple_dark.svg) no-repeat center;
291 }
292
293 /* ========================
294 Block Editor Menu Design
295 ===========================*/
296 .darkify_block_editor_switch {
297 height: 33px;
298 cursor: pointer;
299 -webkit-appearance: none;
300 -moz-appearance: none;
301 outline: 0;
302 border: 0;
303 background: #121116;
304 border-radius: 3px;
305 padding: 0 12px;
306 margin-right: 8px;
307 }
308 .darkify_dark_mode_enabled .darkify_block_editor_switch {
309 background: #ffffff;
310 }
311 .darkify_block_editor_switch .icon {
312 width: 20px;
313 height: 20px;
314 background-color: #ffffff !important;
315 -webkit-mask: url(../../Admin/assets/images/switch_apple_light.svg) no-repeat center;
316 mask: url(../../Admin/assets/images/switch_apple_light.svg) no-repeat center;
317 }
318
319 .darkify_dark_mode_enabled .darkify_block_editor_switch .icon {
320 background-color: #171717 !important;
321 -webkit-mask: url(../../Admin/assets/images/switch_apple_dark.svg) no-repeat center;
322 mask: url(../../Admin/assets/images/switch_apple_dark.svg) no-repeat center;
323 }
324
325 /* ========================
326 Switch Design
327 ===========================*/
328
329 .darkify_switch,
330 .darkify_switch * {
331 box-sizing: border-box;
332 }
333 .darkify_switch.darkify_top_left,
334 .darkify_switch.darkify_top_right,
335 .darkify_switch.darkify_bottom_left,
336 .darkify_switch.darkify_bottom_right {
337 position: fixed;
338 z-index: 99999;
339 }
340 .darkify_switch.darkify_top_left {
341 top: var(--darkify_switch_position_from_top_left_top);
342 left: var(--darkify_switch_position_from_top_left_left);
343 }
344 .darkify_switch.darkify_top_right {
345 top: var(--darkify_switch_position_from_top_right_top);
346 right: var(--darkify_switch_position_from_top_right_right);
347 }
348 .darkify_switch.darkify_bottom_left {
349 bottom: var(--darkify_switch_position_from_bottom_left_bottom);
350 left: var(--darkify_switch_position_from_bottom_left_left);
351 }
352 .darkify_switch.darkify_bottom_right {
353 bottom: var(--darkify_switch_position_from_bottom_right_bottom);
354 right: var(--darkify_switch_position_from_bottom_right_right);
355 }
356 .darkify_switch.darkify_absolute_position {
357 position: absolute;
358 }
359
360 @media only screen and (max-width: 600px) {
361 .darkify_switch.darkify_hide_on_mobile {
362 display: none;
363 }
364 }
365
366 @media only screen and (max-width: 600px) {
367 .darkify_switch.darkify_top_left_in_mobile,
368 .darkify_switch.darkify_top_right_in_mobile,
369 .darkify_switch.darkify_bottom_left_in_mobile,
370 .darkify_switch.darkify_bottom_right_in_mobile {
371 position: fixed;
372 }
373 .darkify_switch.darkify_top_left_in_mobile {
374 top: var(--darkify_switch_position_from_top_left_top_in_mobile);
375 left: var(--darkify_switch_position_from_top_left_left_in_mobile);
376 bottom: unset;
377 right: unset;
378 }
379 .darkify_switch.darkify_top_right_in_mobile {
380 top: var(--darkify_switch_position_from_top_right_top_in_mobile);
381 right: var(--darkify_switch_position_from_top_right_right_in_mobile);
382 bottom: unset;
383 left: unset;
384 }
385 .darkify_switch.darkify_bottom_left_in_mobile {
386 bottom: var(--darkify_switch_position_from_bottom_left_bottom_in_mobile);
387 left: var(--darkify_switch_position_from_bottom_left_left_in_mobile);
388 top: unset;
389 right: unset;
390 }
391 .darkify_switch.darkify_bottom_right_in_mobile {
392 bottom: var(--darkify_switch_position_from_bottom_right_bottom_in_mobile);
393 right: var(--darkify_switch_position_from_bottom_right_right_in_mobile);
394 top: unset;
395 left: unset;
396 }
397 }
398
399 .darkify_tooltip .darkify_tooltiptext {
400 visibility: hidden;
401 width: 120px;
402 background-color: var(--darkify_switch_tooltip_bg_color);
403 color: var(--darkify_switch_tooltip_text_color);
404 font-size: 12px;
405 text-align: center;
406 border-radius: 0;
407 padding: 5px 5px;
408 position: absolute;
409 z-index: 1;
410 border-radius: 3px;
411 }
412 .darkify_tooltip .darkify_tooltiptext::after {
413 content: "";
414 position: absolute;
415 border-width: 5px;
416 border-style: solid;
417 }
418 .darkify_tooltip:hover .darkify_tooltiptext {
419 visibility: visible;
420 }
421 .darkify_tooltip.darkify_tooltip_top .darkify_tooltiptext {
422 bottom: calc(100% + 10px);
423 left: 50%;
424 margin-left: -60px;
425 }
426 .darkify_tooltip.darkify_tooltip_top .darkify_tooltiptext::after {
427 left: 50%;
428 margin-left: -5px;
429 top: 100%;
430 border-color: var(--darkify_switch_tooltip_bg_color) transparent transparent
431 transparent;
432 }
433 .darkify_tooltip.darkify_tooltip_bottom .darkify_tooltiptext {
434 top: calc(100% + 10px);
435 left: 50%;
436 margin-left: -60px;
437 }
438 .darkify_tooltip.darkify_tooltip_bottom .darkify_tooltiptext::after {
439 left: 50%;
440 margin-left: -5px;
441 bottom: 100%;
442 border-color: transparent transparent var(--darkify_switch_tooltip_bg_color)
443 transparent;
444 }
445 .darkify_tooltip.darkify_tooltip_left .darkify_tooltiptext {
446 right: calc(100% + 10px);
447 top: calc(50% - 15px);
448 }
449 .darkify_tooltip.darkify_tooltip_left .darkify_tooltiptext::after {
450 top: 50%;
451 left: 100%;
452 margin-top: -5px;
453 border-color: transparent transparent transparent
454 var(--darkify_switch_tooltip_bg_color);
455 }
456 .darkify_tooltip.darkify_tooltip_right .darkify_tooltiptext {
457 left: calc(100% + 10px);
458 top: calc(50% - 15px);
459 }
460 .darkify_tooltip.darkify_tooltip_right .darkify_tooltiptext::after {
461 top: 50%;
462 right: 100%;
463 margin-top: -5px;
464 border-color: transparent var(--darkify_switch_tooltip_bg_color) transparent
465 transparent;
466 }
467
468 /* ==============
469 Switch Style
470 ============== */
471
472 .darkify_switch_style {
473 cursor: pointer;
474 z-index: 9999;
475 width: calc(60px * var(--darkify-switch-scale, 1));
476 height: calc(60px * var(--darkify-switch-scale, 1));
477 border-radius: var(--darkify_switch_border_radius);
478 background: var(--darkify_switch_light_mode_bg);
479 display: flex;
480 align-items: center;
481 justify-content: center;
482 border-width: var(--darkify_switch_border);
483 border-style: solid;
484 border-color: var(--darkify_switch_border_light_color);
485 }
486
487 .darkify_dark_mode_enabled .darkify_switch_style {
488 border-color: var(--darkify_switch_border_dark_color);
489 }
490 .darkify_switch_style .theme-toggle {
491 display: flex;
492 align-items: center;
493 justify-content: center;
494 }
495 .darkify_switch_style svg {
496 width: calc(40px * var(--darkify-switch-scale, 1));
497 height: calc(40px * var(--darkify-switch-scale, 1));
498 color: var(--darkify_switch_light_mode_color);
499 stroke: var(--darkify_switch_light_mode_color);
500 }
501 .darkify_dark_mode_enabled .darkify_switch_style {
502 background: var(--darkify_switch_dark_mode_bg);
503 }
504 .darkify_dark_mode_enabled .darkify_switch_style svg {
505 color: var(--darkify_switch_dark_mode_color);
506 stroke: var(--darkify_switch_dark_mode_color);
507 }
508 .switch-orbit,
509 .switch-duality,
510 .switch-dual,
511 .switch-shift {
512 box-sizing: content-box;
513 }
514 .darkify_dark_mode_enabled
515 .block-editor-page.post-content-style-boxed
516 .editor-styles-wrapper:before {
517 background-color: unset;
518 }
519 .darkify_dark_mode_enabled h3#color-palette-1-0,
520 .darkify_dark_mode_enabled .components-color-palette__custom-color-name {
521 color: var(--darkify_dark_mode_text_color)!important;
522 }
523 .darkify-dropdown {
524 position: relative;
525 width: 160px;
526 margin-left: 8px;
527 }
528
529 .darkify-dropdown .darkify-selected {
530 padding: 5px;
531 background: #fff;
532 color: #000;
533 cursor: pointer;
534 border-radius: 3px;
535 border: 1px solid #c0c0c0;
536 }
537
538 .darkify-dropdown .darkify-options {
539 display: none;
540 position: absolute;
541 width: 100%;
542 background: #fff;
543 border-radius: 6px;
544 margin-top: 5px;
545 overflow: hidden;
546 z-index: 1000;
547 box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
548 color: #000;
549 top: 30px;
550 }
551
552 .darkify-dropdown .darkify-options.show {
553 display: block;
554 }
555
556 .darkify-dropdown .darkify-option {
557 padding: 8px;
558 cursor: pointer;
559 display: flex;
560 align-items: center;
561 gap: 4px;
562 }
563 .darkify-dropdown .darkify-pro-option {
564 cursor: not-allowed;
565 opacity: 0.55;
566 pointer-events: none;
567 gap: 4px;
568 }
569 .darkify-option-pro-badge {
570 margin-left: auto;
571 font-size: 10px;
572 font-weight: 600;
573 background: #cbd6df;
574 color: #5e6e7d;
575 padding: 2px 5px;
576 border-radius: 3px;
577 white-space: nowrap;
578 flex-shrink: 0;
579 }
580 .darkify-dropdown .darkify-selected {
581 display: flex;
582 align-items: center;
583 width: 100%;
584 gap: 4px;
585 }
586 .darkify-dropdown .theme_color {
587 display: inline-block;
588 width: 20px;
589 height: 20px;
590 border-radius: 50%;
591 border: 1px solid gray;
592 }
593 .darkify-dropdown .default {
594 background-color: #fff;
595 }
596 .darkify-dropdown .carbon_mist {
597 background-color: #171717;
598 }
599 .darkify-dropdown .midnight_reverie {
600 background-color: #4e478d;
601 }
602 .darkify-dropdown .verdant_depths {
603 background-color: #073d2f;
604 }
605 .darkify-dropdown .celestial_tide {
606 background-color: #144e78;
607 }
608 .darkify-dropdown .emberwood {
609 background-color: #372911;
610 }
611 .darkify-dropdown .glacier_drift {
612 background-color: #123d52;
613 }
614 .darkify-dropdown .indigo_veil {
615 background-color: #46598c;
616 }
617 .darkify-dropdown .duskmire {
618 background-color: #403953;
619 }
620 .darkify-dropdown .tidal_frost {
621 background-color: #286f8d;
622 }
623 .darkify-dropdown .blue_bastion {
624 background-color: #244892;
625 }
626 .darkify-dropdown .crimson_veil {
627 background-color: #440649;
628 }
629
630 .darkify_dark_mode_enabled .darkify-dropdown,
631 .darkify_dark_mode_enabled .darkify-options.show {
632 background-color: var(--darkify_dark_mode_bg) !important;
633 }
634
635 /* Switch Attention Effects */
636 @keyframes darkify_attention_pulse {
637 0%, 100% { transform: scale(1); }
638 50% { transform: scale(1.1); }
639 }
640 @keyframes darkify_attention_radiance {
641 0%, 100% { box-shadow: 0 0 0 0 rgba(100, 100, 100, 0.45); }
642 50% { box-shadow: 0 0 0 14px rgba(100, 100, 100, 0); }
643 }
644 @keyframes darkify_attention_leap {
645 0%, 55%, 100% { transform: translateY(0); }
646 30% { transform: translateY(-14px); }
647 45% { transform: translateY(-8px); }
648 }
649 @keyframes darkify_attention_swing {
650 0%, 100% { transform: rotate(0deg); transform-origin: center bottom; }
651 20% { transform: rotate(-9deg); transform-origin: center bottom; }
652 40% { transform: rotate(7deg); transform-origin: center bottom; }
653 60% { transform: rotate(-5deg); transform-origin: center bottom; }
654 80% { transform: rotate(3deg); transform-origin: center bottom; }
655 }
656 @keyframes darkify_attention_drift {
657 0%, 100% { transform: translateY(0); }
658 50% { transform: translateY(-8px); }
659 }
660 @keyframes darkify_attention_nudge {
661 0%, 65%, 100% { transform: translateX(0); }
662 10% { transform: translateX(-6px); }
663 20% { transform: translateX(6px); }
664 30% { transform: translateX(-4px); }
665 40% { transform: translateX(4px); }
666 50% { transform: translateX(-2px); }
667 57% { transform: translateX(2px); }
668 }
669 .darkify_switch.darkify_attention_pulse {
670 animation: darkify_attention_pulse 2s ease-in-out 2s infinite;
671 }
672 .darkify_switch.darkify_attention_radiance {
673 animation: darkify_attention_radiance 2s ease-in-out 2s infinite;
674 }
675 .darkify_switch.darkify_attention_leap {
676 animation: darkify_attention_leap 2.5s ease-in-out 2s infinite;
677 }
678 .darkify_switch.darkify_attention_swing {
679 animation: darkify_attention_swing 1.6s ease-in-out 2s infinite;
680 }
681 .darkify_switch.darkify_attention_drift {
682 animation: darkify_attention_drift 3s ease-in-out 2s infinite;
683 }
684 .darkify_switch.darkify_attention_nudge {
685 animation: darkify_attention_nudge 2.5s ease-in-out 2s infinite;
686 }
687 .darkify_switch.darkify_attention_pulse:hover,
688 .darkify_switch.darkify_attention_radiance:hover,
689 .darkify_switch.darkify_attention_leap:hover,
690 .darkify_switch.darkify_attention_swing:hover,
691 .darkify_switch.darkify_attention_drift:hover,
692 .darkify_switch.darkify_attention_nudge:hover {
693 animation-play-state: paused;
694 }
695 /*
696 * Transition suppression for the duration of an engine pass.
697 *
698 * The engine classifies an element from its computed colours, and a colour
699 * mid-transition computes to an interpolated value that belongs to neither the
700 * start nor the end state — so a pass that runs while the page is animating
701 * reads colours the design never actually paints. Suppressing transitions for
702 * the length of the pass makes every read a settled one.
703 *
704 * This replaces an inline `transition-property: none !important` that was
705 * written to, and then removed from, every element individually. Writing a
706 * style and then reading a computed style off the same element forces a
707 * synchronous style recalculation, so that pattern cost one full recalc per
708 * element; as one class on the root it costs one invalidation per pass.
709 *
710 * `!important` is warranted here and is the reason the declaration can stay a
711 * single rule: it has to beat inline transitions written by builders and
712 * animation libraries, which is precisely the case it exists to neutralise. It
713 * is present only while a pass is running — never in the page's resting state.
714 */
715 /*
716 * The switcher is deliberately outside this suppression, and leaving it in was
717 * a real bug: it silently removed the toggle's animation.
718 *
719 * The switcher is the one animated thing on the page that the engine does not
720 * manage — it never receives `darkify_processed`, its colours are never read to
721 * classify it, and its whole visual job is to animate between the two states.
722 * Suppressing transitions on it therefore protects nothing and costs the
723 * feature.
724 *
725 * The damage is not obvious from reading the rule, because the class is added
726 * and removed inside a single synchronous task, so it is never painted. What
727 * matters is that the pass calls `getComputedStyle` thousands of times while
728 * the class is on, and every one of those forces a style recalculation. A
729 * recalculation that sees `transition-property: none` *cancels the transitions
730 * already running* — and the switcher's transitions started moments earlier,
731 * when the state class flipped. Removing the class afterwards does not revive
732 * them; the values have already been committed to their end state. Measured on
733 * the stress page: 17 transitions created on `d`, `opacity` and `transform`,
734 * all with `currentTime` still 0, gone by the next frame — the toggle snapped
735 * instead of animating.
736 *
737 * `.darkify_ignore` is excluded for the same reason it is excluded from every
738 * other rule in this file: it marks a subtree the plugin has been told to keep
739 * its hands off, and cancelling its animations is exactly the interference the
740 * marker exists to prevent.
741 *
742 * This costs nothing. The exclusion is evaluated only while a pass is running,
743 * and it removes work rather than adding it — the excluded subtrees are the
744 * ones the engine was never going to read.
745 */
746 html.darkify_suspend_transitions,
747 html.darkify_suspend_transitions
748 *:not(
749 .darkify_switch,
750 .darkify_switch *,
751 .darkify_ignore,
752 .darkify_ignore *
753 ) {
754 transition-property: none !important;
755 }
756