Skip to main content

euv_ui/style/class/overlay/
fn.rs

1use super::*;
2
3class! {
4    pub c_euv_tooltip {
5        position: "relative";
6        display: "inline-flex";
7        align-items: "center";
8    }
9
10    pub c_euv_tooltip_bubble {
11        position: "absolute";
12        z-index: "100";
13        padding: format!("{} {}", var!(space-xs), var!(space-sm));
14        box-sizing: "border-box";
15        border: format!("1px solid {}", var!(border));
16        border-radius: "0px";
17        background: var!(accent);
18        color: var!(text-on-accent);
19        font-size: var!(font-xs);
20        font-weight: "500";
21        line-height: "1.3";
22        white-space: "nowrap";
23        opacity: "0";
24        visibility: "hidden";
25        pointer-events: "none";
26        transition: format!("opacity {} {}", var!(duration-fast), var!(ease-out));
27    }
28
29    pub c_euv_tooltip_bubble_top {
30        position: "absolute";
31        z-index: "100";
32        padding: format!("{} {}", var!(space-xs), var!(space-sm));
33        box-sizing: "border-box";
34        border: format!("1px solid {}", var!(border));
35        border-radius: "0px";
36        background: var!(accent);
37        color: var!(text-on-accent);
38        font-size: var!(font-xs);
39        font-weight: "500";
40        line-height: "1.3";
41        white-space: "nowrap";
42        opacity: "0";
43        visibility: "hidden";
44        pointer-events: "none";
45        bottom: "calc(100% + 8px)";
46        left: "50%";
47        transform: "translateX(-50%)";
48        transition: format!("opacity {} {}", var!(duration-fast), var!(ease-out));
49    }
50
51    pub c_euv_tooltip_bubble_bottom {
52        position: "absolute";
53        z-index: "100";
54        padding: format!("{} {}", var!(space-xs), var!(space-sm));
55        box-sizing: "border-box";
56        border: format!("1px solid {}", var!(border));
57        border-radius: "0px";
58        background: var!(accent);
59        color: var!(text-on-accent);
60        font-size: var!(font-xs);
61        font-weight: "500";
62        line-height: "1.3";
63        white-space: "nowrap";
64        opacity: "0";
65        visibility: "hidden";
66        pointer-events: "none";
67        top: "calc(100% + 8px)";
68        left: "50%";
69        transform: "translateX(-50%)";
70        transition: format!("opacity {} {}", var!(duration-fast), var!(ease-out));
71    }
72
73    pub c_euv_tooltip_bubble_left {
74        position: "absolute";
75        z-index: "100";
76        padding: format!("{} {}", var!(space-xs), var!(space-sm));
77        box-sizing: "border-box";
78        border: format!("1px solid {}", var!(border));
79        border-radius: "0px";
80        background: var!(accent);
81        color: var!(text-on-accent);
82        font-size: var!(font-xs);
83        font-weight: "500";
84        line-height: "1.3";
85        white-space: "nowrap";
86        opacity: "0";
87        visibility: "hidden";
88        pointer-events: "none";
89        top: "50%";
90        right: "calc(100% + 8px)";
91        transform: "translateY(-50%)";
92        transition: format!("opacity {} {}", var!(duration-fast), var!(ease-out));
93    }
94
95    pub c_euv_tooltip_bubble_right {
96        position: "absolute";
97        z-index: "100";
98        padding: format!("{} {}", var!(space-xs), var!(space-sm));
99        box-sizing: "border-box";
100        border: format!("1px solid {}", var!(border));
101        border-radius: "0px";
102        background: var!(accent);
103        color: var!(text-on-accent);
104        font-size: var!(font-xs);
105        font-weight: "500";
106        line-height: "1.3";
107        white-space: "nowrap";
108        opacity: "0";
109        visibility: "hidden";
110        pointer-events: "none";
111        top: "50%";
112        left: "calc(100% + 8px)";
113        transform: "translateY(-50%)";
114        transition: format!("opacity {} {}", var!(duration-fast), var!(ease-out));
115    }
116
117    pub c_euv_popover {
118        position: "relative";
119        display: "inline-flex";
120        align-items: "center";
121    }
122
123    pub c_euv_popover_body {
124        position: "absolute";
125        z-index: "100";
126        min-width: "200px";
127        box-sizing: "border-box";
128        border-radius: "0px";
129        background: var!(background);
130        color: var!(foreground);
131        font-size: var!(font-base);
132        transition: format!("opacity {} {}, visibility {} {}", var!(duration-overlay), var!(ease-out), var!(duration-overlay), var!(ease-out));
133    }
134
135    pub c_euv_popover_body_open {
136        position: "absolute";
137        z-index: "100";
138        min-width: "200px";
139        box-sizing: "border-box";
140        border: format!("1px solid {}", var!(border));
141        box-shadow: var!(shadow-sm);
142        border-radius: "0px";
143        background: var!(background);
144        color: var!(foreground);
145        font-size: var!(font-base);
146        opacity: "1";
147        visibility: "visible";
148        pointer-events: "auto";
149        transition: format!("opacity {} {}, visibility {} {}", var!(duration-overlay), var!(ease-out), var!(duration-overlay), var!(ease-out));
150    }
151
152    pub c_euv_popover_body_closed {
153        position: "absolute";
154        z-index: "100";
155        min-width: "200px";
156        box-sizing: "border-box";
157        border: format!("1px dashed {}", var!(border));
158        border-radius: "0px";
159        background: var!(background);
160        color: var!(foreground);
161        font-size: var!(font-base);
162        opacity: "0";
163        visibility: "hidden";
164        pointer-events: "none";
165        transition: format!("opacity {} {}, visibility {} {}", var!(duration-overlay), var!(ease-out), var!(duration-overlay), var!(ease-out));
166    }
167
168    pub c_euv_popover_header {
169        display: "flex";
170        align-items: "center";
171        justify-content: "space-between";
172        gap: var!(space-sm);
173        padding: format!("{} {}", var!(space-sm), var!(space-md));
174        border-bottom: format!("1px dashed {}", var!(border));
175    }
176
177    pub c_euv_popover_title {
178        font-size: var!(font-base);
179        font-weight: "600";
180        color: var!(foreground);
181        margin: "0px";
182    }
183
184    pub c_euv_calendar {
185        display: "flex";
186        flex-direction: "column";
187        gap: var!(space-md);
188        width: "100%";
189        box-sizing: "border-box";
190        padding: var!(space-md);
191        border: format!("1px solid {}", var!(border));
192        background: var!(background);
193    }
194
195    pub c_euv_calendar_header {
196        display: "flex";
197        align-items: "center";
198        justify-content: "space-between";
199        gap: var!(space-sm);
200    }
201
202    pub c_euv_calendar_title {
203        font-size: var!(font-base);
204        font-weight: "600";
205        color: var!(foreground);
206        margin: "0px";
207    }
208
209    pub c_euv_calendar_nav {
210        display: "flex";
211        align-items: "center";
212        gap: var!(space-xs);
213    }
214
215    pub c_euv_calendar_weekdays {
216        display: "grid";
217        grid-template-columns: "repeat(7, 1fr)";
218        gap: "0px";
219        width: "100%";
220    }
221
222    pub c_euv_calendar_weekday {
223        display: "flex";
224        align-items: "center";
225        justify-content: "center";
226        min-height: "24px";
227        font-size: var!(font-xs);
228        font-weight: "600";
229        color: var!(muted-foreground);
230        border-bottom: format!("1px dashed {}", var!(border));
231    }
232
233    pub c_euv_calendar_grid {
234        display: "grid";
235        grid-template-columns: "repeat(7, 1fr)";
236        gap: "0px";
237        width: "100%";
238    }
239
240    pub c_euv_calendar_day {
241        display: "flex";
242        align-items: "center";
243        justify-content: "center";
244        min-height: "36px";
245        box-sizing: "border-box";
246        font-size: var!(font-base);
247        font-weight: "500";
248        color: var!(foreground);
249        background: var!(background);
250        border: "1px solid transparent";
251        border-radius: "0px";
252        cursor: "pointer";
253        touch-action: "manipulation";
254        user-select: "none";
255        -webkit-user-select: "none";
256        :hover {
257            background: var!(accent-muted);
258            color: var!(accent);
259        }
260    }
261
262    pub c_euv_calendar_day_muted {
263        display: "flex";
264        align-items: "center";
265        justify-content: "center";
266        min-height: "36px";
267        box-sizing: "border-box";
268        font-size: var!(font-base);
269        font-weight: "400";
270        color: var!(muted-foreground);
271        background: var!(background);
272        border: "1px dashed transparent";
273        border-radius: "0px";
274        cursor: "pointer";
275        touch-action: "manipulation";
276        user-select: "none";
277        -webkit-user-select: "none";
278    }
279
280    pub c_euv_calendar_day_today {
281        display: "flex";
282        align-items: "center";
283        justify-content: "center";
284        min-height: "36px";
285        box-sizing: "border-box";
286        font-size: var!(font-base);
287        font-weight: "700";
288        color: var!(foreground);
289        background: var!(background);
290        border: format!("2px solid {}", var!(accent));
291        border-radius: "0px";
292        cursor: "pointer";
293        touch-action: "manipulation";
294        user-select: "none";
295        -webkit-user-select: "none";
296        :hover {
297            background: var!(accent-muted);
298            color: var!(accent);
299        }
300    }
301
302    pub c_euv_calendar_day_selected {
303        display: "flex";
304        align-items: "center";
305        justify-content: "center";
306        min-height: "36px";
307        box-sizing: "border-box";
308        font-size: var!(font-base);
309        font-weight: "600";
310        color: var!(text-on-accent);
311        background: var!(accent);
312        border: format!("2px solid {}", var!(accent));
313        border-radius: "0px";
314        cursor: "pointer";
315        touch-action: "manipulation";
316        user-select: "none";
317        -webkit-user-select: "none";
318    }
319
320    pub c_euv_upload {
321        display: "flex";
322        flex-direction: "column";
323        gap: var!(space-md);
324        width: "100%";
325    }
326
327    pub c_euv_upload_input {
328        position: "absolute";
329        width: "1px";
330        height: "1px";
331        opacity: "0";
332        pointer-events: "none";
333        margin: "0px";
334        padding: "0px";
335        border: "none";
336        outline: "none";
337    }
338
339    pub c_euv_upload_drop_active {
340        display: "flex";
341        flex-direction: "column";
342        align-items: "center";
343        justify-content: "center";
344        gap: var!(space-sm);
345        width: "100%";
346        min-height: var!(space-7xl);
347        box-sizing: "border-box";
348        padding: var!(space-2xl);
349        border: format!("2px solid {}", var!(accent));
350        background: var!(accent-muted);
351        color: var!(accent);
352        font-size: var!(font-base);
353        text-align: "center";
354        cursor: "pointer";
355        touch-action: "manipulation";
356        user-select: "none";
357        -webkit-user-select: "none";
358        @media ((max-width: 767px)) {
359            padding: var!(space-lg);
360        }
361    }
362
363    pub c_euv_upload_list {
364        display: "flex";
365        flex-direction: "column";
366        gap: var!(space-sm);
367        width: "100%";
368    }
369
370    pub c_euv_upload_file {
371        display: "flex";
372        align-items: "center";
373        justify-content: "space-between";
374        gap: var!(space-sm);
375        width: "100%";
376        min-height: var!(min-height-base);
377        box-sizing: "border-box";
378        padding: format!("{} {}", var!(space-sm), var!(space-md));
379        border: format!("1px dashed {}", var!(border));
380    }
381
382    pub c_euv_upload_file_name {
383        font-size: var!(font-sm);
384        font-weight: "500";
385        color: var!(foreground);
386        overflow: "hidden";
387        text-overflow: "ellipsis";
388        white-space: "nowrap";
389        min-width: "0px";
390    }
391
392    pub c_euv_upload_file_size {
393        font-size: var!(font-xs);
394        color: var!(muted-foreground);
395        font-family: "ui-monospace, monospace";
396        white-space: "nowrap";
397        flex-shrink: "0";
398    }
399
400    pub c_euv_upload_file_status_pending {
401        display: "flex";
402        align-items: "center";
403        gap: var!(space-xs);
404        font-size: var!(font-xs);
405        font-weight: "400";
406        color: var!(muted-foreground);
407        border: format!("1px dashed {}", var!(border));
408        padding: "0px";
409        white-space: "nowrap";
410        flex-shrink: "0";
411    }
412
413    pub c_euv_upload_file_status_uploading {
414        display: "flex";
415        align-items: "center";
416        gap: var!(space-xs);
417        font-size: var!(font-xs);
418        font-weight: "500";
419        color: var!(foreground);
420        border: format!("1px solid {}", var!(border));
421        padding: "0px";
422        white-space: "nowrap";
423        flex-shrink: "0";
424    }
425
426    pub c_euv_upload_file_status_done {
427        display: "flex";
428        align-items: "center";
429        gap: var!(space-xs);
430        font-size: var!(font-xs);
431        font-weight: "600";
432        color: var!(accent);
433        border: format!("2px solid {}", var!(accent));
434        padding: "0px";
435        white-space: "nowrap";
436        flex-shrink: "0";
437    }
438
439    pub c_euv_upload_file_status_failed {
440        display: "flex";
441        align-items: "center";
442        gap: var!(space-xs);
443        font-size: var!(font-xs);
444        font-weight: "700";
445        color: var!(muted-foreground);
446        border: format!("1px dashed {}", var!(foreground));
447        padding: "0px";
448        text-decoration: "line-through";
449        white-space: "nowrap";
450        flex-shrink: "0";
451    }
452
453    pub c_euv_feature_grid {
454        display: "grid";
455        grid-template-columns: "repeat(auto-fit, minmax(220px, 1fr))";
456        gap: var!(space-md);
457        width: "100%";
458        @media ((max-width: 767px)) {
459            grid-template-columns: "1fr";
460        }
461    }
462
463    pub c_euv_feature_card {
464        display: "flex";
465        flex-direction: "column";
466        gap: var!(space-sm);
467        padding: var!(space-lg);
468        overflow: "hidden";
469        box-sizing: "border-box";
470        border: format!("1px dashed {}", var!(border));
471    }
472
473    pub c_euv_feature_header {
474        display: "flex";
475        align-items: "center";
476        gap: var!(space-sm);
477    }
478
479    pub c_euv_feature_icon {
480        display: "flex";
481        align-items: "center";
482        justify-content: "center";
483        font-size: var!(font-2xl);
484        line-height: "1";
485        color: var!(foreground);
486        flex-shrink: "0";
487    }
488
489    pub c_euv_feature_name {
490        font-size: var!(font-lg);
491        font-weight: "600";
492        color: var!(foreground);
493        margin: "0px";
494        overflow: "hidden";
495        text-overflow: "ellipsis";
496        white-space: "nowrap";
497    }
498
499    pub c_euv_feature_desc {
500        font-size: var!(font-sm);
501        color: var!(foreground);
502        margin: "0px";
503    }
504
505    // ═══════════════════════════════════════════════════════════════════════════
506    // Modal
507    // ═══════════════════════════════════════════════════════════════════════════
508
509    pub c_modal_overlay {
510        position: "fixed";
511        top: "0px";
512        left: "0px";
513        width: "100%";
514        height: "100%";
515        background: var!(bg-overlay);
516        contain: "layout style paint";
517        display: "flex";
518        align-items: "center";
519        justify-content: "center";
520        z-index: "1000";
521        animation: format!("euv-fade-in {} {}", var!(duration-modal-overlay), var!(ease-out));
522        @media ((max-width: 767px)) {
523            align-items: "center";
524            justify-content: "center";
525        }
526    }
527
528    pub c_modal_content {
529        background: var!(background);
530        padding: "0px";
531        max-width: "480px";
532        width: "90%";
533        animation: format!("euv-scale-in-modal {} {}", var!(duration-modal-content), var!(ease-bounce));
534        overflow: "hidden";
535        color: var!(foreground);
536        box-sizing: "border-box";
537        @media ((max-width: 767px)) {
538            max-width: "100%";
539            width: "calc(100% - 32px)";
540            // Percentage of the fixed overlay (which is already the full
541            // window), so the sheet is capped by the screen it sits on
542            // rather than by a viewport unit that ignores the safe-area
543            // insets the overlay does not account for.
544            max-height: "85%";
545            overflow-y: "auto";
546        }
547    }
548
549    pub c_modal_header {
550        display: "flex";
551        justify-content: "space-between";
552        align-items: "center";
553        padding: format!("{} {} 0px {}", var!(space-md), var!(space-xl), var!(space-xl));
554    }
555
556    pub c_modal_title {
557        margin: "0px";
558        font-size: var!(font-xl);
559        font-weight: "600";
560        color: "inherit";
561    }
562
563    pub c_modal_body {
564        padding: format!("0px {} {} {}", var!(space-xl), var!(space-md), var!(space-xl));
565        color: "inherit";
566    }
567
568    pub c_modal_actions {
569        display: "flex";
570        flex-wrap: "wrap";
571        gap: var!(space-md);
572        margin: format!("{} 0px", var!(space-md));
573    }
574
575    // ═══════════════════════════════════════════════════════════════════════════
576    // VConsole Panel
577    // ═══════════════════════════════════════════════════════════════════════════
578
579    pub c_vconsole_badge {
580        position: "absolute";
581        top: "-6px";
582        right: "-8px";
583        min-width: "18px";
584        height: "18px";
585        background: var!(background);
586        color: var!(foreground);
587        font-size: "10px";
588        font-weight: "600";
589        display: "flex";
590        align-items: "center";
591        justify-content: "center";
592        padding: format!("0px {}", var!(space-xs));
593        border: format!("1px solid {}", var!(accent));
594        pointer-events: "none";
595        transition: format!("transform {} {}, opacity {} {}", var!(duration-normal), var!(ease-out), var!(duration-normal), var!(ease-out));
596    }
597
598    pub c_vconsole_overlay {
599        position: "fixed";
600        top: "0px";
601        left: "0px";
602        right: "0px";
603        bottom: "0px";
604        z-index: "10000";
605        background: var!(bg-overlay);
606        contain: "layout style paint";
607        transition: format!("opacity {} {}", var!(duration-overlay), var!(ease-out));
608    }
609
610    pub c_vconsole_overlay_hidden {
611        opacity: "0";
612        pointer-events: "none";
613    }
614
615    pub c_vconsole_panel {
616        position: "fixed";
617        bottom: "0px";
618        left: "0px";
619        right: "0px";
620        // A fixed element with `bottom` anchored resolves percentage heights
621        // against the initial containing block, so `76%` and `76vh` measure
622        // the same box here — the percentage form is used to keep viewport
623        // units out of the codebase. The safe-area inset is still subtracted
624        // so the panel clears a home indicator.
625        height: format!("calc(76% - {})", var!(safe-area-inset-bottom));
626        background: var!(background);
627        z-index: "10001";
628        display: "flex";
629        flex-direction: "column";
630        contain: "layout style paint";
631        will-change: "transform";
632        transition: format!("transform {} {}", var!(duration-overlay), var!(ease-out));
633        overflow: "hidden";
634        padding: format!("{} {}", var!(padding-main-top), var!(edge-gutter));
635        @media ((max-width: 767px)) {
636            padding: format!("{} {}", var!(space-md), var!(edge-gutter-mobile));
637        }
638    }
639
640    pub c_vconsole_panel_closed {
641        transform: "translateY(100%)";
642        will-change: "auto";
643    }
644
645    pub c_vconsole_fab {
646        position: "fixed";
647        bottom: format!("calc({} + {})", var!(edge-gutter-bottom), var!(safe-area-inset-bottom));
648        right: var!(edge-gutter);
649        z-index: "9999";
650        @media ((max-width: 767px)) {
651            bottom: format!("calc({} + {})", var!(edge-gutter-mobile), var!(safe-area-inset-bottom));
652            right: var!(edge-gutter-mobile);
653        }
654    }
655
656    pub c_vconsole_header {
657        display: "flex";
658        justify-content: "space-between";
659        align-items: "center";
660        flex-shrink: "0";
661    }
662
663    pub c_vconsole_title {
664        color: var!(foreground);
665        font-size: var!(font-md);
666        font-weight: "600";
667        margin: "0px";
668        letter-spacing: "0.03em";
669        display: "flex";
670        align-items: "center";
671        gap: var!(space-sm);
672    }
673
674    pub c_vconsole_title_dot {
675        width: "8px";
676        height: "8px";
677        background: var!(accent);
678        display: "inline-block";
679        animation: "euv-pulse 2s ease-in-out infinite";
680    }
681
682    pub c_vconsole_header_actions {
683        display: "flex";
684        gap: var!(space-sm);
685        align-items: "center";
686    }
687
688    pub c_vconsole_clear_button {
689        display: "inline-flex";
690        justify-content: "center";
691        align-items: "center";
692        color: var!(foreground);
693        padding: format!("{} {}", var!(space-2xs), var!(space-sm));
694        font-size: var!(font-xs);
695        font-weight: "600";
696        cursor: "pointer";
697        text-align: "center";
698        border: format!("1.5px solid {}", var!(border));
699        margin-left: "auto";
700        :focus-visible {
701            outline: "none";
702        }
703    }
704
705    pub c_vconsole_close_button {
706        display: "inline-flex";
707        justify-content: "center";
708        align-items: "center";
709        color: var!(foreground);
710        padding: format!("{} {}", var!(space-xs), var!(space-md));
711        cursor: "pointer";
712        font-size: var!(font-sm);
713        font-weight: "400";
714        text-align: "center";
715        white-space: "nowrap";
716        user-select: "none";
717        -webkit-user-select: "none";
718        vertical-align: "middle";
719        outline: "none";
720        transition: format!("all {} {}", var!(duration-fast), var!(ease-out));
721        :hover {
722            border-color: var!(foreground);
723            color: var!(foreground);
724            background: var!(background);
725        }
726        :focus-visible {
727            outline: "none";
728        }
729        :active {
730            background: "transparent";
731            color: var!(foreground);
732            border-color: var!(border);
733        }
734    }
735
736    pub c_vconsole_body {
737        flex: "1";
738        overflow-y: "auto";
739        contain: "content";
740        padding-bottom: var!(space-md);
741        font-family: "ui-monospace, monospace";
742        font-size: var!(font-xs);
743    }
744
745    pub c_vconsole_log_item {
746        display: "flex";
747        align-items: "center";
748        padding: format!("{} 0px", var!(space-sm));
749        border-bottom: format!("1px dashed {}", var!(border));
750        color: var!(foreground);
751        font-size: var!(font-xs);
752        word-break: "break-all";
753    }
754
755    pub c_vconsole_empty {
756        color: var!(muted-foreground);
757        font-size: var!(font-xs);
758        text-align: "center";
759        padding: format!("{} 0px", var!(space-4xl));
760        overflow: "hidden";
761    }
762
763    pub c_vconsole_empty_hidden {
764        height: "0";
765        overflow: "hidden";
766        padding: "0";
767    }
768
769    pub c_vconsole_log_list {
770        overflow: "hidden";
771    }
772
773    pub c_vconsole_log_list_hidden {
774        height: "0";
775        overflow: "hidden";
776    }
777
778    pub c_vconsole_count {
779        color: var!(muted-foreground);
780        font-size: var!(font-sm);
781        font-weight: "400";
782    }
783
784    pub c_vconsole_filter_bar {
785        display: "flex";
786        gap: var!(space-sm);
787        padding: format!("{} 0px", var!(space-sm));
788        border-bottom: format!("1px dashed {}", var!(border));
789        flex-shrink: "0";
790        align-items: "center";
791    }
792
793    pub c_vconsole_filter_badge {
794        display: "inline-flex";
795        justify-content: "center";
796        align-items: "center";
797        color: var!(text-on-accent);
798        padding: format!("{} {}", var!(space-2xs), var!(space-sm));
799        border: format!("1px solid {}", var!(accent));
800        font-size: var!(font-xs);
801        font-weight: "600";
802        cursor: "pointer";
803        text-align: "center";
804        background: var!(accent);
805        :focus-visible {
806            outline: "none";
807        }
808    }
809
810    pub c_vconsole_filter_badge_outline {
811        display: "inline-flex";
812        justify-content: "center";
813        align-items: "center";
814        color: var!(foreground);
815        padding: format!("{} {}", var!(space-2xs), var!(space-sm));
816        font-size: var!(font-xs);
817        font-weight: "600";
818        cursor: "pointer";
819        text-align: "center";
820        border: format!("1.5px solid {}", var!(border));
821    }
822
823    pub c_vconsole_level_badge {
824        padding: format!("{} {}", var!(space-2xs), var!(space-sm));
825        font-size: var!(font-xs);
826        margin-right: var!(space-sm);
827        letter-spacing: "0.05em";
828        color: var!(foreground);
829        border: "1px solid currentColor";
830        wrap: "nowrap";
831        flex-shrink: "0";
832    }
833
834    // ═══════════════════════════════════════════════════════════════════════════
835    // euv_dropdown
836    // ═══════════════════════════════════════════════════════════════════════════
837
838    pub c_euv_dropdown {
839        position: "relative";
840    }
841
842    pub c_euv_dropdown_menu {
843        position: "absolute";
844        top: "44px";
845        right: "0px";
846    /* `width: 100%` instead of `min-width: 140px` so the menu
847                                                                                                                                                           matches the dropdown container (and therefore the
848                                                                                                                                                           trigger button) width exactly. With only `min-width`,
849                                                                                                                                                           a trigger wider than 140px (e.g. the 206px-wide
850                                                                                                                                                           nav-column locale switcher button) leaves a large
851                                                                                                                                                           empty gap on the left of the menu, since `right: 0`
852                                                                                                                                                           anchors only the right edge to the container. With
853                                                                                                                                                           `width: 100%`, the menu's left edge lines up with the
854                                                                                                                                                           trigger's left edge. The default minimum content width
855                                                                                                                                                           is still guaranteed by the inner items' own padding,
856                                                                                                                                                           so we keep the rule without an explicit min. */
857        width: "100%";
858        background: var!(background);
859        border: format!("1px solid {}", var!(border));
860        box-shadow: var!(shadow-accent-lg);
861        flex-direction: "column";
862        z-index: "101";
863    }
864
865    pub c_euv_dropdown_menu_open {
866        display: "flex";
867    }
868
869    pub c_euv_dropdown_menu_closed {
870        display: "none";
871    }
872
873    pub c_euv_dropdown_item {
874        padding: format!("{} {}", var!(space-sm), var!(space-lg));
875        font-size: var!(font-sm);
876        text-align: "left";
877        cursor: "pointer";
878        // Hover mirrors the sidebar's affordance (see `c_euv_sidebar_link`):
879        // an inset 3px bar painted inside the padding box, which never
880        // participates in layout and therefore never shifts the label. A
881        // translucent wash is deliberately NOT used — `accent-muted` resolves
882        // to the same value as `background` in the monochrome palette
883        // (white on light, black on dark), so a background there is
884        // invisible. `color-mix` derives the wash from the actual text colour
885        // so it reads in both themes.
886        :hover {
887            background: format!("color-mix(in srgb, {} 8%, transparent)", var!(foreground));
888            box-shadow: format!("inset 3px 0 0 0 {}", var!(foreground));
889        }
890    }
891
892    pub c_euv_dropdown_item_active {
893        padding: format!("{} {}", var!(space-sm), var!(space-lg));
894        font-size: var!(font-sm);
895        text-align: "left";
896        cursor: "pointer";
897        font-weight: "600";
898        // The selected item wears the accent fill and the text colour that
899        // reads on top of it, the same pairing the sidebar's `_active` link
900        // uses. The inset bar is dropped: the full-width fill already carries
901        // the current-page signal, and a bar in the same monochrome accent
902        // would be invisible against it.
903        background: var!(accent);
904        color: var!(text-on-accent);
905        :hover {
906            background: var!(accent);
907            color: var!(text-on-accent);
908            box-shadow: "none";
909        }
910    }
911
912    // ═══════════════════════════════════════════════════════════════════════════
913    // File Upload
914    // ═══════════════════════════════════════════════════════════════════════════
915
916    pub c_file_upload_input_hidden {
917        position: "absolute";
918        width: "1px";
919        height: "1px";
920        padding: "0px";
921        margin: "-1px";
922        overflow: "hidden";
923        clip: "rect(0, 0, 0, 0)";
924        white-space: "nowrap";
925        border: "0px";
926    }
927
928    pub c_file_upload_options {
929        margin: format!("{} 0px", var!(gap-component));
930    }
931
932    pub c_file_upload_item {
933        display: "flex";
934        align-items: "center";
935        gap: format!("{}", var!(space-md));
936        margin: format!("{} 0px", var!(space-sm));
937        font-size: var!(font-base);
938        color: "inherit";
939    }
940
941    pub c_file_upload_item_index {
942        font-size: var!(font-sm);
943        font-weight: "600";
944        color: var!(accent);
945        min-width: "24px";
946    }
947
948    pub c_file_upload_item_name {
949        color: "inherit";
950        word-break: "break-all";
951    }
952
953    // ═══════════════════════════════════════════════════════════════════════════
954    // euv_drawer
955    // ═══════════════════════════════════════════════════════════════════════════
956
957    pub c_euv_drawer_overlay {
958        position: "fixed";
959        top: "0px";
960        left: "0px";
961        right: "0px";
962        bottom: "0px";
963        background: var!(bg-overlay);
964        z-index: "200";
965        transition: format!("opacity {} {}, visibility {} {}", var!(duration-overlay), var!(ease-out), var!(duration-overlay), var!(ease-out));
966    }
967
968    pub c_euv_drawer_overlay_open {
969        opacity: "1";
970        visibility: "visible";
971    }
972
973    pub c_euv_drawer_overlay_closed {
974        opacity: "0";
975        visibility: "hidden";
976    }
977
978    pub c_euv_drawer {
979        position: "fixed";
980        top: "0px";
981        left: "0px";
982        bottom: "0px";
983        width: "260px";
984        background: var!(background);
985        border-right: format!("1px solid {}", var!(border));
986        z-index: "201";
987        overflow-y: "auto";
988        padding: var!(space-xl);
989        transition: format!("transform {} {}, visibility {} {}", var!(duration-normal), var!(ease-out), var!(duration-normal), var!(ease-out));
990    }
991
992    pub c_euv_drawer_open {
993        transform: "translateX(0px)";
994        visibility: "visible";
995    }
996
997    pub c_euv_drawer_closed {
998        transform: "translateX(-100%)";
999        visibility: "hidden";
1000    }
1001}