From 88497826ecfd3cdf6f5049a509eacf115cd52a96 Mon Sep 17 00:00:00 2001 From: Gabriel Brown Date: Thu, 20 Aug 2026 21:24:15 -0400 Subject: [PATCH] Let a machine say what it is for, and give Firefox its face back Phase 4: the optional application categories, and the Firefox chrome. Everything Panama installed until now was what every machine gets, which meant a work laptop acquired emulators and a desktop that wanted Steam had to be told about it by hand. The interview now offers the categories in setup/packages/extras/ as a checklist -- gaming, creative, communication, virtualization -- and nothing is preselected, because a default here installs applications nobody chose on a machine whose owner answered a question they thought was about something else. A category is one file, and a category mixes both package managers because the applications do: Steam is in RPM Fusion, Slack publishes only a flatpak. So a bare line is a dnf package and a flatpak: line is a Flathub ID, and one file holds the whole answer rather than splitting each category across two. The menu is read from the directory rather than written down, so adding a category is adding a file. Every name in all four was resolved against the actual repositories before being written down, and the contract re-resolves them -- the point of admitting applications one at a time is that they stay installable, and a typo here fails on somebody else's machine, not this one. Firefox is declared, and its chrome is Edge-Frfox, vendored into config/firefox. sunhat carried that theme with no license and no attribution; it is MIT, and now it says so and says whose it is. It is the only piece of Panama's configuration that does not go to a path this repository chooses. Firefox owns the profile directory, names it with a random salt, and does not create one until the browser has been run -- so link-dotfiles finds or creates a profile and links both halves into it. Both, or neither works: chrome/ is the CSS and user.js sets the preference that makes Firefox read chrome/ at all, without which the theme is a directory of dead files. Two assumptions there were wrong, and the contract exists for both. Firefox has moved to the XDG directories -- the profile root is ~/.config/mozilla/firefox on this build, not ~/.mozilla/firefox, and writing to the wrong one themes nothing and says nothing about it. And -CreateProfile turns out to be non-interactive, so a fresh machine gets the theme on the first install rather than the second. The contract runs link-dotfiles for real against a throwaway home with no profile in it and looks at what came out; it was checked by pointing the search at the legacy path only and watching it fail. Also: the enrolment/enrollment spellings from the last commit are corrected. This repository is US-spelled everywhere else -- color 1131 times against colour never -- and consistency in prose is worth as much as it is in code. Claude-Session: https://claude.ai/code/session_01NvgBuSWB5sE43yWmg21ozj --- README.md | 17 +- config/firefox/README.md | 35 + config/firefox/chrome/content/common.css | 105 ++ config/firefox/chrome/content/newtab.css | 415 +++++++ config/firefox/chrome/custom.css | 8 + config/firefox/chrome/global/browser.css | 206 ++++ config/firefox/chrome/global/colors.css | 366 ++++++ config/firefox/chrome/global/popup.css | 847 +++++++++++++ config/firefox/chrome/global/tree.css | 87 ++ config/firefox/chrome/global/tweaks.css | 247 ++++ config/firefox/chrome/icons/accessibility.svg | 3 + .../firefox/chrome/icons/account-private.svg | 13 + config/firefox/chrome/icons/account.svg | 7 + .../chrome/icons/add-to-dictionary.svg | 4 + config/firefox/chrome/icons/arrow-down.svg | 3 + .../chrome/icons/arrow-filled-down.svg | 3 + .../chrome/icons/arrow-filled-left.svg | 3 + .../chrome/icons/arrow-filled-right.svg | 3 + config/firefox/chrome/icons/arrow-left.svg | 3 + config/firefox/chrome/icons/arrow-right.svg | 3 + config/firefox/chrome/icons/arrow-up.svg | 3 + config/firefox/chrome/icons/audio-save.svg | 4 + .../chrome/icons/autoplay-media-blocked.svg | 5 + .../firefox/chrome/icons/autoplay-media.svg | 3 + config/firefox/chrome/icons/back.svg | 3 + .../firefox/chrome/icons/bookmark-hollow.svg | 3 + .../chrome/icons/bookmark-star-on-tray.svg | 4 + config/firefox/chrome/icons/bookmark.svg | 3 + .../firefox/chrome/icons/camera-blocked.svg | 5 + config/firefox/chrome/icons/camera.svg | 3 + .../firefox/chrome/icons/canvas-blocked.svg | 5 + config/firefox/chrome/icons/canvas.svg | 3 + config/firefox/chrome/icons/checkmark.svg | 3 + config/firefox/chrome/icons/chevron.svg | 4 + config/firefox/chrome/icons/close-9px.svg | 3 + config/firefox/chrome/icons/close.svg | 3 + config/firefox/chrome/icons/container-tab.svg | 3 + config/firefox/chrome/icons/customize.svg | 3 + .../icons/desktop-notification-blocked.svg | 5 + .../chrome/icons/desktop-notification.svg | 3 + config/firefox/chrome/icons/developer.svg | 3 + config/firefox/chrome/icons/downloads.svg | 4 + config/firefox/chrome/icons/duplicate-tab.svg | 3 + .../icons/edit-copy-without-tracking.svg | 5 + config/firefox/chrome/icons/edit-copy.svg | 3 + config/firefox/chrome/icons/edit-cut.svg | 3 + config/firefox/chrome/icons/edit-delete.svg | 3 + config/firefox/chrome/icons/edit-paste.svg | 3 + config/firefox/chrome/icons/edit-redo.svg | 3 + .../firefox/chrome/icons/edit-select-all.svg | 3 + config/firefox/chrome/icons/edit-undo.svg | 3 + config/firefox/chrome/icons/edit.svg | 3 + .../chrome/icons/extension-blocked.svg | 5 + config/firefox/chrome/icons/extension.svg | 3 + config/firefox/chrome/icons/firefox-view.svg | 3 + config/firefox/chrome/icons/firefox.svg | 3 + config/firefox/chrome/icons/folder.svg | 4 + config/firefox/chrome/icons/forget.svg | 3 + config/firefox/chrome/icons/forward.svg | 3 + .../firefox/chrome/icons/fullscreen-exit.svg | 3 + config/firefox/chrome/icons/fullscreen.svg | 3 + config/firefox/chrome/icons/geo-blocked.svg | 5 + config/firefox/chrome/icons/geo.svg | 3 + config/firefox/chrome/icons/help.svg | 3 + config/firefox/chrome/icons/history.svg | 4 + config/firefox/chrome/icons/home.svg | 3 + config/firefox/chrome/icons/icons.css | 1063 +++++++++++++++++ config/firefox/chrome/icons/image-copy.svg | 5 + config/firefox/chrome/icons/image-open.svg | 8 + config/firefox/chrome/icons/image-save.svg | 4 + config/firefox/chrome/icons/info.svg | 3 + config/firefox/chrome/icons/inspect.svg | 3 + config/firefox/chrome/icons/library.svg | 3 + config/firefox/chrome/icons/link.svg | 3 + config/firefox/chrome/icons/mail.svg | 3 + config/firefox/chrome/icons/manage.svg | 3 + config/firefox/chrome/icons/media-loop.svg | 3 + config/firefox/chrome/icons/media-mute.svg | 3 + config/firefox/chrome/icons/media-pause.svg | 3 + config/firefox/chrome/icons/media-pip.svg | 3 + config/firefox/chrome/icons/media-play.svg | 3 + config/firefox/chrome/icons/media-speed.svg | 3 + config/firefox/chrome/icons/media-unmute.svg | 3 + config/firefox/chrome/icons/menu.svg | 5 + .../chrome/icons/microphone-blocked.svg | 5 + config/firefox/chrome/icons/microphone.svg | 3 + config/firefox/chrome/icons/midi.svg | 3 + config/firefox/chrome/icons/move-tab.svg | 3 + config/firefox/chrome/icons/new-tab-image.svg | 6 + config/firefox/chrome/icons/new-tab.svg | 4 + config/firefox/chrome/icons/open.svg | 3 + config/firefox/chrome/icons/page-portrait.svg | 3 + config/firefox/chrome/icons/passwords.svg | 3 + config/firefox/chrome/icons/paste-and-go.svg | 4 + config/firefox/chrome/icons/permissions.svg | 3 + .../icons/persistent-storage-blocked.svg | 5 + .../chrome/icons/persistent-storage.svg | 3 + config/firefox/chrome/icons/pin.svg | 3 + config/firefox/chrome/icons/plus.svg | 3 + .../firefox/chrome/icons/pocket-outline.svg | 3 + config/firefox/chrome/icons/popup.svg | 5 + config/firefox/chrome/icons/print.svg | 3 + .../firefox/chrome/icons/private-window.svg | 4 + .../firefox/chrome/icons/privateBrowsing.svg | 3 + config/firefox/chrome/icons/reader-mode.svg | 4 + .../firefox/chrome/icons/reload-to-stop.svg | 28 + config/firefox/chrome/icons/reload.svg | 3 + config/firefox/chrome/icons/report.svg | 3 + config/firefox/chrome/icons/save.svg | 3 + .../firefox/chrome/icons/screen-blocked.svg | 5 + config/firefox/chrome/icons/screen.svg | 3 + config/firefox/chrome/icons/screenshot.svg | 3 + config/firefox/chrome/icons/search-glass.svg | 3 + config/firefox/chrome/icons/search-page.svg | 3 + .../firefox/chrome/icons/security-broken.svg | 3 + .../firefox/chrome/icons/security-warning.svg | 4 + config/firefox/chrome/icons/security.svg | 3 + .../firefox/chrome/icons/send-to-device.svg | 3 + config/firefox/chrome/icons/settings.svg | 3 + config/firefox/chrome/icons/share.svg | 3 + .../firefox/chrome/icons/sidebars-right.svg | 3 + config/firefox/chrome/icons/sidebars.svg | 3 + config/firefox/chrome/icons/source-code.svg | 3 + .../firefox/chrome/icons/stop-to-reload.svg | 35 + .../chrome/icons/tab-audio-blocked-small.svg | 4 + .../chrome/icons/tab-audio-muted-small.svg | 4 + .../chrome/icons/tab-audio-playing-small.svg | 4 + config/firefox/chrome/icons/tab.svg | 3 + config/firefox/chrome/icons/tag.svg | 3 + config/firefox/chrome/icons/tool-profiler.svg | 3 + .../chrome/icons/tracking-protection.svg | 3 + config/firefox/chrome/icons/translate.svg | 3 + config/firefox/chrome/icons/video-open.svg | 5 + config/firefox/chrome/icons/video-save.svg | 5 + .../firefox/chrome/icons/win11-close-dark.svg | 3 + config/firefox/chrome/icons/win11-close.svg | 3 + .../firefox/chrome/icons/win11-maximize.svg | 3 + .../firefox/chrome/icons/win11-minimize.svg | 4 + config/firefox/chrome/icons/win11-restore.svg | 3 + config/firefox/chrome/icons/window.svg | 3 + config/firefox/chrome/icons/xr-blocked.svg | 5 + config/firefox/chrome/icons/xr.svg | 3 + config/firefox/chrome/icons/zoom-out.svg | 3 + config/firefox/chrome/toolbar/findbar.css | 73 ++ config/firefox/chrome/toolbar/navbar.css | 105 ++ config/firefox/chrome/toolbar/personalbar.css | 85 ++ config/firefox/chrome/toolbar/tabbar.css | 700 +++++++++++ config/firefox/chrome/toolbar/urlbar.css | 262 ++++ .../firefox/chrome/tweaks/hide-tabs-bar.css | 252 ++++ .../chrome/tweaks/shrink-sideberry.css | 19 + config/firefox/chrome/tweaks/sidebery.css | 334 ++++++ config/firefox/chrome/userChrome.css | 21 + config/firefox/chrome/userContent.css | 5 + config/firefox/user.js | 14 + .../2026-08-20-panama-fresh-install-design.md | 50 +- install | 4 +- setup/packages/desktop-packages | 4 + setup/packages/extras/communication | 8 + setup/packages/extras/creative | 7 + setup/packages/extras/gaming | 14 + setup/packages/extras/virtualization | 6 + setup/scripts/install-hardware | 12 +- setup/scripts/install-packages | 47 + setup/scripts/interview | 45 +- setup/scripts/link-dotfiles | 64 + tests/setup/extras-contract | 165 +++ tests/setup/firefox-chrome-contract | 99 ++ tests/setup/hardware-contract | 10 +- 168 files changed, 6293 insertions(+), 32 deletions(-) create mode 100644 config/firefox/README.md create mode 100644 config/firefox/chrome/content/common.css create mode 100644 config/firefox/chrome/content/newtab.css create mode 100644 config/firefox/chrome/custom.css create mode 100644 config/firefox/chrome/global/browser.css create mode 100644 config/firefox/chrome/global/colors.css create mode 100644 config/firefox/chrome/global/popup.css create mode 100644 config/firefox/chrome/global/tree.css create mode 100644 config/firefox/chrome/global/tweaks.css create mode 100755 config/firefox/chrome/icons/accessibility.svg create mode 100644 config/firefox/chrome/icons/account-private.svg create mode 100644 config/firefox/chrome/icons/account.svg create mode 100644 config/firefox/chrome/icons/add-to-dictionary.svg create mode 100644 config/firefox/chrome/icons/arrow-down.svg create mode 100644 config/firefox/chrome/icons/arrow-filled-down.svg create mode 100644 config/firefox/chrome/icons/arrow-filled-left.svg create mode 100644 config/firefox/chrome/icons/arrow-filled-right.svg create mode 100644 config/firefox/chrome/icons/arrow-left.svg create mode 100644 config/firefox/chrome/icons/arrow-right.svg create mode 100644 config/firefox/chrome/icons/arrow-up.svg create mode 100644 config/firefox/chrome/icons/audio-save.svg create mode 100644 config/firefox/chrome/icons/autoplay-media-blocked.svg create mode 100644 config/firefox/chrome/icons/autoplay-media.svg create mode 100644 config/firefox/chrome/icons/back.svg create mode 100644 config/firefox/chrome/icons/bookmark-hollow.svg create mode 100644 config/firefox/chrome/icons/bookmark-star-on-tray.svg create mode 100644 config/firefox/chrome/icons/bookmark.svg create mode 100644 config/firefox/chrome/icons/camera-blocked.svg create mode 100644 config/firefox/chrome/icons/camera.svg create mode 100644 config/firefox/chrome/icons/canvas-blocked.svg create mode 100644 config/firefox/chrome/icons/canvas.svg create mode 100644 config/firefox/chrome/icons/checkmark.svg create mode 100644 config/firefox/chrome/icons/chevron.svg create mode 100644 config/firefox/chrome/icons/close-9px.svg create mode 100644 config/firefox/chrome/icons/close.svg create mode 100644 config/firefox/chrome/icons/container-tab.svg create mode 100644 config/firefox/chrome/icons/customize.svg create mode 100644 config/firefox/chrome/icons/desktop-notification-blocked.svg create mode 100644 config/firefox/chrome/icons/desktop-notification.svg create mode 100644 config/firefox/chrome/icons/developer.svg create mode 100644 config/firefox/chrome/icons/downloads.svg create mode 100644 config/firefox/chrome/icons/duplicate-tab.svg create mode 100644 config/firefox/chrome/icons/edit-copy-without-tracking.svg create mode 100644 config/firefox/chrome/icons/edit-copy.svg create mode 100644 config/firefox/chrome/icons/edit-cut.svg create mode 100755 config/firefox/chrome/icons/edit-delete.svg create mode 100644 config/firefox/chrome/icons/edit-paste.svg create mode 100644 config/firefox/chrome/icons/edit-redo.svg create mode 100755 config/firefox/chrome/icons/edit-select-all.svg create mode 100755 config/firefox/chrome/icons/edit-undo.svg create mode 100644 config/firefox/chrome/icons/edit.svg create mode 100644 config/firefox/chrome/icons/extension-blocked.svg create mode 100644 config/firefox/chrome/icons/extension.svg create mode 100644 config/firefox/chrome/icons/firefox-view.svg create mode 100644 config/firefox/chrome/icons/firefox.svg create mode 100644 config/firefox/chrome/icons/folder.svg create mode 100644 config/firefox/chrome/icons/forget.svg create mode 100644 config/firefox/chrome/icons/forward.svg create mode 100644 config/firefox/chrome/icons/fullscreen-exit.svg create mode 100644 config/firefox/chrome/icons/fullscreen.svg create mode 100644 config/firefox/chrome/icons/geo-blocked.svg create mode 100644 config/firefox/chrome/icons/geo.svg create mode 100644 config/firefox/chrome/icons/help.svg create mode 100644 config/firefox/chrome/icons/history.svg create mode 100644 config/firefox/chrome/icons/home.svg create mode 100644 config/firefox/chrome/icons/icons.css create mode 100644 config/firefox/chrome/icons/image-copy.svg create mode 100644 config/firefox/chrome/icons/image-open.svg create mode 100644 config/firefox/chrome/icons/image-save.svg create mode 100644 config/firefox/chrome/icons/info.svg create mode 100755 config/firefox/chrome/icons/inspect.svg create mode 100644 config/firefox/chrome/icons/library.svg create mode 100644 config/firefox/chrome/icons/link.svg create mode 100644 config/firefox/chrome/icons/mail.svg create mode 100644 config/firefox/chrome/icons/manage.svg create mode 100644 config/firefox/chrome/icons/media-loop.svg create mode 100644 config/firefox/chrome/icons/media-mute.svg create mode 100644 config/firefox/chrome/icons/media-pause.svg create mode 100644 config/firefox/chrome/icons/media-pip.svg create mode 100644 config/firefox/chrome/icons/media-play.svg create mode 100644 config/firefox/chrome/icons/media-speed.svg create mode 100644 config/firefox/chrome/icons/media-unmute.svg create mode 100644 config/firefox/chrome/icons/menu.svg create mode 100644 config/firefox/chrome/icons/microphone-blocked.svg create mode 100644 config/firefox/chrome/icons/microphone.svg create mode 100644 config/firefox/chrome/icons/midi.svg create mode 100644 config/firefox/chrome/icons/move-tab.svg create mode 100644 config/firefox/chrome/icons/new-tab-image.svg create mode 100644 config/firefox/chrome/icons/new-tab.svg create mode 100644 config/firefox/chrome/icons/open.svg create mode 100644 config/firefox/chrome/icons/page-portrait.svg create mode 100644 config/firefox/chrome/icons/passwords.svg create mode 100644 config/firefox/chrome/icons/paste-and-go.svg create mode 100644 config/firefox/chrome/icons/permissions.svg create mode 100644 config/firefox/chrome/icons/persistent-storage-blocked.svg create mode 100644 config/firefox/chrome/icons/persistent-storage.svg create mode 100644 config/firefox/chrome/icons/pin.svg create mode 100644 config/firefox/chrome/icons/plus.svg create mode 100644 config/firefox/chrome/icons/pocket-outline.svg create mode 100644 config/firefox/chrome/icons/popup.svg create mode 100644 config/firefox/chrome/icons/print.svg create mode 100644 config/firefox/chrome/icons/private-window.svg create mode 100644 config/firefox/chrome/icons/privateBrowsing.svg create mode 100644 config/firefox/chrome/icons/reader-mode.svg create mode 100644 config/firefox/chrome/icons/reload-to-stop.svg create mode 100644 config/firefox/chrome/icons/reload.svg create mode 100644 config/firefox/chrome/icons/report.svg create mode 100644 config/firefox/chrome/icons/save.svg create mode 100644 config/firefox/chrome/icons/screen-blocked.svg create mode 100644 config/firefox/chrome/icons/screen.svg create mode 100644 config/firefox/chrome/icons/screenshot.svg create mode 100644 config/firefox/chrome/icons/search-glass.svg create mode 100755 config/firefox/chrome/icons/search-page.svg create mode 100644 config/firefox/chrome/icons/security-broken.svg create mode 100644 config/firefox/chrome/icons/security-warning.svg create mode 100644 config/firefox/chrome/icons/security.svg create mode 100644 config/firefox/chrome/icons/send-to-device.svg create mode 100644 config/firefox/chrome/icons/settings.svg create mode 100644 config/firefox/chrome/icons/share.svg create mode 100644 config/firefox/chrome/icons/sidebars-right.svg create mode 100644 config/firefox/chrome/icons/sidebars.svg create mode 100755 config/firefox/chrome/icons/source-code.svg create mode 100644 config/firefox/chrome/icons/stop-to-reload.svg create mode 100644 config/firefox/chrome/icons/tab-audio-blocked-small.svg create mode 100644 config/firefox/chrome/icons/tab-audio-muted-small.svg create mode 100644 config/firefox/chrome/icons/tab-audio-playing-small.svg create mode 100644 config/firefox/chrome/icons/tab.svg create mode 100644 config/firefox/chrome/icons/tag.svg create mode 100644 config/firefox/chrome/icons/tool-profiler.svg create mode 100644 config/firefox/chrome/icons/tracking-protection.svg create mode 100644 config/firefox/chrome/icons/translate.svg create mode 100644 config/firefox/chrome/icons/video-open.svg create mode 100644 config/firefox/chrome/icons/video-save.svg create mode 100644 config/firefox/chrome/icons/win11-close-dark.svg create mode 100644 config/firefox/chrome/icons/win11-close.svg create mode 100644 config/firefox/chrome/icons/win11-maximize.svg create mode 100644 config/firefox/chrome/icons/win11-minimize.svg create mode 100644 config/firefox/chrome/icons/win11-restore.svg create mode 100644 config/firefox/chrome/icons/window.svg create mode 100644 config/firefox/chrome/icons/xr-blocked.svg create mode 100644 config/firefox/chrome/icons/xr.svg create mode 100644 config/firefox/chrome/icons/zoom-out.svg create mode 100644 config/firefox/chrome/toolbar/findbar.css create mode 100644 config/firefox/chrome/toolbar/navbar.css create mode 100644 config/firefox/chrome/toolbar/personalbar.css create mode 100644 config/firefox/chrome/toolbar/tabbar.css create mode 100644 config/firefox/chrome/toolbar/urlbar.css create mode 100644 config/firefox/chrome/tweaks/hide-tabs-bar.css create mode 100644 config/firefox/chrome/tweaks/shrink-sideberry.css create mode 100644 config/firefox/chrome/tweaks/sidebery.css create mode 100644 config/firefox/chrome/userChrome.css create mode 100644 config/firefox/chrome/userContent.css create mode 100644 config/firefox/user.js create mode 100644 setup/packages/extras/communication create mode 100644 setup/packages/extras/creative create mode 100644 setup/packages/extras/gaming create mode 100644 setup/packages/extras/virtualization create mode 100755 tests/setup/extras-contract create mode 100755 tests/setup/firefox-chrome-contract diff --git a/README.md b/README.md index 4e46c45..9f65cd9 100644 --- a/README.md +++ b/README.md @@ -14,17 +14,28 @@ in order, without stopping again: | Script | Does | |---|---| | `interview` | Every prompt, before anything is installed. Answers last one run and are never written to a durable path | -| `install-packages` | Repos (RPM Fusion, Terra, Hyprland COPR), then the package lists in `setup/packages/` | -| `link-dotfiles` | Symlinks `config/dot/` → `~/.config/`, and seeds the wallpaper and cursor theme | +| `install-packages` | Repos (RPM Fusion, Terra, Hyprland COPR), the package lists in `setup/packages/`, then whichever optional categories were chosen | +| `link-dotfiles` | Symlinks `config/dot/` → `~/.config/`, and seeds the wallpaper, cursor theme and Firefox chrome | | `change-settings` | Copies `config/copy/` over `/`, applies gsettings, enables user services | | `link-vicinae-scripts` | Publishes the Vicinae script commands | | `setup-identity` | git config, `gh auth login`, an SSH key — whichever were asked for | -| `install-hardware` | NVIDIA, Secure Boot enrolment, Fedora's extras, firmware — each only if it was asked for. Last, because enrolment and firmware are consumed at the next boot | +| `install-hardware` | NVIDIA, Secure Boot enrollment, Fedora's extras, firmware — each only if it was asked for. Last, because enrollment and firmware are consumed at the next boot | The run ends with a health summary from `panama-doctor`, which reports what is actually running rather than what was attempted. It never fails the install: on a fresh machine it legitimately reports things as not yet configured. +### Optional applications + +Every machine gets the lists in `setup/packages/`. The interview also offers the +categories in `setup/packages/extras/` as a checklist, so a work laptop need not +acquire emulators and a desktop need not skip Steam. Nothing is preselected. + +A category is one file. A bare line is a dnf package and a `flatpak:` line is a +Flathub ID, because the applications in a category do not all come from one +place. Adding a category is adding a file — the menu is read from the directory, +not written down anywhere. + Existing configs are moved to `config/old/` rather than overwritten. ## Desktops diff --git a/config/firefox/README.md b/config/firefox/README.md new file mode 100644 index 0000000..e753104 --- /dev/null +++ b/config/firefox/README.md @@ -0,0 +1,35 @@ +# Firefox chrome + +This directory is **not Panama's work**. It is [Edge-Frfox][upstream] — "a +Firefox userChrome.css theme that aims to recreate the look and feel of +Microsoft Edge" — vendored here, plus two local tweaks. + +- Upstream: +- License: MIT + +`link-dotfiles` places `user.js` and `chrome/` into the Firefox profile. The +preferences in `user.js` are what the theme needs to work at all — +`toolkit.legacyUserProfileCustomizations.stylesheets` in particular, without +which Firefox ignores `chrome/` entirely. + +## Why it is vendored rather than fetched + +The same reason the cursor theme is: downloading it during the install would add +a URL that can rot, and this repository is trying to stop installing things that +way. 732K in git once, and then the theme is simply there. + +## Two things to know before editing + +`userChrome.css` imports `custom.css` last, deliberately — local changes go +there, not into the upstream files, so a future update to the theme is a +directory replacement rather than a merge. The imports of +`tweaks/hide-tabs-bar.css` and `tweaks/shrink-sideberry.css` are personal +choices carried over from sunhat, not upstream defaults. + +`userChrome.css` is unsupported by Mozilla. It breaks on major Firefox releases, +and when it does, the fix is upstream's or none. Panama installs Firefox as a +second engine to test pages against; if the theme ever costs more than it is +worth, deleting this directory and the `link-dotfiles` block that reads it +leaves a working browser behind. + +[upstream]: https://github.com/bmFtZQ/edge-frfox diff --git a/config/firefox/chrome/content/common.css b/config/firefox/chrome/content/common.css new file mode 100644 index 0000000..ff134de --- /dev/null +++ b/config/firefox/chrome/content/common.css @@ -0,0 +1,105 @@ +/* Edge-Frfox - content/common.css */ + +/* + MARK: Default colours +*/ +@-moz-document url-prefix(about:) { + :root { + --in-content-page-color: light-dark(#252525, #fff) !important; + --in-content-page-background: light-dark(#f7f7f7, #252525) !important; + --in-content-deemphasized-text: light-dark(#666, #bbb) !important; + --in-content-box-background: light-dark(#fff, #333) !important; + --in-content-box-background-odd: light-dark(rgb(0 0 0 / .05), rgb(255 255 255 / .05)) !important; + --in-content-box-info-background: light-dark(#f7f7f7, rgb(255 255 255 / 0.15)) !important; + --in-content-icon-color: light-dark(#666, #fff) !important; + --in-content-accent-color: light-dark(#006CBE, #75B6E8) !important; + --in-content-accent-color-active: light-dark(#1683D8, #4C98D1) !important; + --in-content-border-hover: light-dark(rgb(0 0 0 / .5), rgb(255 255 255 / .3)) !important; + --in-content-border-invalid: var(--red-50) !important; + --in-content-border-color: light-dark(#bebebe, rgb(255 255 255 / .2)) !important; + --in-content-error-text-color: light-dark(#FF848A, #FF9AA2) !important; + --in-content-link-color: light-dark(#0078D4, #75B6E8) !important; + --in-content-link-color-hover: light-dark(#006CBE, #63ADE5) !important; + --in-content-link-color-active: light-dark(#0749AC, #4C98D1) !important; + --in-content-link-color-visited: light-dark(#0078D4, #75B6E8) !important; + --link-color: var(--in-content-link-color) !important; + --link-color-hover: var(--in-content-link-color-hover) !important; + --link-color-active: var(--in-content-link-color-active) !important; + --link-color-visited: var(--in-content-link-color-visited) !important; + --in-content-button-text-color: var(--in-content-text-color) !important; + --in-content-button-text-color-hover: var(--in-content-text-color) !important; + --in-content-button-text-color-active: var(--in-content-button-text-color-hover) !important; + --in-content-button-background: light-dark(#EDEDED, #3B3B3B) !important; + --in-content-button-background-hover: light-dark(#e5e5e5, #545454) !important; + --in-content-button-background-active: light-dark(#d5d5d5, #606060) !important; + --in-content-primary-button-text-color: light-dark(#fff, #fff) !important; + --in-content-primary-button-background: light-dark(#0061e0, #006CBE) !important; + --in-content-primary-button-background-hover: light-dark(#0250bb, #0078D4) !important; + --in-content-primary-button-background-active: light-dark(#053e94, #005CA3) !important; + --color-accent-primary: light-dark(#0078D4, #006CBE) !important; + --color-accent-primary-hover: light-dark(#006CBE, #0078D4) !important; + --color-accent-primary-active: light-dark(#0749AC, #005CA3) !important; + --in-content-danger-button-background: light-dark(#DF4951, #E12424) !important; + --in-content-danger-button-background-hover: light-dark(#EA656C, #F94343) !important; + --in-content-danger-button-background-active: light-dark(#BB353C, #AA1E1E) !important; + --in-content-focus-outline-color: light-dark(rgb(0 85 215 / .5), #63ADE5) !important; + --focus-outline-color: var(--in-content-focus-outline-color) !important; + --in-content-table-background: light-dark(#f7f7f7, #252525) !important; + --in-content-text-color: var(--in-content-page-color) !important; + --border-interactive-color: light-dark(#929292, #858585) !important; + scrollbar-color: + light-dark(rgb(37 37 37 / .4), rgb(255 255 255 / .4)) + light-dark(#f7f7f7, #252525) !important; + } + + ::selection { + background-color: light-dark(#0078D4, #93B8E7); + color: light-dark(#fff, #000); + } +} + +/* + MARK: Preferences page +*/ +@-moz-document url-prefix(about:preferences), +url-prefix(about:addons) { + .category[selected] { + position: relative !important; + border-radius: 4px !important; + } + + .category[selected]:not(:hover, :active) { + background-color: var(--in-content-button-background) !important; + } + + .category[selected]::before { + content: ""; + position: absolute; + inset-block: 0; + margin-block: auto; + height: 24px; + width: 3px; + left: 2px; + background-color: var(--in-content-accent-color); + border-radius: 3px; + } + + button.tab-button:hover { + border-block-color: transparent var(--in-content-box-border-color) !important; + } + + button.tab-button[selected], + button.tab-button[selected]:hover { + border-block-color: transparent currentColor !important; + } + + .toggle-button { + --toggle-dot-margin: 4px !important; + --toggle-width: 40px !important; + --toggle-height: 20px !important; + --toggle-background-color: transparent !important; + --toggle-dot-background-color: var(--in-content-page-color) !important; + --toggle-dot-background-color-on-pressed: #fff !important; + --toggle-dot-transform-x: calc(var(--toggle-width) - 2 * var(--toggle-dot-margin) - 2 * var(--toggle-border-width) - var(--toggle-dot-width)) !important; + } +} diff --git a/config/firefox/chrome/content/newtab.css b/config/firefox/chrome/content/newtab.css new file mode 100644 index 0000000..f73d018 --- /dev/null +++ b/config/firefox/chrome/content/newtab.css @@ -0,0 +1,415 @@ +/* Edge-Frfox - content/newtab.css */ + +/* + MARK: Default colours +*/ +@-moz-document url-prefix("about:newtab"), +url-prefix("about:home"), +url-prefix("about:firefoxview") { + :root:not([lwt-newtab], [lwt-newtab-brighttext]) { + --newtab-background-color: #F7F7F7 !important; + --newtab-background-color-secondary: #fff !important; + --newtab-text-primary-color: #252525 !important; + --newtab-primary-action-background: #0078D4 !important; + --newtab-text-secondary-color: color-mix(in srgb, var(--newtab-text-primary-color) 80%, transparent) !important; + --newtab-element-hover-color: color-mix(in srgb, var(--newtab-background-color) 95%, #000) !important; + --newtab-element-active-color: color-mix(in srgb, var(--newtab-background-color) 90%, #000) !important; + --newtab-element-secondary-color: color-mix(in srgb, currentColor 5%, transparent) !important; + --newtab-element-secondary-hover-color: color-mix(in srgb, currentColor 12%, transparent) !important; + --newtab-element-secondary-active-color: color-mix(in srgb, currentColor 25%, transparent) !important; + --newtab-primary-element-hover-color: color-mix(in srgb, var(--newtab-primary-action-background) 90%, #000) !important; + --newtab-primary-element-active-color: color-mix(in srgb, var(--newtab-primary-action-background) 80%, #000) !important; + --newtab-primary-element-text-color: #fff !important; + --newtab-primary-action-background-dimmed: color-mix(in srgb, var(--newtab-primary-action-background) 25%, transparent) !important; + --newtab-border-color: color-mix(in srgb, var(--newtab-background-color) 75%, #000) !important; + --newtab-wordmark-color: #737373 !important; + --newtab-status-success: #50B080 !important; + --newtab-status-error: #FF848A !important; + --newtab-inner-box-shadow-color: rgb(0 0 0 / .1) !important; + --newtab-overlay-color: color-mix(in srgb, var(--newtab-background-color) 85%, transparent) !important; + --newtab-text-emphasis-background: #FFED32 !important; + --newtab-text-emphasis-text-color: #000 !important; + --newtab-textbox-focus-color: var(--newtab-primary-action-background) !important; + --newtab-textbox-focus-boxshadow: 0 0 0 1px var(--newtab-primary-action-background), 0 0 0 4px rgba(var(--newtab-primary-action-background), 0.3) !important; + --newtab-button-secondary-color: inherit !important; + } + + :root:not([style*="color"])[lwt-newtab-brighttext] { + --newtab-background-color: #252525 !important; + --newtab-background-color-secondary: #4A4A4A !important; + --newtab-text-primary-color: #fff !important; + --newtab-primary-action-background: #75B6E8 !important; + --newtab-element-hover-color: color-mix(in srgb, var(--newtab-background-color) 95%, #FFF) !important; + --newtab-element-active-color: color-mix(in srgb, var(--newtab-background-color) 90%, #FFF) !important; + --newtab-element-secondary-color: color-mix(in srgb, currentColor 10%, transparent) !important; + --newtab-element-secondary-hover-color: color-mix(in srgb, currentColor 17%, transparent) !important; + --newtab-element-secondary-active-color: color-mix(in srgb, currentColor 30%, transparent) !important; + --newtab-border-color: color-mix(in srgb, var(--newtab-background-color) 75%, #FFF) !important; + --newtab-primary-element-text-color: #252525 !important; + --newtab-wordmark-color: #fff !important; + --newtab-status-success: #50B080 !important; + } + + /* + MARK: Custom GTK colours + */ + @media (-moz-gtk-csd-available) { + :root:not([lwt-newtab]):not([style*="color"]) { + /* Colour adjusted for readability. */ + --uc-accent-adjusted: light-dark(color-mix(in oklch, AccentColor 92%, black), color-mix(in oklch, AccentColor 60%, white)); + --newtab-background-color: light-dark(-moz-dialog, color-mix(in srgb, -moz-dialog 82%, black)) !important; + --newtab-background-color-secondary: light-dark(Field, color-mix(in srgb, -moz-dialog 86%, white)) !important; + --newtab-text-primary-color: -moz-dialogtext !important; + --newtab-wordmark-color: light-dark(color-mix(in srgb, -moz-dialogtext 65%, transparent), -moz-dialogtext) !important; + --newtab-primary-action-background: var(--uc-accent-adjusted) !important; + } + } + + /* Adjustments for themes. */ + :root[style*="--newtab-background-color"] { + /* Make the Firefox logo workmark follow text colour. */ + --newtab-wordmark-color: color-mix(in srgb, var(--newtab-text-primary-color) 60%, var(--newtab-background-color)) !important; + + /* If there is no secondary background, create one from other colours. */ + &:not([style*="--newtab-background-color-secondary"]) { + --newtab-background-color-secondary: color-mix(in srgb, var(--newtab-background-color) 15%, white) !important; + } + + /* Dark adjustments for themes. */ + &[lwt-newtab-brighttext] { + /* Make the Firefox logo workmark follow text colour. */ + --newtab-wordmark-color: var(--newtab-text-primary-color) !important; + + /* If there is no secondary background, create one from other colours. */ + &:not([style*="--newtab-background-color-secondary"]) { + --newtab-background-color-secondary: color-mix(in srgb, var(--newtab-text-primary-color) 15%, var(--newtab-background-color)) !important; + } + } + } +} + +/* + MARK: New tab page +*/ +@-moz-document url-prefix("about:newtab"), +url-prefix("about:home") { + /* Enforce system font selection. */ + :where(body) { + font-family: system-ui !important; + } + + /* Hide pin icons. */ + .icon.icon-pin-small { + display: none !important; + } + + /* Unpinned sites have lower opacity titles. */ + .top-site-button .title:not(.pinned) { + opacity: 0.7 !important; + } + + /* + MARK: Search bar + */ + .search-wrapper { + & .search-handoff-button { + border-radius: 99px !important; + background-position: 12px !important; + padding-inline-start: 48px !important; + white-space: nowrap !important; + text-overflow: ellipsis !important; + --elevation: 4; + box-shadow: + 0 0 calc((var(--elevation) * 0.225px) + 2px) rgb(0 0 0 / .11), + 0 calc(var(--elevation) * 0.4px) calc((var(--elevation) * 0.9px)) rgb(0 0 0 / .13) !important; + + &:hover { + --elevation: 6; + } + } + + & .search-inner-wrapper { + min-height: 44px !important; + } + + &.fake-focus:not(.search.disabled) .search-handoff-button { + border-color: transparent !important; + outline: 2px solid var(--newtab-primary-action-background) !important; + outline-offset: -1px !important; + } + + &.search-disabled .search-handoff-button { + opacity: 0 !important; + } + + .search-handoff-button .fake-caret { + inset-inline-start: 48px !important; + top: 13px !important; + } + + @media (height > 700px) { + .fixed-search & { + padding: 15px 0 !important; + min-height: auto !important; + border-bottom: none !important; + } + } + } + + .fake-textbox { + overflow: hidden !important; + text-overflow: ellipsis !important; + } + + .outer-wrapper.only-search { + display: flex !important; + padding: 30px !important; + } + + /* Sticky search bar header when scrolling. */ + @media (height > 700px) { + body:not(.inline-onboarding) .fixed-search.visible-logo main { + padding-top: 246px !important; + + @media (-moz-bool-pref: "uc.tweak.hide-newtab-logo") { + padding-top: 82px !important; + } + } + } + + .icon-settings { + background-image: url("../icons/settings.svg") !important; + } + + /* + MARK: Top sites tiles + */ + .top-site-outer { + & .tile { + border-radius: 12px !important; + height: 44px !important; + width: 44px !important; + box-shadow: rgb(0 0 0 / 0.1) 0px 2px 4px !important; + + & .icon-wrapper { + border-radius: 4px !important; + width: 24px !important; + height: 24px !important; + + &.letter-fallback::before { + font-size: 32px !important; + } + } + } + + & .default-icon, + & .search-topsite { + background-size: 16px !important; + height: 24px !important; + width: 24px !important; + } + } + + /* + MARK: Recent activity cards + */ + .card-outer { + --uc-border-radius: 8px; + + &, + & .card, + & .ds-card-grid.ds-card-grid-border .ds-card:not(.placeholder) { + border-radius: var(--uc-border-radius) !important; + } + + & .card, + & .ds-card-grid.ds-card-grid-border .ds-card:not(.placeholder) { + box-shadow: + rgb(0 0 0 / 0.14) 0px 1px 2px, + rgb(0 0 0 / 0.12) 0px 0px 2px !important; + } + + & .card-preview-image-outer, + & .ds-card-grid.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img { + border-radius: var(--uc-border-radius) var(--uc-border-radius) 0 0 !important + } + } + + /* Add background & adjust padding for Recent activity & Pocket section. */ + .collapsible-section:not(.top-sites) { + background-color: var(--newtab-background-color) !important; + border-radius: 12px !important; + padding: 10px 20px 20px !important; + + & .section-list { + gap: 12px !important; + } + } + + @media (-moz-bool-pref: "uc.tweak.hide-newtab-logo") { + .logo-and-wordmark { + display: none !important; + } + + .outer-wrapper:not(.fixed-search) .search-wrapper { + padding-top: 0 !important; + } + } +} + +/* + MARK: Private browsing +*/ +@-moz-document url-prefix(about:privatebrowsing) { + :root { + --uc-wordmark-color: light-dark(#737373, #fff); + --uc-background-color-secondary: light-dark(#fff, #4a4a4a); + + @media (-moz-bool-pref: "browser.theme.dark-private-windows") { + color-scheme: dark !important; + } + } + + /* Custom GTK colours. */ + @media (-moz-gtk-csd-available) { + :root:not([lwt-newtab]):not([style*="color"]) { + /* Colour adjusted for readability. */ + --uc-accent-adjusted: light-dark(color-mix(in oklch, AccentColor 92%, black), color-mix(in oklch, AccentColor 60%, white)); + --in-content-page-background: light-dark(-moz-dialog, color-mix(in srgb, -moz-dialog 82%, black)) !important; + --uc-background-color-secondary: light-dark(Field, color-mix(in srgb, -moz-dialog 86%, white)) !important; + --in-content-page-color: -moz-dialogtext !important; + --in-content-focus-outline-color: var(--uc-accent-adjusted) !important; + } + } + + /* + MARK: Search bar + */ + .search-inner-wrapper { + height: 44px !important; + + .search-handoff-button, + .search-handoff-button:active, + .search-handoff-button:enabled:hover:active { + background-color: var(--uc-background-color-secondary) !important; + border: 0 !important; + border-radius: 99px !important; + padding-inline-start: 48px !important; + --elevation: 4; + box-shadow: + 0 0 calc((var(--elevation) * 0.225px) + 2px) rgb(0 0 0 / .11), + 0 calc(var(--elevation) * 0.4px) calc((var(--elevation) * 0.9px)) rgb(0 0 0 / .13) !important; + + &:hover { + --elevation: 6; + } + + &.focused:not(.disabled) { + box-shadow: none !important; + outline: 2px solid var(--in-content-focus-outline-color) !important; + outline-offset: -1px !important; + } + + &.disabled { + opacity: 0 !important; + } + + & .fake-textbox { + color: var(--in-content-page-color) !important; + } + } + } + + .wordmark { + fill: var(--uc-wordmark-color) !important; + } + + /* Information box in private browsing. */ + .info { + background-color: var(--uc-background-color-secondary) !important; + background-image: none !important; + position: relative !important; + + /* Private browsing icon. */ + &::before { + content: ""; + position: absolute; + left: 32px; + top: 20px; + height: 32px; + aspect-ratio: 1 / 1; + background: center / contain url("../icons/account-private.svg"); + border-radius: 99px; + } + } + +} + +/* + MARK: Background images +*/ +@media (-moz-bool-pref: "uc.tweak.newtab-background") { + @-moz-document url(about:newtab), + url(about:home), + url(about:privatebrowsing) { + body { + /* Specify both jpg and png file extensions, but jpg images will always + * have a higher priority. */ + --bg-0: url(../background-0.jpg), url(../background-0.png); + --bg-1: url(../background-1.jpg), url(../background-1.png); + --newtab-element-hover-color: rgb(239 239 239 / .3) !important; + --newtab-element-active-color: rgb(239 239 239 / .45) !important; + --text-shadow: 0 1px 2px #000; + --icon-shadow: drop-shadow(0 0.3px 0.6px #000); + background-color: #252525 !important; + background-image: var(--bg-0) !important; + background-position: center !important; + background-size: cover !important; + background-attachment: fixed !important; + + :root[lwt-newtab-brighttext] &, + :root.private & { + background-image: var(--bg-1), var(--bg-0) !important; + --newtab-element-hover-color: rgb(66 66 66 / .4) !important; + --newtab-element-active-color: rgb(66 66 66 / .55) !important; + } + + @media not (-moz-bool-pref: "browser.theme.dark-private-windows") { + :root.private & { + background-image: var(--bg-0) !important; + + @media (prefers-color-scheme: dark) { + background-image: var(--bg-1), var(--bg-0) !important; + } + } + } + } + + /* Change text colour & add backgrounds to text over the background. */ + .top-site-outer .title { + text-shadow: var(--text-shadow) !important; + color: #fff !important; + -moz-osx-font-smoothing: auto !important; + } + + .wordmark, + .icon-settings, + .top-site-outer .context-menu-button { + filter: var(--icon-shadow) !important; + color: #fff !important; + fill: currentColor !important + } + + .top-site-outer .title .sponsored-label { + color: #eee !important; + } + + /* Add transparent sticky search header. */ + @media (height > 700px) { + .fixed-search .search-wrapper { + border-bottom: 0 !important; + background: transparent linear-gradient(#0004, transparent) !important; + } + } + } +} diff --git a/config/firefox/chrome/custom.css b/config/firefox/chrome/custom.css new file mode 100644 index 0000000..4b2b53d --- /dev/null +++ b/config/firefox/chrome/custom.css @@ -0,0 +1,8 @@ +/* Local overrides. + * + * userChrome.css imports this last, so anything here wins over Edge-Frfox + * without editing its files -- which keeps updating the theme a matter of + * replacing the directory rather than merging into it. + * + * Deliberately empty. The import resolving to nothing is not an error in CSS, + * but a file that exists is a seam somebody can find. */ diff --git a/config/firefox/chrome/global/browser.css b/config/firefox/chrome/global/browser.css new file mode 100644 index 0000000..73ad75a --- /dev/null +++ b/config/firefox/chrome/global/browser.css @@ -0,0 +1,206 @@ +/* Edge-Frfox - browser.css + * https://github.com/bmFtZQ/edge-frfox */ + +/* Windows has 1px missing space on top of window, but not when accent colour is + * applied to the title bar. */ +@media (-moz-platform: windows) and (not (-moz-windows-accent-color-in-titlebar)) { + :root[sizemode="normal"][tabsintitlebar]:not([inFullscreen]) #navigator-toolbox { + padding-top: 1px !important; + } +} + +/* Add a shadow when the toolbars move over content, eg. in macOS hovering over + * the menu bar in fullscreen mode. */ +#navigator-toolbox[style*="transform"] { + box-shadow: 0 -3px 5px 3px light-dark(rgb(0 0 0 / .3), rgb(0 0 0 / .6)) !important; +} + +/* + MARK: Rounded corners (Rc) +*/ +@media (-moz-bool-pref: "uc.tweak.rounded-corners") { + /* Since Firefox 120, when the bookmarks bar is set to only open on new tabs, + * the bookmarks bar overlaps the #browser element. */ + + /* Change the element that shifts the browser content to the correct position. */ + #main-window[BookmarksToolbarOverlapsBrowser] .newTabBrowserPanel, + #main-window[BookmarksToolbarOverlapsBrowser] #sidebar-box { + padding-top: 0 !important; + } + + #main-window[BookmarksToolbarOverlapsBrowser] #browser { + margin-top: var(--bookmarks-toolbar-overlapping-browser-height); + } + + /* Make sure that the toolbars are not positioned in-front of the browser + * element. */ + #main-window[BookmarksToolbarOverlapsBrowser] #navigator-toolbox:not([style*="z-index"]) { + z-index: auto !important; + } + + /* Move the browser element in-front of the toolbars when on the new tab page. */ + #main-window:not([BookmarksToolbarOverlapsBrowser]) #browser { + z-index: 1 !important; + } + + /* + MARK: Rc Variables + */ + #main-window:not([chromehidden~="toolbar"]) { + --uc-tweak-rounded-corners-padding: 4px; + --uc-tweak-rounded-corners-radius: 8px; + --uc-tweak-rounded-corners-shadow: + 0 -.8px 0 0 rgb(0 0 0 / 0.02), + 0 0.5px 1px 1px rgb(0 0 0 / 0.06), + 0 1px 1px rgb(0 0 0 / 0.1); + --browser-frame-bgcolor: var(--toolbar-bgcolor, var(--lwt-accent-color)); + + /* Different shadow for higher resolution displays. */ + @media (resolution > 1.8dppx) { + --uc-tweak-rounded-corners-shadow: + 0 0 0.5px 0.5px rgb(0 0 0 / 0.06), + 0 0.5px 1.5px rgb(0 0 0 / 0.1); + } + + @media (-moz-bool-pref: "uc.tweak.floating-tabs") { + --browser-frame-bgcolor: var(--lwt-accent-color); + + &:-moz-window-inactive { + --browser-frame-bgcolor: var(--lwt-accent-color-inactive, var(--lwt-accent-color)); + } + } + } + + /* Hide border below titlebar on macOS, as its titlebar already has a border. */ + @media (-moz-platform: macos) { + :root[chromehidden~="toolbar"][chromehidden~="location"][chromehidden~="directories"] { + border-top: none !important; + } + } + + /* Remove separator between toolbars and the browser window. */ + #navigator-toolbox { + border-bottom: none !important; + } + + /* Disable rounded corners in fullscreen, only if the toolbar is hidden. */ + :root[inFullscreen] #navigator-toolbox[style*="margin-top"] + #browser, + :root[inDOMFullscreen] #browser { + --uc-tweak-rounded-corners-padding: 0; + --uc-tweak-rounded-corners-radius: 0; + --uc-tweak-rounded-corners-shadow: unset; + } + + /* + MARK: Rc Browser + */ + #appcontent .browserStack { + margin-inline: var(--uc-tweak-rounded-corners-padding) !important; + margin-block-end: var(--uc-tweak-rounded-corners-padding) !important; + border-radius: var(--uc-tweak-rounded-corners-radius) !important; + box-shadow: var(--uc-tweak-rounded-corners-shadow) !important; + background-color: var(--tabpanel-background-color) !important; + position: relative !important; + + /* Use pseudo element overlay to simulate rounded corners, similar to the + * tab corners, fixes bug with backdrop-filter. */ + &::after { + content: ""; + position: absolute; + inset: 0; + border-radius: inherit; + /* Draw toolbar background on the negative corner space, then draw the + * same shadow from the browser window on top. */ + box-shadow: + var(--uc-tweak-rounded-corners-shadow, 0 0 transparent), + 0 0 0 16px var(--browser-frame-bgcolor) !important; + clip-path: inset(0); + pointer-events: none; + } + } + + /* Prevent status panel corners and shadow from appearing outside the browser. */ + #statuspanel { + overflow: hidden; + } + + /* + MARK: Rc Sidebar + */ + #sidebar-box { + margin-inline-start: var(--uc-tweak-rounded-corners-padding) !important; + margin-block-end: var(--uc-tweak-rounded-corners-padding) !important; + border-radius: var(--uc-tweak-rounded-corners-radius) !important; + overflow: hidden !important; + box-shadow: var(--uc-tweak-rounded-corners-shadow) !important; + + &[positionend] { + margin-inline-start: 0 !important; + margin-inline-end: var(--uc-tweak-rounded-corners-padding) !important; + } + } + + /* + MARK: Rc Devtools + */ + + /* Devtools window when docked to the left or right. */ + .devtools-toolbox-side-iframe { + margin-block-end: var(--uc-tweak-rounded-corners-padding) !important; + border-radius: var(--uc-tweak-rounded-corners-radius) !important; + overflow: hidden !important; + box-shadow: var(--uc-tweak-rounded-corners-shadow) !important; + + /* Devtools window when docked to the left. */ + &:first-child { + margin-inline-start: var(--uc-tweak-rounded-corners-padding) !important; + } + + /* Devtools window when docked to the right. */ + &:last-child { + margin-inline-end: var(--uc-tweak-rounded-corners-padding) !important; + } + } + + /* Devtools window when docked to the bottom. */ + .devtools-toolbox-bottom-iframe { + margin: var(--uc-tweak-rounded-corners-padding) !important; + margin-block-start: 0 !important; + border-radius: var(--uc-tweak-rounded-corners-radius) !important; + overflow: hidden !important; + box-shadow: var(--uc-tweak-rounded-corners-shadow) !important; + } + + /* Hide devtools splitter. */ + .devtools-side-splitter, + .devtools-horizontal-splitter { + background-color: transparent !important; + } + + /* Responsive design mode. */ + .browserContainer.responsive-mode { + background-color: transparent !important; + + & .rdm-toolbar { + margin-inline: var(--uc-tweak-rounded-corners-padding) !important; + border-top-left-radius: var(--uc-tweak-rounded-corners-radius) !important; + border-top-right-radius: var(--uc-tweak-rounded-corners-radius) !important; + width: calc(100% - var(--uc-tweak-rounded-corners-padding) * 2) !important; + } + } + + /* Remove sidebar border when not in full screen. */ + :not(:root[inFullscreen] #navigator-toolbox[style*="margin-top"]) + #browser #sidebar-splitter { + border-inline-width: 0 !important; + } + + /* Apply colour to the frame around the browser window. */ + #browser { + background-color: var(--browser-frame-bgcolor); + } + + /* Change colour of page when loading */ + #tabbrowser-tabpanels { + background-color: transparent !important; + } +} diff --git a/config/firefox/chrome/global/colors.css b/config/firefox/chrome/global/colors.css new file mode 100644 index 0000000..abaf8dc --- /dev/null +++ b/config/firefox/chrome/global/colors.css @@ -0,0 +1,366 @@ +/* Edge-Frfox - colors.css + * https://github.com/bmFtZQ/edge-frfox */ + +/* + MARK: Default colours +*/ +:root:not([lwtheme]), +/* `--newtab-background-color-secondary used` to differentiate between a dark + * private window and private window with the 'Dark' theme enabled. + * May not be the most reliable method, but works for now up to FF 123. */ +:root[privatebrowsingmode="temporary"]:where([style*="--lwt-accent-color: rgb(28, 27, 34)"]:not([style*="--newtab-background-color-secondary: rgb(66, 65, 77)"])) { + /* Toolbars */ + --lwt-accent-color: light-dark(#cecece, #1C1C1C) !important; + --lwt-accent-color-inactive: light-dark(#e8e8e8, #2e2e2e) !important; + --lwt-text-color: light-dark(#000, #FFF) !important; + --lwt-text-color-inactive: light-dark(#3A3A3A, #CBCBCB) !important; + --tab-selected-textcolor: light-dark(#000, #fff) !important; + --tab-selected-textcolor-inactive: light-dark(#3E3E3E, #CBCBCB) !important; + --tab-selected-bgcolor: var(--toolbar-bgcolor) !important; + --tab-attention-icon-color: light-dark(#0078D4, #93d0ff) !important; + --toolbar-bgcolor: light-dark(#f7f7f7, #3B3B3B) !important; + --toolbar-non-lwt-bgcolor: var(--toolbar-bgcolor) !important; + --toolbar-color: light-dark(#000, #fff) !important; + --toolbarbutton-icon-fill: var(--toolbar-color) !important; + --toolbarbutton-icon-fill-attention: light-dark(#0078D4, #4C98D1) !important; + --toolbarseparator-color: color-mix(in srgb, currentColor 25%, transparent) !important; + --chrome-content-separator-color: light-dark(#bfbfbf, #686868) !important; + --newtab-background-color: light-dark(#f7f7f7, #252525) !important; + --tabpanel-background-color: var(--newtab-background-color, var(--toolbar-bgcolor, transparent)) !important; + /* Toolbar button overlays */ + --toolbarbutton-hover-background: color-mix(in srgb, currentColor 8%, transparent) !important; + --toolbarbutton-active-background: color-mix(in srgb, currentColor 13.5%, transparent) !important; + /* Tab audio indicator overlay icon */ + --tab-icon-overlay-fill: var(--toolbar-color) !important; + --tab-icon-overlay-stroke: var(--toolbar-bgcolor) !important; + /* URL bar */ + --toolbar-field-background-color: light-dark(#fff, #2B2B2B) !important; + --toolbar-field-color: light-dark(#000, #fff) !important; + --toolbar-field-border-color: transparent !important; + --toolbar-field-focus-background-color: var(--toolbar-field-background-color) !important; + --toolbar-field-focus-color: var(--toolbar-field-color) !important; + --toolbar-field-focus-border-color: light-dark(#0055D780, #63ADE5) !important; + --urlbar-icon-fill-opacity: 0.58 !important; + --urlbar-box-bgcolor: light-dark(rgb(0 0 0 / .09), rgb(255 255 255 / .11)) !important; + --urlbar-box-hover-bgcolor: light-dark(rgb(0 0 0 / .09), rgb(255 255 255 / .11)) !important; + --urlbar-box-active-bgcolor: light-dark(rgb(0 0 0 / .22), rgb(255 255 255 / .28)) !important; + --urlbar-box-focus-bgcolor: var(--urlbar-box-hover-bgcolor) !important; + /* URL bar suggestions */ + --link-color: light-dark(#0078D4, #75B6E8) !important; + --uc-urlbarView-accent-color: light-dark(#1A6397, #75B6E8) !important; + --urlbarView-highlight-background: light-dark(#F2F2F2, #383838) !important; + --urlbarView-highlight-color: light-dark(#000, #fff) !important; + --urlbarView-hover-background: light-dark(#e5e5e5, #444444) !important; + --urlbarView-separator-color: light-dark(#EFEFEF, #5F5F5F) !important; + /* Menus/panels */ + --arrowpanel-background: light-dark(#fff, #4A4A4A) !important; + --arrowpanel-color: light-dark(#1c1c1c, #fff) !important; + --arrowpanel-border-color: light-dark(#fff, #636363) !important; + --arrowpanel-dimmed: light-dark(#565656, #565656) !important; + --arrowpanel-dimmed-further: light-dark(#707070, #707070) !important; + --panel-separator-color: light-dark(#dadada, #636363) !important; + --panel-description-color: light-dark(#000a, #fffb) !important; + --panel-disabled-color: light-dark(#9E9E9E, #B9B9B9) !important; + --panel-item-hover-bgcolor: light-dark(#eee, #646464) !important; + --panel-item-active-bgcolor: light-dark(#ddd, #747474) !important; + --panel-banner-item-update-supported-bgcolor: light-dark(#188038, #81C995) !important; + /* Primary button */ + --button-primary-bgcolor: light-dark(#0078D4, #006CBE) !important; + --button-primary-color: light-dark(#fff, #fff) !important; + --button-primary-hover-bgcolor: light-dark(#006BBD, #1C7CC5) !important; + --button-primary-active-bgcolor: light-dark(#0060AA, #3289CB) !important; + /* Secondary button */ + --button-bgcolor: light-dark(#EFEFEF, #5C5C5C) !important; + --button-color: light-dark(#000, #fff) !important; + --button-hover-bgcolor: light-dark(#D5D5D5, #6E6E6E) !important; + --button-active-bgcolor: light-dark(#C0C0C0, #7C7C7C) !important; + /* Text input field, e.g. bookmarks editor */ + --focus-outline-color: light-dark(#0055D780, #63ADE5) !important; + --input-bgcolor: light-dark(#fff, #4A4A4A) !important; + --input-color: light-dark(#2b2b2b, #fff) !important; + --input-border-color: light-dark(#bebebe, #808080) !important; + --error-text-color: light-dark(#FF9AA2, #FF9AA2) !important; + --input-error-border-color: light-dark(#FF848A, #FF848A) !important; + /* Side bar colours. */ + --sidebar-background-color: light-dark(#f7f7f7, #3b3b3b) !important; + --sidebar-text-color: light-dark(#000, #fff) !important; + --sidebar-border-color: light-dark(#bfbfbf, #686868) !important; + + /* ::::: Dialog theme ::::: */ + & #window-modal-dialog::backdrop { + /* Overlay when dialog is shown. */ + background-color: rgb(20 20 20 / .2) !important; + } + + &[dialogroot] { + /* Dialog */ + --in-content-page-background: var(--arrowpanel-background) !important; + --in-content-page-color: var(--arrowpanel-color) !important; + /* Primary button */ + --in-content-primary-button-text-color: var(--button-primary-color) !important; + --in-content-primary-button-background: var(--button-primary-bgcolor) !important; + --in-content-primary-button-background-hover: var(--button-primary-hover-bgcolor) !important; + --in-content-primary-button-background-active: var(--button-primary-active-bgcolor) !important; + /* Secondary button */ + --in-content-button-text-color: var(--button-color) !important; + --in-content-button-background: var(--button-bgcolor) !important; + --in-content-button-background-hover: var(--button-hover-bgcolor) !important; + --in-content-button-background-active: var(--button-active-bgcolor) !important; + /* Text input */ + --in-content-box-background: var(--input-bgcolor) !important; + --in-content-box-border-color: var(--input-border-color) !important; + } +} + +/* Ensure that dark mode is enabled completely in private browsing mode. */ +@media (-moz-bool-pref: "browser.theme.dark-private-windows") { + :root[privatebrowsingmode="temporary"], + :root[privatebrowsingmode="temporary"] #nav-bar, + :root[privatebrowsingmode="temporary"] #PersonalToolbar { + --toolbar-color-scheme: dark !important; + --tab-selected-color-scheme: dark !important; + color-scheme: dark !important; + } +} + +/* Apply colours to the default 'Auto' theme. */ +:root:not([lwtheme]) #navigator-toolbox { + background-color: var(--lwt-accent-color) !important; + color: var(--lwt-text-color) !important; + + /* Inactive window background colours. */ + &:-moz-window-inactive { + background-color: var(--lwt-accent-color-inactive, var(--lwt-accent-color)) !important; + color: var(--lwt-text-color-inactive, var(--lwt-text-color)) !important; + } +} + +/* Make sure that the tab toolbar opacity is always 1, inactive window colours + * are already supplied by this theme. */ + :root[tabsintitlebar] #titlebar:-moz-window-inactive { + opacity: 1 !important; +} + +/* Make the titlebar buttons black/white on default themes */ +:root:not([lwtheme])[tabsintitlebar] .titlebar-buttonbox { + color: var(--lwt-text-color) !important; +} + +/* Status/link preview panel */ +#statuspanel-label { + background-color: var(--toolbar-field-focus-background-color) !important; + color: var(--toolbar-field-focus-color) !important; + border-color: transparent !important; + box-shadow: 0 2px 5px #0002, 0 0 0 1px light-dark(#0001, #0002) !important; + border-radius: 0 4px 0 0 !important; + + #statuspanel[mirror] & { + border-radius: 4px 0 0 0 !important; + } +} + +/* + MARK: Windows +*/ +@media (-moz-platform: windows) { + /* Colour the text selection background and foreground. */ + ::selection { + background-color: light-dark(#0078D4, #93B8E7) !important; + color: light-dark(#fff, #000) !important; + } + + tooltip { + background-color: var(--arrowpanel-background) !important; + color: var(--arrowpanel-color) !important; + border-color: var(--arrowpanel-border-color) !important; + } + + /* Use accent colour in titlebar when Windows option is enabled. */ + @media (-moz-windows-accent-color-in-titlebar) and (-moz-bool-pref: "browser.theme.windows.accent-color-in-tabs.enabled") { + /* Uses :root:root to beat specificity of floating tabs adjustments. */ + :root:root:not([lwtheme]) { + --lwt-accent-color: ActiveCaption !important; + --lwt-text-color: CaptionText !important; + --lwt-accent-color-inactive: InActiveCaption !important; + --lwt-text-color-inactive: InActiveCaptionText !important; + } + } + + .titlebar-button:not(.titlebar-close):hover { + background-color: color-mix(in srgb, currentColor 11%, transparent) !important; + + &:active { + background-color: color-mix(in srgb, currentColor 20%, transparent) !important; + } + } + + .titlebar-close:hover { + stroke: white !important; + background-color: #e81123 !important; + + &:active { + background-color: #DC5C66 !important; + } + + toolbar[brighttext] &:active { + background-color: #971821 !important; + } + } + + /* Library window colour theme. */ + window#places { + --organizer-color: light-dark(#000, #fff) !important; + --organizer-deemphasized-color: light-dark(#666, #bbb) !important; + --organizer-toolbar-background: light-dark(#f7f7f7, #3B3B3B) !important; + --organizer-pane-background: light-dark(#f7f7f7, #2B2B2B) !important; + --organizer-content-background: light-dark(#f7f7f7, #1C1C1C) !important; + --organizer-hover-background: light-dark(#00000025, #ffffff25) !important; + --organizer-selected-background: light-dark(#006CBE80, #006CBE80) !important; + --organizer-outline-color: light-dark(#0055D7a0, #63ADE5) !important; + --organizer-toolbar-field-background: light-dark(#fff, #2B2B2B) !important; + --organizer-toolbar-field-background-focused: light-dark(#fff, #2B2B2B) !important; + --organizer-border-color: light-dark(#bfbfbf, #686868) !important; + scrollbar-color: + light-dark(#0006, #fff6) + light-dark(#f7f7f740, #2B2B2B40) !important; + } + + #placesViewsBox #downloadsListBox richlistitem[selected="true"] { + background-color: light-dark(#006CBE, #006CBE) !important; + color: light-dark(#fff, #fff) !important; + } + + #placeContentColumns :is(treecol, treecolpicker) { + background-color: light-dark(#f7f7f7, #3B3B3B) !important; + color: light-dark(#000, #fff) !important; + border-inline-start: 1px solid light-dark(#bfbfbf, #686868) !important; + box-shadow: inset 0 -1px light-dark(#bfbfbf, #686868) !important; + appearance: none !important; + } + + #placeContentColumns :is(treecol, treecolpicker):where(:hover) { + background-color: light-dark(#cecece, #4A4A4A) !important; + color: light-dark(#000, #fff) !important; + } +} + +/* Prevent macOS vibrancy appearance, instead using a solid background. */ +#sidebar-box { + appearance: none !important; +} + +.sidebar-panel:not([lwt-sidebar]) { + color: light-dark(#000, #fff) !important; + scrollbar-color: light-dark(#0006, #fff6) light-dark(#f7f7f740, #3b3b3b40) !important; + + /* Sidebar search box (Windows) */ + @media(-moz-platform: windows) { + & #sidebar-search-container > #search-box, + & #viewButton { + appearance: none !important; + background-color: var(--toolbar-field-background-color) !important; + color: inherit !important; + border: 1px solid var(--input-border-color) !important; + border-radius: 4px !important; + padding: 6px 8px !important; + + &:focus { + outline: 2px solid var(--input-border-color) !important; + outline-offset: -2px !important; + border-color: transparent !important; + } + } + } +} + +@-moz-document url(chrome://browser/content/syncedtabs/sidebar.xhtml) { + body { + background: transparent !important; + } +} + +/* + MARK: Linux / GTK csd +*/ +@media (-moz-gtk-csd-available) { + :root:not([lwtheme]), + /* `--newtab-background-color-secondary used` to differentiate between a dark + * private window and private window with the 'Dark' theme enabled. + * May not be the most reliable method, but works for now up to FF 123. */ + :root[privatebrowsingmode="temporary"]:where([style*="--lwt-accent-color: rgb(28, 27, 34)"]:not([style*="--newtab-background-color-secondary: rgb(66, 65, 77)"])) { + /* Used for mixing colours differently in light/dark themes. */ + --uc-tint: light-dark(black, white); + /* Colour adjusted for readability. */ + --uc-accent-adjusted: light-dark( + color-mix(in oklch, AccentColor 92%, black), + color-mix(in oklch, AccentColor 60%, white) + ); + /* Toolbars */ + --lwt-accent-color: light-dark(color-mix(in srgb, ActiveCaption 90%, black), ActiveCaption) !important; + --lwt-accent-color-inactive: light-dark(color-mix(in srgb, InactiveCaption 94%, black), InactiveCaption) !important; + --lwt-text-color: CaptionText !important; + --lwt-text-color-inactive: color-mix(in srgb, CaptionText 65%, transparent) !important; + --tab-selected-textcolor: var(--toolbar-color) !important; + --tab-selected-textcolor-inactive: color-mix(in srgb, var(--toolbar-color) 65%, transparent) !important; + --tab-selected-bgcolor: var(--toolbar-bgcolor) !important; + --tab-attention-icon-color: var(--uc-accent-adjusted) !important; + --toolbar-bgcolor: light-dark(-moz-dialog, color-mix(in srgb, -moz-dialog 92%, white)) !important; + --toolbar-color: -moz-dialogtext !important; + --toolbarbutton-icon-fill-attention: var(--uc-accent-adjusted) !important; + --chrome-content-separator-color: color-mix(in srgb, currentColor 17%, var(--toolbar-bgcolor)) !important; + --newtab-background-color: light-dark(-moz-dialog, color-mix(in srgb, -moz-dialog 82%, black)) !important; + /* URL bar */ + --toolbar-field-background-color: light-dark(Field, color-mix(in srgb, Field 96%, -moz-dialogtext)) !important; + --toolbar-field-color: FieldText !important; + --toolbar-field-focus-border-color: light-dark(color-mix(in srgb, var(--focus-outline-color) 50%, transparent), var(--focus-outline-color)) !important; + --urlbar-box-bgcolor: var(--button-bgcolor) !important; + --urlbar-box-hover-bgcolor: var(--button-hover-bgcolor) !important; + --urlbar-box-active-bgcolor: var(--button-active-bgcolor) !important; + /* URL bar suggestions. */ + --link-color: var(--uc-accent-adjusted) !important; + --uc-urlbarView-accent-color: var(--uc-accent-adjusted) !important; + --urlbarView-highlight-background: var(--panel-item-hover-bgcolor) !important; + --urlbarView-highlight-color: var(--toolbar-field-color) !important; + --urlbarView-hover-background: var(--panel-item-active-bgcolor) !important; + --urlbarView-separator-color: var(--panel-separator-color) !important; + /* Menus/panels */ + --arrowpanel-background: Field !important; + --arrowpanel-color: FieldText !important; + --arrowpanel-border-color: light-dark(transparent, var(--panel-separator-color)) !important; + --arrowpanel-dimmed: color-mix(in srgb, currentColor 17%, transparent) !important; + --arrowpanel-dimmed-further: color-mix(in srgb, currentColor 30%, transparent) !important; + --panel-separator-color: color-mix(in srgb, currentColor 17%, var(--arrowpanel-background)) !important; + --panel-description-color: GrayText !important; + --panel-disabled-color: GrayText !important; + --panel-item-hover-bgcolor: color-mix(in srgb, currentColor 8%, transparent) !important; + --panel-item-active-bgcolor: color-mix(in srgb, currentColor 13%, transparent) !important; + /* Primary button */ + --button-primary-bgcolor: AccentColor !important; + --button-primary-color: AccentColorText !important; + --button-primary-hover-bgcolor: color-mix(in srgb, var(--uc-tint) 10%, var(--button-primary-bgcolor)) !important; + --button-primary-active-bgcolor: color-mix(in srgb, var(--uc-tint) 20%, var(--button-primary-bgcolor)) !important; + /* Secondary button */ + --button-bgcolor: color-mix(in srgb, currentColor 10%, transparent) !important; + --button-color: currentColor !important; + --button-hover-bgcolor: color-mix(in srgb, currentColor 14%, transparent) !important; + --button-active-bgcolor: color-mix(in srgb, currentColor 20%, transparent) !important; + /* Text input field, e.g. bookmarks editor. */ + --focus-outline-color: var(--uc-accent-adjusted) !important; + --input-bgcolor: var(--arrowpanel-background) !important; + --input-color: var(--arrowpanel-color) !important; + --input-border-color: color-mix(in srgb, currentColor 35%, var(--arrowpanel-background)) !important; + /* Sidebar */ + --sidebar-background-color: var(--toolbar-bgcolor) !important; + --sidebar-text-color: var(--toolbar-color) !important; + --sidebar-border-color: var(--chrome-content-separator-color) !important; + } + + /* Use the same sidebar splitter style as other platforms. */ + .sidebar-splitter { + border: 0 solid var(--sidebar-border-color) !important; + border-inline-end-width: 1px !important; + width: 4px !important; + background-color: transparent !important; + margin-inline-start: -4px !important; + } +} diff --git a/config/firefox/chrome/global/popup.css b/config/firefox/chrome/global/popup.css new file mode 100644 index 0000000..8805a81 --- /dev/null +++ b/config/firefox/chrome/global/popup.css @@ -0,0 +1,847 @@ +/* Edge-Frfox - popup.css */ + +/* + MARK: Variables +*/ +:root { + --panel-subview-body-padding: 2px 0 !important; + --arrowpanel-border-radius: 8px !important; + --arrowpanel-menuitem-border-radius: 4px !important; + --arrowpanel-menuitem-margin: var(--uc-arrowpanel-menuitem-margin-block) var(--uc-arrowpanel-menuitem-margin-inline) !important; + --arrowpanel-menuitem-padding-block: 6px !important; + --arrowpanel-menuitem-padding-inline: 10px !important; + --uc-arrowpanel-menuicon-margin-inline: 14px; + --uc-arrowpanel-menuitem-margin-inline: 4px; + --uc-arrowpanel-menuitem-margin-block: 2px; + --panel-separator-margin-vertical: 2px !important; + --panel-separator-margin-horizontal: 0 !important; + + --uc-panel-zoom-button-padding: 8px; + --uc-panel-zoom-button-inline-padding: 9px; + --uc-panel-zoom-padding-block: calc(var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block)); + + --uc-autocomplete-panel-menuitem-margin: 4px; + --uc-autocomplete-panel-menuicon-padding-inline: 14px; + --uc-autocomplete-panel-separator-margin-vertical: 4px; + + --uc-permission-itemcontainer-padding-block: 8px; + --uc-permission-item-margin-block: 4px; + --uc-permission-item-padding-inline: 16px; + + --uc-contextmenu-border-radius: 8px; + --uc-contextmenu-padding: calc(4px - var(--uc-contextmenu-menuitem-border-width)) 0; + --uc-contextmenu-menuitem-border-radius: calc(4px + var(--uc-contextmenu-menuitem-border-width)); + --uc-contextmenu-menuitem-padding-block: 6px; + --uc-contextmenu-menuitem-padding-inline: 10px; + --uc-contextmenu-menuitem-border-width: 2px; + --uc-contextmenu-menuicon-margin-inline: 12px; + --uc-contextmenu-menuitem-margin-inline: calc(4px - var(--uc-contextmenu-menuitem-border-width)); + --uc-contextmenu-menuitem-margin-block: 0px; + --uc-contextmenu-menuitem-margin: var(--uc-contextmenu-menuitem-margin-block) var(--uc-contextmenu-menuitem-margin-inline); + --uc-contextmenu-separator-vertical: calc(4px - var(--uc-contextmenu-menuitem-border-width)); + --uc-contextmenu-separator-horizontal: 0; +} + +/* + MARK: App menu +*/ +.addon-banner-item, +.panel-banner-item { + margin: 2px 4px 2px !important; + padding-inline: 4px 12px !important; + padding-block: var(--arrowpanel-menuitem-padding-block) !important; + border-radius: var(--arrowpanel-menuitem-border-radius) !important; +} + +#appMenu-fxa-label2 label, +#PanelUI-fxa-menu-syncnow-button label { + margin-block: 0 !important; +} + +.widget-overflow-list .toolbarbutton-1:not(.toolbarbutton-combined) > .toolbarbutton-text, +.subviewbutton:not(#appMenu-zoom-controls > .subviewbutton) > .toolbarbutton-icon + .toolbarbutton-text, +#appMenu-fxa-label2 > vbox { + padding-inline-start: var(--uc-arrowpanel-menuicon-margin-inline) !important; +} + +/* special case menuitems with no icons */ +#appMenu-zoom-controls > .toolbarbutton-text, +#fxa-manage-account-button > vbox, +#PanelUI-fxa-menu-syncnow-button > hbox { + padding-inline-start: calc(16px + var(--uc-arrowpanel-menuicon-margin-inline)) !important; +} + +.subviewbutton > .toolbarbutton-icon { + width: 16px !important; +} + +/* firefox profile avatar in appmenu */ +#appMenu-fxa-label2::before { + content: ""; + display: flex; + height: 16px; + width: 16px; + background: var(--avatar-image-url) 0/16px; + scale: 1.25; + border-radius: 99px; +} + +/* disable proton account separator */ +#appMenu-fxa-separator { + border-image: none !important; +} + +#appMenu-fxa-status2:not([fxastatus]) { + padding-block: 0 !important; +} + +#appMenu-fxa-status2:not([fxastatus]) > #appMenu-fxa-label2 { + margin-inline-end: calc(var(--arrowpanel-menuitem-padding-inline) * -1) !important; +} + +/* zoom controls */ +#appMenu-zoom-controls { + border-top: 1px solid var(--panel-separator-color) !important; + padding-inline: calc(var(--arrowpanel-menuitem-padding-inline) + var(--uc-arrowpanel-menuitem-margin-inline)) var(--uc-arrowpanel-menuitem-margin-inline) !important; + padding-block: var(--uc-panel-zoom-padding-block) !important; + margin: var(--panel-separator-margin-vertical) 0 calc(var(--panel-separator-margin-vertical) * -1) !important; +} + +#appMenu-zoom-controls > .subviewbutton { + padding: var(--uc-panel-zoom-button-padding) var(--uc-panel-zoom-button-inline-padding) !important; + margin: 0 !important; +} + +#appMenu-zoom-controls > #appMenu-zoomReset-button2 { + padding: var(--uc-panel-zoom-button-padding) calc(var(--uc-panel-zoom-button-padding) / 2) !important; +} + +/* #appMenu-zoomReduce-button2, */ +#appMenu-zoom-controls > #appMenu-fullscreen-button2 { + margin-left: calc((var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block)) * 2 + 1px) !important; +} + +#appMenu-zoom-controls > #appMenu-fullscreen-button2::before { + content: ""; + border-inline-start: 1px solid var(--panel-separator-color); + display: block; + position: relative; + height: 32px; + margin-block: calc(var(--uc-panel-zoom-button-padding) * -1); + transform: translateX(calc(var(--uc-panel-zoom-button-inline-padding) * -1 - (var(--panel-separator-margin-vertical) + var(--uc-arrowpanel-menuitem-margin-block)) - 1px)); +} + +#appMenu-zoomReset-button2 { + height: calc(16px + var(--uc-panel-zoom-button-padding) * 2) !important; + min-height: calc(16px + var(--uc-panel-zoom-button-padding) * 2) !important; +} + +#appMenu-zoomReduce-button2:not([disabled], [open], :active):is(:hover), +#appMenu-zoomEnlarge-button2:not([disabled], [open], :active):is(:hover), +#appMenu-fullscreen-button2:not([disabled], [open], :active):is(:hover), +#appMenu-zoomReset-button2:not([disabled], [open], :active):is(:hover) { + background-color: var(--panel-item-hover-bgcolor) !important; +} + +#appMenu-zoomReduce-button2:not([disabled]):is([open], :hover:active), +#appMenu-zoomEnlarge-button2:not([disabled]):is([open], :hover:active), +#appMenu-fullscreen-button2:not([disabled]):is([open], :hover:active), +#appMenu-zoomReset-button2:not([disabled]):is([open], :hover:active) { + background-color: var(--panel-item-active-bgcolor) !important; +} + +#appMenu-zoomReduce-button2 > .toolbarbutton-icon, +#appMenu-zoomEnlarge-button2 > .toolbarbutton-icon { + fill: currentColor !important; + stroke: none !important; +} + +#appMenu-zoomReset-button2 > .toolbarbutton-text, +#appMenu-fullscreen-button2 > .toolbarbutton-icon { + background-color: transparent !important; + padding: 0 !important; +} + +.subviewbutton[shortcut]::after { + opacity: 0.7 !important; +} + +#widget-overflow-mainView .panel-subview-body { + padding-bottom: 0 !important; +} + +.PanelUI-subView > .panel-header + toolbarseparator { + margin-bottom: 0 !important; +} + +.PanelUI-subView > .panel-header + toolbarseparator + .panel-subview-body { + padding-top: var(--panel-separator-margin-vertical) !important; +} + +#identity-popup-security-button { + margin-bottom: var(--panel-separator-margin-vertical) !important; +} + +#permission-popup-mainView-panel-header, +#identity-popup-mainView-panel-header, +#protections-popup-mainView-panel-header, +.panel-header { + min-height: calc((var(--arrowpanel-menuitem-padding-block) + 4px) * 2 + 16px) !important; +} + +/* URL bar popup */ +.panel-footer > button { + border-radius: 2px !important; +} + +.identity-popup-security-connection > hbox > description { + margin-inline-start: 0 !important; +} + +.identity-popup-security-connection.identity-button { + margin-inline-end: calc(-1 * (var(--arrowpanel-menuitem-padding-inline) - 10px)) !important; +} + +#identity-popup-mainView-panel-header-span, +#permission-popup-mainView-panel-header-span, +#identity-popup-mainView-panel-header label, +#permission-popup-mainView-panel-header label, +#protections-popup-mainView-panel-header-span { + margin-block: 0 !important; +} + +.permission-popup-section { + padding-block: var(--uc-permission-itemcontainer-padding-block) !important; +} + +#permission-popup-permissions-content { + padding-inline: var(--uc-permission-item-padding-inline) !important; +} + +.permission-popup-permission-item, +#permission-popup-storage-access-permission-list-header { + margin-block: var(--uc-permission-item-margin-block) !important; +} + +.permission-popup-permission-label, +.permission-popup-permission-header-label { + margin-inline-start: var(--uc-arrowpanel-menuicon-margin-inline) !important; +} + +#editBookmarkPanel > #editBookmarkHeaderSeparator, +#editBookmarkPanel > .panel-subview-body > #editBookmarkSeparator { + margin-inline: 0 !important; +} + +/* subview */ +.panel-header { + padding: 4px !important; + padding-top: 4px !important; +} + +.panel-header + toolbarseparator, +#identity-popup-mainView-panel-header + toolbarseparator, +#permission-popup-mainView-panel-header + toolbarseparator, +#protections-popup-mainView-panel-header-section + toolbarseparator { + margin-block-start: 0 !important; +} + +.panel-header > .subviewbutton-back { + margin: 0 !important; + padding: var(--arrowpanel-menuitem-padding-block) !important; +} + +.panel-subview-footer-button { + margin-bottom: 4px !important; +} + +.webextension-popup-browser, +.webextension-popup-stack { + margin-block-start: calc(var(--panel-separator-margin-vertical) * -.5) !important; +} + +/* + MARK: Downloads +*/ +.downloadTypeIcon { + height: 16px !important; + width: 16px !important; +} + +.downloadButton { + min-width: calc(16px + var(--uc-toolbarbutton-inner-inline-padding) * 2) !important; + height: calc(16px + var(--toolbarbutton-inner-padding) * 2) !important; + border-radius: var(--toolbarbutton-border-radius) !important; +} + +.downloadProgress::-moz-progress-bar, +.downloadProgress > div { + background-color: var(--toolbarbutton-icon-fill-attention) !important; +} + +.downloadMainArea { + padding-block: 4px !important; + padding-inline: 12px !important; + border-radius: 0 !important; +} + +#downloadsListBox > richlistitem { + padding-inline-end: 8px !important; + border-radius: var(--arrowpanel-menuitem-border-radius) !important; +} + +#downloadsListBox, +.downloadsPanelFooterButton { + margin: var(--arrowpanel-menuitem-margin) !important; + width: auto !important; + min-width: auto !important; +} + +#downloadsPanel-blockedSubview, +#downloadsPanel-mainView { + padding: var(--panel-separator-margin-vertical) 0 !important; +} + +#emptyDownloads { + padding: 1.5em 16px 1.7em !important; +} + +#downloadsHistory .button-text { + margin-block: 0 !important; + margin-inline: 0 !important; +} + +.PanelUI-subView .subviewbutton-nav::after, +#PlacesToolbar menu > .menu-right, +.subviewbutton > .menu-right { + fill-opacity: 1 !important; +} + +/* + MARK: Extensions +*/ +/* #region */ + +.toolbaritem-combined-buttons:is(:not([cui-areatype="toolbar"]), [overflowedItem="true"]) > toolbarbutton:not(.toolbarbutton-1)[disabled] { + opacity: 1 !important; + color: var(--panel-disabled-color) !important; +} + +/* Removes space above extensions items. */ +#unified-extensions-messages-container { + margin-block: 0 !important; +} + +:root { + --uei-icon-size: 24px !important; +} + +@media (-moz-bool-pref: "uc.tweak.context-menu.compact-extensions-menu") { + :root { + --uei-icon-size: 16px !important; + } + + /* Hide site access permissions label. */ + .unified-extensions-item-message-deck { + display: none !important; + } + + /* Use smaller toolbar extension icon if available. */ + toolbaritem:is([overflowedItem="true"], [cui-areatype="panel"]) > .webextension-browser-action { + list-style-image: var(--webextension-toolbar-image, var(--webextension-menupanel-image, inherit)) !important; + } +} + +/* Use smaller font-size in extensions menu on Windows. */ +@media (-moz-platform: windows) { + #unified-extensions-panel .toolbarbutton-text { + font: menu !important; + font-family: inherit !important; + } +} + +/* Prevent extension labels from using >1 line, adding ellipsis if necessary. */ +.unified-extensions-item-contents { + flex: 1 !important; + + & > .unified-extensions-item-name, + & > .unified-extensions-item-message-deck > .unified-extensions-item-message { + max-width: calc(100% - 4px) !important; + overflow: hidden !important; + text-overflow: ellipsis !important; + white-space: nowrap !important; + } +} + +/* Extension item menu button. */ +.unified-extensions-item-menu-button { + padding: 0 !important; + + & > .toolbarbutton-icon { + border: none !important; + padding-inline: var(--arrowpanel-menuitem-padding-inline) !important; + padding-block: var(--arrowpanel-menuitem-padding-block) !important; + margin-inline-start: var(--uc-arrowpanel-menuitem-margin-inline) !important; + } +} + +/* Add grayscale filter to extensions with no access to current site. */ +.unified-extensions-list .unified-extensions-item-action-button:has(.unified-extensions-item-message[data-l10n-id="origin-controls-state-no-access"]) .unified-extensions-item-icon { + filter: grayscale(1) !important; +} + +/* Adjust spacing between the extension item's icon and label. */ +.unified-extensions-item-name, +.unified-extensions-item-message { + padding-inline-start: var(--uc-arrowpanel-menuicon-margin-inline) !important; +} + +.unified-extensions-item-icon, +.unified-extensions-item .webextension-browser-action > .toolbarbutton-badge-stack { + margin-inline-end: 0 !important; +} +/* #endregion */ + +/* + MARK: Autocomplete +*/ +#PopupAutoComplete { + /* workaround for inaccessible shadow-root element + moves the shadow-root element underneath, and away from panel edges */ + padding-block: 10px !important; + padding-inline: 2px !important; + + & > .autocomplete-richlistbox { + background: var(--arrowpanel-background) !important; + box-shadow: 0 0 0 1px inset var(--arrowpanel-border-color) !important; + height: auto !important; + margin-block: -10px !important; + margin-inline: -2px !important; + padding: var(--uc-contextmenu-padding) !important; + border-radius: var(--uc-contextmenu-border-radius) !important; + color: inherit !important; + } + + & .autocomplete-richlistitem[originaltype="loginsFooter"] { + justify-content: start !important; + color: inherit !important; + background-color: transparent !important; + height: 28px !important; + min-height: 28px !important; + padding-inline-start: var(--uc-contextmenu-menuitem-padding-inline) !important; + position: relative !important; + overflow: visible !important; + margin-top: calc(var(--uc-contextmenu-separator-vertical) * 2 + 1px) !important; + } + + /* Separator */ + & .autocomplete-richlistitem[originaltype="loginsFooter"]::before { + content: ""; + width: calc(100% + var(--uc-contextmenu-menuitem-margin-inline) * 2); + border-top: 1px solid var(--panel-separator-color); + position: absolute; + top: calc((var(--uc-contextmenu-separator-vertical) + var(--uc-contextmenu-menuitem-border-width)) * -1 - 1px); + left: calc(var(--uc-contextmenu-menuitem-margin-inline) * -1); + } + + & .autocomplete-richlistitem:hover { + background-color: var(--panel-item-hover-bgcolor) !important; + } + + & .autocomplete-richlistitem[selected] { + background-color: var(--panel-item-active-bgcolor) !important; + color: inherit !important; + } + + & .ac-site-icon { + fill: currentColor !important; + margin-block: auto !important; + margin-inline: 0 var(--uc-autocomplete-panel-menuicon-padding-inline) !important; + } + + & .ac-title { + margin-inline: calc(16px + var(--uc-autocomplete-panel-menuicon-padding-inline)) !important; + } + + & .two-line-wrapper { + padding: 0 !important; + gap: 0 !important; + } +} + +#PlacesToolbar menuitem, +#PlacesToolbar menu, +panelview .toolbarbutton-1, +.subviewbutton, +.widget-overflow-list .toolbarbutton-1 { + min-height: calc(16px + var(--uc-contextmenu-menuitem-padding-block) * 2) !important; +} + +/* + MARK: Search bar suggestions +*/ +#PopupSearchAutoComplete { + & .searchbar-separator { + margin: 4px 0 !important; + } + + /* Search suggestions. */ + & .autocomplete-richlistitem, + & .search-panel-header { + padding-block: 2px !important; + padding-inline: var(--uc-contextmenu-menuitem-padding-inline) !important; + margin: 0 var(--uc-arrowpanel-menuitem-margin-inline) !important; + border-radius: var(--arrowpanel-menuitem-border-radius) !important; + + & > .ac-type-icon { + margin-inline-start: 0 !important; + } + } + + /* Search engine selector. */ + & .search-one-offs { + padding-block: 0 5px !important; + + & #searchbar-one-offs-header-label { + margin-inline-start: 0 !important; + } + + & .search-panel-one-offs-container { + margin-inline: 1px 7px !important; + } + } + +} + +/* + MARK: Context menu +*/ + +/* disable context menu when this tweak is applied */ +@media not (-moz-bool-pref: "uc.tweak.revert-context-menu") { + /* Context Menu */ + menupopup:not(.PanelUI-subView), + menupopup:not(.PanelUI-subView) menuitem, + menupopup:not(.PanelUI-subView) menu, + menupopup:not(.PanelUI-subView) menuseparator, + panel:not(#PopupSearchAutoComplete) { + appearance: none !important; + } + + menupopup:not(.PanelUI-subView), + #PopupAutoComplete, + menulist > menupopup:not(.PanelUI-subView) > menucaption { + -moz-window-shadow: none !important; + background: 0 !important; + border: 0 !important; + color: var(--arrowpanel-color) !important; + } + + .popup-internal-box, + #PopupAutoComplete > .autocomplete-richlistbox, + .menupopup-arrowscrollbox { + background: var(--arrowpanel-background) !important; + border: 1px solid var(--arrowpanel-border-color) !important; + } + + /* make room for menu shadow */ + menupopup:not(.PanelUI-subView) { + padding: 4px 12px 20px !important; + margin: -6px -12px -16px !important; + } + + /* cut off shadow so it doesn't get in the way of the menubar items */ + menubar menupopup { + padding: 1px 8px 20px !important; + margin: -1px -4px -16px !important; + } + + menupopup { + --uc-margin: 0 !important; + --uc-outline-color: #0001; + --uc-box-shadow: + 0 8px 12px #0003, + 0 4px 5px #0002, + 0 2px 4px #0002; + } + + @media (prefers-color-scheme:dark) { + menupopup { + --uc-outline-color: #0002; + --uc-box-shadow: + 0 8px 12px #0003, + 0 4px 5px #0003, + 0 2px 4px #0002; + } + } + + /* use default shadow for subview menupopup (eg. bookmarks) */ + menupopup.PanelUI-subView { + --uc-box-shadow: 0 0 0 1px var(--panel-border-color); + --uc-margin: 1px !important; + margin-top: -5px !important; + } + + .menupopup-arrowscrollbox { + box-shadow: var(--uc-box-shadow) !important; + outline: .5px solid var(--uc-outline-color) !important; + } + + .popup-internal-box { + margin: 0 !important; + } + + .popup-internal-box, + .menupopup-arrowscrollbox { + padding: var(--uc-contextmenu-padding) !important; + border-radius: var(--uc-contextmenu-border-radius) !important; + color: inherit !important; + } + + menupopup menu[disabled="true"], + menupopup menuitem[disabled="true"] { + color: var(--panel-disabled-color) !important; + background: none !important; + } + + menupopup menu:hover:not([disabled=true]), + menupopup menuitem:hover:not([disabled=true]), + menupopup menu[_moz-menuactive]:not([disabled=true]), + menupopup menuitem[_moz-menuactive]:not([disabled=true]) { + background-color: var(--panel-item-hover-bgcolor) !important; + color: inherit !important; + } + + menupopup menuitem:hover:active:not([disabled=true]), + menupopup menu:hover:active:not([disabled=true]) { + background-color: var(--panel-item-active-bgcolor) !important; + color: inherit !important; + } + + menupopup menuseparator, + panel menuseparator, + #PopupSearchAutoComplete .searchbar-separator { + margin: var(--uc-contextmenu-separator-vertical) 0 !important; + padding: 0 !important; + background: none !important; + border-top: 1px solid var(--panel-separator-color) !important; + + &::before { + content: unset !important; + } + } + + #PlacesToolbar menupopup[placespopup="true"] menuseparator::before { + display: none !important; + } + + menupopup menu, + menupopup menuitem, + menupopup menucaption, + #PopupAutoComplete > richlistbox > richlistitem, + #PopupSearchAutoComplete .autocomplete-richlistitem { + padding: var(--uc-contextmenu-menuitem-padding-block) var(--uc-contextmenu-menuitem-padding-inline) !important; + margin: var(--uc-contextmenu-menuitem-margin) !important; + border-radius: var(--uc-contextmenu-menuitem-border-radius) !important; + border: var(--uc-contextmenu-menuitem-border-width) solid transparent !important; + background-clip: padding-box !important; + min-height: calc(16px + (var(--uc-contextmenu-menuitem-padding-block) + var(--uc-contextmenu-menuitem-border-width)) * 2) !important; + } + + :not(:not(menubar)>menu, #ContentSelectDropdown) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], [type="radio"], .in-menulist, .in-menulist menuitem, .unified-nav-current), + :not(:not(menubar)>menu, #ContentSelectDropdown) > menupopup > menu:not(.menu-iconic, [type="checkbox"], [type="radio"], .in-menulist, .in-menulist menu, .unified-nav-current), + :not(:not(menubar)>menu, #ContentSelectDropdown) > menupopup > menucaption { + padding-inline-start: calc(var(--uc-contextmenu-menuitem-padding-inline) + 16px + var(--uc-contextmenu-menuicon-margin-inline)) !important; + } + + .menu-iconic-icon { + margin-block: 0 !important; + margin-inline-end: 0 !important; + margin-inline-start: 0 !important; + } + + menu > .menu-iconic-text, + menuitem > .menu-iconic-text, + /* Used for vertical context navigation tweak. */ + #context-navigation > .menuitem-iconic::after { + padding-inline-start: var(--uc-contextmenu-menuicon-margin-inline) !important; + } + + .menu-text, + .menu-iconic-text { + margin-inline-start: 0 !important; + padding-block: 0 !important; + } + + .menu-accel, + .menu-iconic-accel { + margin-inline-end: 0 !important; + padding-block: 0 !important; + opacity: 0.7 !important; + } + + .menu-iconic > .menu-iconic-left, + .menuitem-iconic > .menu-iconic-left { + padding-inline-end: 0 !important; + padding-block: 0 !important; + } + + menuitem:is(.menuitem-iconic:not([data-usercontextid]), [type="checkbox"], [type="radio"], [checked], [selected]) .menu-iconic-icon { + -moz-context-properties: fill !important; + fill: currentColor !important; + } + + .menu-right, + .menu-accel-container { + appearance: none !important; + margin-inline-end: 0 !important; + -moz-context-properties: fill; + fill: currentColor !important; + } + + menupopup menuitem:is([type="checkbox"], [type="radio"]) .menu-iconic-icon, + menulist > menupopup > menuitem .menu-iconic-icon, + menu .menu-right { + height: 16px !important; + width: 16px !important; + } + + menulist > menupopup > menuitem:is([checked="true"], [selected="true"])::before, + menupopup > menuitem::before, + menupopup > menu::before, + menupopup > menuitem::after { + display: none !important; + } + + menuitem:is([type="checkbox"], [checked="true"], [type="radio"]) > .menu-iconic-left > .menu-iconic-icon { + display: flex !important; + } + + menuitem[checked="true"] > .menu-iconic-left, + menu > .menu-iconic-left, + menuitem > .menu-iconic-left { + margin: 0 !important; + padding: 0 !important + } + + #context-navigation:not([hidden]) { + padding: 0 !important; + --menuitem-min-width: calc(16px + var(--uc-contextmenu-menuitem-padding-inline) * 2) !important; + min-width: calc(4 * var(--menuitem-min-width)); + } + + #context-navigation > .menuitem-iconic > .menu-iconic-left > .menu-iconic-icon { + width: 16px !important; + height: 16px !important; + padding: 0 !important; + } + + #context-navigation { + margin-inline: var(--uc-contextmenu-menuitem-margin-inline) !important; + } + + #context-navigation > .menuitem-iconic { + justify-content: center !important; + } + + #context-navigation > .menuitem-iconic { + margin: 0 !important; + } + + #context-navigation > .menuitem-iconic { + flex-grow: 1 !important; + width: unset !important; + } + + #context-navigation > .menuitem-iconic[_moz-menuactive="true"] > .menu-iconic-left > .menu-iconic-icon { + background-color: transparent !important; + } + + #context-bookmarkpage[starred] .menu-iconic-icon { + fill: var(--lwt-toolbarbutton-icon-fill-attention, var(--toolbarbutton-icon-fill-attention, currentColor)) !important; + } + + @media (not (-moz-bool-pref: "uc.tweak.smaller-context-menu-text")) and (-moz-platform: windows) { + .menu-text, + .menu-iconic-text, + panel .toolbarbutton-text, + #PopupSearchAutoComplete .ac-title, + /* Used for vertical context navigation tweak. */ + #context-navigation > .menuitem-iconic::after { + margin-inline-start: 0 !important; + margin-block: -3px -1px !important; + padding-block: 0 !important; + } + + .menu-text, + .menu-iconic-text, + panel .toolbarbutton-text, + #appMenu-fxa-status2, + .panel-header, + #PopupSearchAutoComplete, + /* Used for vertical context navigation tweak. */ + #context-navigation > .menuitem-iconic::after { + font-size: 13.6px !important; + } + } +} + +/* + MARK: Dialog box +*/ + +/* Dialog shadow and outline adjustments. */ +.dialogBox:not(.spotlightBox) { + border-radius: 8px !important; + outline: 0.5px solid var(--panel-separator-color) !important; + box-shadow: + 0 20px 38px rgb(0 0 0 / 0.23), + 0 5px 9px rgb(0 0 0 / 0.22) !important; +} + +dialog { + /* Dialog title. */ + & #titleContainer { + /* Add larger gap between icon and title text. */ + & .titleIcon { + padding-inline-end: 8px !important; + } + + /* Match font style in Edge. */ + & #titleText { + font-size: 1.18em !important; + font-weight: 700 !important; + } + + /* Adjust vertical alignment of title text. */ + @media (-moz-platform: macOS) { + &:not([noicon]) > #titleCropper { + translate: 0 calc(-1px - max(.55 * var(--icon-size) - .6em, 0px)) !important; + } + } + } + + /* Input focus style. */ + & input:where([type="email"], [type="tel"], [type="text"], [type="password"], [type="url"], [type="number"]):focus { + outline: 2px solid var(--in-content-box-border-color) !important; + outline-offset: -2px !important; + } +} + +/* FF123+ tab preview pop-up. + * CSS reference: https://searchfox.org/mozilla-central/source/browser/components/tabpreview/tabpreview.css + * Requires `browser.tabs.cardPreview.enabled` set to `true` */ +.tab-preview-container { + background-color: var(--arrowpanel-background) !important; + color: var(--arrowpanel-color) !important; + border: 0.5px solid var(--panel-separator-color) !important; + border-radius: 8.5px !important; + + /* Place thumbnail at the top of the tooltip. */ + display: flex !important; + flex-direction: column-reverse !important; + + & .tab-preview-uri { + color: var(--panel-description-color) !important; + } +} diff --git a/config/firefox/chrome/global/tree.css b/config/firefox/chrome/global/tree.css new file mode 100644 index 0000000..2bbffb4 --- /dev/null +++ b/config/firefox/chrome/global/tree.css @@ -0,0 +1,87 @@ +/* Edge-Frfox - tree.css */ + +/* Change height of tree items and add rounded corners */ +treechildren::-moz-tree-row, +treecol:not([hideheader="true"]), +.tree-columnpicker-button { + min-height: max(28px, 1.3em) !important; + border-radius: 2px !important; +} + +/* Change the background colour on hover */ +@media not (prefers-contrast) { + treechildren::-moz-tree-row(hover) { + background-color: var(--toolbarbutton-hover-background) !important; + } +} + +/* Change the background colour when pressed */ +treechildren::-moz-tree-row(selected) { + background-color: var(--toolbarbutton-active-background) !important; +} + +/* Change the background colour when focused */ +treechildren::-moz-tree-row(selected, focus) { + background-color: var(--button-primary-bgcolor) !important; +} + +treechildren::-moz-tree-row(current, focus) { + outline: var(--default-focusring); + outline-color: var(--button-primary-bgcolor) !important; + outline-offset: calc(-1 * var(--default-focusring-width)); +} + +treechildren::-moz-tree-image(selected), +treechildren::-moz-tree-twisty(selected), +treechildren::-moz-tree-cell-text(selected) { + color: inherit !important; +} + +treechildren::-moz-tree-image(selected, focus), +treechildren::-moz-tree-twisty(selected, focus), +treechildren::-moz-tree-cell-text(selected, focus) { + color: var(--button-primary-color) !important; +} + +/* Spacing between icon and label */ +treechildren::-moz-tree-image { + margin-inline-end: 8px !important; +} + +/* Separator appearance */ +treechildren::-moz-tree-separator { + border-top: 1px solid var(--toolbarseparator-color) !important; + border-bottom: none !important; +} + +/* Change the colour of the drop feedback elements */ +treechildren::-moz-tree-cell-text(primary, dropOn) { + background-color: var(--button-primary-bgcolor) !important; + color: var(--button-primary-color) !important; +} + +treechildren::-moz-tree-drop-feedback { + background-color: var(--toolbarbutton-icon-fill-attention) !important; + border-radius: 2px !important; +} + +/* Change the appearance for the expandable items */ +treechildren::-moz-tree-twisty { + padding-top: 0 !important; + padding-inline: 4px !important; + width: 16px !important; + list-style-image: url("../icons/arrow-filled-right.svg") !important; +} + +treechildren:-moz-locale-dir(rtl)::-moz-tree-twisty(closed) { + list-style-image: url("../icons/arrow-filled-left.svg") !important; +} + +treechildren::-moz-tree-twisty(open) { + list-style-image: url("../icons/arrow-filled-down.svg") !important; +} + +/* Change the identation of child items */ +treechildren::-moz-tree-indentation { + width: 16px !important; +} diff --git a/config/firefox/chrome/global/tweaks.css b/config/firefox/chrome/global/tweaks.css new file mode 100644 index 0000000..d3114b2 --- /dev/null +++ b/config/firefox/chrome/global/tweaks.css @@ -0,0 +1,247 @@ +/* Edge-Frfox - tweaks.css */ + +/* + MARK: Disable drag space +*/ +@media (-moz-bool-pref: "uc.tweak.disable-drag-space") { + /* disable drag space above tabs */ + :root { + --uc-tab-top-margin: 0px !important; + } +} + +/* + MARK: Force tab colour +*/ +/* force tabs to toolbar bg (useful for proton themes) (might experience some +bugs with certain themes eg. dark text on dark background.) */ +@media (-moz-bool-pref: "uc.tweak.force-tab-colour") { + :root[lwtheme] { + --tab-selected-bgcolor: var(--toolbar-bgcolor) !important; + --tab-selected-textcolor: var(--toolbar-color) !important; + } +} + +/* + MARK: Remove tab separators +*/ +@media (-moz-bool-pref: "uc.tweak.remove-tab-separators") { + .tabbrowser-tab .tab-stack { + &::before, + &::after { + content: initial !important; + } + } +} + +/* + MARK: Floating tabs +*/ +@media (-moz-bool-pref: "uc.tweak.floating-tabs") { + :root:not([lwtheme]), + /* `--newtab-background-color-secondary used` to differentiate between a dark + * private window and private window with the 'Dark' theme enabled. + * May not be the most reliable method, but works for now up to FF 123. */ + :root[privatebrowsingmode="temporary"]:where([style*="--lwt-accent-color: rgb(28, 27, 34)"]:not([style*="--newtab-background-color-secondary: rgb(66, 65, 77)"])) { + --lwt-accent-color: light-dark(#f3f3f3, #202020) !important; + --lwt-accent-color-inactive: unset !important; + --toolbar-bgcolor: light-dark(#fff, #3F3F3F) !important; + --lwt-tab-text: light-dark(#262626, #fff) !important; + --chrome-content-separator-color: light-dark(#bfbfbf, #535353) !important; + --lwt-tab-line-color: light-dark(transparent, rgb(255 255 255 / 0.06)) !important; + } + + /* Uses :root body to avoid affecting other variables by changing + * --toolbar-color. */ + :root body { + /* Use tabbar colours for better readability when using custom themes. */ + --toolbar-color: var(--lwt-text-color) !important; + --toolbarbutton-icon-fill: var(--lwt-text-color) !important; + + &:-moz-window-inactive { + --toolbar-color: var(--lwt-text-color-inactive, var(--lwt-text-color)) !important; + --toolbarbutton-icon-fill: var(--lwt-text-color-inactive, var(--lwt-text-color)) !important; + } + } + + @media (-moz-gtk-csd-available) { + :root:not([lwtheme]) { + --toolbar-bgcolor: color-mix(in srgb, -moz-dialog 80%, #fff) !important; + --toolbar-field-background-color: Field !important; + --lwt-tab-text: -moz-dialogtext !important; + --lwt-tab-line-color: rgb(255 255 255 / 0.06) !important; + --lwt-accent-color: var(--toolbox-non-lwt-bgcolor) !important; + + &:-moz-window-inactive { + --lwt-accent-color: var(--toolbox-non-lwt-bgcolor-inactive) !important; + } + } + } + + /* Shadow for navbar and tabs */ + :root, + :root .tabbrowser-tab { + --uc-titlebar-shadow: none; + --uc-tab-shadow-outline: rgb(0 0 0 / .11); + --uc-tab-shadow: 0 2.5px 3px 1px rgb(0 0 0 / .08); + + & [brighttext], + & [brighttext] .tabbrowser-tab { + --uc-titlebar-shadow: none; + --uc-tab-shadow-outline: transparent; + --uc-tab-shadow: 0 2px 3px rgb(0 0 0 / .12); + } + + & #TabsToolbar { + --tab-border-radius: 8px !important; + } + } + + /* remove toolbar bg */ + #nav-bar, + #PersonalToolbar { + background-color: transparent !important; + } + + /* invert bottom corner radius for tabs */ + .tab-background { + border-radius: var(--tab-border-radius) !important; + + &::before, + &::after { + display: none !important; + } + } + + .tab-background[selected] { + border: 1px solid var(--lwt-tab-line-color, var(--lwt-tabs-border-color, transparent)) !important; + outline: 1px solid var(--uc-tab-shadow-outline) !important; + + /* Fractional scaling adjustments (150%, 175%, etc.) */ + @media (1dppx < resolution < 2dppx) { + outline-width: 1.5px !important; + } + } + + /* adjust spacing of area above tabs */ + @media not (-moz-platform: macos) { + :root[sizemode="maximized"] { + --uc-tab-top-margin: 4px !important; + } + } + + :root:is([inFullscreen], :not([tabsintitlebar])) { + --uc-tab-top-margin: 4px !important; + } + + @media (-moz-bool-pref: "uc.tweak.disable-drag-space") { + :root { + --uc-tab-top-margin: 4px !important; + } + } + + /* IMPORTANT: Adds padding and removes margin on top of tabs to allow user to + * select it from the top edge of the window */ + #tabbrowser-tabs { + margin-top: calc(var(--uc-tab-top-margin) - 4px) !important; + + & .tabbrowser-tab, + & #tabs-newtab-button { + padding-top: 4px !important; + } + } + + #scrollbutton-up:not(.menupopup-scrollbutton), + #scrollbutton-down:not(.menupopup-scrollbutton) { + &, + & ~ spacer { + margin-top: 4px !important; + } + } + + /* move tab shadow behind urlbar */ + .tabbrowser-tab[visuallyselected="true"], + #nav-bar { + z-index: 2 !important; + } + + /* tab shadow adjustments */ + .tabbrowser-tab { + overflow-clip-margin: 8px !important; + } + + #tabbrowser-arrowscrollbox > *, + #scrollbutton-up:not(.menupopup-scrollbutton), + #scrollbutton-up:not(.menupopup-scrollbutton) ~ spacer, + #scrollbutton-down:not(.menupopup-scrollbutton) { + margin-bottom: 8px !important; + } + + #tabbrowser-arrowscrollbox { + margin-bottom: -8px !important; + } +} + +/* + MARK: Vertical context nav +*/ +@media (not (-moz-platform: macos)) and (not (-moz-bool-pref: "uc.tweak.revert-context-menu")) { + @media (-moz-bool-pref: "uc.tweak.vertical-context-navigation") { + #context-navigation { + /* Stack menu items vertically. */ + flex-direction: column !important; + + /* Align the image and label to the left edge. */ + & > .menuitem-iconic { + justify-content: start !important; + + &::after { + /* Get the menuitem label from the aria-label attribute. */ + content: attr(aria-label); + } + } + } + } +} + +/* + MARK: Hide access key +*/ +@media (-moz-bool-pref: "uc.tweak.context-menu.hide-access-key") { + :where(menuitem, menu) > :is(.menu-text, .menu-iconic-text)[value]:not([value=""]) { + &::before { + /* The default value is -moz-label-content, which takes the data from the + * value attribute and highlights the character found in the accesskey + * attribute. This skips that and uses the value attribute directly. */ + content: attr(value) !important; + } + } +} + +/* + MARK: Show tab close button +*/ +@media (-moz-bool-pref: "uc.tweak.show-tab-close-button-on-hover") { + #tabbrowser-tabs[closebuttons="activetab"] .tabbrowser-tab:not([pinned], [selected]):hover .tab-close-button { + display: flex !important; + } +} + +/* + MARK: Hide forward button +*/ +@media (-moz-bool-pref: "uc.tweak.hide-forward-button") { + :root:not([customizing]) #forward-button[disabled] { + display: none !important; + } +} + +/* + MARK: Hide Firefox account +*/ +@media (-moz-bool-pref: "uc.tweak.context-menu.hide-firefox-account") { + #appMenu-fxa-status2, + #appMenu-fxa-separator { + display: none !important; + } +} diff --git a/config/firefox/chrome/icons/accessibility.svg b/config/firefox/chrome/icons/accessibility.svg new file mode 100755 index 0000000..bfcf02a --- /dev/null +++ b/config/firefox/chrome/icons/accessibility.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/account-private.svg b/config/firefox/chrome/icons/account-private.svg new file mode 100644 index 0000000..4c3040e --- /dev/null +++ b/config/firefox/chrome/icons/account-private.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/config/firefox/chrome/icons/account.svg b/config/firefox/chrome/icons/account.svg new file mode 100644 index 0000000..1400006 --- /dev/null +++ b/config/firefox/chrome/icons/account.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/config/firefox/chrome/icons/add-to-dictionary.svg b/config/firefox/chrome/icons/add-to-dictionary.svg new file mode 100644 index 0000000..ebcb80f --- /dev/null +++ b/config/firefox/chrome/icons/add-to-dictionary.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/arrow-down.svg b/config/firefox/chrome/icons/arrow-down.svg new file mode 100644 index 0000000..ddf8622 --- /dev/null +++ b/config/firefox/chrome/icons/arrow-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/arrow-filled-down.svg b/config/firefox/chrome/icons/arrow-filled-down.svg new file mode 100644 index 0000000..bd111a7 --- /dev/null +++ b/config/firefox/chrome/icons/arrow-filled-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/arrow-filled-left.svg b/config/firefox/chrome/icons/arrow-filled-left.svg new file mode 100644 index 0000000..c0f6945 --- /dev/null +++ b/config/firefox/chrome/icons/arrow-filled-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/arrow-filled-right.svg b/config/firefox/chrome/icons/arrow-filled-right.svg new file mode 100644 index 0000000..2f65f5e --- /dev/null +++ b/config/firefox/chrome/icons/arrow-filled-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/arrow-left.svg b/config/firefox/chrome/icons/arrow-left.svg new file mode 100644 index 0000000..1da2ba2 --- /dev/null +++ b/config/firefox/chrome/icons/arrow-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/arrow-right.svg b/config/firefox/chrome/icons/arrow-right.svg new file mode 100644 index 0000000..a7b1606 --- /dev/null +++ b/config/firefox/chrome/icons/arrow-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/arrow-up.svg b/config/firefox/chrome/icons/arrow-up.svg new file mode 100644 index 0000000..a3bfad7 --- /dev/null +++ b/config/firefox/chrome/icons/arrow-up.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/audio-save.svg b/config/firefox/chrome/icons/audio-save.svg new file mode 100644 index 0000000..21b6752 --- /dev/null +++ b/config/firefox/chrome/icons/audio-save.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/autoplay-media-blocked.svg b/config/firefox/chrome/icons/autoplay-media-blocked.svg new file mode 100644 index 0000000..0de5a38 --- /dev/null +++ b/config/firefox/chrome/icons/autoplay-media-blocked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/autoplay-media.svg b/config/firefox/chrome/icons/autoplay-media.svg new file mode 100644 index 0000000..8df77df --- /dev/null +++ b/config/firefox/chrome/icons/autoplay-media.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/back.svg b/config/firefox/chrome/icons/back.svg new file mode 100644 index 0000000..b6e67d7 --- /dev/null +++ b/config/firefox/chrome/icons/back.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/bookmark-hollow.svg b/config/firefox/chrome/icons/bookmark-hollow.svg new file mode 100644 index 0000000..47e2f1d --- /dev/null +++ b/config/firefox/chrome/icons/bookmark-hollow.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/bookmark-star-on-tray.svg b/config/firefox/chrome/icons/bookmark-star-on-tray.svg new file mode 100644 index 0000000..e35453e --- /dev/null +++ b/config/firefox/chrome/icons/bookmark-star-on-tray.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/bookmark.svg b/config/firefox/chrome/icons/bookmark.svg new file mode 100644 index 0000000..c5ff2e0 --- /dev/null +++ b/config/firefox/chrome/icons/bookmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/camera-blocked.svg b/config/firefox/chrome/icons/camera-blocked.svg new file mode 100644 index 0000000..7d6aa1a --- /dev/null +++ b/config/firefox/chrome/icons/camera-blocked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/camera.svg b/config/firefox/chrome/icons/camera.svg new file mode 100644 index 0000000..23e2384 --- /dev/null +++ b/config/firefox/chrome/icons/camera.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/canvas-blocked.svg b/config/firefox/chrome/icons/canvas-blocked.svg new file mode 100644 index 0000000..f6fba0f --- /dev/null +++ b/config/firefox/chrome/icons/canvas-blocked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/canvas.svg b/config/firefox/chrome/icons/canvas.svg new file mode 100644 index 0000000..e71396f --- /dev/null +++ b/config/firefox/chrome/icons/canvas.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/checkmark.svg b/config/firefox/chrome/icons/checkmark.svg new file mode 100644 index 0000000..ade387a --- /dev/null +++ b/config/firefox/chrome/icons/checkmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/chevron.svg b/config/firefox/chrome/icons/chevron.svg new file mode 100644 index 0000000..c61ab0a --- /dev/null +++ b/config/firefox/chrome/icons/chevron.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/close-9px.svg b/config/firefox/chrome/icons/close-9px.svg new file mode 100644 index 0000000..c567b9a --- /dev/null +++ b/config/firefox/chrome/icons/close-9px.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/close.svg b/config/firefox/chrome/icons/close.svg new file mode 100644 index 0000000..4aa95d0 --- /dev/null +++ b/config/firefox/chrome/icons/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/container-tab.svg b/config/firefox/chrome/icons/container-tab.svg new file mode 100644 index 0000000..3a11413 --- /dev/null +++ b/config/firefox/chrome/icons/container-tab.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/customize.svg b/config/firefox/chrome/icons/customize.svg new file mode 100644 index 0000000..0087061 --- /dev/null +++ b/config/firefox/chrome/icons/customize.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/desktop-notification-blocked.svg b/config/firefox/chrome/icons/desktop-notification-blocked.svg new file mode 100644 index 0000000..5e6dd9c --- /dev/null +++ b/config/firefox/chrome/icons/desktop-notification-blocked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/desktop-notification.svg b/config/firefox/chrome/icons/desktop-notification.svg new file mode 100644 index 0000000..d09f0df --- /dev/null +++ b/config/firefox/chrome/icons/desktop-notification.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/developer.svg b/config/firefox/chrome/icons/developer.svg new file mode 100644 index 0000000..bf2f355 --- /dev/null +++ b/config/firefox/chrome/icons/developer.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/downloads.svg b/config/firefox/chrome/icons/downloads.svg new file mode 100644 index 0000000..e9cd7c6 --- /dev/null +++ b/config/firefox/chrome/icons/downloads.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/duplicate-tab.svg b/config/firefox/chrome/icons/duplicate-tab.svg new file mode 100644 index 0000000..5c80180 --- /dev/null +++ b/config/firefox/chrome/icons/duplicate-tab.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/edit-copy-without-tracking.svg b/config/firefox/chrome/icons/edit-copy-without-tracking.svg new file mode 100644 index 0000000..1967f0b --- /dev/null +++ b/config/firefox/chrome/icons/edit-copy-without-tracking.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/edit-copy.svg b/config/firefox/chrome/icons/edit-copy.svg new file mode 100644 index 0000000..079c113 --- /dev/null +++ b/config/firefox/chrome/icons/edit-copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/edit-cut.svg b/config/firefox/chrome/icons/edit-cut.svg new file mode 100644 index 0000000..dea6b9e --- /dev/null +++ b/config/firefox/chrome/icons/edit-cut.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/edit-delete.svg b/config/firefox/chrome/icons/edit-delete.svg new file mode 100755 index 0000000..cf851d6 --- /dev/null +++ b/config/firefox/chrome/icons/edit-delete.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/edit-paste.svg b/config/firefox/chrome/icons/edit-paste.svg new file mode 100644 index 0000000..2b1c074 --- /dev/null +++ b/config/firefox/chrome/icons/edit-paste.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/edit-redo.svg b/config/firefox/chrome/icons/edit-redo.svg new file mode 100644 index 0000000..4fd020f --- /dev/null +++ b/config/firefox/chrome/icons/edit-redo.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/edit-select-all.svg b/config/firefox/chrome/icons/edit-select-all.svg new file mode 100755 index 0000000..f39494d --- /dev/null +++ b/config/firefox/chrome/icons/edit-select-all.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/edit-undo.svg b/config/firefox/chrome/icons/edit-undo.svg new file mode 100755 index 0000000..7595ba6 --- /dev/null +++ b/config/firefox/chrome/icons/edit-undo.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/edit.svg b/config/firefox/chrome/icons/edit.svg new file mode 100644 index 0000000..f77c003 --- /dev/null +++ b/config/firefox/chrome/icons/edit.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/extension-blocked.svg b/config/firefox/chrome/icons/extension-blocked.svg new file mode 100644 index 0000000..3ebb9a9 --- /dev/null +++ b/config/firefox/chrome/icons/extension-blocked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/extension.svg b/config/firefox/chrome/icons/extension.svg new file mode 100644 index 0000000..8671aad --- /dev/null +++ b/config/firefox/chrome/icons/extension.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/firefox-view.svg b/config/firefox/chrome/icons/firefox-view.svg new file mode 100644 index 0000000..6288a1e --- /dev/null +++ b/config/firefox/chrome/icons/firefox-view.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/firefox.svg b/config/firefox/chrome/icons/firefox.svg new file mode 100644 index 0000000..312a76f --- /dev/null +++ b/config/firefox/chrome/icons/firefox.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/folder.svg b/config/firefox/chrome/icons/folder.svg new file mode 100644 index 0000000..766d6f0 --- /dev/null +++ b/config/firefox/chrome/icons/folder.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/forget.svg b/config/firefox/chrome/icons/forget.svg new file mode 100644 index 0000000..cf23a92 --- /dev/null +++ b/config/firefox/chrome/icons/forget.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/forward.svg b/config/firefox/chrome/icons/forward.svg new file mode 100644 index 0000000..e7fd370 --- /dev/null +++ b/config/firefox/chrome/icons/forward.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/fullscreen-exit.svg b/config/firefox/chrome/icons/fullscreen-exit.svg new file mode 100644 index 0000000..38d42d9 --- /dev/null +++ b/config/firefox/chrome/icons/fullscreen-exit.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/fullscreen.svg b/config/firefox/chrome/icons/fullscreen.svg new file mode 100644 index 0000000..109ce72 --- /dev/null +++ b/config/firefox/chrome/icons/fullscreen.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/geo-blocked.svg b/config/firefox/chrome/icons/geo-blocked.svg new file mode 100644 index 0000000..1576b8d --- /dev/null +++ b/config/firefox/chrome/icons/geo-blocked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/geo.svg b/config/firefox/chrome/icons/geo.svg new file mode 100644 index 0000000..2899170 --- /dev/null +++ b/config/firefox/chrome/icons/geo.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/help.svg b/config/firefox/chrome/icons/help.svg new file mode 100644 index 0000000..e01d242 --- /dev/null +++ b/config/firefox/chrome/icons/help.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/history.svg b/config/firefox/chrome/icons/history.svg new file mode 100644 index 0000000..cd06463 --- /dev/null +++ b/config/firefox/chrome/icons/history.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/home.svg b/config/firefox/chrome/icons/home.svg new file mode 100644 index 0000000..f9ecfaf --- /dev/null +++ b/config/firefox/chrome/icons/home.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/icons.css b/config/firefox/chrome/icons/icons.css new file mode 100644 index 0000000..885220d --- /dev/null +++ b/config/firefox/chrome/icons/icons.css @@ -0,0 +1,1063 @@ +/* Edge-Frfox - icons.css */ + +/* + MARK: Win 11 window controls +*/ +@media (-moz-platform: windows) { + .titlebar-min { + list-style-image: url("win11-minimize.svg") !important; + + @media (resolution > 1.25dppx) { + list-style-image: url("win11-minimize.svg#high-dpi") !important; + } + } + + .titlebar-max { + list-style-image: url("win11-maximize.svg") !important; + } + + .titlebar-restore { + list-style-image: url("win11-restore.svg") !important; + } + + .titlebar-close { + list-style-image: url("win11-close.svg") !important; + + /* Alternative icon that uses a thicker stroke, making it easier to see when + * displayed on a dark background, only needed at 100% UI scale. + */ + @media (resolution = 1dppx) { + toolbar[brighttext] &, + &:hover { + list-style-image: url("win11-close-dark.svg") !important; + } + } + } +} + +.subviewbutton { + -moz-context-properties: fill, fill-opacity !important; + fill: currentColor !important; +} + +:root[fxastatus="not_configured"] #fxa-avatar-image { + list-style-image: url("account.svg") !important; +} + +.private-browsing-indicator-icon { + list-style-image: url("account-private.svg") !important; + border-radius: 100% !important; +} + +/* disable context menu icons on macOS */ +@media not (-moz-platform: macos) { + #context-back { + list-style-image: url("back.svg") !important; + } + + #context-forward { + list-style-image: url("forward.svg") !important; + } + + #context-reload { + list-style-image: url("reload.svg") !important; + } + + #context-stop { + list-style-image: url("close.svg") !important; + } + + #context-bookmarkpage { + list-style-image: url("bookmark-hollow.svg") !important; + } + + #context-bookmarkpage[starred] { + list-style-image: url("bookmark.svg") !important; + } +} + +#back-button { + list-style-image: url("back.svg") !important; +} + +#forward-button { + list-style-image: url("forward.svg") !important; +} + +#reload-button { + list-style-image: url("reload.svg") !important; +} + +#stop-button, +.close-icon { + list-style-image: url("close.svg") !important; +} + +.tab-close-button { + list-style-image: url("close-9px.svg") !important; +} + +#sidebar-button { + list-style-image: url("sidebars-right.svg") !important; +} + +#sidebar-button:-moz-locale-dir(ltr):not([positionend]), +#sidebar-button:-moz-locale-dir(rtl)[positionend] { + list-style-image: url("sidebars.svg") !important; +} + +#downloads-button, +#downloads-indicator-anchor, +#appMenu-downloads-button, +#appMenu-library-downloads-button { + list-style-image: url("downloads.svg") !important; +} + +#appMenu-passwords-button, +#password-notification-icon, +#PopupAutoComplete > richlistbox > richlistitem[originaltype="generatedPassword"] > .two-line-wrapper > .ac-site-icon, +#PopupAutoComplete > richlistbox > richlistitem[originaltype="loginWithOrigin"] > .two-line-wrapper > .ac-site-icon, +#PopupAutoComplete > richlistbox > richlistitem[originaltype="login"] > .ac-site-icon { + list-style-image: url("passwords.svg") !important; +} + +#nav-bar-overflow-button { + list-style-image: url("chevron.svg") !important; +} + +#PanelUI-menu-button, +#appMenu-more-button2, +.unified-extensions-item-menu-button { + list-style-image: url("menu.svg") !important; +} + +#appMenu-help-button2 { + list-style-image: url("help.svg") !important; +} + +#new-tab-button { + list-style-image: url("new-tab.svg") !important; +} + +#firefox-view-button { + list-style-image: url("firefox-view.svg") !important; +} + +#sync-button, +.urlbarView-row[source="tabs"] > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-favicon, +#urlbar-engine-one-off-item-tabs { + list-style-image: url("tab.svg") !important; +} + +#history-panelmenu, +.urlbarView-row[source="history"] > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-favicon, +#urlbar-engine-one-off-item-history, +#appMenu-history-button, +#appMenu-library-history-button, +#sidebar-switcher-history, +#sidebar-box[sidebarcommand="viewHistorySidebar"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon { + list-style-image: url("history.svg") !important; +} + +#save-page-button, +#appMenu-save-file-button2 { + list-style-image: url("save.svg") !important; +} + +#print-button, +#appMenu-print-button2 { + list-style-image: url("print.svg") !important; +} + +.searchbar-search-icon { + list-style-image: url("search-glass.svg") !important; +} + +#find-button, +#appMenu-find-button2 { + list-style-image: url("search-page.svg") !important; +} + +#appMenu-translate-button, +#translations-button-icon { + list-style-image: url("translate.svg") !important; +} + +#open-file-button { + list-style-image: url("open.svg") !important; +} + +#add-ons-button, +#appMenu-extensions-themes-button, +#unified-extensions-button, +#unified-extensions-manage-extensions { + list-style-image: url("extension.svg") !important; +} + +#zoom-out-button, +#appMenu-zoomReduce-button2 { + list-style-image: url("zoom-out.svg") !important; +} + +#zoom-in-button, +#tabs-newtab-button, +#TabsToolbar #new-tab-button, +#appMenu-zoomEnlarge-button2 { + list-style-image: url("plus.svg") !important; +} + +#cut-button { + list-style-image: url("edit-cut.svg") !important; +} + +#copy-button { + list-style-image: url("edit-copy.svg") !important; +} + +#paste-button { + list-style-image: url("edit-paste.svg") !important; +} + +#email-link-button { + list-style-image: url("mail.svg") !important; +} + +#screenshot-button { + list-style-image: url("screenshot.svg") !important; +} + +#preferences-button, +.search-setting-button > .button-box > .button-icon, +#appMenu-settings-button, +.unified-extensions-item-open-menu.subviewbutton { + list-style-image: url("settings.svg") !important; +} + +#panic-button { + list-style-image: url("forget.svg") !important; +} + +#appMenu-new-private-window-button2 { + list-style-image: url("private-window.svg") !important; +} + +#privatebrowsing-button { + list-style-image: url("privateBrowsing.svg") !important; +} + +#save-to-pocket-button { + list-style-image: url("pocket-outline.svg") !important; +} + +#profiler-button-button > .toolbarbutton-icon, +.subviewbutton[label="Task Manager"] { + list-style-image: url("tool-profiler.svg") !important; +} + +#developer-button { + list-style-image: url("developer.svg") !important; +} + +#new-window-button, +#appMenu-new-window-button2 { + list-style-image: url("window.svg") !important; +} + +#restore-button, +#fullscreen-button, +#appMenu-fullscreen-button2 { + list-style-image: url("fullscreen.svg") !important; +} + +#restore-button[checked], +#fullscreen-button[checked], +#appMenu-fullscreen-button2[checked] { + list-style-image: url("fullscreen-exit.svg") !important; +} + +#bookmarks-menu-button, +#appMenu-bookmarks-button, +#sidebar-switcher-bookmarks, +#appMenu-library-bookmarks-button, +#sidebar-box[sidebarcommand="viewBookmarksSidebar"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon { + list-style-image: url("bookmark-star-on-tray.svg") !important; +} + +#home-button { + list-style-image: url("home.svg") !important; +} + +#library-button { + list-style-image: url("library.svg") !important; +} + +/* identity icons */ +#identity-icon { + list-style-image: url("info.svg") !important; +} + +#identity-box[pageproxystate="valid"].chromeUI #identity-icon { + list-style-image: url("firefox.svg") !important; +} + +#identity-box[pageproxystate="valid"].localResource #identity-icon { + list-style-image: url("page-portrait.svg") !important; +} + +#urlbar:not(.searchButton) > :is(#urlbar-input-container, .urlbar-input-container) > #identity-box[pageproxystate="invalid"] #identity-icon { + list-style-image: url("search-glass.svg") !important; +} + +#urlbar[actiontype="extension"] > :is(#urlbar-input-container, .urlbar-input-container) > #identity-box #identity-icon, +#identity-box[pageproxystate="valid"].extensionPage #identity-icon { + list-style-image: url("extension.svg") !important; +} + +#identity-box[pageproxystate="valid"].verifiedDomain #identity-icon, +#identity-box[pageproxystate="valid"].mixedActiveBlocked #identity-icon { + list-style-image: url("security.svg") !important; +} + +:is(#urlbar-input-container, .urlbar-input-container)[pageproxystate="valid"] > #tracking-protection-icon-container > #tracking-protection-icon-box > #tracking-protection-icon { + list-style-image: url("tracking-protection.svg") !important; +} + +/* security */ +.identity-popup-security-connection { + list-style-image: url("security-broken.svg") !important; +} + +#identity-box[pageproxystate="valid"].notSecure #identity-icon, +#identity-box[pageproxystate="valid"].mixedActiveContent #identity-icon, +#identity-box[pageproxystate="valid"].httpsOnlyErrorPage #identity-icon { + list-style-image: url("security-broken.svg") !important; +} + +#identity-popup[connection=chrome] .identity-popup-security-connection { + list-style-image: url("firefox.svg") !important; +} + +#identity-popup[connection="file"] .identity-popup-security-connection { + list-style-image: url("page-portrait.svg") !important; +} + +#identity-popup[connection^=secure] .identity-popup-security-connection { + list-style-image: url("security.svg") !important; +} + +#identity-popup[ciphers=weak] .identity-popup-security-connection, +#identity-popup[mixedcontent~=passive-loaded][isbroken] .identity-popup-security-connection, +#identity-popup[connection=secure-cert-user-overridden] .identity-popup-security-connection, +#identity-popup[connection=cert-error-page] .identity-popup-security-connection { + list-style-image: url("security-warning.svg") !important; +} + +#identity-popup[connection=net-error-page] .identity-popup-security-connection { + list-style-image: url("info.svg") !important; +} + +#identity-popup[connection=extension] .identity-popup-security-connection { + list-style-image: url("extension.svg") !important; +} + +#appMenu-new-tab-button2 { + list-style-image: url("new-tab-image.svg") !important; +} + +.findbar-find-previous { + list-style-image: url("arrow-up.svg") !important; +} + +.findbar-find-next { + list-style-image: url("arrow-down.svg") !important; +} + +#protections-popup-mainView .subviewbutton-nav:not(.notFound)::after, +#identity-popup-mainView .subviewbutton-nav::after, +.widget-overflow-list .subviewbutton-nav::after, +.PanelUI-subView .subviewbutton-nav::after, +.menu-right { + content: url("arrow-filled-right.svg") !important; + opacity: 0.6 !important; + scale: 0.75 !important; +} + +#PlacesChevron, +#urlbar-go-button { + list-style-image: url("arrow-right.svg") !important; +} + +.panel-header > .subviewbutton-back { + list-style-image: url("arrow-left.svg") !important; +} + +#overflowMenu-customize-button, +#appmenu-moreTools-button { + list-style-image: url("customize.svg") !important; +} + +.bookmark-item[container] { + list-style-image: url("folder.svg") !important; +} + +#pageAction-panel-bookmark, +#star-button { + list-style-image: url("bookmark-hollow.svg") !important; +} + +#pageAction-panel-bookmark[starred], +#star-button[starred] { + list-style-image: url("bookmark.svg") !important; +} + +#sidebar-box[sidebarcommand="viewTabsSidebar"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon, +#sidebar-switcher-tabs { + list-style-image: url("send-to-device.svg") !important; +} + +/* tab icons */ +.tab-icon-image[src="chrome://branding/content/icon32.png"], +.tab-icon-image[src="chrome://browser/skin/privatebrowsing/favicon.svg"] { + content: url("new-tab-image.svg") !important; +} + +.tab-icon-image[src="chrome://global/skin/icons/settings.svg"] { + content: url("settings.svg") !important; +} + +.tab-icon-image[src="chrome://mozapps/skin/extensions/extension.svg"] { + content: url("extension.svg") !important; +} + +.tab-icon-image[src="chrome://browser/skin/customize.svg"] { + content: url("customize.svg") !important; +} + +/* permissions */ +#permissions-granted-icon { + list-style-image: url("permissions.svg") !important; +} + +.geo-icon { + list-style-image: url("geo.svg") !important; +} + +.geo-icon.blocked-permission-icon { + list-style-image: url("geo-blocked.svg") !important; +} + +.xr-icon { + list-style-image: url("xr.svg") !important; +} + +.xr-icon.blocked-permission-icon { + list-style-image: url("xr-blocked.svg") !important; +} + +.popup-notification-icon[popupid="web-notifications"], +.desktop-notification-icon { + list-style-image: url("desktop-notification.svg") !important; +} + +.desktop-notification-icon.blocked-permission-icon { + list-style-image: url("desktop-notification-blocked.svg") !important; +} + +.camera-icon, +#webRTC-sharingCamera-menu, +#webrtc-sharing-icon[sharing="camera"] { + list-style-image: url("camera.svg") !important; +} + +.camera-icon.blocked-permission-icon { + list-style-image: url("camera-blocked.svg") !important; +} + +.microphone-icon, +#webRTC-sharingMicrophone-menu, +#webrtc-sharing-icon[sharing="microphone"] { + list-style-image: url("microphone.svg") !important; +} + +.microphone-icon.blocked-permission-icon { + list-style-image: url("microphone-blocked.svg") !important; +} + +.screen-icon, +#webRTC-sharingScreen-menu, +#webrtc-sharing-icon[sharing="screen"] { + list-style-image: url("screen.svg") !important; +} + +.screen-icon.blocked-permission-icon { + list-style-image: url("screen-blocked.svg") !important; +} + +.popup-notification-icon[popupid="persistent-storage"], +.persistent-storage-icon, +.indexedDB-icon { + list-style-image: url("persistent-storage.svg") !important; +} + +.persistent-storage-icon.blocked-permission-icon { + list-style-image: url("persistent-storage-blocked.svg") !important; +} + +.popup-icon { + list-style-image: url("popup.svg") !important; +} + +.autoplay-media-icon { + list-style-image: url("autoplay-media.svg") !important; +} + +.autoplay-media-icon.blocked-permission-icon { + list-style-image: url("autoplay-media-blocked.svg") !important; +} + +#canvas-notification-icon, +.popup-notification-icon[popupid="canvas-permissions-prompt"], +.canvas-icon { + list-style-image: url("canvas.svg") !important; +} + +.canvas-icon.blocked-permission-icon { + list-style-image: url("canvas-blocked.svg") !important; +} + +.midi-icon, +.midi-sysex-icon, +.popup-notification-icon[popupid="midi"], +.popup-notification-icon[popupid="midi-sysex"] { + list-style-image: url("midi.svg") !important; +} + +.install-icon { + list-style-image: url("extension.svg") !important; +} + +.install-icon.blocked-permission-icon, +.popup-notification-icon[popupid="xpinstall-disabled"], +.popup-notification-icon[popupid="addon-install-blocked"], +.popup-notification-icon[popupid="addon-install-origin-blocked"] { + list-style-image: url("extension-blocked.svg") !important; +} + +/* tab sound icons */ +.tab-icon-overlay[soundplaying] { + list-style-image: url("tab-audio-playing-small.svg") !important; +} + +.tab-icon-overlay[muted] { + list-style-image: url("tab-audio-muted-small.svg") !important; +} + +.tab-icon-overlay[activemedia-blocked] { + list-style-image: url("tab-audio-blocked-small.svg") !important; +} + +/* reload/stop animation */ +#stop-reload-button[animate] > #reload-button[displaystop] + #stop-button > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image { + background-image: url("reload-to-stop.svg") !important; +} + +#stop-reload-button[animate] > #reload-button > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image { + background-image: url("stop-to-reload.svg") !important; +} + +#reader-mode-button > .urlbar-icon { + list-style-image: url("reader-mode.svg") !important; +} + +#appMenu-report-broken-site-button { + list-style-image: url("report.svg") !important; +} + +/* + MARK: Context menu +*/ + +/* disable context menu icons when this tweak is applied */ +@media not (-moz-bool-pref: "uc.tweak.revert-context-menu") { + + /* Context Menu Icons */ + menupopup > menuitem:is([checked="true"], [selected="true"]) .menu-iconic-icon { + list-style-image: url("checkmark.svg") !important; + + @media (-moz-platform: linux) { + list-style-image: none !important; + } + } + + #context-video-pictureinpicture:not([checked="true"]) .menu-iconic-icon { + list-style-image: url("media-pip.svg") !important; + } + + #context-media-loop:not([checked="true"]) .menu-iconic-icon { + list-style-image: url("media-loop.svg") !important; + } + + :not(:not(menubar) > menu, #ContentSelectDropdown) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], [type="radio"], .in-menulist, .in-menulist menuitem, .unified-nav-current), + :not(:not(menubar) > menu, #ContentSelectDropdown) > menupopup > menu:not(.menu-iconic, [type="checkbox"], [type="radio"], .in-menulist, .in-menulist menu, .unified-nav-current) { + background-image: var(--menu-image) !important; + background-size: 16px !important; + background-position: var(--uc-contextmenu-menuitem-padding-inline) center !important; + background-repeat: no-repeat !important; + -moz-context-properties: fill, fill-opacity !important; + fill: currentColor !important; + } + + @media (-moz-platform: macos) { + #context-back { + --menu-image: url("back.svg"); + } + + #context-forward { + --menu-image: url("forward.svg"); + } + + #context-reload { + --menu-image: url("reload.svg"); + } + + #context-stop { + --menu-image: url("close.svg"); + } + + #context-bookmarkpage { + --menu-image: url("bookmark-hollow.svg"); + } + + #contentAreaContextMenu #context-bookmarkpage[starred] { + --menu-image: url("bookmark.svg"); + fill: var(--toolbarbutton-icon-fill-attention, currentColor) !important; + } + } + + #context-savepage { + --menu-image: url("save.svg"); + } + + #context-selectall, + .textbox-contextmenu menuitem[cmd*="selectAll"], + #context_selectAllTabs, + #toolbar-context-selectAllTabs { + --menu-image: url("edit-select-all.svg"); + } + + #context-undo, + .textbox-contextmenu menuitem[cmd*="undo"], + #context_undoCloseTab, + #toolbar-context-undoCloseTab { + --menu-image: url("edit-undo.svg"); + } + + #context-redo, + .textbox-contextmenu menuitem[cmd*="redo"] { + --menu-image: url("edit-redo.svg"); + } + + #context-copy, + .textbox-contextmenu menuitem[cmd*="copy"], + #placesContext_copy { + --menu-image: url("edit-copy.svg"); + } + + #context-stripOnShareLink, + #strip-on-share { + --menu-image: url("edit-copy-without-tracking.svg"); + } + + #context-paste, + .textbox-contextmenu menuitem[cmd*="paste"], + #placesContext_paste_group { + --menu-image: url("edit-paste.svg"); + } + + #context-cut, + .textbox-contextmenu menuitem[cmd*="cut"], + #placesContext_cut { + --menu-image: url("edit-cut.svg"); + } + + #context-delete, + .customize-context-removeExtension, + .unified-extensions-context-menu-remove-extension, + .textbox-contextmenu menuitem[cmd*="delete"], + menuitem[id="placesContext_deleteBookmark"], + menuitem[id="placesContext_deleteFolder"], + menuitem[id="placesContext_delete"], + menuitem[id="placesContext_delete_history"], + menuitem[id="placesContext_deleteHost"] { + --menu-image: url("edit-delete.svg"); + } + + #paste-and-go, + .searchbar-paste-and-search { + --menu-image: url("paste-and-go.svg"); + } + + #context-print-selection { + --menu-image: url("print.svg"); + } + + #context-take-screenshot { + --menu-image: url("screenshot.svg"); + } + + #context-viewsource, + #context-viewpartialsource-selection { + --menu-image: url("source-code.svg"); + } + + #context-inspect-a11y { + --menu-image: url("accessibility.svg"); + } + + #context-inspect { + --menu-image: url("inspect.svg"); + } + + #context-searchselect { + --menu-image: url("search-glass.svg"); + } + + #context-viewimage { + --menu-image: url("image-open.svg"); + } + + #context-saveimage, + #context-video-saveimage { + --menu-image: url("image-save.svg"); + } + + #context-savevideo { + --menu-image: url("video-save.svg"); + } + + #context-viewvideo { + --menu-image: url("video-open.svg"); + } + + #context-saveaudio { + --menu-image: url("audio-save.svg"); + } + + #context-copyimage-contents { + --menu-image: url("image-copy.svg"); + } + + #context-copyimage, + #context-copyvideourl, + #context-copylink { + --menu-image: url("link.svg"); + } + + #context-sendimage, + #context-sendvideo, + #context-sendaudio { + --menu-image: url("mail.svg"); + } + + #context-setDesktopBackground, + .viewCustomizeToolbar { + --menu-image: url("customize.svg"); + } + + #context-reloadimage, + #context_reloadTab, + #context_reloadSelectedTabs, + #toolbar-context-reloadSelectedTab, + #toolbar-context-reloadSelectedTabs { + --menu-image: url("reload.svg"); + } + + #context-sendlinktodevice, + #context_sendTabToDevice, + #context-sendpagetodevice, + #sidebar-switcher-tabs { + --menu-image: url("send-to-device.svg"); + } + + #context-openlinkintab, + #context-openlinkincontainertab, + menuitem[id="placesContext_open:newtab"], + menuitem[id="placesContext_openLinks:tabs"], + menuitem[id="placesContext_openBookmarkLinks:tabs"], + menuitem[id="placesContext_openBookmarkContainer:tabs"] { + --menu-image: url("tab.svg"); + } + + #context_openANewTab, + #toolbar-context-openANewTab { + --menu-image: url("new-tab-image.svg"); + } + + #context-openlinkinusercontext-menu, + menu[id="placesContext_open:newcontainertab"], + menu[id="placesContext_openContainer:tabs"] { + --menu-image: url("container-tab.svg"); + } + + #context-openlink, + menuitem[id="placesContext_open:newwindow"] { + --menu-image: url("window.svg"); + } + + #context-openlinkprivate, + menuitem[id="placesContext_open:newprivatewindow"] { + --menu-image: url("private-window.svg"); + } + + #context-savelink { + --menu-image: url("downloads.svg"); + } + + #spell-add-to-dictionary { + --menu-image: url("add-to-dictionary.svg"); + } + + #manage-saved-logins { + --menu-image: url("passwords.svg"); + } + + #context-media-play, + #context_playTab, + #context_playSelectedTabs { + --menu-image: url("media-play.svg"); + } + + #context-media-pause { + --menu-image: url("media-pause.svg"); + } + + #context-media-mute, + #context_toggleMuteTab, + #context_toggleMuteSelectedTabs { + --menu-image: url("media-mute.svg"); + } + + #context-media-unmute, + #context_toggleMuteTab[muted], + #context_toggleMuteSelectedTabs[muted] { + --menu-image: url("media-unmute.svg"); + } + + #context-media-playbackrate { + --menu-image: url("media-speed.svg"); + } + + #context-video-fullscreen { + --menu-image: url("fullscreen.svg"); + } + + #context-leave-dom-fullscreen, + menuitem[contexttype="fullscreen"][label*="Exit"] { + --menu-image: url("fullscreen-exit.svg"); + } + + #context-media-hidecontrols, + #context-media-showcontrols { + --menu-image: url("permissions.svg"); + } + + #context_pinTab, + #context_unpinTab, + #context_pinSelectedTabs, + #context_unpinSelectedTabs, + .customize-context-moveToPanel { + --menu-image: url("pin.svg"); + } + + #context_duplicateTab, + #context_duplicateTabs { + --menu-image: url("duplicate-tab.svg"); + } + + #context_bookmarkTab, + #context_bookmarkSelectedTabs, + #toggle_PersonalToolbar, + #context-bookmarklink, + #toolbar-context-bookmarkSelectedTab, + #toolbar-context-bookmarkSelectedTabs { + --menu-image: url("bookmark-hollow.svg"); + } + + #sidebar-switcher-bookmarks { + --menu-image: url("bookmark-star-on-tray.svg"); + } + + menuitem[id="placesContext_show_bookmark:info"], + menuitem[id="placesContext_show_folder:info"], + menuitem[id="placesContext_show:info"] { + --menu-image: url("edit.svg"); + } + + menuitem[id="placesContext_showAllBookmarks"], + #BMB_bookmarksShowAllTop, + #BMB_bookmarksShowAll, + .customize-context-manageExtension, + .unified-extensions-context-menu-manage-extension { + --menu-image: url("manage.svg"); + } + + menuitem[id="placesContext_new:bookmark"], + menuitem[id="placesContext_new:folder"], + menuitem[id="placesContext_new:separator"] { + --menu-image: url("plus.svg"); + } + + #context-savelinktopocket, + #context-pocket { + --menu-image: url("pocket-outline.svg"); + } + + #context_moveTabOptions { + --menu-image: url("move-tab.svg"); + } + + .share-tab-url-item { + --menu-image: url("share.svg"); + } + + #context_reopenInContainer { + --menu-image: url("container-tab.svg"); + } + + #context_closeTab { + --menu-image: url("close.svg"); + } + + .customize-context-reportExtension, + .unified-extensions-context-menu-report-extension { + --menu-image: url("report.svg"); + } + + #sidebar-switcher-history { + --menu-image: url("history.svg"); + } +} + +/* + MARK: App menu header +*/ + +/* Header icons for the app menu sub menus (eg. fx account, history...) */ +.panel-header > h1 > span { + &::before { + content: ""; + background: var(--header-image, none) center / 16px no-repeat; + -moz-context-properties: fill, fill-opacity; + fill: currentColor; + padding-inline-start: calc(var(--uc-enabled, 0) * 16px); + margin-inline-end: calc(var(--uc-enabled, 0) * 8px); + } + + #PanelUI-fxa &::before { + --header-image: var(--avatar-image-url); + --uc-enabled: 1; + transform: scale(1.25); + border-radius: 99px; + display: inline-block; + height: 16px; + vertical-align: text-bottom; + } + + #PanelUI-bookmarks &::before { + --header-image: url("bookmark-star-on-tray.svg"); + --uc-enabled: 1; + } + + #PanelUI-history &::before { + --header-image: url("history.svg"); + --uc-enabled: 1; + } + + #PanelUI-helpView &::before { + --header-image: url("help.svg"); + --uc-enabled: 1; + } + + #appMenu-libraryView &::before { + --header-image: url("library.svg"); + --uc-enabled: 1; + } + + #unified-extensions-panel &::before { + --header-image: url("extension.svg"); + --uc-enabled: 1; + } + + #report-broken-site-popup-mainView &::before { + --header-image: url("report.svg"); + --uc-enabled: 1; + } +} + +/* + MARK: Tree items +*/ + +/* Tree items used for side bar and library windows */ +treechildren::-moz-tree-image { + fill-opacity: 1 !important; +} + +treechildren::-moz-tree-image(title) { + list-style-image: url("page-portrait.svg") !important; +} + +/* default folder icon */ +treechildren::-moz-tree-image(title, container), +treechildren::-moz-tree-image(title, open) { + list-style-image: url("folder.svg") !important; +} + +/* bookmarks bar icon */ +treechildren::-moz-tree-image(container, queryFolder_toolbar_____) { + list-style-image: url("bookmark-hollow.svg") !important; +} + +/* bookmarks menu icon */ +treechildren::-moz-tree-image(container, queryFolder_menu________) { + list-style-image: url("folder.svg") !important; +} + +/* smart folder icon */ +treechildren::-moz-tree-image(query) { + list-style-image: url("settings.svg") !important; +} + +/* bookmarks category icon */ +treechildren::-moz-tree-image(query, OrganizerQuery_allbms_____v) { + list-style-image: url("bookmark-hollow.svg") !important; +} + +/* downloads category icon */ +treechildren::-moz-tree-image(query, OrganizerQuery_downloads__v) { + list-style-image: url("downloads.svg") !important; +} + +/* tags category icon */ +treechildren::-moz-tree-image(title, query, tagContainer), +treechildren::-moz-tree-image(query, OrganizerQuery_tags_______v) { + list-style-image: url("tag.svg") !important; +} + +/* calendar icon for folders grouping items by date */ +treechildren::-moz-tree-image(title, query, dayContainer) { + list-style-image: url("history.svg") !important; +} + +treechildren::-moz-tree-image(title, query, hostContainer) { + list-style-image: url("folder.svg") !important; +} + +/* history category icon */ +treechildren::-moz-tree-image(query, OrganizerQuery_history____v) { + list-style-image: url("history.svg") !important; +} + +treechildren::-moz-tree-image(title, query, folder) { + list-style-image: url("folder.svg") !important; +} diff --git a/config/firefox/chrome/icons/image-copy.svg b/config/firefox/chrome/icons/image-copy.svg new file mode 100644 index 0000000..8266f7c --- /dev/null +++ b/config/firefox/chrome/icons/image-copy.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/image-open.svg b/config/firefox/chrome/icons/image-open.svg new file mode 100644 index 0000000..b17d039 --- /dev/null +++ b/config/firefox/chrome/icons/image-open.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/config/firefox/chrome/icons/image-save.svg b/config/firefox/chrome/icons/image-save.svg new file mode 100644 index 0000000..4ed3345 --- /dev/null +++ b/config/firefox/chrome/icons/image-save.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/info.svg b/config/firefox/chrome/icons/info.svg new file mode 100644 index 0000000..50f7757 --- /dev/null +++ b/config/firefox/chrome/icons/info.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/inspect.svg b/config/firefox/chrome/icons/inspect.svg new file mode 100755 index 0000000..8f29365 --- /dev/null +++ b/config/firefox/chrome/icons/inspect.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/library.svg b/config/firefox/chrome/icons/library.svg new file mode 100644 index 0000000..f1e0c01 --- /dev/null +++ b/config/firefox/chrome/icons/library.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/link.svg b/config/firefox/chrome/icons/link.svg new file mode 100644 index 0000000..4509293 --- /dev/null +++ b/config/firefox/chrome/icons/link.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/mail.svg b/config/firefox/chrome/icons/mail.svg new file mode 100644 index 0000000..a8c9112 --- /dev/null +++ b/config/firefox/chrome/icons/mail.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/manage.svg b/config/firefox/chrome/icons/manage.svg new file mode 100644 index 0000000..59e1249 --- /dev/null +++ b/config/firefox/chrome/icons/manage.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/media-loop.svg b/config/firefox/chrome/icons/media-loop.svg new file mode 100644 index 0000000..0ff335c --- /dev/null +++ b/config/firefox/chrome/icons/media-loop.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/media-mute.svg b/config/firefox/chrome/icons/media-mute.svg new file mode 100644 index 0000000..bfcc81f --- /dev/null +++ b/config/firefox/chrome/icons/media-mute.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/media-pause.svg b/config/firefox/chrome/icons/media-pause.svg new file mode 100644 index 0000000..6212a20 --- /dev/null +++ b/config/firefox/chrome/icons/media-pause.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/media-pip.svg b/config/firefox/chrome/icons/media-pip.svg new file mode 100644 index 0000000..a83fb54 --- /dev/null +++ b/config/firefox/chrome/icons/media-pip.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/media-play.svg b/config/firefox/chrome/icons/media-play.svg new file mode 100644 index 0000000..da95f78 --- /dev/null +++ b/config/firefox/chrome/icons/media-play.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/media-speed.svg b/config/firefox/chrome/icons/media-speed.svg new file mode 100644 index 0000000..a7767c7 --- /dev/null +++ b/config/firefox/chrome/icons/media-speed.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/media-unmute.svg b/config/firefox/chrome/icons/media-unmute.svg new file mode 100644 index 0000000..9a7d4b7 --- /dev/null +++ b/config/firefox/chrome/icons/media-unmute.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/menu.svg b/config/firefox/chrome/icons/menu.svg new file mode 100644 index 0000000..44b77db --- /dev/null +++ b/config/firefox/chrome/icons/menu.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/microphone-blocked.svg b/config/firefox/chrome/icons/microphone-blocked.svg new file mode 100644 index 0000000..36663f2 --- /dev/null +++ b/config/firefox/chrome/icons/microphone-blocked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/microphone.svg b/config/firefox/chrome/icons/microphone.svg new file mode 100644 index 0000000..e93a61d --- /dev/null +++ b/config/firefox/chrome/icons/microphone.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/midi.svg b/config/firefox/chrome/icons/midi.svg new file mode 100644 index 0000000..8f8bd4e --- /dev/null +++ b/config/firefox/chrome/icons/midi.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/move-tab.svg b/config/firefox/chrome/icons/move-tab.svg new file mode 100644 index 0000000..9c5d46f --- /dev/null +++ b/config/firefox/chrome/icons/move-tab.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/new-tab-image.svg b/config/firefox/chrome/icons/new-tab-image.svg new file mode 100644 index 0000000..f1201ed --- /dev/null +++ b/config/firefox/chrome/icons/new-tab-image.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/config/firefox/chrome/icons/new-tab.svg b/config/firefox/chrome/icons/new-tab.svg new file mode 100644 index 0000000..062c3c6 --- /dev/null +++ b/config/firefox/chrome/icons/new-tab.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/open.svg b/config/firefox/chrome/icons/open.svg new file mode 100644 index 0000000..067f3ae --- /dev/null +++ b/config/firefox/chrome/icons/open.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/page-portrait.svg b/config/firefox/chrome/icons/page-portrait.svg new file mode 100644 index 0000000..8ed9c54 --- /dev/null +++ b/config/firefox/chrome/icons/page-portrait.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/passwords.svg b/config/firefox/chrome/icons/passwords.svg new file mode 100644 index 0000000..099f498 --- /dev/null +++ b/config/firefox/chrome/icons/passwords.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/paste-and-go.svg b/config/firefox/chrome/icons/paste-and-go.svg new file mode 100644 index 0000000..18f1553 --- /dev/null +++ b/config/firefox/chrome/icons/paste-and-go.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/permissions.svg b/config/firefox/chrome/icons/permissions.svg new file mode 100644 index 0000000..0df27b3 --- /dev/null +++ b/config/firefox/chrome/icons/permissions.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/persistent-storage-blocked.svg b/config/firefox/chrome/icons/persistent-storage-blocked.svg new file mode 100644 index 0000000..23caa39 --- /dev/null +++ b/config/firefox/chrome/icons/persistent-storage-blocked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/persistent-storage.svg b/config/firefox/chrome/icons/persistent-storage.svg new file mode 100644 index 0000000..0746caa --- /dev/null +++ b/config/firefox/chrome/icons/persistent-storage.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/pin.svg b/config/firefox/chrome/icons/pin.svg new file mode 100644 index 0000000..fbfc31c --- /dev/null +++ b/config/firefox/chrome/icons/pin.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/plus.svg b/config/firefox/chrome/icons/plus.svg new file mode 100644 index 0000000..7072c1c --- /dev/null +++ b/config/firefox/chrome/icons/plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/pocket-outline.svg b/config/firefox/chrome/icons/pocket-outline.svg new file mode 100644 index 0000000..24c7a41 --- /dev/null +++ b/config/firefox/chrome/icons/pocket-outline.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/popup.svg b/config/firefox/chrome/icons/popup.svg new file mode 100644 index 0000000..1f8a8cf --- /dev/null +++ b/config/firefox/chrome/icons/popup.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/print.svg b/config/firefox/chrome/icons/print.svg new file mode 100644 index 0000000..ed311c7 --- /dev/null +++ b/config/firefox/chrome/icons/print.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/private-window.svg b/config/firefox/chrome/icons/private-window.svg new file mode 100644 index 0000000..59126a2 --- /dev/null +++ b/config/firefox/chrome/icons/private-window.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/privateBrowsing.svg b/config/firefox/chrome/icons/privateBrowsing.svg new file mode 100644 index 0000000..d576a31 --- /dev/null +++ b/config/firefox/chrome/icons/privateBrowsing.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/reader-mode.svg b/config/firefox/chrome/icons/reader-mode.svg new file mode 100644 index 0000000..370fda6 --- /dev/null +++ b/config/firefox/chrome/icons/reader-mode.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/reload-to-stop.svg b/config/firefox/chrome/icons/reload-to-stop.svg new file mode 100644 index 0000000..13b1bd9 --- /dev/null +++ b/config/firefox/chrome/icons/reload-to-stop.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/firefox/chrome/icons/reload.svg b/config/firefox/chrome/icons/reload.svg new file mode 100644 index 0000000..772c9bd --- /dev/null +++ b/config/firefox/chrome/icons/reload.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/report.svg b/config/firefox/chrome/icons/report.svg new file mode 100644 index 0000000..7b7517f --- /dev/null +++ b/config/firefox/chrome/icons/report.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/save.svg b/config/firefox/chrome/icons/save.svg new file mode 100644 index 0000000..e3179f3 --- /dev/null +++ b/config/firefox/chrome/icons/save.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/screen-blocked.svg b/config/firefox/chrome/icons/screen-blocked.svg new file mode 100644 index 0000000..1a9f603 --- /dev/null +++ b/config/firefox/chrome/icons/screen-blocked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/screen.svg b/config/firefox/chrome/icons/screen.svg new file mode 100644 index 0000000..9aec149 --- /dev/null +++ b/config/firefox/chrome/icons/screen.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/screenshot.svg b/config/firefox/chrome/icons/screenshot.svg new file mode 100644 index 0000000..65e9cff --- /dev/null +++ b/config/firefox/chrome/icons/screenshot.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/search-glass.svg b/config/firefox/chrome/icons/search-glass.svg new file mode 100644 index 0000000..79a5001 --- /dev/null +++ b/config/firefox/chrome/icons/search-glass.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/search-page.svg b/config/firefox/chrome/icons/search-page.svg new file mode 100755 index 0000000..05c3b53 --- /dev/null +++ b/config/firefox/chrome/icons/search-page.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/security-broken.svg b/config/firefox/chrome/icons/security-broken.svg new file mode 100644 index 0000000..e931dc1 --- /dev/null +++ b/config/firefox/chrome/icons/security-broken.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/security-warning.svg b/config/firefox/chrome/icons/security-warning.svg new file mode 100644 index 0000000..467d5aa --- /dev/null +++ b/config/firefox/chrome/icons/security-warning.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/security.svg b/config/firefox/chrome/icons/security.svg new file mode 100644 index 0000000..c79b8c2 --- /dev/null +++ b/config/firefox/chrome/icons/security.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/send-to-device.svg b/config/firefox/chrome/icons/send-to-device.svg new file mode 100644 index 0000000..2d77ac2 --- /dev/null +++ b/config/firefox/chrome/icons/send-to-device.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/settings.svg b/config/firefox/chrome/icons/settings.svg new file mode 100644 index 0000000..de58959 --- /dev/null +++ b/config/firefox/chrome/icons/settings.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/share.svg b/config/firefox/chrome/icons/share.svg new file mode 100644 index 0000000..1d135f4 --- /dev/null +++ b/config/firefox/chrome/icons/share.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/sidebars-right.svg b/config/firefox/chrome/icons/sidebars-right.svg new file mode 100644 index 0000000..626ee35 --- /dev/null +++ b/config/firefox/chrome/icons/sidebars-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/sidebars.svg b/config/firefox/chrome/icons/sidebars.svg new file mode 100644 index 0000000..ab58502 --- /dev/null +++ b/config/firefox/chrome/icons/sidebars.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/source-code.svg b/config/firefox/chrome/icons/source-code.svg new file mode 100755 index 0000000..a65f35d --- /dev/null +++ b/config/firefox/chrome/icons/source-code.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/stop-to-reload.svg b/config/firefox/chrome/icons/stop-to-reload.svg new file mode 100644 index 0000000..0f9d2d1 --- /dev/null +++ b/config/firefox/chrome/icons/stop-to-reload.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/firefox/chrome/icons/tab-audio-blocked-small.svg b/config/firefox/chrome/icons/tab-audio-blocked-small.svg new file mode 100644 index 0000000..f5af4d4 --- /dev/null +++ b/config/firefox/chrome/icons/tab-audio-blocked-small.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/tab-audio-muted-small.svg b/config/firefox/chrome/icons/tab-audio-muted-small.svg new file mode 100644 index 0000000..442fd7f --- /dev/null +++ b/config/firefox/chrome/icons/tab-audio-muted-small.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/tab-audio-playing-small.svg b/config/firefox/chrome/icons/tab-audio-playing-small.svg new file mode 100644 index 0000000..896a890 --- /dev/null +++ b/config/firefox/chrome/icons/tab-audio-playing-small.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/tab.svg b/config/firefox/chrome/icons/tab.svg new file mode 100644 index 0000000..d21577b --- /dev/null +++ b/config/firefox/chrome/icons/tab.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/tag.svg b/config/firefox/chrome/icons/tag.svg new file mode 100644 index 0000000..8864d48 --- /dev/null +++ b/config/firefox/chrome/icons/tag.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/tool-profiler.svg b/config/firefox/chrome/icons/tool-profiler.svg new file mode 100644 index 0000000..8760328 --- /dev/null +++ b/config/firefox/chrome/icons/tool-profiler.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/tracking-protection.svg b/config/firefox/chrome/icons/tracking-protection.svg new file mode 100644 index 0000000..8491ded --- /dev/null +++ b/config/firefox/chrome/icons/tracking-protection.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/translate.svg b/config/firefox/chrome/icons/translate.svg new file mode 100644 index 0000000..58e8c43 --- /dev/null +++ b/config/firefox/chrome/icons/translate.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/video-open.svg b/config/firefox/chrome/icons/video-open.svg new file mode 100644 index 0000000..5aba487 --- /dev/null +++ b/config/firefox/chrome/icons/video-open.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/video-save.svg b/config/firefox/chrome/icons/video-save.svg new file mode 100644 index 0000000..9523d94 --- /dev/null +++ b/config/firefox/chrome/icons/video-save.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/win11-close-dark.svg b/config/firefox/chrome/icons/win11-close-dark.svg new file mode 100644 index 0000000..ccc02b4 --- /dev/null +++ b/config/firefox/chrome/icons/win11-close-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/win11-close.svg b/config/firefox/chrome/icons/win11-close.svg new file mode 100644 index 0000000..8fa6779 --- /dev/null +++ b/config/firefox/chrome/icons/win11-close.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/win11-maximize.svg b/config/firefox/chrome/icons/win11-maximize.svg new file mode 100644 index 0000000..81f1254 --- /dev/null +++ b/config/firefox/chrome/icons/win11-maximize.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/win11-minimize.svg b/config/firefox/chrome/icons/win11-minimize.svg new file mode 100644 index 0000000..fa479fe --- /dev/null +++ b/config/firefox/chrome/icons/win11-minimize.svg @@ -0,0 +1,4 @@ + + + + diff --git a/config/firefox/chrome/icons/win11-restore.svg b/config/firefox/chrome/icons/win11-restore.svg new file mode 100644 index 0000000..09f94a2 --- /dev/null +++ b/config/firefox/chrome/icons/win11-restore.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/window.svg b/config/firefox/chrome/icons/window.svg new file mode 100644 index 0000000..f5d3426 --- /dev/null +++ b/config/firefox/chrome/icons/window.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/xr-blocked.svg b/config/firefox/chrome/icons/xr-blocked.svg new file mode 100644 index 0000000..b4df6f3 --- /dev/null +++ b/config/firefox/chrome/icons/xr-blocked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/config/firefox/chrome/icons/xr.svg b/config/firefox/chrome/icons/xr.svg new file mode 100644 index 0000000..80772b3 --- /dev/null +++ b/config/firefox/chrome/icons/xr.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/icons/zoom-out.svg b/config/firefox/chrome/icons/zoom-out.svg new file mode 100644 index 0000000..9023b66 --- /dev/null +++ b/config/firefox/chrome/icons/zoom-out.svg @@ -0,0 +1,3 @@ + + + diff --git a/config/firefox/chrome/toolbar/findbar.css b/config/firefox/chrome/toolbar/findbar.css new file mode 100644 index 0000000..499e501 --- /dev/null +++ b/config/firefox/chrome/toolbar/findbar.css @@ -0,0 +1,73 @@ +/* Edge-Frfox - findbar.css + * https://github.com/bmFtZQ/edge-frfox */ + +/* + MARK: Findbar textbox +*/ +.findbar-textbox { + border: 0 !important; + border-radius: var(--toolbarbutton-border-radius) !important; + background-color: var(--toolbar-field-background-color) !important; + + /* Add shadow when in light mode with no theme applied, like the URL bar. */ + :root:not([lwtheme]) & { + box-shadow: 0 0 4px light-dark(rgb(0 0 0 / .1), transparent) !important; + } + + &:focus { + outline-width: 2px !important; + outline-offset: -1px !important; + } + + &[status="notfound"] { + outline: 2px solid var(--input-error-border-color, #E22850) !important; + outline-offset: -1px !important; + } +} + +/* Prevent focus outline from being cut off on the findbar textbox. */ +.findbar-container { + overflow-inline: visible !important; + + /* Add ability to drag window from empty space in the findbar. */ + &::after { + content: ""; + flex: 1; + align-self: stretch; + margin-block: -6px; + -moz-window-dragging: drag; + } +} + +/* + MARK: Findbar buttons +*/ +.findbar-find-previous, +.findbar-find-next, +findbar .close-icon { + border-radius: var(--toolbarbutton-border-radius) !important; + + &:not([disabled]):hover { + background-color: var(--toolbarbutton-hover-background, rgb(190 190 190 / .2)) !important; + + &:active { + background-color: var(--toolbarbutton-active-background, rgb(190 190 190 / .4)) !important; + } + } +} + +/* + MARK: Rounded corners +*/ +@media (-moz-bool-pref: "uc.tweak.rounded-corners") { + findbar { + border: none !important; + margin-bottom: var(--uc-tweak-rounded-corners-padding, 0px) !important; + background-color: transparent !important; + padding-inline: var(--uc-tweak-rounded-corners-padding, 0px) !important; + + &[hidden] { + margin-bottom: calc(var(--uc-tweak-rounded-corners-padding, 0px) - 40px) !important; + } + } +} diff --git a/config/firefox/chrome/toolbar/navbar.css b/config/firefox/chrome/toolbar/navbar.css new file mode 100644 index 0000000..20c6310 --- /dev/null +++ b/config/firefox/chrome/toolbar/navbar.css @@ -0,0 +1,105 @@ +/* Edge-Frfox - navbar.css + * https://github.com/bmFtZQ/edge-frfox */ + +/* + MARK: Variables +*/ +:root { + --toolbarbutton-border-radius: 4px !important; + --toolbarbutton-inner-padding: 7px !important; + --uc-toolbarbutton-inner-inline-padding: 12px !important; + --toolbarbutton-outer-padding: 2px !important; + --tabs-navbar-shadow-size: 0px !important; +} + +#nav-bar { + border-top: none !important; +} + +/* + MARK: Toolbar buttons +*/ +#nav-bar .toolbarbutton-1>.toolbarbutton-icon { + width: calc(2 * var(--uc-toolbarbutton-inner-inline-padding) + 16px) !important; +} + +#nav-bar .toolbarbutton-1>.toolbarbutton-icon, +#nav-bar .toolbarbutton-1>.toolbarbutton-text, +#nav-bar .toolbarbutton-1>.toolbarbutton-badge-stack { + padding-inline: var(--uc-toolbarbutton-inner-inline-padding) !important; +} + +/* move reload/stop icon to middle of button */ +#reload-button>.toolbarbutton-animatable-box, +#stop-button>.toolbarbutton-animatable-box { + top: calc(50% - 10px) !important; +} + +#nav-bar-customization-target :where(#reload-button, #stop-button)>.toolbarbutton-icon { + padding: var(--toolbarbutton-inner-padding) var(--uc-toolbarbutton-inner-inline-padding) !important; +} + +toolbar .toolbaritem-combined-buttons { + margin-inline: var(--toolbarbutton-outer-padding) !important; +} + +/* + MARK: Account button +*/ +.browser-toolbar #fxa-toolbar-menu-button, +.browser-toolbar #fxa-toolbar-menu-button>.toolbarbutton-badge-stack, +#fxa-avatar-image { + border-radius: 99px !important; +} + +.browser-toolbar #fxa-toolbar-menu-button>.toolbarbutton-badge-stack { + padding: var(--toolbarbutton-inner-padding) !important; + margin-inline: calc(var(--uc-toolbarbutton-inner-inline-padding) - var(--toolbarbutton-inner-padding)) !important; +} + +#TabsToolbar #fxa-toolbar-menu-button>.toolbarbutton-badge-stack { + margin-inline: calc(var(--uc-toolbarbutton-inner-inline-padding) - (var(--toolbarbutton-inner-padding) + 2px)) !important; +} + +#fxa-toolbar-menu-button { + display: flex !important; +} + +#widget-overflow-list>#fxa-toolbar-menu-button #fxa-avatar-image { + scale: 1.25 !important; +} + +.customization-target>#fxa-toolbar-menu-button #fxa-avatar-image { + scale: 1.5 !important; +} + +/* + MARK: Button transitions +*/ +@media not (prefers-reduced-motion) { + .toolbarbutton-1>.toolbarbutton-icon, + .toolbarbutton-1>.toolbarbutton-text, + .toolbarbutton-1>.toolbarbutton-badge-stack, + :not(.panel-subview-body>toolbaritem)>.bookmark-item:not(menu, menuitem), + .urlbar-page-action, + .identity-box-button, + #tracking-protection-icon-container, + panel button, + panel menulist, + .titlebar-button { + transition: background-color 0.25s ease !important; + } + + .toolbarbutton-1:not([disabled=true]):is([open], [checked], :hover:active)>.toolbarbutton-icon, + .toolbarbutton-1:not([disabled=true]):is([open], [checked], :hover:active)>.toolbarbutton-text, + .toolbarbutton-1:not([disabled=true]):is([open], [checked], :hover:active)>.toolbarbutton-badge-stack, + :not(.panel-subview-body>toolbaritem)>.bookmark-item:not(menu, menuitem):not([disabled=true]):is([open], [checked], :hover:active), + .urlbar-page-action:not([disabled=true]):is([open], [checked], :hover:active), + .identity-box-button:not([disabled=true]):is([open], [checked], :hover:active), + #tracking-protection-icon-container:not([disabled=true]):is([open], [checked], :hover:active), + panel button:not([disabled=true]):is([open], [checked], :hover:active), + panel menulist:not([disabled=true]):is([open], [checked], :hover:active), + .titlebar-button:not([disabled=true]):hover:active { + transition-duration: 0s !important; + } +} diff --git a/config/firefox/chrome/toolbar/personalbar.css b/config/firefox/chrome/toolbar/personalbar.css new file mode 100644 index 0000000..0294ce9 --- /dev/null +++ b/config/firefox/chrome/toolbar/personalbar.css @@ -0,0 +1,85 @@ +/* Edge-Frfox - personalbar.css + * https://github.com/bmFtZQ/edge-frfox */ + +/* + MARK: Variables +*/ +:root { + --bookmark-block-padding: 6px !important; + --bookmark-inline-padding: 6px !important; + --bookmark-block-margin: 2px !important; + --bookmark-inline-margin: 2px !important; + --uc-bookmark-toolbar-padding-bottom: 2px; + --bookmarks-toolbar-overlapping-browser-height: calc(var(--uc-bookmark-toolbar-padding-bottom) + 16px + (var(--bookmark-block-margin) + var(--bookmark-block-padding)) * 2) !important; +} + +#PersonalToolbar { + padding-bottom: var(--uc-bookmark-toolbar-padding-bottom) !important; +} + +/* + MARK: Bookmark items +*/ +#personal-toolbar-empty-description, +#PersonalToolbar .toolbarbutton-1, +toolbarbutton.bookmark-item:not(.subviewbutton) { + margin-block: var(--bookmark-block-margin) !important; + margin-inline: var(--bookmark-inline-margin) !important; + padding-block: var(--bookmark-block-padding) !important; + padding-inline: var(--bookmark-inline-padding) !important; + font-size: 12px !important; + + /* Adjust vertical label position on Windows */ + @media (-moz-platform: windows) { + & .toolbarbutton-text { + margin-block: -1px 0 !important; + } + } +} + +#PersonalToolbar .toolbarbutton-1 { + padding: 0 !important; +} + +/* Spacing between icon and label for bookmarks bar items */ +#managed-bookmarks>.toolbarbutton-icon, +#bookmarks-toolbar-placeholder>.toolbarbutton-icon, +#PlacesToolbarItems>.bookmark-item>.toolbarbutton-icon[label]:not([label=""]), +#OtherBookmarks.bookmark-item[container]>.toolbarbutton-icon { + margin-inline-end: 8px !important; +} + +/* Sizing for bookmarks bar icons */ +#PersonalToolbar .toolbarbutton-1>.toolbarbutton-icon { + width: calc(2 * var(--bookmark-block-padding) + 16px) !important; + height: calc(2 * var(--bookmark-block-padding) + 16px) !important; + padding: var(--bookmark-block-padding) !important; +} + +/* + MARK: Separators +*/ +#PlacesToolbarItems > toolbarseparator { + padding-inline: calc(3px - var(--bookmark-inline-margin)) !important; + align-items: center !important; + + &::before { + content: ""; + border-inline-start: 1px solid var(--toolbarseparator-color) !important; + height: 16px !important; + border-image: none !important; + } + + /* Fractional scaling adjustments (150%, 175%, etc.) */ + @media (1dppx < resolution < 2dppx) { + &::before { + border-inline-start-width: 1.5px !important; + } + } +} + +/* Left and Right padding of bookmarks bar */ +#PersonalToolbar { + padding-inline: calc(var(--toolbar-start-end-padding) - 2px) calc(var(--toolbar-start-end-padding) + 4px) !important; +} + diff --git a/config/firefox/chrome/toolbar/tabbar.css b/config/firefox/chrome/toolbar/tabbar.css new file mode 100644 index 0000000..f0bc4f0 --- /dev/null +++ b/config/firefox/chrome/toolbar/tabbar.css @@ -0,0 +1,700 @@ +/* Edge-Frfox - tabbar.css + * https://github.com/bmFtZQ/edge-frfox */ + +/* + MARK: Variables +*/ +:root { + /* Extra space at the top of the window. */ + --uc-tab-top-margin: 8px !important; + + /* Remove extra space at the top of the window when in fullscreen or when + * title bars are enabled. */ + &[inFullscreen], + &:not([tabsintitlebar]) { + --uc-tab-top-margin: 0px !important; + } + + /* Remove extra space at the top when the window is maximised or the menu bar + * is active, only on platforms other than macOS. */ + @media not (-moz-platform: macos) { + &[sizemode="maximized"], + & #toolbar-menubar:not([inactive]) + #TabsToolbar, + &:has(#toolbar-menubar:not([inactive])) { + --uc-tab-top-margin: 0px !important; + } + } + + & #TabsToolbar { + --tab-min-height: 32px !important; + --inline-tab-padding: 11px !important; + --uc-inline-pinned-tab-padding: 12px !important; + --tab-border-radius: 4px !important; + --toolbarbutton-inner-padding: 6px !important; + --uc-toolbarbutton-inner-inline-padding: 8px !important; + --toolbarbutton-border-radius: 4px !important; + --tabs-navbar-shadow-size: 0px !important; + --tab-shadow-max-size: 0 !important; + --uc-tab-separator-height: 20px; + --uc-toolbarbutton-block-margin: 2px; + + /* Gap between tab and adjacent buttons (+2px button margin). */ + --uc-toolbarbutton-tab-gap: 2px; + + @media (-moz-bool-pref: "uc.tweak.rounded-corners") { + --tab-border-radius: 8px !important; + --uc-toolbarbutton-tab-gap: 6px; + } + } +} + +/* Tab grow/shrink transition. */ +.tabbrowser-tab:not([pinned]) { + transition-property: min-width, max-width !important; + transition-duration: 150ms !important; + transition-timing-function: cubic-bezier(0, .75, .25, 1) !important; +} + +/* Tab moving transition. */ +#tabbrowser-tabs[movingtab] > #tabbrowser-arrowscrollbox > .tabbrowser-tab[fadein]:not([selected]):not([multiselected]), +.tabbrowser-tab[tab-grouping], +.tabbrowser-tab[tabdrop-samewindow] { + transition: transform 200ms cubic-bezier(0, .75, .25, 1) !important; +} + +/* Remove tab toolbar background transition on inactive windows. */ +#navigator-toolbox { + transition: none !important; +} + +/* + MARK: Toolbar & buttons +*/ +/* #region */ + +#TabsToolbar { + /* Padding between the edge of the toolbar and its content. */ + padding-inline-start: 8px !important; + + /* Remove any existing margins from toolbar buttons. */ + & .toolbarbutton-1 { + margin: 0 !important; + } + + /* Tab toolbar button sizing. */ + & .toolbarbutton-1 > .toolbarbutton-icon, + & .toolbarbutton-1 > .toolbarbutton-badge-stack { + border-radius: var(--toolbarbutton-border-radius) !important; + padding: var(--toolbarbutton-inner-padding) var(--uc-toolbarbutton-inner-inline-padding) !important; + /* Add margin-block to buttons so they are positioned correctly. */ + margin: var(--uc-toolbarbutton-block-margin) 0 !important; + } + + & .toolbarbutton-1 > .toolbarbutton-icon { + width: calc(2 * var(--uc-toolbarbutton-inner-inline-padding) + 16px) !important; + height: calc(2 * var(--toolbarbutton-inner-padding) + 16px) !important; + } + + /* Keep certain buttons (such as new tab) square shaped. */ + & #tabs-newtab-button > .toolbarbutton-icon, + & #alltabs-button > .toolbarbutton-badge-stack, + & #tabbrowser-tabs[hasadjacentnewtabbutton][overflow] ~ #new-tab-button > .toolbarbutton-icon { + padding: var(--toolbarbutton-inner-padding) !important; + width: calc(2 * var(--toolbarbutton-inner-padding) + 16px) !important; + } + + /* Toolbar buttons should use the same colour as unselected tabs. */ + & .toolbarbutton-animatable-box, + & .toolbarbutton-1 { + fill: currentColor !important; + } + + & #TabsToolbar-customization-target { + /* Vertically align toolbar buttons to the bottom of the tab bar. */ + align-items: end !important; + + /* Reduce space between start of the window and first toolbar button. */ + & > .toolbarbutton-1:nth-child(1 of .toolbarbutton-1:not(#tabbrowser-tabs ~ *)) { + margin-inline-start: -2px !important; + } + + /* Add space after the last toolbar button before the tabs. */ + & > .toolbarbutton-1:nth-last-child(1 of .toolbarbutton-1:not(#tabbrowser-tabs ~ *)), + :root[privatebrowsingmode] & > .toolbarbutton-1:nth-last-child(1 of .toolbarbutton-1:not(#tabbrowser-tabs ~ *):not(#firefox-view-button)) { + margin-inline-end: calc(var(--uc-toolbarbutton-tab-gap) + 2px) !important; + + /* Reduces space between this button and the tab scroll button when + * overflowed for consistency. */ + &:has(~ #tabbrowser-tabs[overflow]) { + margin-inline-end: 2px !important; + } + } + } +} + +#tabbrowser-tabs { + /* Remove the border from the left of the tab bar. */ + border-inline: none !important; + padding-inline-start: var(--tab-overflow-pinned-tabs-width) !important; + + /* Add space above the tabs. */ + margin-top: var(--uc-tab-top-margin) !important; + + /* Pull tabs closer to toolbar buttons when overflowed. */ + &[overflow]:not([haspinnedtabs]) { + margin-inline-start: -2px !important; + } + + /* Remove gap between pinned and unpinned tabs. */ + &[haspinnedtabs]:not([positionpinnedtabs]) .tabbrowser-tab:nth-child(1 of :not([pinned], [hidden])) { + margin-inline-start: 0 !important; + } +} + +/* Add space between last tab and new tab button. */ +#tabbrowser-tabs #tabs-newtab-button { + margin-inline-start: var(--uc-toolbarbutton-tab-gap) !important; +} + +/* Tab scrolling buttons. */ +#scrollbutton-up:not(.menupopup-scrollbutton), +#scrollbutton-down:not(.menupopup-scrollbutton) { + border-width: 2px !important; + border-radius: calc(var(--toolbarbutton-border-radius) + 2px) !important; + padding-inline: calc(var(--toolbarbutton-inner-padding) - 4px) !important; + padding-block: var(--toolbarbutton-inner-padding) !important; +} + +/* Add margin to the side of the button facing the tabs so the buttons line up + * on the opposite side with others in the toolbar. */ +#scrollbutton-up:not(.menupopup-scrollbutton) { + margin-inline: 0 2px !important; +} + +#scrollbutton-down:not(.menupopup-scrollbutton) { + margin-inline: 2px 0 !important; +} + +/* Hide pre-tabs spacer as it isn't needed. */ +.titlebar-spacer[type="pre-tabs"] { + display: none !important; +} + +/* Make sure that the post-tabs spacer appears. */ +.titlebar-spacer[type="post-tabs"] { + display: flex !important; +} + +/* macOS titlebar buttons positioning. */ +@media (-moz-platform: macos) { + /* Compensate for padding added to the Tabs Toolbar. */ + .titlebar-buttonbox-container { + margin-inline-start: -8px !important; + + /* Make sure that titlebar buttons have equal spacing on all sides. */ + & .titlebar-buttonbox { + margin-inline: calc((var(--tab-min-height) + var(--uc-tab-top-margin) - 14px) / 2) !important; + } + } +} + +/* Linux titlebar button positioning. */ +@media (-moz-platform: linux) { + .titlebar-buttonbox-container { + /* Add space between buttons and other toolbar buttons. */ + margin-inline: 8px 0 !important; + + @media (-moz-gtk-csd-reversed-placement) { + /* Compensate for padding added to the Tabs Toolbar. */ + margin-inline: -8px 8px !important; + } + } +} +/* #endregion */ + + +/* + MARK: Tab inner content +*/ +/* #region */ + +.tabbrowser-tab { + font-size: 12px !important; + padding-inline: 0 !important; + /* Allow shadows to appear outside the tabs. */ + overflow-clip-margin: 8px !important; + + /* Set width of tabs. */ + &:not([pinned], [style*="max-width"])[fadein] { + max-width: 240px !important; + } + + /* Enforce tab foreground colour. */ + &:is([visuallyselected], [multiselected]) { + color: var(--tab-selected-textcolor) !important; + + &:-moz-window-inactive { + color: var(--tab-selected-textcolor-inactive, var(--tab-selected-textcolor)) !important; + } + } +} + +/* Tab inner content padding. */ +.tab-content { + padding-inline: var(--inline-tab-padding) 0 !important; + + /* Pinned tab padding. */ + &[pinned] { + padding: 0 var(--uc-inline-pinned-tab-padding) !important; + } + + /* Indicator for when the title of a pinned tab changes. */ + &[pinned][titlechanged]:not([selected]), + .tabbrowser-tab:is([image], [pinned]) &[attention]:not([selected]) { + background-position: center bottom 2px !important; + } +} + +/* Space between tab icons and the tab titles. */ +.tab-throbber:not([pinned]), +.tab-icon-pending:not([pinned]), +.tab-icon-image:not([pinned]), +.tab-sharing-icon-overlay:not([pinned]) { + margin-inline-end: calc(var(--inline-tab-padding) - 1px) !important; +} + +/* Make sure that the tabs are the correct height. */ +#tabbrowser-tabs .tab-label-container { + height: var(--tab-min-height) !important; + + /* Hide tab audio indicator label. */ + & .tab-secondary-label { + display: none !important; + } +} + +/* Tab close button styling. */ +.tab-close-button { + margin-inline-end: 8px !important; + width: 17px !important; + height: 17px !important; + padding: 4px !important; + border-radius: var(--toolbarbutton-border-radius) !important; +} + +/* Ensure that unselected tabs use full opacity and correct colours. + * Also ensures that the tab's icon is always visible. + */ +.tab-label-container:not([selected="true"], [multiselected]), +.tab-icon-stack[indicator-replaces-favicon] > :not(.tab-icon-overlay) { + opacity: 1 !important; +} + +/* Change width of the gradient mask located on the right of the tab labels. */ +#tabbrowser-tabs[closebuttons="activetab"] .tabbrowser-tab .tab-label-container { + --tab-label-mask-size: 1em !important; +} + +/* Tab container indicator. */ +.tabbrowser-tab[usercontextid] { + & .tab-context-line { + height: 2px !important; + border-radius: 2px !important; + margin: 2px 7px 0 !important; + } + + &[selected] .tab-context-line { + margin-inline: 9px !important; + } +} + +/* + MARK: Sound playing indicator +*/ + +/* Move the audio indicator to the right of the tab's icon. */ +#tabbrowser-tabs:not([closebuttons="activetab"]) .tab-icon-overlay:not([pinned]) { + margin-inline: 22px 6px !important; +} + +/* When there is no tab icon, move indicator to the left. */ +#tabbrowser-tabs .tabbrowser-tab:not([image]) .tab-icon-overlay:not([pinned]) { + margin-inline: 0px 6px !important; +} + +/* Overlay the audio indicator onto the tab icon when there isn't enough space. */ +.tab-icon-overlay:not([crashed]):is([pinned], [sharing]), +#tabbrowser-tabs[closebuttons="activetab"] .tab-icon-overlay:not([crashed]) { + top: -5.5px !important; + inset-inline-end: -6px !important; +} + +/* Set colour for the overlay tab audio indicator. */ +#tabbrowser-tabs[closebuttons="activetab"] { + & .tab-icon-overlay:is([soundplaying], [muted], [activemedia-blocked]):not([crashed]) { + stroke: var(--tab-icon-overlay-stroke, light-dark(white, black)) !important; + color: var(--tab-icon-overlay-fill, light-dark(black, white)) !important; + fill-opacity: 1 !important; + + &:hover { + background-color: var(--tab-icon-overlay-stroke, light-dark(white, black)) !important; + } + } +} + +/* Add border radius to the tab audio indicator. */ +.tab-icon-overlay:is([soundplaying], [muted], [activemedia-blocked]):not([crashed]) { + border-radius: var(--toolbarbutton-border-radius) !important; + padding: 0 !important; +} + +/* Ensure the audio indicator is visible when needed. */ +.tab-icon-stack:is([soundplaying], [muted], [activemedia-blocked]) > .tab-icon-overlay { + opacity: 1 !important; +} +/* #endregion */ + + +/* + MARK: Background and corners +*/ +/* #region */ + +.tab-background { + border-radius: var(--tab-border-radius); + border-bottom-left-radius: 0 !important; + border-bottom-right-radius: 0 !important; + margin-block: 0 !important; + border: 0 !important; + position: relative !important; + --uc-tab-corner-bg: transparent; + --uc-tab-corner-outline: transparent; + + /* Both rounded bottom corners. */ + &::before, + &::after { + content: "" !important; + position: absolute !important; + width: var(--tab-border-radius) !important; + aspect-ratio: 1 / 1; + bottom: 0 !important; + pointer-events: none !important; + clip-path: inset(0); + } + + /* Bottom left corner. */ + &::before { + border-bottom-right-radius: var(--tab-border-radius) !important; + left: 0 !important; + translate: calc(-1 * var(--tab-border-radius)) 0 !important; + box-shadow: + /* First shadow is a 1px outline for better theming support. */ + -1px -1px var(--uc-tab-corner-outline) inset, + /* Second shadow is to add the background colour to the corner. */ + 0 0 0 var(--tab-border-radius) var(--uc-tab-corner-bg) !important; + } + + /* Bottom right corner. */ + &::after { + border-bottom-left-radius: var(--tab-border-radius) !important; + right: 0 !important; + translate: var(--tab-border-radius) 0 !important; + box-shadow: + /* First shadow is a 1px outline for better theming support. */ + 1px -1px var(--uc-tab-corner-outline) inset, + /* Second shadow is to add the background colour to the corner. */ + 0 0 0 var(--tab-border-radius) var(--uc-tab-corner-bg) !important; + } + + /* Make sure that the bottom corners have the same background colour. */ + &:is([selected], [multiselected]) { + --uc-tab-corner-bg: var(--tab-selected-bgcolor, var(--lwt-selected-tab-background-color, var(--toolbar-bgcolor))); + --uc-tab-corner-outline: var(--lwt-tab-line-color, transparent); + /* Disable tab outlines when selected. */ + outline: none !important; + } + + /* Tab hover background colour. */ + .tabbrowser-tab:hover &:not([selected], [multiselected]) { + background-color: color-mix(in srgb, currentColor 8%, transparent) !important; + --uc-tab-corner-bg: color-mix(in srgb, currentColor 8%, transparent) !important; + + /* When in light mode, the hover colour should be white. */ + #TabsToolbar:not([brighttext]) & { + background-color: rgb(255 255 255 / .3) !important; + --uc-tab-corner-bg: rgb(255 255 255 / .3) !important; + + @media (-moz-bool-pref: "uc.tweak.floating-tabs") { + background-color: var(--toolbar-bgcolor) !important; + --uc-tab-corner-bg: var(--toolbar-bgcolor) !important; + } + } + } + + /* When tabs are selected but not active, they should have a partially + * transparent background. */ + #tabbrowser-tabs &[multiselected]:not([selected]) { + box-shadow: none !important; + opacity: 0.7 !important; + } +} + +/* Disable bottom left rounded corner to prevent overlapping transparent tabs. + * + * If a tab is selected, then the next tab's bottom-left corner should be + * inverted to prevent overlap with the transparent backgrounds. + * + * If the next tab is hidden, then find the next visible tab which would be + * positioned next to the active tab. + */ +.tabbrowser-tab:is([selected], [multiselected]):not([hidden]) { + & + .tabbrowser-tab .tab-background:not([selected]), + & + .tabbrowser-tab[hidden] ~ .tabbrowser-tab:not([hidden]):is([hidden] + *) .tab-background:not([selected]) { + border-bottom-left-radius: var(--tab-border-radius) !important; + + &::before { + --uc-tab-corner-bg: transparent !important; + } + } +} +/* #endregion */ + + +/* + MARK: Tab separators +*/ +/* #region */ + +.tabbrowser-tab .tab-stack { + /* Both side separators. */ + &::before, + &::after { + content: ""; + position: absolute; + height: var(--uc-tab-separator-height); + inset-block: 0; + margin-block: auto; + border-left: 1px solid transparent; + + } + + /* Fractional scaling adjustments (150%, 175%, etc.) */ + @media (1dppx < resolution < 2dppx) { + &::before, + &::after { + border-left-width: 1.5px !important; + } + } + + /* Left side separators. */ + &::before { + left: 0; + } + + /* Right side separators. */ + &::after { + right: 0; + } +} + +/* Set separator color and add separator for last visible tab. */ +.tabbrowser-tab:not([selected], [multiselected], :hover) { + /* All tabs. */ + & .tab-stack::before, + /* Last visible tab. */ + &:nth-last-child(1 of .tabbrowser-tab:not([hidden])) .tab-stack::after, + /* Last visible pinned tab when overflowed. */ + #tabbrowser-tabs[overflow] &:nth-last-child(1 of .tabbrowser-tab[pinned]:not([hidden])) .tab-stack::after { + border-color: color-mix(in srgb, currentColor 34%, transparent); + } +} + +/* Hide tab separator when previous tab is hovered or selected. + * + * If a tab is selected, then the next tab's left separator should be hidden. + * + * If the next tab is hidden, then find the next visible tab. + */ +.tabbrowser-tab:is([selected], [multiselected], :hover):not([hidden]) { + & + .tabbrowser-tab .tab-stack::before, + & + .tabbrowser-tab[hidden] ~ .tabbrowser-tab:not([hidden]):is([hidden] + *) .tab-stack::before { + border-color: transparent !important; + } +} + +/* Hide the first tab's separator for specific buttons before the tabs. + * + * If in private browsing mode, the Firefox View button is hidden, so the + * separator should also be hidden as long as there are no other buttons before + * it. If the Firefox account button is just before the tabs, then the separator + * should stay hidden. + * + * If the button directly before the tabs is the Firefox account button, the + * separator should be hidden. + * + * If there are no buttons before the tabs, hide the separator. + */ +:root[privatebrowsingmode] #firefox-view-button + #tabbrowser-tabs:not(.toolbarbutton-1:not(#fxa-toolbar-menu-button) + #firefox-view-button + #tabbrowser-tabs), +#fxa-toolbar-menu-button + #tabbrowser-tabs, +#tabbrowser-tabs:first-child { + & .tabbrowser-tab:nth-child(1 of .tabbrowser-tab:not([hidden])) .tab-stack::before { + border-color: transparent !important; + } +} +/* #endregion */ + + +/* + MARK: Tab shadows +*/ +/* #region */ + +/* Tab and toolbar shadows. */ +@media not (-moz-bool-pref: "uc.tweak.rounded-corners") { + /* Edge now removes the shadow when rounded corners are enabled. */ + :root, + :root .tabbrowser-tab { + /* Light mode shadows. */ + --uc-titlebar-shadow: + 0 -1px var(--tabs-navbar-shadow-color, transparent) inset, + 0 -3px 2px -3px rgb(0 0 0 / .2) inset; + --uc-tab-shadow: + 0 0 0 1px var(--lwt-tab-line-color, transparent), + 0 4px 5px rgb(0 0 0 / .21), + 0 0px 2px rgb(0 0 0 / .18); + + & [brighttext], + & [brighttext] .tabbrowser-tab { + /* Dark mode shadows. */ + --uc-titlebar-shadow: + 0 -1px var(--tabs-navbar-shadow-color, transparent) inset, + 0 -3px 2px -3px rgb(0 0 0 / .7) inset; + --uc-tab-shadow: + 0 0 0 1px var(--lwt-tab-line-color, transparent), + 0 5px 7px rgb(0 0 0 / .44), + 0 0px 2px rgb(0 0 0 / .7); + } + } +} + +/* Apply tab shadows. */ +#tabbrowser-tabs .tab-background:is([selected], [multiselected]), +#TabsToolbar #firefox-view-button[open] > .toolbarbutton-icon { + box-shadow: var(--uc-tab-shadow) !important; +} + +/* Apply toolbar shadows. */ +#TabsToolbar { + box-shadow: var(--uc-titlebar-shadow) !important; +} + +/* Prevent interference with context menu arrowscrollbox. */ +#tabbrowser-arrowscrollbox { + --uc-padding-top: 4px; + --uc-margin-top: -4px; + --uc-padding-inline-end: var(--tab-border-radius) +} + +/* Make room for the tab shadows so they aren't clipped at the top. */ +.scrollbox-clip > scrollbox { + padding-top: var(--uc-padding-top, 0) !important; + margin-top: var(--uc-margin-top, 0) !important; + /* Used to fix tab overflow issue with rounded corners. */ + padding-inline-end: var(--uc-padding-inline-end, 0) !important; +} + +/* Add some room horizontally for the tab shadows and rounded corners. */ +#tabbrowser-tabs { + &:not([overflow]) { + margin-inline-start: -8px !important; + margin-inline-end: calc(-1 * var(--tab-border-radius)) !important; + + :where(#tabbrowser-arrowscrollbox .tabbrowser-tab:nth-child(1 of .tabbrowser-tab:not([hidden]))) { + margin-inline-start: 8px !important; + } + } +} + +/* Clip the bottom of the tabs so the shadows don't bleed into other areas. */ +#tabbrowser-tabs[positionpinnedtabs] > #tabbrowser-arrowscrollbox > .tabbrowser-tab[pinned] { + clip-path: inset(-8px -8px 0) !important; +} +/* #endregion */ + + +/* + MARK: Private browsing icon +*/ +/* #region */ + +:root[privatebrowsingmode="temporary"] { + /* Move the other content in the Tabs Toolbar in-front of the indicator. */ + & #TabsToolbar .toolbar-items, + & #TabsToolbar .titlebar-buttonbox-container { + position: relative; + z-index: 1; + } + + /* Hide the post tab spacer as it is not needed. */ + .titlebar-spacer[type="post-tabs"] { + display: none !important; + } +} + +/* String for the custom label. */ +:root, +:root[lang^="en"] { + --uc-string-private: "Private"; +} + +/* Appearance & sizing for the private browsing indicator. */ +#private-browsing-indicator-with-label { + position: relative !important; + isolation: isolate; + font-size: 12px; + + /* Allow space for the gradient to underlay other toolbar items. */ + margin-inline: -16px -16px !important; + padding-inline: 32px 24px !important; + color: var(--button-primary-color, var(--toolbar-bgcolor)) !important; + text-shadow: none !important; + background: var(--uc-gradient); + --uc-bg-color: var(--button-primary-bgcolor, var(--toolbarbutton-icon-fill-attention)); + + /* Primay gradient, fades to transparent on the left. */ + --uc-gradient: linear-gradient(to right, transparent, var(--uc-bg-color) 35%); + + /* Alternate gradient, fades to transparent on both sides. */ + --uc-gradient-alt: linear-gradient(to right, transparent, var(--uc-bg-color) 25%, var(--uc-bg-color) 75%, transparent); + + /* If the titlebar buttons are on the right, then use the alternate gradient + * if the menu bar is not permanently enabled. */ + @media (-moz-platform: windows), + (-moz-gtk-csd-available) and (not (-moz-gtk-csd-reversed-placement)) { + :root[tabsintitlebar] #toolbar-menubar:not([autohide="false"]) ~ #TabsToolbar & { + background: var(--uc-gradient-alt); + } + } + + /* Private browsing icon size. */ + & .private-browsing-indicator-icon { + height: 24px !important; + width: 24px !important; + } + + /* Change "Private Browsing" text to "Private" (English locale only). */ + :root:is([lang^="en"]) & { + /* Hide original label. */ + & > label { + display: none !important; + } + + /* Add custom "Private" label. */ + &::after { + content: var(--uc-string-private); + margin-block: 1px 2px; + margin-inline: 6px 5px; + } + } +} +/* #endregion */ diff --git a/config/firefox/chrome/toolbar/urlbar.css b/config/firefox/chrome/toolbar/urlbar.css new file mode 100644 index 0000000..b035de4 --- /dev/null +++ b/config/firefox/chrome/toolbar/urlbar.css @@ -0,0 +1,262 @@ +/* Edge-Frfox - urlbar.css + * https://github.com/bmFtZQ/edge-frfox */ + +/* + MARK: Variables +*/ +:root { + --urlbar-min-height: 30px !important; + --urlbarView-item-inline-padding: calc(1px + var(--uc-urlbar-inline-padding) + var(--uc-urlbar-icon-inline-padding)) !important; + --urlbar-icon-border-radius: 99px !important; + --urlbar-icon-padding: calc(var(--toolbarbutton-inner-padding) - 2px) !important; + --urlbar-margin-inline: 6px !important; + --identity-box-margin-inline: 6px !important; + --uc-urlbar-icon-inline-padding: var(--uc-toolbarbutton-inner-inline-padding); + --uc-urlbar-inline-padding: 5px; + --uc-urlbar-shadow: 0 0 4px rgb(0 0 0 / .1); + --urlbarView-rich-suggestion-default-icon-size: 32px !important; + + /* urlbar height */ + & #urlbar-container { + --urlbar-container-height: calc(8px + 16px + var(--toolbarbutton-inner-padding) * 2) !important; + } + + & #urlbar { + --urlbar-toolbar-height: calc(8px + 16px + var(--toolbarbutton-inner-padding) * 2) !important; + --urlbar-height: calc(16px + var(--toolbarbutton-inner-padding) * 2) !important; + --urlbar-min-height: calc(16px + var(--toolbarbutton-inner-padding) * 2) !important; + } + + /* Spacing for urlbar suggestion icons. */ + .urlbarView-row { + --urlbarView-icon-margin-start: 0px !important; + --urlbarView-icon-margin-end: calc(var(--uc-urlbar-icon-inline-padding) + var(--identity-box-margin-inline)) !important; + } +} + +/* + MARK: URL bar +*/ +#urlbar-background, +#searchbar { + border-radius: calc(var(--urlbar-icon-border-radius) + 2px) !important; + + /* Shadow for URL bar, only appears in light mode. */ + :root:not([lwtheme]) #nav-bar:not([brighttext]) & { + box-shadow: var(--uc-urlbar-shadow, none); + } + + /* Appearance when the URL bar is expanded. */ + #urlbar[open] & { + border-radius: 8px !important; + border-color: transparent !important; + box-shadow: 0 10px 16px rgb(0 0 0 / 0.18), 0 3px 5px rgb(0 0 0 / 0.33) !important; + outline: 0.5px solid var(--arrowpanel-border-color) !important; + + :root:not([lwtheme]) & { + outline-color: var(--panel-separator-color) !important; + } + } +} + +/* Add padding to sides of URL bar. */ +:is(#urlbar-input-container, .urlbar-input-container), +#searchbar { + padding-inline: var(--uc-urlbar-inline-padding) !important; +} + +/* URL bar suggestions container. */ +.urlbarView { + margin-inline: 0 !important; + width: 100% !important; + border-inline: 0 !important; + padding-block: 0 !important; + + & .urlbarView-body-inner { + width: 100% !important; + margin-inline: 0 !important; + } + + /* Remove padding from top of URL bar results, not needed as URL bar input already has padding. */ + & .urlbarView-results { + padding-block-start: 0 !important; + } +} + +/* URL bar item. */ +.urlbarView-row { + padding-block: 0 !important; + border: none !important; + border-radius: 0 !important; + + & .urlbarView-row-inner { + padding-block: 8px !important; + } + + /* Vertically align search suggestion thumbnail images. */ + &[rich-suggestion] > .urlbarView-row-inner > .urlbarView-favicon { + margin-inline-start: calc(var(--urlbarView-icon-margin-start) + (16px - var(--urlbarView-rich-suggestion-default-icon-size)) / 2) !important; + margin-inline-end: calc(var(--urlbarView-icon-margin-end) + (16px - var(--urlbarView-rich-suggestion-default-icon-size)) / 2) !important; + } +} + +/* Add highlighted marker to the left of selected URL bar items. */ +.urlbarView-row:not([type="tip"], [type="dynamic"])[selected] > .urlbarView-row-inner, +.urlbarView-row-inner[selected] { + box-shadow: 3px 0 var(--uc-urlbarView-accent-color, var(--toolbar-field-focus-border-color)) inset !important; +} + +/* Keep URL bar in place when expanding. */ +#urlbar[breakout][breakout-extend] { + left: 0 !important; + width: 100% !important; +} + +/* Search engine selector */ +.search-one-offs:not([hidden]) { + padding-block: 6px !important; + + & .searchbar-engine-one-off-item { + min-width: 30px !important; + height: 30px !important; + } + + .urlbarView:not([noresults]) > & { + border-color: var(--urlbarView-separator-color) !important; + } + + #urlbar-anon-search-settings { + margin-inline-end: 8px !important; + } +} + +/* Search engine indicator. */ +#urlbar-search-mode-indicator { + :root:not([lwtheme]) & { + background-color: var(--urlbar-box-hover-bgcolor) !important; + } + + & #urlbar-search-mode-indicator-title { + font-size: 0.9em !important; + } +} + +/* Remove border between URL bar input and suggestions. */ +#urlbar[open] > .urlbarView > .urlbarView-body-outer > .urlbarView-body-inner { + border-top: 0 !important; +} + +/* + MARK: URL bar buttons +*/ +.urlbar-page-action, +#urlbar-go-button, +.search-go-button, +#tracking-protection-icon-container, +#identity-icon-box { + padding-inline: var(--uc-urlbar-icon-inline-padding) !important; + width: calc(var(--uc-urlbar-icon-inline-padding) * 2 + 16px) !important; +} + +/* Site information and Permissions buttons. */ +#identity-icon-box, +#identity-permission-box, +.notification-anchor-icon { + padding-inline: var(--uc-urlbar-icon-inline-padding) !important; +} + +/* Zoom level and tab container indicators. */ +#userContext-icons, +#urlbar-zoom-button { + padding-inline: var(--uc-urlbar-icon-inline-padding) !important; + margin-block: 0 !important; + margin-inline: 0 !important; +} + +/* Move tracking protection button. */ +#tracking-protection-icon-container, +#page-action-buttons { + order: 2 !important; +} + +/* Hide tracking protection button when not hovering over URL bar. */ +#urlbar-container:not(:hover) #tracking-protection-icon-container:not([open]) { + visibility: collapse !important; +} + +/* Focus border for URL bar. */ +#urlbar[focused="true"]:not([suppress-focus-border]) > #urlbar-background, +#searchbar:focus-within { + outline-offset: calc(var(--focus-outline-width) * -1 + 1px) !important; +} + +/* Pin icon for URL bar suggested sites. */ +.urlbarView-row[pinned] > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-type-icon { + fill: var(--toolbar-field-color) !important; +} + +#urlbar-input::placeholder, +.searchbar-textbox::placeholder { + opacity: 0.6 !important; +} + +/* Make the lock icon brighter in dark mode. */ +#nav-bar[brighttext] #identity-box:not([pageproxystate="invalid"]) #identity-icon { + fill-opacity: calc(var(--urlbar-icon-fill-opacity) * 1.8) !important; +} + +/* Make the URL bar label opaque in light mode, matching the icons. */ +#nav-bar:not([brighttext]) #identity-box #identity-icon-label { + opacity: var(--urlbar-icon-fill-opacity) !important; +} + +/* + MARK: URL bar label +*/ + +/* Label on the left of the URL bar, shown when viewing Firefox or extension pages. */ +#identity-box[pageproxystate="valid"]:is(.notSecureText, .chromeUI, .extensionPage) > .identity-box-button { + position: relative; + width: unset !important; + + /* Spacing between the icon and label. */ + & #identity-icon-label { + padding-inline-start: 8px !important; + } + + /* Separator to the right of the label. */ + &::after { + content: ""; + position: absolute; + height: 16px; + border-right: 1px solid currentColor; + right: 0; + inset-block: 0; + margin-block: auto; + opacity: 0; + } + + /* Fractional scaling adjustments (150%, 175%, etc.) */ + @media (1dppx < resolution < 2dppx) { + &::after { + border-right-width: 1.5px !important; + } + } + + /* Remove background from urlbar box. */ + &:not(:hover, [open]) { + background-color: transparent !important; + + /* Separator opacity */ + &::after { + opacity: 0.375; + } + } + + /* Fade transition for separator. */ + @media not (prefers-reduced-motion) { + &::after { + transition: opacity 0.2s ease; + } + } +} diff --git a/config/firefox/chrome/tweaks/hide-tabs-bar.css b/config/firefox/chrome/tweaks/hide-tabs-bar.css new file mode 100644 index 0000000..070bf67 --- /dev/null +++ b/config/firefox/chrome/tweaks/hide-tabs-bar.css @@ -0,0 +1,252 @@ +/* Edge-Frfox - tweaks/hide-tabs-bar.css + * https://github.com/bmFtZQ/edge-frfox */ + +/* + MARK: Hide tabs toolbar +*/ +@media (-moz-bool-pref: "uc.tweak.hide-tabs-bar"), +(-moz-bool-pref: "uc.tweak.hide-tabs-bar.no-window-controls") { + /* Only hide the tabs toolbar if one of the following sidebar extensions is + * active: Sidebery, Tree Style Tab, or Tab Center Reborn. */ + :root:not([customizing]):has(#sidebar-box[sidebarcommand="_3c078156-979c-498b-8990-85f7987dd929_-sidebar-action"]:not([hidden])), + :root:not([customizing]):has(#sidebar-box[sidebarcommand="treestyletab_piro_sakura_ne_jp-sidebar-action"]:not([hidden])), + :root:not([customizing]):has(#sidebar-box[sidebarcommand="tabcenter-reborn_ariasuni-sidebar-action"]:not([hidden])) { + /* Height of navbar, used for determining height and position of window controls */ + --uc-navbar-height: 38px; + /* Drag space next to the window controls, allows you to move the window more easily */ + --uc-titlebar-drag-space: 40px; + + /* Hide the tabs */ + #TabsToolbar { + visibility: collapse !important; + } + + /* Fix issue with missing window controls. */ + &[tabsintitlebar] #titlebar { + will-change: auto !important; + } + + /* Add some padding to the top of the navbar */ + &[tabsintitlebar] #nav-bar { + padding-top: var(--uc-tab-top-margin, 0) !important; + } + + /* Set background colour of the menu bar to maintain consistency with the navbar */ + @media not (-moz-bool-pref: "uc.tweak.floating-tabs") { + #toolbar-menubar { + background-color: var(--toolbar-bgcolor) !important; + color: var(--toolbar-color) !important; + } + } + + /* Make sure window controls are removed in full screen mode. */ + &[inDOMFullscreen] #TabsToolbar .titlebar-buttonbox, + &[inFullscreen] #navigator-toolbox[style*="margin-top"] #TabsToolbar .titlebar-buttonbox { + visibility: collapse !important; + } + + /* Disable the replacement window controls if tweak is enabled. */ + @media not (-moz-bool-pref: "uc.tweak.hide-tabs-bar.no-window-controls") { + /* + MARK: macOS styles + */ + @media (-moz-platform: macos) { + /* Offset navbar contents to make space for the window controls */ + &[tabsintitlebar]:not([inFullscreen]) #nav-bar { + padding-left: calc(70px + var(--uc-titlebar-drag-space)) !important; + + /* Remove the padding from the side of the navbar */ + #nav-bar-customization-target > :is(toolbarbutton, toolbaritem):first-child { + padding-inline-start: 0 !important; + } + } + + /* Positioning of the window controls */ + #TabsToolbar .titlebar-buttonbox-container { + visibility: visible !important; + position: fixed !important; + height: calc(var(--uc-navbar-height) + var(--uc-tab-top-margin, 0px)); + margin: 0 !important; + top: 0; + left: 0; + + .titlebar-buttonbox { + margin-inline: calc((var(--uc-navbar-height) + var(--uc-tab-top-margin, 0px) - 14px) / 2) !important; + } + } + } + + /* + MARK: Windows styles + */ + @media (-moz-platform: windows) { + /* Offset navbar contents to make space for the window controls */ + &:where([inFullscreen], [tabsintitlebar]) #nav-bar { + padding-inline-end: calc(140px + var(--uc-titlebar-drag-space)) !important; + + /* Remove the padding from the side of the navbar */ + #PanelUI-menu-button { + padding-inline-end: 0 !important; + } + } + + /* Positioning of the window controls */ + :where(#toolbar-menubar[inactive]) + #TabsToolbar .titlebar-buttonbox { + visibility: visible !important; + position: fixed !important; + top: 0; + inset-inline-end: 0; + height: calc(var(--uc-navbar-height) + var(--uc-tab-top-margin, 0)) !important; + z-index: 100 !important; + color: var(--toolbar-color) !important; + } + } + + /* + MARK: Linux/GTK styles + */ + @media (-moz-gtk-csd-minimize-button), + (-moz-gtk-csd-maximize-button), + (-moz-gtk-csd-close-button) { + /* Width of single window control button. */ + --uc-window-control-btn: 34px; + + /* Navbar space reserved for one button. */ + --uc-window-controls-width: var(--uc-window-control-btn); + + /* Navbar space reserved for two buttons. */ + @media (-moz-gtk-csd-minimize-button) and (-moz-gtk-csd-maximize-button), + (-moz-gtk-csd-minimize-button) and (-moz-gtk-csd-close-button), + (-moz-gtk-csd-maximize-button) and (-moz-gtk-csd-close-button) { + --uc-window-controls-width: calc(var(--uc-window-control-btn) * 2); + } + + /* Navbar space reserved for three buttons. */ + @media (-moz-gtk-csd-minimize-button) and (-moz-gtk-csd-maximize-button) and (-moz-gtk-csd-close-button) { + --uc-window-controls-width: calc(var(--uc-window-control-btn) * 3); + } + + /* Offset navbar contents to make space for the window controls */ + &:where([inFullscreen], [tabsintitlebar]) #nav-bar { + /* Window controls on the right. */ + @media not (-moz-gtk-csd-reversed-placement) { + padding-inline-end: calc(var(--uc-window-controls-width, 0px) + var(--uc-titlebar-drag-space)) !important; + + /* Remove the padding from the side of the navbar */ + #PanelUI-menu-button { + padding-inline-end: 0 !important; + } + } + + /* Window controls on the left. */ + @media (-moz-gtk-csd-reversed-placement) { + padding-inline-start: calc(var(--uc-window-controls-width, 0px) + var(--uc-titlebar-drag-space)) !important; + + /* Remove the padding from the side of the navbar */ + #nav-bar-customization-target > :is(toolbarbutton, toolbaritem):first-child { + padding-inline-start: 0 !important; + } + } + } + + /* Positioning of the window controls */ + :where(#toolbar-menubar[inactive]) + #TabsToolbar .titlebar-buttonbox { + visibility: visible !important; + position: fixed !important; + top: 0; + height: calc(var(--uc-navbar-height) + var(--uc-tab-top-margin, 0)) !important; + z-index: 100 !important; + inset-inline: auto 0; + + @media (-moz-gtk-csd-reversed-placement) { + inset-inline: 0 auto !important; + } + } + } + } + } +} + +/* + MARK: Sidebar styles +*/ +#sidebar-box:where([sidebarcommand="_3c078156-979c-498b-8990-85f7987dd929_-sidebar-action"]:not([hidden])), +#sidebar-box:where([sidebarcommand="treestyletab_piro_sakura_ne_jp-sidebar-action"]:not([hidden])), +#sidebar-box:where([sidebarcommand="tabcenter-reborn_ariasuni-sidebar-action"]:not([hidden])) { + --sidebar-background-color: var(--toolbar-bgcolor) !important; + --sidebar-text-color: var(--toolbar-color) !important; + --sidebar-border-color: var(--chrome-content-separator-color) !important; + position: relative !important; + + /* Floating tabs tweak uses the tab toolbar background instead. */ + @media (-moz-bool-pref: "uc.tweak.floating-tabs") { + --sidebar-background-color: var(--lwt-accent-color) !important; + --sidebar-text-color: var(--lwt-text-color) !important; + + &:-moz-window-inactive { + --sidebar-background-color: var(--lwt-accent-color-inactive) !important; + --sidebar-text-color: var(--lwt-text-color-inactive) !important; + } + } + + #sidebar-header { + border-bottom: 0 !important; + padding: 10px 4px 0 !important; + overflow: hidden; + position: relative; + + #sidebar-switcher-target, + #sidebar-close { + width: auto !important; + height: 28px !important; + padding: 0 8px !important; + border: none !important; + margin-inline: 0 !important; + } + + #sidebar-spacer { + min-width: 8px !important; + } + } + + /* Sidebar positioned on the left. */ + &:not([positionend]) { + border-inline-end: 1px solid var(--sidebar-border-color); + /* Use less padding on the side with the border. */ + padding-inline: 4px 3px; + } + + /* Sidebar positioned on the right. */ + &[positionend] { + border-inline-start: 1px solid var(--sidebar-border-color); + /* Use less padding on the side with the border. */ + padding-inline: 3px 4px; + } + + /* Rounded corners tweak optimisations. */ + @media (-moz-bool-pref: "uc.tweak.rounded-corners") { + /* Remove padding and border from sidebar. */ + &:not([positionend]), + &[positionend] { + border-inline: none; + padding-inline: 0; + } + + @media (-moz-bool-pref: "uc.tweak.theme.sidebery") { + border-radius: 0 !important; + box-shadow: none !important; + + &:not([positionend]) { + padding-inline-end: 3px; + } + + &[positionend] { + padding-inline-start: 3px; + } + } + + #sidebar-header { + padding-top: 4px !important; + } + } +} diff --git a/config/firefox/chrome/tweaks/shrink-sideberry.css b/config/firefox/chrome/tweaks/shrink-sideberry.css new file mode 100644 index 0000000..77db384 --- /dev/null +++ b/config/firefox/chrome/tweaks/shrink-sideberry.css @@ -0,0 +1,19 @@ +/* Make Sidebery look good */ +#sidebar{ + --uc-sidebar-width: 120px; + min-width: var(--uc-sidebar-width); + width: var(--uc-sidebar-width); + max-width: var(--uc-sidebar-width); +} +#sidebar-header{ + display: none; + min-width: var(--uc-sidebar-width) !important; + width: var(--uc-sidebar-width) !important; + max-width: var(--uc-sidebar-width) !important; +} +#sidebar-box{ + min-width: var(--uc-sidebar-width) !important; + width: var(--uc-sidebar-width) !important; + max-width: var(--uc-sidebar-width) !important; +} +#sidebar-splitter{ display: none } diff --git a/config/firefox/chrome/tweaks/sidebery.css b/config/firefox/chrome/tweaks/sidebery.css new file mode 100644 index 0000000..4e45d01 --- /dev/null +++ b/config/firefox/chrome/tweaks/sidebery.css @@ -0,0 +1,334 @@ +/* Edge-Frfox - sidebery.css + * https://github.com/bmFtZQ/edge-frfox + */ + +/* This file needs to loaded into userContent.css so the @media rules can be + * used for automatic tweaks configuration. */ + +/* Since the UUIDs are randomly generated, only a generic path can be specified, + * this can cause conflicts with other extensions that use the same file + * structure, but is unlikely to cause any major issues. */ +@-moz-document regexp("^moz-extension://.*?/sidebar/sidebar.html") { + /* Fix issues with rounded corners rendering. */ + :root { + color-scheme: light dark !important; + background: light-dark(#aaa, #222) !important; + } + + /* On macOS, ensure that text is rendered correctly. */ + body { + -moz-osx-font-smoothing: auto !important; + } + + /* + MARK: Default theme colours + */ + + /* macOS light mode. */ + body[style*="--s-frame-fg: rgba(0, 0, 0, 0.847)"], + /* macOS dark mode. */ + body[style*="--s-frame-fg: rgba(255, 255, 255, 0.847)"], + /* Windows light mode. */ + body[style*="--s-frame-bg: rgb(240, 240, 240)"], + /* Windows dark mode. */ + body[style*="--s-frame-bg: rgb(35, 34, 43)"], + /* No theme enabled. */ + body:not([style*="--s-frame-bg"]) { + --s-frame-bg: light-dark(#cecece, #1C1C1C) !important; + --s-frame-fg: light-dark(#000, #FFF) !important; + --s-toolbar-bg: light-dark(#f7f7f7, #3B3B3B) !important; + --s-toolbar-fg: light-dark(#252525, #fff) !important; + --s-act-el-bg: light-dark(#fff, #4D4D4D) !important; + --s-act-el-fg: light-dark(#000, #fff) !important; + --s-act-el-border: transparent !important; + --s-popup-bg: light-dark(#fff, #4A4A4A) !important; + --s-popup-fg: light-dark(#1c1c1c, #fff) !important; + --s-popup-border: light-dark(#dadada, #636363) !important; + --s-accent: light-dark(#0078D4, #63ADE5) !important; + } + + /* Linux/GTK support, side effect: Firefox themes do not work. */ + @media (-moz-gtk-csd-available) { + body:not([style*="--s-frame-bg"]) { + --s-frame-bg: light-dark(color-mix(in srgb, ActiveCaption 90%, black), ActiveCaption) !important; + --s-frame-fg: CaptionText !important; + --s-toolbar-bg: light-dark(-moz-dialog, color-mix(in srgb, -moz-dialog 92%, white)) !important; + --s-toolbar-fg: -moz-dialogtext !important; + --s-act-el-bg: light-dark(-moz-dialog, color-mix(in srgb, -moz-dialog 80%, white)) !important; + --s-act-el-fg: -moz-dialogtext !important; + --s-act-el-border: transparent !important; + --s-popup-bg: Field !important; + --s-popup-fg: FieldText !important; + --s-popup-border: light-dark(transparent, color-mix(in srgb, currentColor 17%, Field)) !important; + --s-accent: AccentColor !important; + } + } + + /* + MARK: Variables + */ + #root.root { + --frame-bg: var(--s-toolbar-bg) !important; + --frame-fg: var(--s-toolbar-fg) !important; + --general-margin: 4px !important; + --tabs-font: 12px system-ui !important; + --tabs-height: 32px !important; + --tabs-pinned-width: 32px !important; + --tabs-pinned-height: 32px !important; + --tabs-close-btn-margin: 8px !important; + --ntb-btn-height: 32px !important; + --tabs-inner-gap: 8px !important; + --tabs-border-radius: 4px !important; + --general-border-radius: 4px !important; + --tabs-activated-shadow: 0 4px 4px rgb(0 0 0 / .18), 0 0px 2px rgb(0 0 0 / .19) !important; + --tabs-normal-fg: color-mix(in srgb, var(--frame-fg) 87%, transparent) !important; + --nav-btn-height: 32px !important; + --nav-btn-width: 32px !important; + --separator-color: color-mix(in srgb, var(--frame-fg) 20%, transparent) !important; + --nav-btn-active-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.086), inset 0 1px 3px 0 rgb(0 0 0 / 0.086) !important; + + /* Light mode adjustments. */ + &[data-frame-color-scheme="light"] { + color-scheme: light !important; + --tabs-normal-fg: color-mix(in srgb, var(--frame-fg) 82%, transparent) !important; + } + + /* Dark mode adjustments. */ + &[data-frame-color-scheme="dark"] { + color-scheme: dark !important; + --tabs-activated-shadow: 0 4px 4px rgb(0 0 0 / .44), 0 0px 2px rgb(0 0 0 / .47) !important; + --nav-btn-active-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.071), 0 1px 3px 0 rgb(0 0 0 / 0.212) !important; + } + + @media (-moz-bool-pref: "uc.tweak.rounded-corners") { + --tabs-border-radius: 8px !important; + } + } + + /* + MARK: Floating tabs vars + */ + @media (-moz-bool-pref: "uc.tweak.floating-tabs") { + body[style*="--s-frame-fg: rgba(0, 0, 0, 0.847)"], + body[style*="--s-frame-fg: rgba(255, 255, 255, 0.847)"], + body[style*="--s-frame-bg: rgb(240, 240, 240)"], + body[style*="--s-frame-bg: rgb(35, 34, 43)"], + body:not([style*="--s-frame-bg"]) { + --s-frame-bg: light-dark(#f3f3f3, #202020) !important; + --s-act-el-bg: light-dark(#fff, #3F3F3F) !important; + --s-act-el-border: light-dark(transparent, rgb(255 255 255 / 0.06)) !important; + } + + #root.root { + --frame-bg: var(--s-frame-bg) !important; + --frame-fg: var(--s-frame-fg) !important; + + --toolbar-bg: var(--s-frame-bg) !important; + --toolbar-fg: var(--s-frame-fg) !important; + --s-toolbar-bg: light-dark(#f3f3f3, #202020) !important; + --tabs-activated-shadow: 0 2.5px 3px 1px rgb(0 0 0 / .08), 0 0 0 1px rgb(0 0 0 / .11) !important; + --tabs-border-radius: 8px !important; + + &[data-frame-color-scheme="dark"] { + --tabs-activated-shadow: 0 2px 3px rgb(0 0 0 / .12) !important; + } + } + } + + /* + MARK: Tabs appearance + */ + .Tab { + /* Active tab border. */ + &[data-active="true"] .body { + outline: 1px solid var(--s-act-el-border, transparent) !important; + outline-offset: -1px !important; + } + + /* Close button border radius. */ + & .close { + border-radius: 4px !important; + } + + /* Make sure that tab icons use full opacity. */ + & .fav svg { + opacity: 1 !important; + } + + /* Adjust spacing between tab icons and labels. */ + & .title { + padding-inline: 0 !important; + } + + /* Colourised tab shadow and outline. */ + &[data-colorized="true"] { + --tabs-activated-shadow: unset !important; + --s-act-el-border: light-dark(rgb(0 0 0 / 0.35), rgb(255 255 255 / 0.25)) !important; + } + + & .ctx { + box-shadow: none !important; + border-radius: 2px !important; + --uc-margin: 8px !important; + --uc-width: 2px !important; + --uc-offset: 1px !important; + } + + &[data-active="true"] .ctx { + --uc-margin: 6px !important; + } + + &[data-pin="false"] { + /* Inner spacing for tabs. */ + & .fav { + margin: 0 calc(var(--tabs-inner-gap) + 2px) 0 var(--tabs-inner-gap) !important; + } + + /* Tab container indicator. */ + & .ctx { + inset-block: 0 !important; + margin-block: auto !important; + left: var(--uc-offset) !important; + width: var(--uc-width) !important; + height: calc(100% - var(--uc-margin) * 2) !important; + } + } + + #root[data-pinned-tabs-position="panel"] &[data-pin="true"] { + /* Tab container indicator. */ + & .ctx { + inset-inline: 0 !important; + margin-inline: auto !important; + bottom: var(--uc-offset) !important; + height: var(--uc-width) !important; + width: calc(100% - var(--uc-margin) * 2) !important; + } + } + } + + .Notifications + .main-box .central-box { + height: 100% !important; + margin-top: 0 !important; + } + + /* Add space to the top of the tabs to allow shadows to be visible. */ + .AnimatedTabList, + .PinnedTabsBar { + padding-top: var(--tabs-margin) !important; + } + + /* Remove space between the tabs and horizontal navigation bar, as tabs have + * their own space applied for the shadows. */ + .top-horizontal-box { + margin-bottom: 0 !important; + + & .NavigationBar.-top { + padding-block-end: 0 !important; + } + } + + /* Pinned tabs separator. */ + .PinnedTabsBar { + /* Pinned tab grid. */ + #root[data-pinned-tabs-position="panel"] & { + padding-bottom: calc(var(--tabs-margin) + 1px) !important; + } + + /* Pinned tab list. */ + #root[data-pinned-tabs-position="panel"][data-pinned-tabs-list="true"] & { + padding-bottom: 1px !important; + } + + /* Separator element. */ + &::after { + display: unset !important; + bottom: 0 !important; + height: auto !important; + border-bottom: 1px solid var(--separator-color) !important; + background: transparent !important; + opacity: 1 !important; + } + } + + /* + MARK: New tab button + */ + .TabsPanel .new-tab-btns { + /* Add space for the separator. */ + padding-top: calc(var(--tabs-margin) + 1px) !important; + + /* Add separator before new tab button. */ + &::before { + width: calc(100% - var(--tabs-margin)*2) !important; + inset-inline: auto !important; + top: 0 !important; + border-top: 1px solid var(--separator-color) !important; + box-shadow: none !important; + } + + /* Make sure the separator is hidden when there are only pinned tabs. */ + &[data-new-tab-bar-position="after_tabs"]:first-child { + padding-top: 0 !important; + + &::before { + display: none !important; + } + } + + /* Hide unnecessary pseudo element. */ + &::after { + content: initial !important; + } + + /* New tab button. */ + & .new-tab-btn { + justify-content: start !important; + white-space: nowrap !important; + overflow: hidden !important; + border-radius: var(--tabs-border-radius) !important; + + /* Make sure images do not shrink when collapsed. */ + & > svg, + & > img { + position: static !important; + margin: 0 calc(var(--tabs-inner-gap) + 2px) 0 var(--tabs-inner-gap) !important; + flex-shrink: 0 !important; + } + + /* Fix new tab icon when badge is placed above it (open in container). */ + & > .-badge { + position: static !important; + margin-top: 10px !important; + margin-inline-start: calc(-1 * (14px + var(--tabs-inner-gap) / 2)) !important; + margin-inline-end: calc(var(--tabs-inner-gap) - 1px) !important; + } + + /* Add new tab label. */ + &::after { + content: "New Tab" !important; + font: var(--tabs-font) !important; + color: var(--frame-fg) !important; + } + } + } + + /* Hide shadows at the top and bottom when scrolling. */ + .ScrollBox > .top-shadow[data-show="true"], + .ScrollBox > .bottom-shadow[data-show="true"] { + display: none !important; + } + + /* + MARK: Icons + */ + + /* New tab page icon. */ + #icon_ff path { + d: path("M3 1h10a2 2 0 01 2 2v10a2 2 0 01-2 2H3a2 2 0 01-2-2V3a2 2 0 01 2-2zm3 1H3a1 1 0 00-1 1v10a1 1 0 00 1 1h10a1 1 0 00 1-1V5H7.5A1.5 1.5 0 01 6 3.5zm1 0v1.5a.5.5 0 00 .5.5H14V3a1 1 0 00-1-1zM5 8a1 1 0 01 0 2 1 1 0 01 0-2zm3 0a1 1 0 01 0 2 1 1 0 01 0-2zm3 0a1 1 0 01 0 2 1 1 0 01 0-2z") !important; + } + + /* Plus icon. */ + #icon_plus path { + d: path("M7 1a.5.5 0 01 1 0v6h6a.5.5 0 01 0 1H8v6a.5.5 0 01-1 0V8H1a.5.5 0 01 0-1h6z") !important; + } +} diff --git a/config/firefox/chrome/userChrome.css b/config/firefox/chrome/userChrome.css new file mode 100644 index 0000000..dfc5924 --- /dev/null +++ b/config/firefox/chrome/userChrome.css @@ -0,0 +1,21 @@ +/* Edge-Frfox main files */ +@import url("icons/icons.css"); +@import url("toolbar/tabbar.css"); +@import url("toolbar/navbar.css"); +@import url("toolbar/personalbar.css"); +@import url("toolbar/findbar.css"); +@import url("toolbar/urlbar.css"); +@import url("global/colors.css"); +@import url("global/popup.css"); +@import url("global/browser.css"); +@import url("global/tree.css"); + +/* Edge-Frfox tweaks */ +@import url("global/tweaks.css"); +@import url("tweaks/hide-tabs-bar.css"); + +/* Personal tweaks */ +@import url("tweaks/shrink-sideberry.css"); + +/* Import custom stylesheet instead of modifying Edge-Frfox theme files. */ +@import url("custom.css"); diff --git a/config/firefox/chrome/userContent.css b/config/firefox/chrome/userContent.css new file mode 100644 index 0000000..6aeb15e --- /dev/null +++ b/config/firefox/chrome/userContent.css @@ -0,0 +1,5 @@ +/* Edge-Frfox */ +@import url("content/common.css"); +@import url("content/newtab.css"); +@import url("tweaks/sidebery.css") (-moz-bool-pref: "uc.tweak.theme.sidebery"); +@import url("tweaks/shrink-sideberry.css") diff --git a/config/firefox/user.js b/config/firefox/user.js new file mode 100644 index 0000000..5755a39 --- /dev/null +++ b/config/firefox/user.js @@ -0,0 +1,14 @@ +// Edge-Frfox - user.js +// https://github.com/bmFtZQ/edge-frfox +// This file contains the settings required for the theme to function correctly. + +// Enables the userChrome.css and userContent.css files. +user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true); +// Allows the theme's SVG icons to be coloured properly. +user_pref("svg.context-properties.content.enabled", true); +// Allows colours used in the theme to be mixed with others. +user_pref("layout.css.color-mix.enabled", true); +// Allows theme to use different colours for light/dark mode. +user_pref("layout.css.light-dark.enabled", true); +// Enables the CSS :has() selector, required for hide tabs toolbar tweak. +user_pref("layout.css.has-selector.enabled", true); diff --git a/docs/superpowers/specs/2026-08-20-panama-fresh-install-design.md b/docs/superpowers/specs/2026-08-20-panama-fresh-install-design.md index 550de76..fa88440 100644 --- a/docs/superpowers/specs/2026-08-20-panama-fresh-install-design.md +++ b/docs/superpowers/specs/2026-08-20-panama-fresh-install-design.md @@ -83,6 +83,15 @@ interview, so a work laptop does not acquire emulators and a desktop does not sk Steam. But the menu starts nearly empty and grows by explicit decision, one application per decision — it is not seeded by porting sunhat's list. +The categories shipped are `gaming`, `creative`, `communication` and +`virtualization`, one file each under `setup/packages/extras/`. A category mixes +both package managers because the applications do — Steam is in RPM Fusion, Slack +publishes only a flatpak — so a bare line is a dnf package and a `flatpak:` line +is a Flathub ID, and one file holds the whole answer for a category rather than +splitting it across two. The interview reads the menu from the directory, so +adding a category is adding a file, and nothing is preselected: a default here +would install applications nobody chose. + The rule is that every application Panama installs must come from dnf or from Flathub, with flatpak preferred where both exist. Anything requiring a pinned RPM URL, a `curl | bash`, or a source build is admitted only case by case, with a stated @@ -173,7 +182,7 @@ for icons and Vicinae themes, so it needs no stage of its own — and because was invented to satisfy holds anyway. `install-hardware` runs *last*, not fourth. The constraint was always "late", and -fourth of eight is not late: MOK enrolment arms a prompt consumed at the next +fourth of eight is not late: MOK enrollment arms a prompt consumed at the next boot and a firmware update may ask for a reboot, so a machine that reboots out of this stage should already be completely configured — dotfiles linked, settings applied, identity set. Placing it after `setup-identity` costs nothing, since @@ -187,8 +196,8 @@ Ordering constraints that are not obvious and must not be broken: installed by `install-packages`, which already runs first. - `setup-identity` follows `install-packages`, because `gh` is installed there. - `install-hardware` is last, for the reason above. It also has to follow its own - driver install: akmods generates the certificate that MOK enrolment enrols, so - there is nothing to enrol until `akmod-nvidia` is on the machine. + driver install: akmods generates the certificate that MOK enrollment enrolls, so + there is nothing to enroll until `akmod-nvidia` is on the machine. Every stage stays independently re-runnable and independently failable, which is the existing contract and the reason Panama exists. @@ -313,14 +322,14 @@ hostname and it was one of the things that made sunhat unmaintainable. Everything below blocks sunhat's deletion. - **NVIDIA and secure boot** — `akmod-nvidia`, `xorg-x11-drv-nvidia-cuda` and MOK - enrolment via `mokutil --import`. sunhat's version opened an editor to hand-edit + enrollment via `mokutil --import`. sunhat's version opened an editor to hand-edit grub; the replacement does not, because a step that requires a human mid-run is the failure this repository exists to avoid. It turned out not to need one: sunhat's editor step existed to delete duplicated kernel arguments, and `grubby --update-kernel=ALL --args=` replaces an argument that already exists rather than appending a second copy, so the duplicates cannot accumulate. - Enrolment is likewise non-interactive, and did not need a compromise either. + Enrollment is likewise non-interactive, and did not need a compromise either. `mokutil --generate-hash` and `--hash-file` are exactly the pair for this: the interview asks for the password, hashes it immediately, and records only the hash — so the plaintext never reaches the answers file, the environment, or a @@ -344,11 +353,27 @@ Everything below blocks sunhat's deletion. to port; most of them install by methods that no longer work. Reviewing them is its own task, done one application at a time against the dnf/flatpak rule above, and it does not block anything else in this spec. -- **Firefox** — the package itself, which Panama does not currently install, plus +- **Firefox** — the package itself, which Panama did not previously install, plus sunhat's `themes/firefox` userChrome. Helium is the daily driver; Firefox stays because web development means checking a second engine. If Helium supports userChrome, it gets the equivalent treatment. + The theme is [Edge-Frfox](https://github.com/bmFtZQ/edge-frfox), MIT, vendored + into `config/firefox` with its provenance recorded — sunhat carried it with + neither. It is the only piece of Panama's configuration that does not go to a + path this repository chooses: Firefox owns the profile directory, names it with + a random salt, and does not create one until the browser has been run. So + `link-dotfiles` finds or creates a profile and links both halves into it — + `chrome/` for the CSS and `user.js` for the preference that makes Firefox read + `chrome/` at all, which without the other is a directory of dead files. + + Two things here were assumptions that turned out wrong, and the contract exists + for both. Firefox has moved to the XDG directories, so the profile root is + `~/.config/mozilla/firefox` on a current build and `~/.mozilla/firefox` on an + older one; writing to the wrong one themes nothing and says nothing. And + `-CreateProfile` turns out to be non-interactive, so a fresh machine gets the + theme on the first install rather than the second. + Deliberately not ported: sunhat's `configs/docker/compose_files`. Those are server workloads — caddy, gitea, homeassistant, nextcloud_aio, pihole, vaultwarden, wireguard, searxng — and belong to whatever runs them, not to a workstation @@ -405,7 +430,7 @@ three places instead: the broken tree. - **The hardware contract**, for the one stage that cannot be verified by running it. `install-hardware` installs a proprietary driver and queues a Secure Boot - enrolment, and the machine Panama is developed on is an AMD desktop; so every + enrollment, and the machine Panama is developed on is an AMD desktop; so every privileged command is stood in on `PATH` and the contract asserts which answer led to which call. That covers the decisions, which is the part that can be wrong. It does not cover whether `akmod-nvidia` builds, and does not claim to — @@ -415,6 +440,17 @@ three places instead: - **`panama test`**, which makes the existing 119 contracts runnable in one command for the first time. +One gap this list did not cover was found while doing phase 4 and is worth +recording, because it is the exact failure mode the spec opens with. Every list +in `setup/packages/` is annotated, and `install-packages` passed the whole file +to dnf, comments included; dnf does not ignore an argument it cannot match, so +`set -e` ended the stage on the first annotated list. It could not be seen from +here — on a machine that already has everything, only the comments fail — and +every contract that reads those lists strips comments before comparing, so the +tests were reading a file the installer was not. A checker with a blind spot is +worse than none, and this one had the same blind spot the dependency contract's +own header warns about. + The open risk this leaves is anything that breaks only on a genuinely clean system and that none of the three notices — a repository that fails to enable, a package renamed between Fedora releases. That risk is accepted; a VM run can settle it later diff --git a/install b/install index dc01075..3c108ea 100755 --- a/install +++ b/install @@ -54,7 +54,7 @@ gsettings set org.gnome.desktop.session idle-delay 0 2>/dev/null || true # which needs both vicinae itself (installed by install-packages) and the # theme files it selects among (symlinked into place by link-dotfiles); # setup-identity needs the gh and git-all that install-packages provides; and -# install-hardware is last because MOK enrolment arms a prompt consumed at the +# install-hardware is last because MOK enrollment arms a prompt consumed at the # next boot and a firmware update may ask for a reboot -- a machine that reboots # out of the final stage has already been completely configured. New scripts # must be added here explicitly, or they will not run at all. @@ -77,7 +77,7 @@ fi source "$PANAMA_ANSWERS" export PANAMA_HOSTNAME PANAMA_GIT_NAME PANAMA_GIT_EMAIL PANAMA_GIT_EDITOR \ PANAMA_GH_LOGIN PANAMA_SSH_KEY PANAMA_NVIDIA PANAMA_MOK_HASH \ - PANAMA_DEBLOAT PANAMA_FIRMWARE + PANAMA_DEBLOAT PANAMA_FIRMWARE PANAMA_EXTRAS # Applied here rather than in a stage, and applied early: it needs sudo, and # sudo is warm right now. At the end of a long unattended run the timestamp has diff --git a/setup/packages/desktop-packages b/setup/packages/desktop-packages index ce9fd86..ea6702b 100644 --- a/setup/packages/desktop-packages +++ b/setup/packages/desktop-packages @@ -10,6 +10,10 @@ desktop-file-utils dnf-plugins-core ffmpeg firamono-nerd-fonts +# A second engine to check pages against; Helium is the daily driver. Its +# chrome is themed from config/firefox, which link-dotfiles places into the +# profile. +firefox fuse-libs # Ghostty and its config in config/dot/ghostty are linked by link-dotfiles. ghostty diff --git a/setup/packages/extras/communication b/setup/packages/extras/communication new file mode 100644 index 0000000..bc67aa9 --- /dev/null +++ b/setup/packages/extras/communication @@ -0,0 +1,8 @@ +# Chat and messaging. Every one of these is Flathub only -- none is packaged +# for Fedora, and each publishes its own flatpak. +# +# Thunderbird is deliberately absent: it is already in flatpak-packages as +# org.mozilla.thunderbird_esr, which every machine gets. +flatpak:com.discordapp.Discord +flatpak:com.slack.Slack +flatpak:org.signal.Signal diff --git a/setup/packages/extras/creative b/setup/packages/extras/creative new file mode 100644 index 0000000..6f13b49 --- /dev/null +++ b/setup/packages/extras/creative @@ -0,0 +1,7 @@ +# Images, video and audio. All from dnf or RPM Fusion. +gimp + +# Video editing, screen capture, and transcoding what comes out of them. +kdenlive +obs-studio +HandBrake diff --git a/setup/packages/extras/gaming b/setup/packages/extras/gaming new file mode 100644 index 0000000..f97fbcd --- /dev/null +++ b/setup/packages/extras/gaming @@ -0,0 +1,14 @@ +# Games and the things that run them. A work laptop declines this whole +# category; a desktop wants all of it. +# +# steam is in RPM Fusion nonfree, which install-packages enables before it +# reads this file. +steam +lutris + +# Frame timings on an overlay, and the compositor Steam's own session uses. +mangohud +gamescope + +# Proton and Wine build management for Steam. Flathub only -- there is no RPM. +flatpak:com.vysp3r.ProtonPlus diff --git a/setup/packages/extras/virtualization b/setup/packages/extras/virtualization new file mode 100644 index 0000000..639d9ac --- /dev/null +++ b/setup/packages/extras/virtualization @@ -0,0 +1,6 @@ +# Other machines, and other distributions, from this one. +# +# podman is not here: the Containers settings page depends on it, so it is a +# declared dependency in development-packages rather than an optional extra. +virt-manager +distrobox diff --git a/setup/scripts/install-hardware b/setup/scripts/install-hardware index b713511..408cd6b 100755 --- a/setup/scripts/install-hardware +++ b/setup/scripts/install-hardware @@ -4,7 +4,7 @@ # NVIDIA driver, the machine owner key that lets it load under Secure Boot, # Fedora's preinstalled extras, and firmware. # -# Runs last. MOK enrolment arms a prompt consumed at the next boot and firmware +# Runs last. MOK enrollment arms a prompt consumed at the next boot and firmware # updates can ask for a reboot, so neither belongs in front of the package work # or the dotfiles -- a machine that reboots out of this stage has already been # fully configured. @@ -66,7 +66,7 @@ fi # ── Secure Boot ────────────────────────────────────────────────────────────── # # akmods signs the modules it builds with a key it generates on installation. -# Under Secure Boot that key means nothing until it is enrolled, and enrolment +# Under Secure Boot that key means nothing until it is enrolled, and enrollment # is deliberately a thing only somebody at the physical machine can complete: # the request is queued here, and the next boot shows a blue screen asking for # the password before it will trust the key. @@ -83,7 +83,7 @@ if [[ -n "$mok_hash" ]]; then cert="${PANAMA_MOK_CERT:-/etc/pki/akmods/certs/public_key.der}" if [[ ! -r "$cert" ]]; then - warn "No akmods certificate at $cert, so there is no key to enrol" + warn "No akmods certificate at $cert, so there is no key to enroll" elif mokutil --test-key "$cert" 2>/dev/null | grep -q 'already enrolled'; then log "The akmods key is already enrolled" else @@ -91,10 +91,10 @@ if [[ -n "$mok_hash" ]]; then chmod 600 "$hash_file" printf '%s\n' "$mok_hash" >"$hash_file" if sudo mokutil --import "$cert" --hash-file "$hash_file"; then - log "Key enrolment requested" - log "At the next boot, choose 'Enrol MOK' and enter the password you gave the installer" + log "Key enrollment requested" + log "At the next boot, choose 'Enroll MOK' and enter the password you gave the installer" else - warn "Key enrolment failed; the NVIDIA module will not load until it is enrolled" + warn "Key enrollment failed; the NVIDIA module will not load until it is enrolled" fi rm -f "$hash_file" fi diff --git a/setup/scripts/install-packages b/setup/scripts/install-packages index 5d655bf..6e65c38 100755 --- a/setup/scripts/install-packages +++ b/setup/scripts/install-packages @@ -180,3 +180,50 @@ if [[ -f "$FLATPAK_FILE" ]]; then else log "Package list was not in specified path: $FLATPAK_FILE" fi + +# --- Install the extras that were chosen ------------------------------------ +# +# Everything above is what every Panama machine gets. This is what one machine +# asked for: the interview offers the categories in setup/packages/extras/ as a +# checklist and records the chosen names, so a work laptop does not acquire +# emulators and a desktop does not skip Steam. +# +# Absent means none. That is what makes this stage safe to re-run by hand while +# repairing one piece of a machine -- and it means a category is installed only +# by an explicit answer, never by a default that drifted. +# +# A category mixes both package managers, because the applications do: some are +# in Fedora or RPM Fusion and some publish only a flatpak. A bare line is a dnf +# package and a `flatpak:` line is a Flathub ID, so one file per category holds +# the whole answer rather than splitting each category across two. +# +# Neither install is fatal. A category is a set of applications somebody wanted, +# not a dependency of the desktop, and losing the rest of the run because one of +# them was renamed upstream would be the wrong trade. +install_extra_category() { + local file="$1" name + name="$(basename "$file")" + + local dnf_packages flatpak_ids + dnf_packages=$(packages_in "$file" | tr ' ' '\n' | grep -v '^flatpak:' | tr "\n" " ") + flatpak_ids=$(packages_in "$file" | tr ' ' '\n' | sed -n 's/^flatpak://p' | tr "\n" " ") + + if [[ -n "${dnf_packages// /}" ]]; then + log "Installing $name: $dnf_packages" + sudo dnf install -y $dnf_packages > /dev/null || log "Some $name packages did not install" + fi + if [[ -n "${flatpak_ids// /}" ]]; then + log "Installing $name flatpaks: $flatpak_ids" + sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo > /dev/null + sudo flatpak install -y flathub $flatpak_ids > /dev/null || log "Some $name flatpaks did not install" + fi +} + +EXTRAS_DIR="$PANAMA_PATH/setup/packages/extras" +for extra in ${PANAMA_EXTRAS:-}; do + if [[ -f "$EXTRAS_DIR/$extra" ]]; then + install_extra_category "$EXTRAS_DIR/$extra" + else + log "No such extras category: $extra" + fi +done diff --git a/setup/scripts/interview b/setup/scripts/interview index 3458fdc..f604432 100755 --- a/setup/scripts/interview +++ b/setup/scripts/interview @@ -15,9 +15,8 @@ # somebody else could clone. Re-answering a handful of questions costs less than # maintaining an answers file that drifts out of date. # -# This asks only what a stage in this repository actually consumes. The extras -# checklist arrives with the stage that acts on it; a prompt whose answer nothing -# reads is a control that lies. +# This asks only what a stage in this repository actually consumes. A prompt +# whose answer nothing reads is a control that lies. # # The hardware questions name what was found rather than asking a person to # recite their own machine, and they are not asked at all on a machine they @@ -109,16 +108,16 @@ if [[ -n "$nvidia_card" ]]; then # Only asked where it does something. On a machine with Secure Boot off, # akmods' signature is never checked and enrolling a key is ceremony. if mokutil --sb-state 2>/dev/null | grep -qi 'secureboot enabled'; then - printf 'Secure Boot is on, so the driver must be signed with a key you enrol.\n' + printf 'Secure Boot is on, so the driver must be signed with a key you enroll.\n' printf 'The next boot will ask for this password on a blue screen.\n' - if yes_no "Enrol a machine owner key?"; then + if yes_no "Enroll a machine owner key?"; then # Hashed here and only the hash recorded. The password never # reaches the answers file, the environment, or a command line # -- mokutil takes a hash file precisely so it does not have to. while :; do first="$(gum input --password --header "MOK password")" if [[ -z "$first" ]]; then - printf 'No password given; skipping enrolment.\n' + printf 'No password given; skipping enrollment.\n' break fi second="$(gum input --password --header "MOK password again")" @@ -160,6 +159,33 @@ if command -v fwupdmgr >/dev/null 2>&1; then fi record PANAMA_FIRMWARE "$firmware" +# ── Applications ───────────────────────────────────────────────────────────── +# +# Everything else in this repository is what every Panama machine gets. This is +# the one question about what this machine is for: a work laptop should not +# acquire emulators and a desktop should not skip Steam. +# +# The categories are read from the directory rather than listed here, so adding +# one is adding a file. Nothing is preselected -- a default here would install +# applications nobody chose, on a machine whose owner answered a question they +# thought was about something else. + +heading "Applications" + +extras_dir="$(dirname "${BASH_SOURCE[0]}")/../packages/extras" +extras="" +if [[ -d "$extras_dir" ]]; then + mapfile -t categories < <(for file in "$extras_dir"/*; do + [[ -f "$file" ]] && basename "$file" + done) + if (( ${#categories[@]} > 0 )); then + printf 'Optional application categories. Space to select, enter to accept.\n' + extras="$(gum choose --no-limit --header "Extras" "${categories[@]}" | tr '\n' ' ')" + extras="${extras% }" + fi +fi +record PANAMA_EXTRAS "$extras" + # ── Confirm ────────────────────────────────────────────────────────────────── # # The last chance to catch a typo before twenty minutes of package work that @@ -176,9 +202,10 @@ gum style --border rounded --padding "0 1" "$( printf 'GitHub %s\n' "$([[ "$gh_login" == yes ]] && echo "sign in" || echo "no change")" printf 'SSH key %s\n' "$([[ "$ssh_key" == yes ]] && echo "generate" || echo "no change")" printf 'NVIDIA %s\n' "$([[ "$nvidia" == yes ]] && echo "install driver" || echo "no")" - printf 'Secure Boot %s\n' "$([[ -n "$mok_hash" ]] && echo "enrol a key" || echo "no change")" - printf 'Extras %s\n' "$([[ "$debloat" == yes ]] && echo "remove ${installed[*]}" || echo "keep")" - printf 'Firmware %s' "$([[ "$firmware" == yes ]] && echo "update" || echo "no")" + printf 'Secure Boot %s\n' "$([[ -n "$mok_hash" ]] && echo "enroll a key" || echo "no change")" + printf 'Fedora apps %s\n' "$([[ "$debloat" == yes ]] && echo "remove ${installed[*]}" || echo "keep")" + printf 'Firmware %s\n' "$([[ "$firmware" == yes ]] && echo "update" || echo "no")" + printf 'Extras %s' "${extras:-none}" )" if ! gum confirm --default=true "Install with these answers?"; then diff --git a/setup/scripts/link-dotfiles b/setup/scripts/link-dotfiles index b3d17e1..d403d47 100755 --- a/setup/scripts/link-dotfiles +++ b/setup/scripts/link-dotfiles @@ -288,6 +288,70 @@ if [ -d "$PANAMA_WALLPAPER_DIR" ]; then done fi +# The Firefox chrome. Edge-Frfox, vendored in config/firefox -- see the README +# there for what it is and whose it is. Both halves have to land or neither +# works: chrome/ holds the CSS, and user.js sets the preference that makes +# Firefox read chrome/ at all. +# +# Firefox has moved to the XDG directories, so a current build keeps profiles in +# ~/.config/mozilla/firefox and an older one in ~/.mozilla/firefox. Both are +# looked for rather than assumed -- assuming picked the wrong one on the machine +# this was written on. +PANAMA_FIREFOX_DIR="$PANAMA_PATH/config/firefox" +firefox_root="" +find_firefox_root() { + local candidate + for candidate in "${XDG_CONFIG_HOME:-$HOME/.config}/mozilla/firefox" "$HOME/.mozilla/firefox"; do + if [ -f "$candidate/profiles.ini" ]; then + firefox_root="$candidate" + return 0 + fi + done + return 1 +} + +if [ -d "$PANAMA_FIREFOX_DIR" ] && command -v firefox >/dev/null 2>&1; then + echo -e "\n--- Setting up Firefox chrome ---" + + # A profile does not exist until Firefox has been run once. -CreateProfile is + # a documented flag that creates one and exits rather than opening a window, + # so a fresh machine gets the theme on the first install instead of the + # second. MOZ_HEADLESS in case a future build decides otherwise. + if ! find_firefox_root; then + log "No Firefox profile yet; creating one" + MOZ_HEADLESS=1 firefox -CreateProfile panama >/dev/null 2>&1 || true + find_firefox_root || true + fi + + if [ -z "$firefox_root" ]; then + log "Could not find or create a Firefox profile; skipping the chrome" + else + # Every profile, not just the default. profiles.ini records each one as a + # path that is relative to the root unless it says otherwise. + while read -r profile; do + [ -n "$profile" ] || continue + [ -d "$profile" ] || continue + + for piece in chrome user.js; do + target="$profile/$piece" + if [ -L "$target" ]; then + rm "$target" + elif [ -e "$target" ]; then + backup="$PANAMA_OLD/firefox-$(basename "$profile")-$piece" + mv "$target" "$backup" + log "Moved existing $target to $backup" + fi + ln -s "$PANAMA_FIREFOX_DIR/$piece" "$target" + log "Linked $PANAMA_FIREFOX_DIR/$piece → $target" + done + done < <(awk -F= -v root="$firefox_root" ' + /^\[/ { relative = 1; next } + /^IsRelative=/ { relative = $2; next } + /^Path=/ { print (relative == 1 ? root "/" $2 : $2) } + ' "$firefox_root/profiles.ini") + fi +fi + PANAMA_APPLICATION_DIR="$PANAMA_PATH/config/local/share/applications" USER_APPLICATION_DIR="$HOME/.local/share/applications" mkdir -p "$USER_APPLICATION_DIR" diff --git a/tests/setup/extras-contract b/tests/setup/extras-contract new file mode 100755 index 0000000..9edbb80 --- /dev/null +++ b/tests/setup/extras-contract @@ -0,0 +1,165 @@ +#!/usr/bin/env bash + +# The optional application categories: what the interview offers, and what +# choosing one actually installs. +# +# The rules: +# +# 1. Every category the interview offers installs something. The menu is read +# from the directory rather than written down, so an empty or missing file +# is a checkbox that does nothing -- the same defect this repository has +# refused to ship twice now. +# 2. A `flatpak:` line reaches flatpak with the prefix removed, and never +# reaches dnf. Getting this backwards installs nothing and says it did. +# 3. Nothing is installed without being asked for. An extras loop that ran on +# its own defaults would put Steam on a work laptop. +# 4. Every name is a real package. The whole point of admitting applications +# one at a time from dnf or Flathub is that they stay installable; a typo +# here is a category that fails on somebody else's machine, not this one. +# Checked against the actual repositories, and skipped when offline. + +set -uo pipefail + +repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +installer="$repo_dir/setup/scripts/install-packages" +interview="$repo_dir/setup/scripts/interview" +extras_dir="$repo_dir/setup/packages/extras" + +findings=() +note() { findings+=("$1"); } + +[[ -d "$extras_dir" ]] || { printf 'extras contract: no %s\n' "$extras_dir" >&2; exit 1; } + +# ── 1. Every category is a real offer ──────────────────────────────────────── + +shopt -s nullglob +categories=("$extras_dir"/*) +(( ${#categories[@]} > 0 )) || note 'the extras directory is empty, so the checklist offers nothing' + +for category in "${categories[@]}"; do + name="$(basename "$category")" + [[ -f "$category" ]] || { note "$name is not a file"; continue; } + entries="$(sed 's/#.*//' "$category" | tr -d ' \t' | grep -cv '^$')" + (( entries > 0 )) || note "the $name category installs nothing, so choosing it does nothing" +done + +# The menu has to come from the directory. A hardcoded list is one that goes +# stale the first time a category is added. +grep -q 'extras_dir' "$interview" \ + || note 'the interview does not read the categories from the extras directory' +grep -q 'gum choose --no-limit' "$interview" \ + || note 'the interview does not offer the categories as a multiple-choice checklist' + +# ── 2 & 3. What a chosen category actually installs ────────────────────────── + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +filter="$(sed -n '/^packages_in()/,/^}/p' "$installer")" +loop="$(sed -n '/^install_extra_category()/,/^}/p' "$installer")" +[[ -n "$filter" && -n "$loop" ]] || { + printf 'extras contract: install-packages no longer defines packages_in and install_extra_category\n' >&2 + exit 1 +} + +stub_dir="$work/bin" +mkdir -p "$stub_dir" +calls="$work/calls" +for command in dnf flatpak; do + cat >"$stub_dir/$command" <>"$calls" +STUB + chmod +x "$stub_dir/$command" +done +cat >"$stub_dir/sudo" <<'STUB' +#!/usr/bin/env bash +exec "$@" +STUB +chmod +x "$stub_dir/sudo" + +fixture="$work/mixed" +cat >"$fixture" <<'LIST' +# Both managers in one category, which is the case this format exists for. +from-dnf +flatpak:org.example.FromFlathub +LIST + +( + PATH="$stub_dir:$PATH" + log() { :; } + eval "$filter" + eval "$loop" + install_extra_category "$fixture" +) + +recorded="$(cat "$calls" 2>/dev/null)" + +grep -q 'dnf install -y from-dnf' <<<"$recorded" \ + || note 'a bare line in a category is not installed with dnf' +grep -q 'flatpak install -y flathub org.example.FromFlathub' <<<"$recorded" \ + || note 'a flatpak: line does not reach flatpak with the prefix removed' +if grep 'dnf install' <<<"$recorded" | grep -q 'flatpak:'; then + note 'a flatpak: line is passed to dnf, which cannot install it' +fi +if grep 'flatpak install' <<<"$recorded" | grep -q 'from-dnf'; then + note 'a dnf package is passed to flatpak' +fi + +# Choosing nothing installs nothing. +: >"$calls" +( + PATH="$stub_dir:$PATH" + PANAMA_PATH="$repo_dir" + log() { :; } + eval "$filter" + eval "$loop" + EXTRAS_DIR="$extras_dir" + for extra in ${PANAMA_EXTRAS:-}; do + [[ -f "$EXTRAS_DIR/$extra" ]] && install_extra_category "$EXTRAS_DIR/$extra" + done +) +[[ -s "$calls" ]] && note 'with no categories chosen the installer still installed something' + +# ── 4. Every name resolves ─────────────────────────────────────────────────── +# +# Skipped rather than failed when the repositories cannot be reached, so this +# contract stays runnable on a train. + +if timeout 60 dnf list --available --quiet bash >/dev/null 2>&1; then + for category in "${categories[@]}"; do + [[ -f "$category" ]] || continue + while read -r package; do + [[ -n "$package" ]] || continue + [[ "$package" == flatpak:* ]] && continue + timeout 90 dnf list --quiet "$package" >/dev/null 2>&1 \ + || note "$(basename "$category") names $package, which dnf cannot resolve" + done < <(sed 's/#.*//' "$category" | tr -d ' \t' | grep -v '^$') + done +else + printf 'extras contract: dnf is unreachable, so package names were not resolved\n' >&2 +fi + +if timeout 60 flatpak remote-info flathub org.mozilla.firefox >/dev/null 2>&1; then + for category in "${categories[@]}"; do + [[ -f "$category" ]] || continue + while read -r id; do + [[ -n "$id" ]] || continue + timeout 90 flatpak remote-info flathub "$id" >/dev/null 2>&1 \ + || note "$(basename "$category") names $id, which is not on Flathub" + done < <(sed 's/#.*//' "$category" | tr -d ' \t' | sed -n 's/^flatpak://p') + done +else + printf 'extras contract: Flathub is unreachable, so flatpak IDs were not resolved\n' >&2 +fi + +# ── Report ─────────────────────────────────────────────────────────────────── + +if (( ${#findings[@]} > 0 )); then + mapfile -t findings < <(printf '%s\n' "${findings[@]}" | sort -u) + printf 'extras contract: %d finding(s)\n' "${#findings[@]}" >&2 + printf ' - %s\n' "${findings[@]}" >&2 + exit 1 +fi + +printf 'extras contract: PASS (%d categories)\n' "${#categories[@]}" diff --git a/tests/setup/firefox-chrome-contract b/tests/setup/firefox-chrome-contract new file mode 100755 index 0000000..a817f76 --- /dev/null +++ b/tests/setup/firefox-chrome-contract @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + +# The Firefox chrome lands in the profile, on a machine that has never run +# Firefox. +# +# This is the one piece of Panama's configuration that does not go to a path the +# repository chooses. Firefox owns the profile directory, names it with a random +# salt, and does not create it until the browser has been run once -- so the +# usual "symlink config/dot/ to ~/.config/" cannot reach it. +# +# Two things about that are easy to get wrong and were: +# +# 1. The profile root moved. A current Firefox keeps profiles under +# ~/.config/mozilla/firefox and an older one under ~/.mozilla/firefox. +# Writing to the wrong one silently themes nothing. +# 2. Both halves have to land. chrome/ holds the CSS, and user.js sets +# toolkit.legacyUserProfileCustomizations.stylesheets -- without which +# Firefox never reads chrome/ at all, and the theme is a directory of dead +# files. +# +# So this runs link-dotfiles for real against a throwaway HOME with no profile in +# it, and looks at what came out. Nothing here touches the running machine. + +set -uo pipefail + +repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +theme_dir="$repo_dir/config/firefox" + +findings=() +note() { findings+=("$1"); } + +command -v firefox >/dev/null 2>&1 || { + printf 'firefox chrome contract: firefox is not installed, so nothing was verified\n' >&2 + exit 0 +} + +# ── The theme is whole ─────────────────────────────────────────────────────── + +[[ -f "$theme_dir/user.js" ]] || note 'config/firefox has no user.js, so Firefox would ignore chrome/ entirely' +[[ -d "$theme_dir/chrome" ]] || note 'config/firefox has no chrome directory' +[[ -f "$theme_dir/README.md" ]] || note 'the vendored theme records no provenance or licence' + +grep -q 'toolkit.legacyUserProfileCustomizations.stylesheets' "$theme_dir/user.js" 2>/dev/null \ + || note 'user.js does not enable userChrome.css, so none of the CSS is read' + +# userChrome.css imports custom.css last so local changes need not touch the +# vendored files. The import resolving to nothing is legal CSS and therefore +# silent, which is exactly why it is worth checking. +if grep -q 'custom.css' "$theme_dir/chrome/userChrome.css" 2>/dev/null; then + [[ -f "$theme_dir/chrome/custom.css" ]] \ + || note 'userChrome.css imports custom.css, which does not exist' +fi + +# ── A real run, into a throwaway home ──────────────────────────────────────── + +fake_home="$(mktemp -d)" +trap 'rm -rf "$fake_home"' EXIT + +HOME="$fake_home" XDG_CONFIG_HOME="$fake_home/.config" PANAMA_PATH="$repo_dir" \ + MOZ_HEADLESS=1 timeout 300 bash "$repo_dir/setup/scripts/link-dotfiles" >/dev/null 2>&1 + +profiles_ini="$(find "$fake_home" -name profiles.ini -print -quit 2>/dev/null)" +if [[ -z "$profiles_ini" ]]; then + note 'no Firefox profile was created, so a fresh machine gets no chrome until the second install' +else + root="$(dirname "$profiles_ini")" + + linked=0 + while read -r profile; do + [[ -d "$profile" ]] || continue + linked=1 + for piece in chrome user.js; do + if [[ ! -e "$profile/$piece" ]]; then + note "$piece never reached the profile at $(basename "$profile")" + elif [[ ! -L "$profile/$piece" ]]; then + note "$piece in the profile is not a link to the repository, so updates will not reach it" + elif [[ "$(readlink -f "$profile/$piece")" != "$(readlink -f "$theme_dir/$piece")" ]]; then + note "$piece in the profile points somewhere other than config/firefox" + fi + done + done < <(awk -F= -v root="$root" ' + /^\[/ { relative = 1; next } + /^IsRelative=/ { relative = $2; next } + /^Path=/ { print (relative == 1 ? root "/" $2 : $2) } + ' "$profiles_ini") + + (( linked == 1 )) || note 'profiles.ini lists no profile directory that exists' +fi + +# ── Report ─────────────────────────────────────────────────────────────────── + +if (( ${#findings[@]} > 0 )); then + mapfile -t findings < <(printf '%s\n' "${findings[@]}" | sort -u) + printf 'firefox chrome contract: %d finding(s)\n' "${#findings[@]}" >&2 + printf ' - %s\n' "${findings[@]}" >&2 + exit 1 +fi + +printf 'firefox chrome contract: PASS\n' diff --git a/tests/setup/hardware-contract b/tests/setup/hardware-contract index 1bde136..2d93b16 100755 --- a/tests/setup/hardware-contract +++ b/tests/setup/hardware-contract @@ -4,7 +4,7 @@ # # This stage cannot be verified the way the rest of Panama is. It installs a # proprietary driver, rewrites kernel arguments and queues a Secure Boot -# enrolment, and the machine it was written on is an AMD desktop with no NVIDIA +# enrollment, and the machine it was written on is an AMD desktop with no NVIDIA # card in it. Running it to see what happens is not available. # # So every privileged command it can reach is stood in on PATH, and the contract @@ -132,19 +132,19 @@ hash='$6$notarealsalt$notarealhashvalue' mok="$(run_stage PANAMA_MOK_HASH="$hash" PANAMA_MOK_CERT="$cert")" called "$mok" 'mokutil --import' \ - || note 'a recorded MOK hash does not queue an enrolment' + || note 'a recorded MOK hash does not queue an enrollment' called "$mok" -- '--hash-file' \ - || note 'the enrolment does not pass a hash file, so mokutil would prompt for a password' + || note 'the enrollment does not pass a hash file, so mokutil would prompt for a password' if grep -qF -- "$hash" <<<"$mok"; then note 'the MOK hash is passed on a command line where any process can read it' fi -# No certificate means akmods never generated a key. Requesting enrolment of a +# No certificate means akmods never generated a key. Requesting enrollment of a # key that does not exist is worse than skipping: it queues a prompt at the next # boot for nothing. without_cert="$(run_stage PANAMA_MOK_HASH="$hash" PANAMA_MOK_CERT="$work/absent.der")" if called "$without_cert" 'mokutil --import'; then - note 'enrolment is requested even with no akmods certificate to enrol' + note 'enrollment is requested even with no akmods certificate to enroll' fi # ── 4. Removal is honest about what it removes ───────────────────────────────