NixDaemon

NixOS pentest workstation as one flake — IceBreaker's successor
git clone https://git.daemon-sec.xyz/NixDaemon.git
Log | Files | Refs | README

shy-menus.css (22173B)


      1 /*== ShyFox Polished Menus ==========================================================================
      2 
      3 Material, colour and state feedback for every popup surface: context menus, the app menu and its
      4 subviews, the unified extensions panel, the downloads panel, the identity / permission / protections
      5 popups, the bookmarks menus and the notification bar.
      6 
      7 Density and geometry are not touched. shy-compact.css owns menuitem height, padding and the
      8 four-column extensions grid; shy-global.css owns popup placement and the accent variable block.
      9 This file only changes what those surfaces are made of.
     10 
     11 Two facts from the platform drive nearly every rule here:
     12 
     13   * a popup paints nothing itself. The whole card -- fill, border, radius, shadow -- is drawn by
     14     ::part(content), which is the <html:slot> of a `panel` and the .menupopup-arrowscrollbox of a
     15     `menupopup`. Both live inside a shadow root, so a plain class selector cannot reach them and
     16     ::part() is the only way in.
     17   * toolkit's xul.css puts `contain: paint` on menupopup/panel/tooltip, so nothing paints outside the
     18     popup widget. The only spare room is --panel-box-shadow-margin (4px), which means --shy-elev-3
     19     reads as a tight edge shadow rather than a wide bloom. Widening that margin also moves the popup
     20     and its click-through region on screen, so it is deliberately left alone.
     21 
     22 ===================================================================================================*/
     23 
     24 @media not -moz-pref("shyfox.disable.polish") {
     25 
     26 /*
     27 --- POPUP MATERIAL ---------------------------------------------------------------------------------
     28 
     29 One card material for menupopup, panel and arrowpanel alike.
     30 
     31 */
     32 
     33 :root {
     34   /* the popup card fill. Opaque by default: on a Linux WM without CSD transparency Gecko forces
     35      `opacity: 1` and square corners on popups, and a translucent fill there would composite against
     36      whatever the opaque widget happens to be. It is upgraded to glass just below. */
     37   --shy-popup-fill: var(--pp-col);
     38 
     39   /* how long a press reads before it settles */
     40   --shy-dur-press: 90ms;
     41 
     42   /* separators everywhere in menus and panels; the platform default is 25% of currentColor */
     43   --panel-separator-color: var(--shy-hairline) !important;
     44 
     45   /* shy-global.css hovers menu items with this variable, but no Gecko version ever defined it, so
     46      those rules resolved to `transparent` and context menu items had no hover at all. Give it a
     47      value and they come back to life. */
     48   --panel-item-hover-bgcolor: var(--shy-accent-weak);
     49 }
     50 
     51 /* a high-contrast user asked for a visible line, not a hairline */
     52 @media (prefers-contrast) {
     53   :root {--panel-separator-color: currentColor !important;}
     54 }
     55 
     56 @media (-moz-gtk-csd-transparency-available), (not (-moz-platform: linux)) {
     57   :root {--shy-popup-fill: var(--shy-surface-popup);}
     58 }
     59 
     60 /* interaction tokens, scoped to popups so toolbar buttons elsewhere keep their own states.
     61    155 renamed the whole family: --button-*-menu-* is the new spelling, --button-*-ghost-* the
     62    140 one, and 155 still uses the ghost names for the downloads list. Set both. */
     63 :is(menupopup, panel) {
     64   --button-background-color-menu-hover:   var(--shy-accent-weak);
     65   --button-background-color-menu-active:  var(--shy-accent-tint);
     66   --button-background-color-ghost-hover:  var(--shy-accent-weak);
     67   --button-background-color-ghost-active: var(--shy-accent-tint);
     68 
     69   --button-text-color-menu:          var(--bt-col);
     70   --button-text-color-menu-hover:    var(--bt-col);
     71   --button-text-color-menu-active:   var(--bt-col);
     72   --button-text-color-ghost:         var(--bt-col);
     73   --button-text-color-ghost-hover:   var(--bt-col);
     74   --button-text-color-ghost-active:  var(--bt-col);
     75 
     76   /* one source of dimming for disabled items: the token, not a stacked opacity */
     77   --button-text-color-menu-disabled:        var(--shy-text-faint);
     78   --button-text-color-ghost-disabled:       var(--shy-text-faint);
     79   --button-background-color-menu-disabled:  transparent;
     80   --button-background-color-ghost-disabled: transparent;
     81   --button-opacity-disabled: 1;
     82 
     83   /* popup scroll containers. scrollbar-color inherits, so one declaration reaches the arrowscrollbox
     84      inside the shadow root as well as .panel-subview-body and every richlistbox. */
     85   scrollbar-color: var(--shy-scrollbar) !important;
     86 }
     87 
     88 /* the platform draws popups natively on Windows (mica) and macOS; reset that before painting our own.
     89    macOS is excluded because its native popup also carries the window shadow. */
     90 @media not (-moz-platform: macos) {
     91   :is(menupopup, panel):not(#ContentSelectDropdown, #ContentSelectDropdownPopup) {
     92     appearance: none !important;
     93     background-color: transparent !important;
     94   }
     95 }
     96 
     97 /* the card. #ContentSelectDropdown is left alone: it renders a page's <select> and carries per-option
     98    colours from content, so a theme text colour there can make options unreadable. */
     99 :is(menupopup, panel):not(#ContentSelectDropdown, #ContentSelectDropdownPopup)::part(content) {
    100   background: var(--shy-popup-fill) !important;
    101   color: var(--bt-col) !important;
    102   border: 1px solid var(--shy-hairline) !important;
    103   box-shadow: var(--shy-elev-3) !important;
    104 }
    105 
    106 /* Blur goes on ::part(content) rather than the popup, which keeps it off every ancestor of the
    107    floating #urlbar. It is decoration only -- a chrome backdrop-filter can silently no-op, so
    108    --shy-popup-fill stays opaque enough to carry the surface by itself. */
    109 @media not -moz-pref("shyfox.disable.blur") {
    110   @media (-moz-gtk-csd-transparency-available), (not (-moz-platform: linux)) {
    111     :is(menupopup, panel):not(#ContentSelectDropdown, #ContentSelectDropdownPopup)::part(content) {
    112       backdrop-filter: blur(var(--shy-glass-blur)) saturate(var(--shy-glass-saturate)) !important;
    113     }
    114   }
    115 }
    116 
    117 /* Entrance. The widget itself cannot be animated reliably -- Gecko sizes the popup window before the
    118    animation runs, so a scale on the popup leaves the shadow and hit region at the old size, and
    119    `@media not (-moz-panel-animations)` disables the platform's own translate on several Linux WMs.
    120    Animating ::part(content) instead is safe: shy-pop-in only ever scales below 1, so it never grows
    121    past the `overflow: clip` on that box. */
    122 :is(menupopup, panel):not(#ContentSelectDropdown, #ContentSelectDropdownPopup)::part(content) {
    123   animation: shy-pop-in var(--shy-dur) var(--shy-ease) !important;
    124 }
    125 
    126 /*
    127 --- MENU ITEMS -------------------------------------------------------------------------------------
    128 
    129 [_moz-menuactive] is what Gecko sets for both pointer hover and keyboard navigation on a menuitem --
    130 :hover is not used there -- and it is spelled the same in 140 and 155, so one hook covers both states
    131 on both versions. The same is true of [disabled] and [checked], which 140 writes as ="true".
    132 
    133 */
    134 
    135 #main-window menupopup > :is(menuitem, menu) {
    136   transition:
    137     background-color var(--shy-dur-fast) var(--shy-ease),
    138     box-shadow var(--shy-dur-fast) var(--shy-ease),
    139     color var(--shy-dur-fast) var(--shy-ease);
    140 }
    141 
    142 /* hover / keyboard highlight. Specificity 1-2-2 so it outranks the 1-1-1 rules in the CONTEXT MENU
    143    section of shy-global.css, which this supersedes. */
    144 #main-window menupopup > :is(menuitem, menu):not([disabled])[_moz-menuactive] {
    145   background-color: var(--shy-accent-weak) !important;
    146   color: var(--bt-col) !important;
    147 }
    148 
    149 /* press: a touch more accent, and quick enough to read as a response rather than a transition */
    150 #main-window menupopup > :is(menuitem, menu):not([disabled])[_moz-menuactive]:active {
    151   background-color: var(--shy-accent-tint) !important;
    152   transition-duration: var(--shy-dur-press);
    153 }
    154 
    155 /* checked items keep a tint and colour the native check itself. On Linux .menu-icon is a real
    156    checkbox widget, which accent-color drives; on Windows it is menu-check.svg, which fill drives. */
    157 #main-window menupopup > menuitem[checked] {
    158   background-color: var(--shy-accent-weak) !important;
    159   accent-color: var(--shy-color);
    160 }
    161 
    162 #main-window menupopup > menuitem[checked] > .menu-icon {
    163   fill: var(--shy-color) !important;
    164   fill-opacity: 1 !important;
    165 }
    166 
    167 /* disabled: one dim, no hover feedback. The platform still paints -moz-menuhoverdisabled when the
    168    keyboard lands on a disabled item, so the transparent fill has to be stated. */
    169 #main-window menupopup > :is(menuitem, menu)[disabled] {
    170   color: var(--shy-text-faint) !important;
    171   background-color: transparent !important;
    172 }
    173 
    174 /* the accel text ("Ctrl+T") is already quieter than the label; keep it in the same family */
    175 #main-window menupopup > :is(menuitem, menu):not([disabled]) > .menu-accel {
    176   color: var(--shy-text-dim) !important;
    177 }
    178 
    179 /* the submenu arrow is a hint, not a label. 140 drives it from --menu-icon-opacity and 155 from
    180    --menu-arrow-opacity, so the property is set directly rather than through either name. */
    181 #main-window menupopup > menu::after {
    182   fill-opacity: 0.55 !important;
    183 }
    184 
    185 /*
    186 --- APP MENU AND SUBVIEWS --------------------------------------------------------------------------
    187 
    188 Everything in a panelview is a .subviewbutton, so the token block above already gives it the same
    189 hover, press and disabled treatment as a menu item. What is left is the checked state, focus, and the
    190 seams between sections.
    191 
    192 */
    193 
    194 /* panel buttons cannot show a checkbox, so a checked one gets a leading accent edge. An inset shadow
    195    draws it without a pseudo-element and without moving anything -- .subviewbutton::before is already
    196    spoken for by several icon rules in shy-icons.css. */
    197 #main-window panel .subviewbutton[checked] {
    198   background-color: var(--shy-accent-weak) !important;
    199   box-shadow: inset 3px 0 0 var(--shy-accent-line) !important;
    200 }
    201 
    202 /* keyboard focus reads like hover plus the accent ring the rest of the theme uses */
    203 #main-window panel :is(.subviewbutton, .panel-info-button, .panel-subview-footer-button):focus-visible {
    204   background-color: var(--shy-accent-weak) !important;
    205   outline: 2px solid var(--shy-accent-line) !important;
    206   outline-offset: -2px !important;
    207 }
    208 
    209 /* The footer is a section of the same card, not a bar sitting on it. Every .panel-header,
    210    #downloadsFooter and #protections-popup-footer in browser.xhtml already has a toolbarseparator
    211    against it, and those are hairlines now, so only .panel-footer -- a moz-button-group with no
    212    separator of its own -- needs a seam drawn. It is drawn inset so nothing shifts by a pixel. */
    213 #main-window panel .panel-footer {
    214   background-color: transparent !important;
    215   box-shadow: inset 0 1px 0 var(--shy-hairline) !important;
    216 }
    217 
    218 #main-window panel .panel-subview-footer-button {
    219   border-radius: var(--rounding) !important;
    220   transition: background-color var(--shy-dur-fast) var(--shy-ease) !important;
    221 }
    222 
    223 /* the update banner is the one item in the app menu that is asking for attention */
    224 #main-window panel .panel-banner-item {
    225   --panel-banner-item-background-color: var(--shy-accent-weak);
    226   --panel-banner-item-hover-bgcolor:    var(--shy-accent-tint);
    227   --panel-banner-item-active-bgcolor:   var(--shy-accent-strong);
    228   --panel-banner-item-color:            var(--bt-col);
    229 }
    230 
    231 /* Icon tinting is already currentColor everywhere (shy-icons.css), which means a disabled item's
    232    icon fades with its label for free now that --button-text-color-*-disabled carries the dimming.
    233    The one thing missing is the other end: shy-icons.css holds every panel icon at the platform's
    234    reduced fill-opacity, so a highlighted or checked row had a full-strength label next to a faded
    235    icon. Bring the icon up with the row. */
    236 #main-window panel .subviewbutton:is(:hover, [checked]):not([disabled]) > image {
    237   fill-opacity: 1 !important;
    238 }
    239 
    240 /*
    241 --- UNIFIED EXTENSIONS -----------------------------------------------------------------------------
    242 
    243 shy-compact.css packs this panel into a four-column icon grid and hides the labels, so each cell is a
    244 bare icon that needs its own hit area. Geometry stays exactly where that file put it.
    245 
    246 */
    247 
    248 #unified-extensions-panel .unified-extensions-item-action-button.subviewbutton {
    249   border-radius: var(--rounding) !important;
    250   transition:
    251     background-color var(--shy-dur-fast) var(--shy-ease),
    252     scale var(--shy-dur-press) var(--shy-ease);
    253 }
    254 
    255 #unified-extensions-panel .unified-extensions-item-action-button.subviewbutton:not([disabled]):hover {
    256   background-color: var(--shy-accent-weak) !important;
    257 }
    258 
    259 /* pressed. A scale on a panel button is safe -- it is nowhere near an ancestor of #urlbar -- and it
    260    is the one property that reads as "pressed" without moving the grid. */
    261 #unified-extensions-panel .unified-extensions-item-action-button.subviewbutton:not([disabled]):hover:active {
    262   background-color: var(--shy-accent-tint) !important;
    263   scale: 0.94;
    264 }
    265 
    266 /* an extension wanting attention already draws an accent dot (shy-global.css pins
    267    --uei-button-attention-dot-color to the accent); back it with a tint so the cell reads at a glance */
    268 #unified-extensions-panel .unified-extensions-item[attention] > .unified-extensions-item-row-wrapper > .unified-extensions-item-action-button.subviewbutton {
    269   background-color: var(--shy-accent-weak) !important;
    270 }
    271 
    272 /*
    273 --- DOWNLOADS --------------------------------------------------------------------------------------
    274 
    275 */
    276 
    277 #downloadsPanel {
    278   --download-progress-fill-color: var(--shy-color) !important;
    279   --download-progress-paused-color: var(--shy-text-faint) !important;
    280   /* the platform flare is a hardcoded 75% white, which fights any theme */
    281   --download-progress-flare-color: color-mix(in srgb, var(--bt-col) 55%, transparent) !important;
    282 }
    283 
    284 #downloadsPanel #downloadsListBox > richlistitem {
    285   transition: background-color var(--shy-dur-fast) var(--shy-ease) !important;
    286 }
    287 
    288 /* the track is the same hairline used for every other seam in the theme */
    289 #downloadsPanel .downloadProgress {
    290   background-color: var(--shy-hairline) !important;
    291 }
    292 
    293 /* the filled part carries the same accent glow the theme uses on focused surfaces */
    294 #downloadsPanel .downloadProgress::-moz-progress-bar {
    295   box-shadow: 0 0 8px color-mix(in srgb, var(--shy-color) 45%, transparent) !important;
    296 }
    297 
    298 #downloadsPanel .downloadProgress[paused]::-moz-progress-bar {
    299   box-shadow: none !important;
    300 }
    301 
    302 /* cancel / retry / show-in-folder */
    303 #downloadsPanel .downloadButton {
    304   transition:
    305     background-color var(--shy-dur-fast) var(--shy-ease),
    306     scale var(--shy-dur-press) var(--shy-ease);
    307 }
    308 
    309 #downloadsPanel .downloadButton:hover:active {
    310   scale: 0.92;
    311 }
    312 
    313 #downloadsPanel .downloadsPanelFooterButton {
    314   border-radius: var(--rounding) !important;
    315   transition: background-color var(--shy-dur-fast) var(--shy-ease) !important;
    316 }
    317 
    318 /* the summary strip sits inside the card, so it takes a tint rather than its own dimmed panel fill */
    319 #downloadsPanel #downloadsSummary {
    320   background-color: var(--shy-hover-tint) !important;
    321   border-radius: var(--rounding) !important;
    322 }
    323 
    324 /*
    325 --- SITE INFORMATION POPUPS ------------------------------------------------------------------------
    326 
    327 The identity, permission, trust and protections popups. Their card material comes from the shared
    328 ::part(content) rule; the rows inside them are .subviewbutton, so they already match the app menu.
    329 These rules cover the pieces that are not buttons.
    330 
    331 */
    332 
    333 /* a permission row is not focusable but it does hold a remove button, so it gets a row highlight */
    334 #main-window :is(#identity-popup, #permission-popup) .permission-popup-permission-item {
    335   border-radius: var(--rounding) !important;
    336   transition: background-color var(--shy-dur-fast) var(--shy-ease) !important;
    337 }
    338 
    339 #main-window :is(#identity-popup, #permission-popup) .permission-popup-permission-item:hover {
    340   background-color: var(--shy-hover-tint) !important;
    341 }
    342 
    343 /* the connection summary is the popup's headline; keep it on the theme text colour and let the
    344    platform's per-state icon carry the meaning */
    345 #main-window .site-information-popup .identity-popup-security-connection,
    346 #main-window #identity-popup .identity-popup-security-connection {
    347   color: var(--bt-col) !important;
    348 }
    349 
    350 /* an enabled protection category reads as active, without an accent fill behind its label */
    351 #main-window #protections-popup .protections-popup-category:not([uidisabled], [disabled]) {
    352   transition: background-color var(--shy-dur-fast) var(--shy-ease) !important;
    353 }
    354 
    355 #main-window #protections-popup .protections-popup-category[uidisabled] {
    356   color: var(--shy-text-faint) !important;
    357 }
    358 
    359 /* the "blocked this week" counter is a number worth highlighting; the footer icons stay neutral */
    360 #main-window #protections-popup #protections-popup-trackers-blocked-counter-description {
    361   color: var(--shy-color) !important;
    362 }
    363 
    364 /*
    365 --- NOTIFICATION BAR -------------------------------------------------------------------------------
    366 
    367 shy-global.css already floats this as a card at the top of the content area. notification-message is a
    368 moz-message-bar, whose entire inside is shadow DOM driven by inherited --message-bar-* properties, so
    369 those tokens are the only way in -- and the only way the close button in the shadow root gets the
    370 theme's text colour.
    371 
    372 */
    373 
    374 #main-window :is(#tab-notification-deck, .global-notificationbox) notification-message {
    375   --message-bar-border-color: var(--shy-hairline);
    376   --message-bar-text-color: var(--bt-col);
    377   --message-bar-icon-background-color: transparent;
    378   --message-bar-border-radius: var(--big-rounding);
    379 
    380   background-color: var(--shy-surface) !important;
    381   box-shadow: var(--shy-elev-2) !important;
    382   animation: shy-drop-in var(--shy-dur) var(--shy-ease) !important;
    383 }
    384 
    385 /* The accent icon is for ordinary notices only. moz-message-bar sets --message-bar-icon-color per
    386    severity inside its shadow root, and an outer declaration would win against all of them, so the
    387    warning / success / error bars are excluded and keep their semantic icon colour -- which, since
    388    the card fill above is now uniform, is the only severity cue left. */
    389 #main-window :is(#tab-notification-deck, .global-notificationbox)
    390   notification-message:not([type="warning"], [type="success"], [type="error"], [type="critical"]) {
    391   --message-bar-icon-color: var(--shy-color);
    392 }
    393 
    394 @media not -moz-pref("shyfox.disable.blur") {
    395   #main-window :is(#tab-notification-deck, .global-notificationbox) notification-message {
    396     backdrop-filter: blur(var(--shy-glass-blur)) saturate(var(--shy-glass-saturate)) !important;
    397   }
    398 }
    399 
    400 /* the infobar's buttons are XUL buttons in the light tree, so they can take the popup states */
    401 #main-window :is(#tab-notification-deck, .global-notificationbox) .notification-button {
    402   --button-background-color-hover:  var(--shy-accent-weak);
    403   --button-background-color-active: var(--shy-accent-tint);
    404   border-radius: var(--rounding) !important;
    405   transition: background-color var(--shy-dur-fast) var(--shy-ease) !important;
    406 }
    407 
    408 #main-window :is(#tab-notification-deck, .global-notificationbox) .notification-button:focus-visible {
    409   outline: 2px solid var(--shy-accent-line) !important;
    410   outline-offset: 1px !important;
    411 }
    412 
    413 /*
    414 --- GRACEFUL DEGRADATION ---------------------------------------------------------------------------
    415 
    416 This file is imported after shy-compat.css, so it has to restate both contracts rather than inherit
    417 them.
    418 
    419 */
    420 
    421 @media (prefers-reduced-motion: reduce) {
    422   :root {--shy-dur-press: 0s;}
    423 
    424   :is(menupopup, panel)::part(content),
    425   #main-window menupopup > :is(menuitem, menu),
    426   #main-window panel .panel-subview-footer-button,
    427   #unified-extensions-panel .unified-extensions-item-action-button.subviewbutton,
    428   #downloadsPanel :is(#downloadsListBox > richlistitem, .downloadButton, .downloadsPanelFooterButton),
    429   #main-window :is(#identity-popup, #permission-popup) .permission-popup-permission-item,
    430   #main-window #protections-popup .protections-popup-category,
    431   #main-window :is(#tab-notification-deck, .global-notificationbox) notification-message,
    432   #main-window :is(#tab-notification-deck, .global-notificationbox) .notification-button {
    433     animation: none !important;
    434     transition: none !important;
    435   }
    436 
    437   /* the pressed states stay, they just arrive instantly */
    438   #unified-extensions-panel .unified-extensions-item-action-button.subviewbutton:not([disabled]):hover:active,
    439   #downloadsPanel .downloadButton:hover:active {
    440     scale: 1;
    441   }
    442 }
    443 
    444 @media (forced-colors: active) {
    445   :root {
    446     --shy-popup-fill: Canvas;
    447     --panel-separator-color: CanvasText !important;
    448     --panel-item-hover-bgcolor: Highlight;
    449   }
    450 
    451   :is(menupopup, panel)::part(content) {
    452     background: Canvas !important;
    453     color: CanvasText !important;
    454     border: 1px solid CanvasText !important;
    455     box-shadow: none !important;
    456     backdrop-filter: none !important;
    457     animation: none !important;
    458   }
    459 
    460   /* Highlight / HighlightText is the one pair the system guarantees is legible together */
    461   #main-window menupopup > :is(menuitem, menu):not([disabled])[_moz-menuactive],
    462   #main-window menupopup > :is(menuitem, menu):not([disabled])[_moz-menuactive]:active,
    463   #main-window menupopup > menuitem[checked],
    464   #main-window panel .subviewbutton[checked],
    465   #unified-extensions-panel .unified-extensions-item-action-button.subviewbutton:not([disabled]):hover {
    466     background-color: Highlight !important;
    467     color: HighlightText !important;
    468     box-shadow: none !important;
    469   }
    470 
    471   #main-window menupopup > :is(menuitem, menu)[disabled],
    472   #main-window #protections-popup .protections-popup-category[uidisabled] {
    473     color: GrayText !important;
    474   }
    475 
    476   #main-window panel .panel-footer {
    477     box-shadow: inset 0 1px 0 CanvasText !important;
    478   }
    479 
    480   #main-window :is(#tab-notification-deck, .global-notificationbox) notification-message {
    481     --message-bar-background-color: Canvas;
    482     --message-bar-border-color: CanvasText;
    483     --message-bar-text-color: CanvasText;
    484     --message-bar-icon-color: CanvasText;
    485 
    486     background-color: Canvas !important;
    487     box-shadow: none !important;
    488     backdrop-filter: none !important;
    489     animation: none !important;
    490   }
    491 
    492   #downloadsPanel .downloadProgress::-moz-progress-bar {
    493     box-shadow: none !important;
    494   }
    495 
    496   #downloadsPanel #downloadsSummary {
    497     background-color: Canvas !important;
    498     box-shadow: inset 0 0 0 1px CanvasText !important;
    499   }
    500 }
    501 
    502 } /* shyfox.disable.polish */