summaryrefslogtreecommitdiffstats
path: root/src/css
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 05:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 05:47:55 +0000
commit31d6ff6f931696850c348007241195ab3b2eddc7 (patch)
tree615cb1c57ce9f6611bad93326b9105098f379609 /src/css
parentInitial commit. (diff)
downloadublock-origin-31d6ff6f931696850c348007241195ab3b2eddc7.tar.xz
ublock-origin-31d6ff6f931696850c348007241195ab3b2eddc7.zip
Adding upstream version 1.55.0+dfsg.upstream/1.55.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/css')
-rw-r--r--src/css/1p-filters.css26
-rw-r--r--src/css/3p-filters.css250
-rw-r--r--src/css/about.css3
-rw-r--r--src/css/advanced-settings.css26
-rw-r--r--src/css/asset-viewer.css79
-rw-r--r--src/css/click2load.css53
-rw-r--r--src/css/cloud-ui.css104
-rw-r--r--src/css/code-viewer.css67
-rw-r--r--src/css/codemirror.css327
-rw-r--r--src/css/common.css347
-rw-r--r--src/css/dashboard-common.css55
-rw-r--r--src/css/dashboard.css115
-rw-r--r--src/css/devtools.css22
-rw-r--r--src/css/document-blocked.css146
-rw-r--r--src/css/dom-inspector.css40
-rw-r--r--src/css/dyna-rules.css79
-rw-r--r--src/css/epicker-ui.css270
-rw-r--r--src/css/fa-icons.css149
-rw-r--r--src/css/fonts/Inter/Inter-Regular.woff2bin0 -> 100368 bytes
-rw-r--r--src/css/fonts/Inter/Inter-SemiBold.woff2bin0 -> 106916 bytes
-rw-r--r--src/css/fonts/Inter/LICENSE.txt93
-rw-r--r--src/css/fonts/Metropolis/Metropolis-Regular.woff2bin0 -> 24152 bytes
-rw-r--r--src/css/fonts/Metropolis/Metropolis-SemiBold.woff2bin0 -> 26564 bytes
-rw-r--r--src/css/fonts/Metropolis/README.md25
-rw-r--r--src/css/fonts/Metropolis/UNLICENSE24
-rw-r--r--src/css/logger-ui-inspector.css122
-rw-r--r--src/css/logger-ui.css985
-rw-r--r--src/css/popup-fenix.css778
-rw-r--r--src/css/settings.css74
-rw-r--r--src/css/support.css110
-rw-r--r--src/css/themes/default.css526
-rw-r--r--src/css/whitelist.css22
32 files changed, 4917 insertions, 0 deletions
diff --git a/src/css/1p-filters.css b/src/css/1p-filters.css
new file mode 100644
index 0000000..679e4b8
--- /dev/null
+++ b/src/css/1p-filters.css
@@ -0,0 +1,26 @@
+html {
+ height: 100vh;
+ overflow: hidden;
+ width: 100vw;
+ }
+body {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ justify-content: stretch;
+ overflow: hidden;
+ width: 100%;
+ }
+.body {
+ flex-shrink: 0;
+ }
+[data-i18n="1pTrustWarning"] {
+ font-weight: bold;
+ }
+.codeMirrorContainer {
+ flex-grow: 1;
+ }
+#userFilters {
+ text-align: left;
+ word-wrap: normal;
+ }
diff --git a/src/css/3p-filters.css b/src/css/3p-filters.css
new file mode 100644
index 0000000..014dd20
--- /dev/null
+++ b/src/css/3p-filters.css
@@ -0,0 +1,250 @@
+@keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+ }
+body {
+ margin-bottom: 6rem;
+ }
+#actions {
+ background-color: var(--surface-1);
+ padding: var(--default-gap-small) 0 var(--default-gap-xsmall) 0;
+ position: sticky;
+ top: 0;
+ z-index: 10;
+ }
+#buttonUpdate.active {
+ pointer-events: none;
+ }
+#buttonUpdate.active .fa-icon svg {
+ animation: spin 1s linear infinite;
+ transform-origin: 50%;
+ }
+
+body.updating #actions,
+body.working #actions {
+ cursor: progress;
+ }
+body.updating #actions button,
+body.working #actions button {
+ pointer-events: none;
+ }
+
+.listExpander {
+ font-size: 18px;
+ padding: 0;
+ }
+.listExpander:first-child {
+ justify-content: flex-start;
+ min-width: 20px;
+ }
+.listExpander:not(:first-child) {
+ color: var(--checkbox-checked-ink);
+ fill: var(--checkbox-checked-ink);
+ }
+.listExpander svg {
+ transform: rotate(90deg);
+ transform-origin: 50%;
+ }
+
+#lists .fa-icon:hover {
+ transform: scale(1.25);
+ }
+
+#lists .rootstats.expanded .listExpander svg {
+ transform: rotate(180deg);
+ }
+
+#lists .searchbar {
+ align-items: center;
+ column-gap: var(--default-gap-xxsmall);
+ display: inline-flex;
+ margin-block-start: calc(var(--font-size) * 0.75);
+ margin-inline-start: var(--checkbox-size);
+ position: relative;
+ }
+#lists .searchbar input {
+ padding-inline-start: var(--default-gap-large);
+ }
+#lists .searchbar .fa-icon {
+ color: var(--ink-4);
+ fill: var(--ink-4);
+ left: 4px;
+ position: absolute;
+ transform: none;
+ }
+#lists.searchMode > .listEntries .listEntries,
+#lists.searchMode > .listEntries .listEntry.searchMatch {
+ display: flex !important;
+ }
+#lists.searchMode > .listEntries .listEntry {
+ display: none;
+ }
+#lists.searchMode > .listEntries .listExpander {
+ visibility: hidden;
+ }
+
+#listsOfBlockedHostsPrompt {
+ cursor: pointer;
+ }
+
+#lists .listEntries {
+ display: flex;
+ flex-direction: column;
+ margin-inline-start: var(--checkbox-size);
+ }
+#lists > .listEntries {
+ margin-inline-start: 0;
+ }
+#lists .listEntry {
+ align-items: flex-start;
+ flex-direction: column;
+ margin-bottom: 0;
+ margin-inline-start: 0;
+ white-space: nowrap;
+ }
+#lists .listEntry[data-key="user"] {
+ margin-top: 0;
+ }
+#lists .listEntry > .detailbar {
+ column-gap: calc(var(--default-gap-xxsmall) + 2px);
+ display: inline-flex;
+ }
+#lists .listEntry[data-key="user"] > .detailbar {
+ display: none;
+ }
+#lists .listEntry[data-role="node"].expanded > .detailbar .listExpander svg {
+ transform: rotate(180deg);
+ }
+#lists .listEntry[data-parent="root"]:not(.expanded) > .listEntries > .listEntry:not(.checked):not(.isDefault):not(.stickied) {
+ display: none;
+ }
+#lists .listEntry:not([data-parent="root"]):not(.expanded) > .listEntries > .listEntry {
+ display: none;
+ }
+#lists .nodestats {
+ align-self: flex-end;
+ color: var(--info0-ink);
+ fill: var(--info0-ink);
+ cursor: default;
+ font-size: var(--font-size-smaller);
+}
+#lists .iconbar {
+ column-gap: var(--default-gap-xxsmall);
+ color: var(--info0-ink);
+ fill: var(--info0-ink);
+ display: inline-flex;
+ flex-direction: row;
+ font-size: 120%;
+ }
+#lists .iconbar a {
+ color: var(--info0-ink);
+ fill: var(--info0-ink);
+ }
+#lists .iconbar .fa-icon {
+ display: none;
+ }
+#lists .iconbar .content {
+ display: inline-flex;
+ }
+#lists .iconbar a.towiki {
+ display: inline-flex;
+ }
+#lists .listEntry > .detailbar .iconbar a.support {
+ display: inline-flex;
+ }
+#lists .listEntry > .detailbar .iconbar a.support[href="#"] {
+ display: none;
+ }
+#lists .iconbar .remove,
+#lists .iconbar .unsecure,
+#lists .iconbar .failed {
+ color: var(--info3-ink);
+ fill: var(--info3-ink);
+ cursor: pointer;
+ }
+#lists .listEntry.external > .detailbar .iconbar .remove {
+ display: inline-flex;
+ }
+#lists .listEntry > .detailbar .iconbar a.mustread {
+ color: var(--info1-ink);
+ fill: var(--info1-ink);
+ display: inline-flex;
+ }
+#lists .listEntry > .detailbar .iconbar a.mustread[href="#"] {
+ display: none;
+ }
+#lists .listEntry .leafstats {
+ align-items: flex-end;
+ color: var(--info0-ink);
+ fill: var(--info0-ink);
+ display: none;
+ font-size: var(--font-size-xsmall);
+ margin-inline-start: calc(var(--checkbox-size) + var(--checkbox-margin-end));
+}
+#lists .listEntry > .detailbar .leafstats {
+ margin-inline-start: 0;
+ }
+#lists .listEntry.checked > .leafstats,
+#lists .listEntry.checked > .detailbar .leafstats {
+ display: inline-flex;
+}
+#lists .iconbar .status {
+ cursor: default;
+ display: none;
+}
+#lists .listEntry.checked.unsecure > .detailbar .iconbar .unsecure {
+ display: inline-flex;
+ }
+#lists .listEntry.failed > .detailbar .iconbar .failed {
+ display: inline-flex;
+ }
+#lists .iconbar .cache {
+ cursor: pointer;
+ }
+#lists .listEntry.checked.cached:not(.obsolete) > .detailbar .iconbar .cache {
+ display: inline-flex;
+ }
+#lists .listEntry.cached.recent:not(.obsolete) > .detailbar .iconbar .cache {
+ color: var(--dashboard-happy-green);
+ fill: var(--dashboard-happy-green);
+ }
+#lists .iconbar .obsolete {
+ color: var(--info2-ink);
+ fill: var(--info2-ink);
+ }
+body:not(.updating) #lists .listEntry.checked.obsolete > .detailbar .iconbar .obsolete {
+ display: inline-flex;
+ }
+#lists .iconbar .updating {
+ transform-origin: 50%;
+ }
+body.updating #lists .listEntry.checked.obsolete > .detailbar .iconbar .updating {
+ animation: spin 1s steps(8) infinite;
+ display: inline-flex;
+ }
+
+#lists .listEntry.toRemove .checkbox {
+ visibility: hidden;
+ }
+#lists .listEntry.toRemove .listname {
+ text-decoration: line-through;
+ }
+
+#lists .listEntry[data-role="import"].expanded .listExpander svg {
+ transform: rotate(180deg);
+ }
+#lists .listEntry[data-role="import"].expanded textarea {
+ visibility: visible;
+ }
+#lists .listEntry[data-role="import"] textarea {
+ border: 1px solid #ccc;
+ box-sizing: border-box;
+ display: block;
+ font-size: smaller;
+ height: 6em;
+ margin: 0;
+ resize: vertical;
+ visibility: hidden;
+ white-space: pre;
+ width: 100%;
+ }
diff --git a/src/css/about.css b/src/css/about.css
new file mode 100644
index 0000000..8c3afcd
--- /dev/null
+++ b/src/css/about.css
@@ -0,0 +1,3 @@
+body {
+ margin-bottom: 6rem;
+ }
diff --git a/src/css/advanced-settings.css b/src/css/advanced-settings.css
new file mode 100644
index 0000000..c67e750
--- /dev/null
+++ b/src/css/advanced-settings.css
@@ -0,0 +1,26 @@
+html {
+ height: 100vh;
+ overflow: hidden;
+ width: 100vw;
+ }
+body {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ justify-content: stretch;
+ overflow: hidden;
+ width: 100%;
+ }
+.body {
+ flex-shrink: 0;
+ }
+.codeMirrorContainer {
+ flex-grow: 1;
+ }
+#advancedSettings {
+ border: var(--default-gap-xxsmall) solid var(--surface-2);
+ text-align: left;
+ }
+.CodeMirror-wrap pre {
+ word-break: break-all;
+ }
diff --git a/src/css/asset-viewer.css b/src/css/asset-viewer.css
new file mode 100644
index 0000000..8b6f1da
--- /dev/null
+++ b/src/css/asset-viewer.css
@@ -0,0 +1,79 @@
+/**
+ uBlock Origin - a browser extension to block requests.
+ Copyright (C) 2014-present Raymond Hill
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see {http://www.gnu.org/licenses/}.
+
+ Home: https://github.com/gorhill/uBlock
+*/
+
+body {
+ border: 0;
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ margin: 0;
+ overflow: hidden;
+ padding: 0;
+ width: 100vw;
+ }
+#subscribe {
+ display: flex;
+ flex-shrink: 0;
+ justify-content: space-between;
+ max-height: 6em;
+ padding-inline-end: 0.5em;
+ }
+#subscribe.hide {
+ display: none;
+ }
+.logo {
+ background-color: #fffa;
+ flex-shrink: 0;
+ width: 2em;
+ }
+#subscribePrompt {
+ display: inline-flex;
+ flex-direction: column;
+ padding: 0.5em;
+ }
+#subscribePrompt > span {
+ font-weight: bold;
+ }
+#subscribePrompt > a {
+ font-size: 14px;
+ word-break: break-all;
+ }
+#subscribe > button {
+ align-self: center;
+ }
+#subscribe > .fa-icon {
+ color: var(--accent-ink-1);
+ fill: var(--accent-ink-1);
+ font-size: 20px;
+ }
+body.loading #subscribe > button,
+body:not(.loading) #subscribe > .fa-icon {
+ display: none;
+ }
+@keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+ }
+body.loading #subscribe > .fa-icon > svg {
+ animation: spin 1s steps(8) infinite;
+ }
+#content {
+ flex-grow: 1;
+ }
diff --git a/src/css/click2load.css b/src/css/click2load.css
new file mode 100644
index 0000000..b6d3924
--- /dev/null
+++ b/src/css/click2load.css
@@ -0,0 +1,53 @@
+/**
+ uBlock Origin - a browser extension to block requests.
+ Copyright (C) 2014-present Raymond Hill
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see {http://www.gnu.org/licenses/}.
+
+ Home: https://github.com/gorhill/uBlock
+*/
+
+body {
+ align-items: center;
+ border: 1px solid var(--ubo-red);
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ padding: 0 2px;
+ position: relative;
+ width: 100vw;
+ }
+
+.logo {
+ left: 0;
+ padding: 2px 1px;
+ position: absolute;
+ top: 0;
+ }
+
+#frameURL {
+ font-family: monospace;
+ font-size: 90%;
+ overflow-y: auto;
+ word-break: break-all;
+ }
+#frameURL > a {
+ font-size: 1rem;
+ }
+
+#clickToLoad {
+ cursor: default;
+ margin-bottom: 1em;
+ }
diff --git a/src/css/cloud-ui.css b/src/css/cloud-ui.css
new file mode 100644
index 0000000..1891a1d
--- /dev/null
+++ b/src/css/cloud-ui.css
@@ -0,0 +1,104 @@
+#cloudWidget {
+ background-color: var(--surface-2);
+ margin: 0.5em 0;
+ min-width: max-content;
+ position: relative;
+ }
+#cloudWidget.hide {
+ display: none;
+ }
+#cloudWidget div {
+ display: flex;
+ }
+#cloudToolbar {
+ align-items: flex-start;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+ }
+#cloudToolbar > div:first-of-type {
+ margin: 0.5em;
+ }
+#cloudToolbar button {
+ padding: 0 0.25em;
+ position: relative;
+ }
+#cloudToolbar button .fa-icon {
+ font-size: 180%;
+ }
+#cloudToolbar button[disabled] {
+ visibility: hidden;
+ }
+#cloudToolbar button.error {
+ color: var(--info3-ink);
+ }
+#cloudPullAndMerge {
+ margin-left: 0.25em;
+ }
+#cloudPullAndMerge > span:nth-of-type(2) {
+ font-size: 90%;
+ position: absolute;
+ right: 0;
+ top: 0;
+ }
+#cloudInfo {
+ flex-shrink: 0;
+ font-size: 90%;
+ margin: 0 1em;
+ overflow: hidden;
+ padding: 0;
+ white-space: pre-line;
+ }
+#cloudCapacity {
+ background-color: var(--surface-3);
+ height: 4px;
+ }
+#cloudCapacity > div {
+ background-color: var(--cloud-total-used-surface);
+ }
+#cloudCapacity > div > div {
+ background-color: var(--cloud-used-surface);
+ }
+#cloudError {
+ color: var(--info3-ink);
+ flex-grow: 1;
+ flex-shrink: 2;
+ font-size: small;
+ margin: 0 0.5em 0.5em 0.5em;
+ }
+#cloudError:empty {
+ display: none;
+ }
+#cloudCog {
+ color: var(--ink-3);
+ fill: var(--ink-3);
+ cursor: pointer;
+ font-size: 110%;
+ justify-content: flex-end;
+ padding: 0.4em;
+ }
+#cloudCog:hover {
+ color: inherit;
+ fill: inherit;
+ }
+#cloudWidget #cloudOptions {
+ align-items: center;
+ background-color: var(--surface-1);
+ bottom: 2px;
+ display: none;
+ font-size: small;
+ padding: 0.5em;
+ position: absolute;
+ right: 2px;
+ text-align: center;
+ top: 2px;
+ z-index: 10;
+ }
+#cloudWidget #cloudOptions label {
+ display: inline-flex;
+ flex-direction: column;
+ align-items: flex-start;
+ }
+#cloudWidget #cloudOptions.show {
+ display: flex;
+ white-space: nowrap;
+ }
diff --git a/src/css/code-viewer.css b/src/css/code-viewer.css
new file mode 100644
index 0000000..774fa69
--- /dev/null
+++ b/src/css/code-viewer.css
@@ -0,0 +1,67 @@
+body {
+ border: 0;
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ margin: 0;
+ overflow: hidden;
+ padding: 0;
+ width: 100vw;
+ }
+#header {
+ background-color: var(--cm-gutter-surface);
+ border-bottom: 1px solid var(--surface-1);
+ padding: var(--default-gap-xsmall);
+ position: relative;
+ z-index: 1000000;
+ }
+#header input[type="url"] {
+ box-sizing: border-box;
+ font-size: var(--font-size-smaller);
+ width: 100%;
+ }
+#header:focus-within #pastURLs {
+ display: flex;
+ }
+#currentURL {
+ display: flex;
+ gap: 0.5rem;
+ }
+#currentURL > .fa-icon {
+ padding: 0 0.5rem;
+ }
+#currentURL > .fa-icon:hover {
+ background-color: var(--surface-3);
+ }
+#pastURLs {
+ background-color: var(--surface-0);
+ border: 1px solid var(--border-1);
+ display: none;
+ flex-direction: column;
+ font-size: var(--font-size-smaller);
+ position: absolute;
+ }
+#pastURLs > span {
+ cursor: pointer;
+ overflow: hidden;
+ padding: 2px 4px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ width: 75vw;
+ }
+#pastURLs > span.selected {
+ font-weight: bold;
+ }
+#pastURLs > span:hover {
+ background-color: var(--surface-1);
+ }
+#content {
+ flex-grow: 1;
+ }
+
+.cm-href {
+ cursor: pointer;
+ }
+.cm-href:hover {
+ text-decoration: underline;
+ }
diff --git a/src/css/codemirror.css b/src/css/codemirror.css
new file mode 100644
index 0000000..2d15bf8
--- /dev/null
+++ b/src/css/codemirror.css
@@ -0,0 +1,327 @@
+.codeMirrorContainer {
+ line-height: 1.25;
+ overflow: hidden;
+ position: relative;
+ }
+.CodeMirror {
+ background-color: var(--surface-0);
+ box-sizing: border-box;
+ color: var(--ink-1);
+ flex-grow: 1;
+ font-size: var(--monospace-size);
+ height: 100%;
+ width: 100%;
+ }
+.CodeMirror-cursor {
+ border-color: var(--cm-cursor);
+ }
+.CodeMirror-selected {
+ background-color: var(--cm-selection-surface);
+ }
+.CodeMirror-focused .CodeMirror-selected {
+ background-color: var(--cm-selection-focused-surface);
+ }
+.CodeMirror-foldmarker {
+ color: var(--cm-foldmarker-ink);
+ cursor: pointer;
+ font-family: sans-serif;
+ font-weight: bold;
+ }
+.CodeMirror-foldgutter-folded::after {
+ content: '\25B6';
+ }
+.CodeMirror-foldgutter-open::after {
+ content: '\25BC';
+ }
+.CodeMirror-gutters {
+ background-color: var(--cm-gutter-surface);
+ border-color: var(--cm-gutter-border);
+ }
+.CodeMirror-line::selection,
+.CodeMirror-line > span::selection,
+.CodeMirror-line > span > span::selection {
+ background-color: var(--cm-selection-focused-surface);
+ }
+.CodeMirror-linenumber {
+ color: var(--cm-gutter-ink);
+ }
+.CodeMirror-lines {
+ padding-bottom: 6rem;
+ }
+.CodeMirror-matchingbracket {
+ color: unset;
+ }
+.CodeMirror-matchingbracket {
+ background-color: var(--cm-matchingbracket) !important;
+ color: inherit !important;
+ font-weight: bold;
+ }
+
+.CodeMirror-search-match {
+ background: none;
+ background-color: var(--cm-search-match-surface);
+ border: 0;
+ opacity: 1;
+ }
+
+/* For when panels are used */
+.codeMirrorContainer > div:not([class^="CodeMirror"]) {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ }
+
+.codeMirrorContainer.codeMirrorBreakAll .CodeMirror-wrap pre {
+ word-break: break-all;
+ }
+
+.cm-theme-override .cm-s-default .cm-comment {
+ color: var(--sf-comment-ink);
+ }
+.cm-theme-override .cm-s-default .cm-def {
+ color: var(--sf-def-ink);
+ }
+.cm-theme-override .cm-s-default .cm-directive {
+ color: var(--sf-directive-ink);
+ font-weight: bold;
+ }
+.cm-theme-override .cm-s-default .cm-error {
+ color: inherit;
+ }
+.cm-theme-override .cm-s-default .cm-error,
+.CodeMirror-linebackground.error {
+ background-color: var(--sf-error-surface);
+ text-decoration: var(--sf-error-ink) dashed underline;
+ }
+.cm-theme-override .cm-s-default .cm-link {
+ text-decoration: none;
+ }
+.cm-theme-override .cm-s-default .cm-link:hover {
+ color: var(--link-ink);
+ }
+.cm-theme-override .cm-s-default .cm-keyword {
+ color: var(--sf-keyword-ink);
+ }
+.cm-theme-override .cm-s-default .cm-negative {
+ color: var(--cm-negative);
+ }
+.cm-theme-override .cm-s-default .cm-positive {
+ color: var(--cm-positive);
+ }
+.cm-theme-override .cm-s-default .cm-notice {
+ text-decoration-color: var(--sf-notice-ink);
+ text-decoration-style: solid;
+ text-decoration-line: underline;
+ }
+.cm-theme-override .cm-s-default .cm-unicode {
+ text-decoration-color: var(--sf-unicode-ink);
+ text-decoration-style: dashed;
+ text-decoration-line: underline;
+ }
+.cm-theme-override .cm-s-default .cm-tag {
+ color: var(--sf-tag-ink);
+ }
+.cm-theme-override .cm-s-default .cm-value {
+ color: var(--sf-value-ink);
+ }
+.cm-theme-override .cm-s-default .cm-variable {
+ color: var(--sf-variable-ink);
+ }
+.cm-theme-override .cm-s-default .cm-warning {
+ background-color: var(--sf-warning-surface);
+ text-decoration: underline var(--sf-warning-ink);
+ }
+.cm-theme-override .cm-s-default .cm-readonly {
+ color: var(--sf-readonly-ink);
+ }
+
+/* Rules */
+.cm-s-default .cm-allowrule {
+ color: var(--df-allow-ink);
+ font-weight: bold;
+ }
+.cm-s-default .cm-blockrule {
+ color: var(--df-block-ink);
+ font-weight: bold;
+ }
+.cm-s-default .cm-nooprule {
+ color: var(--df-noop-ink);
+ font-weight: bold;
+ }
+.cm-s-default .cm-sortkey {
+ color: var(--sf-keyword-ink);
+ }
+
+.cm-search-widget {
+ align-items: center;
+ background-color: var(--cm-gutter-surface);
+ border-bottom: 1px solid var(--cm-gutter-border);
+ cursor: default;
+ direction: ltr;
+ display: flex;
+ flex-shrink: 0;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ padding: var(--default-gap-xsmall);
+ row-gap: var(--default-gap-xsmall);
+ user-select: none;
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ z-index: 1000;
+ }
+.cm-search-widget > * {
+ flex-grow: 1;
+ }
+.cm-search-widget > :last-child {
+ text-align: end;
+ }
+
+.cm-search-widget-input {
+ display: inline-flex;
+ flex-grow: 1;
+ }
+.cm-search-widget .fa-icon {
+ fill: var(--cm-gutter-ink);
+ font-size: 140%;
+ }
+.cm-search-widget .fa-icon:not(.fa-icon-ro):hover {
+ fill: var(--ink-1);
+ }
+.cm-search-widget-input input {
+ border: 1px solid var(--cm-gutter-ink);
+ display: inline-flex;
+ flex-grow: 1;
+ max-width: 16em;
+ }
+.cm-search-widget-count {
+ align-items: center;
+ display: inline-flex;
+ flex-grow: 0;
+ font-size: var(--font-size-smaller);
+ min-width: 6em;
+ visibility: hidden;
+ }
+.cm-search-widget[data-query] .cm-search-widget-count {
+ visibility: visible;
+ }
+.cm-search-widget[data-query] .cm-search-widget-count:empty {
+ visibility: hidden;
+ }
+.cm-search-widget .cm-search-widget-button:hover {
+ color: #000;
+ }
+.cm-search-widget .sourceURL[href=""] {
+ visibility: hidden;
+ }
+:root.mobile .cm-search-widget .sourceURL[href=""] {
+ display: none;
+ }
+
+.cm-linter-widget {
+ align-items: center;
+ display: none;
+ flex-grow: 1;
+ }
+.cm-linter-widget:not([data-lint="0"]) {
+ display: inline-flex;
+ }
+.cm-linter-widget .cm-linter-widget-count {
+ color: var(--accent-surface-1);
+ fill: var(--accent-surface-1);
+ font-size: var(--font-size-smaller);
+ }
+
+.cm-searching.cm-overlay {
+ background-color: var(--cm-searching-surface) !important;
+ border: 0;
+ color: var(--cm-searching-ink) !important;
+ }
+
+.CodeMirror-merge {
+ border-color: var(--cm-gutter-border);
+ }
+.CodeMirror-merge-copy,
+.CodeMirror-merge-copy-reverse {
+ color: var(--cm-merge-copy-ink);
+ }
+.CodeMirror-merge-l-chunk {
+ background-color: var(--cm-merge-chunk-surface);
+ }
+.CodeMirror-merge-l-chunk-start,
+.CodeMirror-merge-l-chunk-end {
+ border-color: var(--cm-merge-chunk-border);
+ }
+.CodeMirror-merge-l-deleted {
+ background-image: none;
+ }
+.CodeMirror-merge-l-inserted {
+ background-image: none;
+ }
+/* This probably needs to be added to CodeMirror repo */
+.CodeMirror-merge-gap {
+ background-color: var(--cm-gutter-surface);
+ border-color: var(--cm-gutter-border);
+ vertical-align: top;
+ }
+.CodeMirror-merge-scrolllock {
+ color: var(--cm-merge-copy-ink);
+ }
+.CodeMirror-merge-spacer {
+ background-color: var(--cm-merge-chunk-surface);
+ }
+
+.CodeMirror-hints {
+ z-index: 10000;
+ }
+
+/* Must appear after other background color declarations to be sure it
+ * overrides them
+ * */
+.CodeMirror-activeline-background {
+ background-color: var(--cm-active-line);
+ }
+
+.CodeMirror-lintmarker {
+ height: calc(var(--font-size) - 2px);
+ margin-top: 1px;
+ position: relative;
+ }
+.CodeMirror-lintmarker > * {
+ position: absolute;
+ }
+.CodeMirror-lintmarker[data-error="y"] {
+ background-color: var(--sf-error-ink);
+ }
+.CodeMirror-lintmarker .msg {
+ background-color: var(--surface-0);
+ border: 1px solid var(--sf-error-ink);
+ color: var(--ink-1);
+ display: none;
+ filter: drop-shadow(2px 2px 4px #0008);
+ left: 100%;
+ padding: var(--default-gap-xsmall);
+ top: -2px;
+ white-space: pre;
+ }
+.CodeMirror-lintmarker svg {
+ height: 70%;
+ left: 15%;
+ top: 15%;
+ width: 70%;
+ }
+.CodeMirror-lintmarker[data-error="y"] svg {
+ display: none;
+ }
+.CodeMirror-lintmarker[data-fold="start"] {
+ fill: var(--cm-foldmarker-ink);
+ }
+.CodeMirror-lintmarker[data-fold="start"].folded svg {
+ transform: rotate(-90deg);
+ }
+.CodeMirror-lintmarker[data-fold="end"] {
+ fill: var(--border-2);
+ }
+.CodeMirror-lintmarker[data-error="y"]:hover > span,
+.CodeMirror-lintmarker[data-error="y"] > span:hover {
+ display: initial;
+ }
diff --git a/src/css/common.css b/src/css/common.css
new file mode 100644
index 0000000..1a8ba0b
--- /dev/null
+++ b/src/css/common.css
@@ -0,0 +1,347 @@
+@charset "UTF-8";
+/* https://protocol.mozilla.org/assets/docs/css/protocol.css */
+@font-face {
+ font-family: Inter;
+ font-style: normal;
+ font-weight: normal;
+ src: url('fonts/Inter/Inter-Regular.woff2') format('woff2');
+}
+@font-face {
+ font-family: Inter;
+ font-style: normal;
+ font-weight: 600;
+ src: url('fonts/Inter/Inter-SemiBold.woff2') format('woff2');
+}
+@font-face {
+ font-family: Metropolis;
+ font-style: normal;
+ font-weight: normal;
+ src: url('fonts/Metropolis/Metropolis-Regular.woff2') format('woff2');
+}
+@font-face {
+ font-family: Metropolis;
+ font-style: normal;
+ font-weight: 600;
+ src: url('fonts/Metropolis/Metropolis-SemiBold.woff2') format('woff2');
+}
+
+/**
+ Common uBO spacing.
+ Ref: https://github.com/uBlockOrigin/uBlock-issues/issues/1005
+*/
+:root {
+ --default-gap-xxlarge: 40px;
+ --default-gap-xlarge: 32px;
+ --default-gap-large: 24px;
+ --default-gap: 16px;
+ --default-gap-small: 12px;
+ --default-gap-xsmall: 8px;
+ --default-gap-xxsmall: 4px;
+ }
+
+/* Common uBO styles */
+body {
+ background-color: var(--surface-1);
+ border: 0;
+ box-sizing: border-box;
+ color: var(--ink-1);
+ fill: var(--ink-1);
+ font-family: var(--font-family);
+ font-size: var(--font-size);
+ line-height: 1.5;
+ margin: 0;
+ padding: 0;
+ }
+a {
+ color: var(--link-ink);
+ fill: var(--link-ink);
+ }
+a:hover {
+ color: var(--link-hover-ink);
+ fill: var(--link-hover-ink);
+ }
+code, .code {
+ background-color: var(--surface-2);
+ font-family: monospace;
+ font-size: var(--monospace-size);
+ padding: 2px 4px;
+ }
+hr {
+ border: 0;
+ border-top: 1px solid var(--surface-2);
+ margin: 1em 0;
+ }
+textarea {
+ font-size: 90%;
+ }
+button {
+ align-items: center;
+ appearance: none;
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ border: 0;
+ border-radius: var(--button-border-radius);
+ background-color: var(--button-surface);
+ color: var(--button-ink);
+ display: inline-flex;
+ fill: var(--button-ink);
+ font-size: max(calc(var(--font-size) * 0.875), 14px);
+ justify-content: center;
+ min-height: 36px;
+ padding: 0 var(--font-size);
+ position: relative;
+ vertical-align: middle;
+ }
+button.vflex {
+ height: 100%;
+ min-height: unset;
+ padding-bottom: 0;
+ padding-top: 0;
+ }
+button > .hover {
+ background-color: var(--elevation-up-surface);
+ border-radius: var(--button-border-radius);
+ height: 100%;
+ left: 0;
+ opacity: 0;
+ pointer-events: none;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ z-index: 100;
+ }
+button:not(.disabled):not([disabled]):hover > .hover {
+ opacity: var(--elevation-up1-opacity);
+ }
+button.notext:not(.disabled):not([disabled]):hover > .hover {
+ opacity: var(--elevation-up2-opacity);
+ }
+button.active {
+ }
+button.disabled,
+button[disabled] {
+ background-color: var(--button-disabled-surface);
+ color: var(--button-ink);
+ fill: var(--button-ink);
+ filter: var(--button-disabled-filter);
+ pointer-events: none;
+ }
+button.preferred:not(.disabled):not([disabled]) {
+ background-color: var(--button-preferred-surface);
+ color: var(--button-preferred-ink);
+ fill: var(--button-preferred-ink);
+ }
+button.preferred:not(.disabled):not([disabled]):hover > .hover {
+ background-color: var(--elevation-down-surface);
+ opacity: var(--elevation-down1-opacity);
+ }
+button.iconified.notext {
+ background-color: transparent;
+ }
+button.iconified > .fa-icon {
+ font-size: 120%;
+ padding-left: 0;
+ padding-right: 0;
+ }
+button.iconified > .fa-icon + [data-i18n] {
+ padding-right: 0;
+ padding-left: 0.4em;
+ }
+body[dir="rtl"] button.iconified > .fa-icon + [data-i18n] {
+ padding-right: 0.4em;
+ padding-left: 0;
+ }
+label {
+ align-items: center;
+ display: inline-flex;
+ position: relative;
+ }
+section.notice {
+ background-color: var(--notice-surface);
+ box-shadow: var(--notice-surface-shadow);
+ color: var(--notice-ink);
+ }
+:root:not(.classic) section.notice a {
+ color: var(--surface-2);
+ }
+
+/**
+ Checkbox design borrowed from:
+ - https://material.io/components/selection-controls
+ Motivation:
+ - To comply with design suggestions to make uBO comply with
+ Firefox Preview design guidelines.
+ - To have a single checkbox design across all platforms.
+*/
+.checkbox {
+ box-sizing: border-box;
+ display: inline-flex;
+ flex-shrink: 0;
+ height: var(--checkbox-size);
+ margin: 0;
+ margin-inline-end: var(--checkbox-margin-end);
+ -webkit-margin-end: var(--checkbox-margin-end);
+ position: relative;
+ width: var(--checkbox-size);
+ }
+label:hover .checkbox:not([disabled]) {
+ background-color: var(--surface-2);
+ }
+.checkbox > input[type="checkbox"] {
+ box-sizing: border-box;
+ height: 100%;
+ margin: 0;
+ min-width: var(--checkbox-size);
+ opacity: 0;
+ position: absolute;
+ width: 100%;
+ }
+.checkbox > input[type="checkbox"] + svg {
+ background-color: transparent;
+ border: 2px solid var(--checkbox-ink);
+ border-radius: 2px;
+ box-sizing: border-box;
+ fill: none;
+ height: 100%;
+ pointer-events: none;
+ position: absolute;
+ stroke: none;
+ stroke-width: 3.12px;
+ width: 100%;
+ }
+.checkbox > input[type="checkbox"]:checked + svg {
+ background-color: var(--checkbox-checked-ink);
+ border-color: var(--checkbox-checked-ink);
+ stroke: var(--surface-1);
+ }
+.checkbox[disabled],
+.checkbox[disabled] ~ span {
+ filter: var(--checkbox-disabled-filter);
+ }
+.checkbox.partial > input[type="checkbox"]:checked + svg {
+ background-color: var(--surface-1);
+ border-color: var(--checkbox-checked-ink);
+ stroke: var(--checkbox-checked-ink);
+ }
+
+.radio {
+ --margin-end: calc(var(--font-size) * 0.75);
+ box-sizing: border-box;
+ display: inline-flex;
+ flex-shrink: 0;
+ height: calc(var(--checkbox-size) + 2px);
+ margin: 0;
+ margin-inline-end: var(--margin-end);
+ -webkit-margin-end: var(--margin-end);
+ position: relative;
+ width: calc(var(--checkbox-size) + 2px);
+ }
+.radio > input[type="radio"] {
+ box-sizing: border-box;
+ height: 100%;
+ margin: 0;
+ min-width: var(--checkbox-size);
+ opacity: 0;
+ position: absolute;
+ width: 100%;
+ }
+.radio > input[type="radio"] + svg {
+ background-color: transparent;
+ box-sizing: border-box;
+ height: 100%;
+ pointer-events: none;
+ position: absolute;
+ width: 100%;
+ }
+.radio > input[type="radio"] + svg > path {
+ fill: var(--checkbox-ink);
+ }
+.radio > input[type="radio"] + svg > circle {
+ fill: transparent;
+ }
+label:hover .radio > input[type="radio"]:not(:checked) + svg > circle {
+ fill: var(--surface-3);
+ }
+.radio > input[type="radio"]:checked + svg > path,
+.radio > input[type="radio"]:checked + svg > circle {
+ fill: var(--checkbox-checked-ink);
+ }
+
+select {
+ padding: 2px;
+ }
+
+.hidden {
+ display: none;
+ height: 0;
+ visibility: hidden;
+ width: 0;
+ }
+.subtil {
+ color: var(--subtil-ink);
+ cursor: default;
+ opacity: 66%;
+ }
+.fieldset {
+ margin: var(--font-size);
+ }
+.fieldset-header {
+ color: var(--fieldset-header-ink);
+ font-size: 14px;
+ font-weight: 600;
+ letter-spacing: 0.5px;
+ }
+.ul {
+ margin: 1em 0;
+ }
+.li {
+ align-items: center;
+ display: flex;
+ margin: calc(var(--font-size) * 0.75) 0;
+ }
+.liul {
+ margin: 0.5em 0;
+ margin-inline-start: 2em;
+ -webkit-margin-start: 2em;
+ }
+@media (max-width: 640px) {
+ button.iconified > .fa-icon {
+ font-size: 1.2rem;
+ padding: 0;
+ }
+ button.iconified > [data-i18n] {
+ display: none;
+ }
+ }
+
+.countryFlag {
+ height: var(--font-size);
+ position: relative;
+ top: calc(var(--font-size) / 7);
+ max-width: calc(var(--font-size) * 1.5);
+ }
+
+.logo {
+ align-items: center;
+ display: inline-flex;
+ padding: 0 0.5em;
+ width: 1.25em;
+ }
+.logo > img {
+ width: 100%;
+ }
+
+/* high dpi devices */
+:root.hidpi button {
+ font-family: Metropolis, sans-serif;
+ font-weight: 600;
+ letter-spacing: 0.5px;
+ }
+:root.hidpi .fieldset-header {
+ font-family: Metropolis, sans-serif;
+ }
+
+/* touch-screen devices */
+:root.mobile label {
+ flex-grow: 1
+ }
diff --git a/src/css/dashboard-common.css b/src/css/dashboard-common.css
new file mode 100644
index 0000000..261aa9a
--- /dev/null
+++ b/src/css/dashboard-common.css
@@ -0,0 +1,55 @@
+body > div.body {
+ padding: 0 0.5em;
+ }
+h2, h3 {
+ margin: 1em 0;
+ }
+h2 {
+ font-size: 18px;
+ }
+h3 {
+ font-size: 16px;
+ }
+a {
+ text-decoration: none;
+ }
+.fa-icon.info {
+ color: var(--info0-ink);
+ fill: var(--info0-ink);
+ font-size: 115%;
+ }
+.fa-icon.info:hover {
+ transform: scale(1.25);
+ }
+.fa-icon.info.important {
+ color: var(--info2-ink);
+ fill: var(--info2-ink);
+ }
+.info.very-important {
+ color: var(--info3-ink);
+ fill: var(--info3-ink);
+ }
+input[type="number"] {
+ width: 5em;
+ }
+@media (max-height: 640px), (max-height: 800px) and (max-width: 480px) {
+ .body > p,
+ .body > ul {
+ margin: 0.5em 0;
+ }
+ .vverbose {
+ display: none !important;
+ }
+ }
+/**
+ On mobile device, the on-screen keyboard may take up
+ so much space that it overlaps the content being edited.
+ The rule below makes it possible to scroll the edited
+ content within view.
+*/
+:root.mobile {
+ overflow: auto;
+ }
+:root.mobile body {
+ min-height: 600px;
+ }
diff --git a/src/css/dashboard.css b/src/css/dashboard.css
new file mode 100644
index 0000000..ba02d97
--- /dev/null
+++ b/src/css/dashboard.css
@@ -0,0 +1,115 @@
+html, body {
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ justify-content: stretch;
+ overflow: hidden;
+ position: relative;
+ width: 100vw;
+ }
+body.notReady {
+ display: none;
+ }
+#dashboard-nav {
+ border: 0;
+ border-bottom: 1px solid var(--border-1);
+ display: flex;
+ flex-shrink: 0;
+ flex-wrap: wrap;
+ overflow-x: hidden;
+ padding: 0;
+ position: sticky;
+ top: 0;
+ width: 100%;
+ z-index: 10;
+ }
+.tabButton {
+ background-color: transparent;
+ border: 0;
+ border-bottom: 3px solid transparent;
+ border-radius: 0;
+ color: var(--dashboard-tab-ink);
+ fill: var(--dashboard-tab-ink);
+ font-family: var(--font-family);
+ font-size: var(--font-size);
+ padding: 0.7em 1.4em calc(0.7em - 3px);
+ text-decoration: none;
+ white-space: nowrap;
+ }
+.tabButton:focus {
+ outline: 0;
+ }
+/*
+ * TODO: support keyboard-driven navigation
+ *
+.tabButton:not(:active):focus {
+ background-color: var(--dashboard-tab-focus-surface);
+ }
+ */
+.tabButton.selected {
+ background-color: var(--dashboard-tab-active-surface);
+ border-bottom: 3px solid var(--dashboard-tab-active-ink);
+ color: var(--dashboard-tab-active-ink);
+ fill: var(--dashboard-tab-active-ink);
+ }
+iframe {
+ background-color: transparent;
+ border: 0;
+ flex-grow: 1;
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ }
+#unsavedWarning {
+ display: none;
+ left: 0;
+ position: absolute;
+ width: 100%;
+ z-index: 20;
+ }
+#unsavedWarning.on {
+ display: initial;
+ }
+#unsavedWarning > div:first-of-type {
+ padding: 0.5em;
+ }
+#unsavedWarning > div:last-of-type {
+ height: 100vh;
+ position: absolute;
+ width: 100vw;
+ }
+
+body .tabButton[data-pane="no-dashboard.html"] {
+ display: none;
+ }
+body.noDashboard #dashboard-nav {
+ display: none;
+ }
+
+/* high dpi devices */
+:root.hidpi .tabButton {
+ font-family: Metropolis, sans-serif;
+ font-weight: 600;
+ letter-spacing: 0.5px;
+ }
+
+/* hover-able devices */
+:root.desktop .tabButton {
+ cursor: default;
+ }
+:root.desktop .tabButton:not(.selected) {
+ cursor: pointer;
+ }
+:root.desktop .tabButton:not(.selected):hover {
+ background-color: var(--dashboard-tab-hover-surface);
+ border-bottom-color: var(--dashboard-tab-hover-border);
+ }
+
+/* touch-screen devices */
+:root.mobile #dashboard-nav {
+ flex-wrap: nowrap;
+ overflow-x: auto;
+ }
+:root.mobile #dashboard-nav .logo {
+ display: none;
+ }
diff --git a/src/css/devtools.css b/src/css/devtools.css
new file mode 100644
index 0000000..425aac4
--- /dev/null
+++ b/src/css/devtools.css
@@ -0,0 +1,22 @@
+html {
+ height: 100vh;
+ overflow: hidden;
+ width: 100vw;
+ }
+body {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ justify-content: stretch;
+ overflow: hidden;
+ width: 100%;
+ }
+.body {
+ flex-shrink: 0;
+ }
+.codeMirrorContainer {
+ flex-grow: 1;
+ }
+#console {
+ text-align: left;
+ }
diff --git a/src/css/document-blocked.css b/src/css/document-blocked.css
new file mode 100644
index 0000000..25dd204
--- /dev/null
+++ b/src/css/document-blocked.css
@@ -0,0 +1,146 @@
+/**
+ uBlock Origin - a browser extension to block requests.
+ Copyright (C) 2018-present Raymond Hill
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see {http://www.gnu.org/licenses/}.
+
+ Home: https://github.com/gorhill/uBlock
+*/
+
+body {
+ display: flex;
+ padding: var(--default-gap-xxlarge) var(--default-gap-small);
+ justify-content: center;
+ }
+:root.mobile body {
+ padding: var(--default-gap-small);
+ }
+
+#rootContainer {
+ width: min(100vw, 640px);
+ }
+#rootContainer > * {
+ margin: 0 0 var(--default-gap-xxlarge) 0;
+ }
+
+a {
+ text-decoration: none;
+ }
+.code {
+ font-size: 13px;
+ word-break: break-all;
+ }
+#warningSign {
+ width: 100%;
+ }
+#warningSign > a {
+ font-size: 96px;
+ }
+#theURL {
+ color: var(--ink-2);
+ padding: 0;
+ }
+#theURL > * {
+ margin: 0;
+ }
+#theURL > p {
+ position: relative;
+ z-index: 10;
+ }
+#theURL #toggleParse {
+ background-color: transparent;
+ top: 100%;
+ box-sizing: border-box;
+ color: var(--ink-3);
+ fill: var(--ink-3);
+ cursor: pointer;
+ font-size: 1.2rem;
+ padding: var(--default-gap-xxsmall);
+ position: absolute;
+ transform: translate(0, -50%);
+ }
+#theURL:not(.collapsed) #toggleParse > span:first-of-type {
+ display: none;
+ }
+#theURL.collapsed #toggleParse > span:last-of-type {
+ display: none;
+ }
+body[dir="ltr"] #toggleParse {
+ right: 0;
+ }
+body[dir="rtl"] #toggleParse {
+ left: 0;
+ }
+#theURL > p:hover #toggleParse {
+ transform: translate(0, -50%) scale(1.15);
+ }
+#parsed {
+ background-color: var(--surface-1);
+ border: 4px solid var(--surface-2);
+ font-size: small;
+ overflow-x: auto;
+ padding: var(--default-gap-xxsmall);
+ text-align: initial;
+ text-overflow: ellipsis;
+ }
+#theURL.collapsed > #parsed {
+ display: none;
+ }
+#parsed ul, #parsed li {
+ list-style-type: none;
+ }
+#parsed li {
+ white-space: nowrap;
+ }
+#parsed span {
+ display: inline-block;
+ }
+#parsed span:first-of-type {
+ font-weight: bold;
+ }
+
+#whyex a {
+ white-space: nowrap;
+}
+#whyex ul {
+ display: flex;
+ flex-direction: column;
+ margin: 0;
+ padding-inline-start: var(--default-gap-xsmall);
+ }
+
+#actionContainer {
+ display: flex;
+ justify-content: space-between;
+ }
+:root.mobile #actionContainer {
+ justify-content: center;
+ display: flex;
+ flex-direction: column;
+ }
+#actionContainer > button {
+ margin-bottom: 2rem
+ }
+
+.filterList {
+ display: flex;
+}
+.filterList .filterListSupport[href=""] {
+ display: none;
+ }
+
+/* Small-screen devices */
+:root.mobile button {
+ width: 100%;
+ }
diff --git a/src/css/dom-inspector.css b/src/css/dom-inspector.css
new file mode 100644
index 0000000..71ba348
--- /dev/null
+++ b/src/css/dom-inspector.css
@@ -0,0 +1,40 @@
+html#ublock0-inspector,
+#ublock0-inspector body {
+ background: transparent;
+ box-sizing: border-box;
+ height: 100vh;
+ margin: 0;
+ overflow: hidden;
+ width: 100vw;
+}
+#ublock0-inspector :focus {
+ outline: none;
+}
+#ublock0-inspector svg {
+ box-sizing: border-box;
+ height: 100%;
+ left: 0;
+ pointer-events: none;
+ position: fixed;
+ top: 0;
+ width: 100%;
+}
+#ublock0-inspector svg > path {
+ stroke-width: 1px;
+ }
+#ublock0-inspector svg > path:nth-of-type(1) {
+ fill: rgba(255,0,0,0.2);
+ stroke: #F00;
+}
+#ublock0-inspector svg > path:nth-of-type(2) {
+ fill: rgba(0,255,0,0.2);
+ stroke: #0F0;
+}
+#ublock0-inspector svg > path:nth-of-type(3) {
+ fill: rgba(255,0,0,0.2);
+ stroke: #F00;
+}
+#ublock0-inspector svg > path:nth-of-type(4) {
+ fill: rgba(0,0,255,0.1);
+ stroke: #00F;
+}
diff --git a/src/css/dyna-rules.css b/src/css/dyna-rules.css
new file mode 100644
index 0000000..35e0f8c
--- /dev/null
+++ b/src/css/dyna-rules.css
@@ -0,0 +1,79 @@
+html {
+ height: 100vh;
+ overflow: hidden;
+ width: 100vw;
+ }
+body {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ justify-content: stretch;
+ overflow: hidden;
+ width: 100%;
+ }
+.body {
+ flex-shrink: 0;
+ }
+#diff {
+ border: 0;
+ white-space: nowrap;
+}
+#diff .tools > * {
+ margin-bottom: 1em;
+ }
+#diff .ruleActions {
+ border: 0;
+ box-sizing: border-box;
+ display: inline-block;
+ padding: 0;
+ text-align: center;
+ vertical-align: top;
+ width: 50%;
+ white-space: nowrap;
+ }
+#diff .ruleActions .fieldset-header {
+ margin: 0.5em 0;
+ }
+
+#ruleFilter {
+ align-items: center;
+ background-color: var(--surface-2);
+ direction: ltr;
+ display: flex;
+ justify-content: center;
+ padding: 0.5em 0;
+ }
+#ruleFilter #diffCollapse {
+ padding: 0 0.5em;
+ font-size: 150%;
+ }
+#ruleFilter #diffCollapse.active {
+ transform: scale(1, -1);
+ }
+
+.codeMirrorContainer {
+ flex-grow: 1;
+ }
+.codeMirrorContainer .CodeMirror {
+ background-color: var(--surface-1);
+ }
+.CodeMirror-merge, .CodeMirror-merge-pane, .CodeMirror-merge .CodeMirror {
+ box-sizing: border-box;
+ height: 100%;
+ }
+body.editing .CodeMirror-merge-copy,
+body.editing .CodeMirror-merge-copy-reverse {
+ display: none;
+ }
+body.editing .CodeMirror-merge-editor .CodeMirror {
+ background-color: var(--surface-0);
+ }
+body[dir="rtl"] .CodeMirror-merge-pane-rightmost {
+ right: unset;
+ left: 0;
+}
+
+/* mobile devices */
+:root.mobile #diff .tools {
+ overflow: auto;
+ }
diff --git a/src/css/epicker-ui.css b/src/css/epicker-ui.css
new file mode 100644
index 0000000..d09e1ef
--- /dev/null
+++ b/src/css/epicker-ui.css
@@ -0,0 +1,270 @@
+html#ublock0-epicker,
+#ublock0-epicker body {
+ background: transparent;
+ cursor: not-allowed;
+ height: 100vh;
+ margin: 0;
+ overflow: hidden;
+ width: 100vw;
+}
+#ublock0-epicker :focus {
+ outline: none;
+}
+#ublock0-epicker aside {
+ background-color: var(--surface-1);
+ border: 1px solid var(--border-2);
+ bottom: 2px;
+ box-sizing: border-box;
+ cursor: default;
+ display: none;
+ max-height: calc(100vh - 4px);
+ max-width: 36rem;
+ min-width: 24rem;
+ overflow-y: auto;
+ padding: 4px;
+ position: fixed;
+ right: 2px;
+ width: calc(40% - 2px);
+}
+/* https://github.com/uBlockOrigin/uBlock-issues/discussions/2114 */
+#ublock0-epicker aside {
+ min-width: min(24rem, 100vw - 4px);
+}
+#ublock0-epicker.paused:not(.zap) aside {
+ display: block;
+}
+#ublock0-epicker #toolbar {
+ display: flex;
+}
+#ublock0-epicker ul {
+ margin: 0.25em 0 0 0;
+}
+#ublock0-epicker.preview #preview {
+ background-color: var(--button-preferred-surface);
+ color: var(--button-preferred-ink);
+}
+#ublock0-epicker #move {
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAFElEQVQI12NgwAfKy8v/M5ANYLoBshgEyQo6H9UAAAAASUVORK5CYII=');
+ cursor: grab;
+ flex-grow: 1;
+ margin: 2px 4px;
+ opacity: 0.8;
+ }
+#ublock0-epicker aside.moving #move {
+ cursor: grabbing;
+}
+#ublock0-epicker section {
+ border: 0;
+ box-sizing: border-box;
+ display: inline-block;
+ width: 100%;
+}
+#ublock0-epicker section > div:first-child {
+ border: 1px solid var(--surface-3);
+ margin: 0;
+ position: relative;
+}
+#ublock0-epicker section.invalidFilter > div:first-child {
+ border-color: var(--error-surface);
+}
+#ublock0-epicker section .codeMirrorContainer {
+ border: none;
+ box-sizing: border-box;
+ height: 8em;
+ max-height: 50vh;
+ min-height: 1em;
+ padding: 2px;
+ width: 100%;
+ }
+.CodeMirror-lines,
+.CodeMirror pre {
+ padding: 0;
+ }
+
+#ublock0-epicker section .resultsetWidgets {
+ display: flex;
+ font-size: var(--font-size-smaller);
+ }
+#resultsetModifiers {
+ align-items: flex-end;
+ display: inline-flex;
+ flex-grow: 1;
+ justify-content: space-evenly;
+ }
+#resultsetModifiers.hide > * {
+ visibility: hidden;
+ }
+.resultsetModifier {
+ border: 0;
+ pointer-events: auto;
+ position: relative;
+ width: 40%;
+ }
+.resultsetModifier > span {
+ align-items: flex-end;
+ display: flex;
+ height: 100%;
+ pointer-events: none;
+ width: 100%;
+ }
+.resultsetModifier > span > span {
+ margin: 2px 0;
+ }
+.resultsetModifier > span > span:nth-of-type(1) {
+ background-color: var(--checkbox-checked-ink);
+ border-inline-end: 1px solid var(--surface-3);
+ display: inline-block;
+ flex-shrink: 0;
+ height: 6px;
+ }
+.resultsetModifier > span > span:nth-of-type(2) {
+ background-color: var(--checkbox-checked-ink);
+ clip-path: polygon(
+ calc(50% - 2px) 0%,
+ 0% calc(100% - 6px),
+ 0% 100%,
+ 100% 100%,
+ 100% calc(100% - 6px),
+ calc(50% + 2px) 0%
+ );
+ display: inline-block;
+ flex-shrink: 0;
+ height: 16px;
+ width: 16px;
+ }
+.resultsetModifier > span > span:nth-of-type(3) {
+ background-color: var(--surface-3);
+ border-inline-start: 1px solid var(--surface-3);
+ display: inline-block;
+ flex-grow: 1;
+ height: 6px;
+ }
+.resultsetModifier input {
+ border: 0;
+ height: 100%;
+ left: 0;
+ margin: 0;
+ opacity: 0;
+ padding: 0;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ }
+#resultsetCount {
+ align-items: center;
+ background-color: var(--surface-3);
+ color: var(--ink-1);
+ display: inline-flex;
+ justify-content: center;
+ min-width: 2.2em;
+ }
+#ublock0-epicker section.invalidFilter #resultsetCount {
+ background-color: var(--error-surface);
+ color: var(--ink-100);
+}
+#ublock0-epicker section > div:first-child + div {
+ direction: ltr;
+ margin: 2px 0;
+ text-align: right;
+}
+#ublock0-epicker ul {
+ padding: 0;
+ list-style-type: none;
+ text-align: left;
+ overflow: hidden;
+}
+#ublock0-epicker #candidateFilters {
+ max-height: 14em;
+ overflow-y: auto;
+}
+#ublock0-epicker #candidateFilters > li:first-of-type {
+ margin-bottom: 0.5em;
+}
+#ublock0-epicker .changeFilter > li > span:nth-of-type(1) {
+ font-weight: bold;
+}
+#ublock0-epicker .changeFilter > li > span:nth-of-type(2) {
+ font-size: smaller;
+ color: gray;
+}
+#ublock0-epicker #candidateFilters .changeFilter {
+ list-style-type: none;
+ margin: 0 0 0 1em;
+ overflow: hidden;
+ text-align: left;
+}
+#ublock0-epicker #candidateFilters .changeFilter li {
+ border: 1px solid transparent;
+ cursor: pointer;
+ direction: ltr;
+ font: 12px monospace;
+ white-space: nowrap;
+}
+#ublock0-epicker #candidateFilters .changeFilter li.active {
+ border: 1px dotted rgb(var(--blue-50));
+ }
+#ublock0-epicker #candidateFilters .changeFilter li:hover {
+ background-color: var(--surface-2);
+}
+
+/**
+ https://github.com/gorhill/uBlock/issues/3449
+ https://github.com/uBlockOrigin/uBlock-issues/issues/55
+**/
+@keyframes startDialog {
+ 0% { opacity: 1.0; }
+ 60% { opacity: 1.0; }
+ 100% { opacity: 0.1; }
+}
+#ublock0-epicker.paused aside {
+ opacity: 0.1;
+ visibility: visible;
+ z-index: 100;
+}
+#ublock0-epicker.paused:not(.show):not(.hide) aside:not(:hover) {
+ animation-duration: 1.6s;
+ animation-name: startDialog;
+ animation-timing-function: linear;
+}
+#ublock0-epicker.paused aside:hover {
+ opacity: 1;
+}
+#ublock0-epicker.paused.show aside {
+ opacity: 1;
+}
+#ublock0-epicker.paused.hide aside {
+ opacity: 0.1;
+}
+
+#ublock0-epicker svg {
+ cursor: crosshair;
+ box-sizing: border-box;
+ height: 100%;
+ left: 0;
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+#ublock0-epicker.paused svg {
+ cursor: not-allowed;
+}
+#ublock0-epicker svg > path:first-child {
+ fill: rgba(0,0,0,0.5);
+ fill-rule: evenodd;
+}
+#ublock0-epicker svg > path + path {
+ stroke: #F00;
+ stroke-width: 0.5px;
+ fill: rgba(255,63,63,0.20);
+}
+#ublock0-epicker.zap svg > path + path {
+ stroke: #FF0;
+ stroke-width: 0.5px;
+ fill: rgba(255,255,63,0.20);
+}
+#ublock0-epicker.preview svg > path {
+ fill: rgba(0,0,0,0.10);
+}
+#ublock0-epicker.preview svg > path + path {
+ stroke: none;
+}
diff --git a/src/css/fa-icons.css b/src/css/fa-icons.css
new file mode 100644
index 0000000..f6d517d
--- /dev/null
+++ b/src/css/fa-icons.css
@@ -0,0 +1,149 @@
+.fa-icon {
+ align-items: center;
+ background-color: transparent;
+ border: 0;
+ display: inline-flex;
+ justify-content: center;
+ margin: 0;
+ padding: 0 0.1em;
+ position: relative;
+ user-select: none;
+ vertical-align: text-bottom;
+ -webkit-user-select: none;
+ }
+.fa-icon > * {
+ pointer-events: none;
+ }
+/*
+.fa-icon.disabled,
+.fa-icon[disabled] {
+ color: var(--button-disabled-ink);
+ fill: var(--button-disabled-ink);
+ filter: var(--button-disabled-filter);
+ stroke: var(--button-disabled-ink);
+ pointer-events: none;
+ }
+*/
+.fa-icon > .fa-icon-badge,
+.fa-icon.disabled > .fa-icon-badge {
+ visibility: hidden;
+ }
+.fa-icon.fa-icon-badged > .fa-icon-badge {
+ bottom: -20%;
+ display: inline-block;
+ font: 60% sans-serif;
+ left: calc(100% - 0.2em);
+ position: absolute;
+ visibility: visible;
+ }
+.fa-icon.fa-icon-hflipped > svg {
+ transform: scale(-1, 1);
+ transform-origin: 50%;
+ }
+.fa-icon.fa-icon-vflipped > svg {
+ transform: scale(1, -1);
+ transform-origin: 50%;
+ }
+.fa-icon.fa-icon-rotright > svg {
+ transform: rotate(90deg);
+ transform-origin: 50%;
+ }
+.fa-icon.fa-icon-rotleft > svg {
+ transform: rotate(-90deg);
+ transform-origin: 50%;
+ }
+
+.fa-icon > svg {
+ height: 1em;
+ overflow: visible;
+ width: 1em;
+ }
+
+.fa-icon > .fa-icon_bar-chart {
+ width: calc(1em * 2048 / 1792);
+ }
+.fa-icon > .fa-icon_cloud-download,
+.fa-icon > .fa-icon_cloud-upload,
+.fa-icon > .fa-icon_cogs,
+.fa-icon > .fa-icon_eraser,
+.fa-icon > .fa-icon_film {
+ width: calc(1em * 1920 / 1792);
+ }
+.fa-icon > .fa-icon_code {
+ width: calc(1em * 1830 / 1792);
+ }
+.fa-icon > .fa-icon_exclamation-triangle {
+ width: calc(1em * 1794 / 1792);
+ }
+.fa-icon > .fa-icon_clipboard,
+.fa-icon > .fa-icon_comment-alt,
+.fa-icon > .fa-icon_external-link,
+.fa-icon > .fa-icon_eye-dropper,
+.fa-icon > .fa-icon_eye-open,
+.fa-icon > .fa-icon_eye-slash,
+.fa-icon > .fa-icon_files-o,
+.fa-icon > .fa-icon_list-alt {
+ width: calc(1em * 1792 / 1792);
+ }
+.fa-icon > .fa-icon_sun,
+.fa-icon > .fa-icon_sun-o {
+ width: calc(1em * 1708 / 1792);
+ }
+.fa-icon > .fa-icon_download-alt,
+.fa-icon > .fa-icon_font,
+.fa-icon > .fa-icon_search,
+.fa-icon > .fa-icon_spinner,
+.fa-icon > .fa-icon_unlink,
+.fa-icon > .fa-icon_upload-alt,
+.fa-icon > .fa-icon_zoom-in,
+.fa-icon > .fa-icon_zoom-out {
+ width: calc(1em * 1664 / 1792);
+ }
+.fa-icon > .fa-icon_magic {
+ width: calc(1em * 1637 / 1792);
+ }
+.fa-icon > .fa-icon_home {
+ width: calc(1em * 1612 / 1792);
+ }
+.fa-icon > .fa-icon_check {
+ width: calc(1em * 1550 / 1792);
+ }
+.fa-icon > .fa-icon_cog,
+.fa-icon > .fa-icon_clock-o,
+.fa-icon > .fa-icon_floppy-o,
+.fa-icon > .fa-icon_info-circle,
+.fa-icon > .fa-icon_pause-circle-o,
+.fa-icon > .fa-icon_play-circle-o,
+.fa-icon > .fa-icon_power-off,
+.fa-icon > .fa-icon_question-circle,
+.fa-icon > .fa-icon_refresh,
+.fa-icon > .fa-icon_save,
+.fa-icon > .fa-icon_sliders,
+.fa-icon > .fa-icon_undo {
+ width: calc(1em * 1536 / 1792);
+ }
+.fa-icon > .fa-icon_arrow-right {
+ width: calc(1em * 1472 / 1792);
+ }
+.fa-icon > .fa-icon_filter {
+ width: calc(1em * 1410 / 1792);
+ }
+.fa-icon > .fa-icon_plus,
+.fa-icon > .fa-icon_trash-o {
+ width: calc(1em * 1408 / 1792);
+ }
+.fa-icon > .fa-icon_times {
+ width: calc(1em * 1188 / 1792);
+ }
+.fa-icon > .fa-icon_angle-up,
+.fa-icon > .fa-icon_double-angle-up,
+.fa-icon > .fa-icon_lock,
+.fa-icon > .fa-icon_unlock-alt {
+ width: calc(1em * 1152 / 1792);
+ }
+.fa-icon > .fa-icon_double-angle-left {
+ width: calc(1em * 966 / 1792);
+ }
+.fa-icon > .fa-icon_bolt {
+ width: calc(1em * 896 / 1792);
+ }
diff --git a/src/css/fonts/Inter/Inter-Regular.woff2 b/src/css/fonts/Inter/Inter-Regular.woff2
new file mode 100644
index 0000000..d5ffd2a
--- /dev/null
+++ b/src/css/fonts/Inter/Inter-Regular.woff2
Binary files differ
diff --git a/src/css/fonts/Inter/Inter-SemiBold.woff2 b/src/css/fonts/Inter/Inter-SemiBold.woff2
new file mode 100644
index 0000000..df746af
--- /dev/null
+++ b/src/css/fonts/Inter/Inter-SemiBold.woff2
Binary files differ
diff --git a/src/css/fonts/Inter/LICENSE.txt b/src/css/fonts/Inter/LICENSE.txt
new file mode 100644
index 0000000..d688280
--- /dev/null
+++ b/src/css/fonts/Inter/LICENSE.txt
@@ -0,0 +1,93 @@
+Copyright (c) 2016-2020 The Inter Project Authors
+https://github.com/rsms/inter
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION AND CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/src/css/fonts/Metropolis/Metropolis-Regular.woff2 b/src/css/fonts/Metropolis/Metropolis-Regular.woff2
new file mode 100644
index 0000000..f50bf34
--- /dev/null
+++ b/src/css/fonts/Metropolis/Metropolis-Regular.woff2
Binary files differ
diff --git a/src/css/fonts/Metropolis/Metropolis-SemiBold.woff2 b/src/css/fonts/Metropolis/Metropolis-SemiBold.woff2
new file mode 100644
index 0000000..fad6dfd
--- /dev/null
+++ b/src/css/fonts/Metropolis/Metropolis-SemiBold.woff2
Binary files differ
diff --git a/src/css/fonts/Metropolis/README.md b/src/css/fonts/Metropolis/README.md
new file mode 100644
index 0000000..ce01464
--- /dev/null
+++ b/src/css/fonts/Metropolis/README.md
@@ -0,0 +1,25 @@
+# Metropolis
+
+A modern, geometric typeface. Influenced by other popular geometric, minimalist sans-serif typefaces of the new millennium. Designed for optimal readability at small point sizes while beautiful at large point sizes.
+
+![Metropolis](./Specimens/Metro-1.png)
+
+---
+
+![Metropolis](./Specimens/Metro-2.png)
+
+### Where am I?
+
+See [Documentation](./Documentation/Documentation.md).
+
+### The Unlicense
+
+Contributions welcome.
+
+### Contact
+
+Reachable via chris.m.simpson [at] icloud.com or tweet @ChrisMSimpson.
+
+### Support
+
+There is none. Oh, you meant support me? I dare you to click the sponsor button above.
diff --git a/src/css/fonts/Metropolis/UNLICENSE b/src/css/fonts/Metropolis/UNLICENSE
new file mode 100644
index 0000000..68a49da
--- /dev/null
+++ b/src/css/fonts/Metropolis/UNLICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
diff --git a/src/css/logger-ui-inspector.css b/src/css/logger-ui-inspector.css
new file mode 100644
index 0000000..975d90b
--- /dev/null
+++ b/src/css/logger-ui-inspector.css
@@ -0,0 +1,122 @@
+#domInspector {
+ display: none;
+ }
+#inspectors.dom #domInspector {
+ display: flex;
+ }
+#domInspector .permatoolbar .highlightMode.invert {
+ transform: rotate(180deg);
+ }
+#domInspector button.vExpandToggler > .fa-icon {
+ transform: scaleY(-1)
+ }
+#domInspector button.vCompactToggler > .fa-icon {
+ transform: scaleY(1)
+ }
+#domInspector .vscrollable {
+ overflow-x: auto;
+ }
+#domInspector > ul:first-of-type {
+ padding-left: 0.5em;
+ }
+#domInspector ul {
+ background-color: var(--surface-1);
+ margin: 0;
+ padding-left: 1em;
+ }
+#domInspector li {
+ list-style-type: none;
+ white-space: nowrap;
+ }
+#domInspector li.isCosmeticHide,
+#domInspector li.isCosmeticHide ul,
+#domInspector li.isCosmeticHide li {
+ background-color: var(--surface-2);
+ }
+#domInspector li > * {
+ display: inline-block;
+ line-height: 1.2;
+ margin-right: 1em;
+ vertical-align: middle;
+ }
+#domInspector li > span {
+ color: #aaa;
+ }
+#domInspector li > span:first-child {
+ color: var(--ink-1);
+ cursor: default;
+ font-size: 1rem;
+ margin-right: 0;
+ opacity: 0.5;
+ padding: 0 4px 0 1px;
+ visibility: hidden;
+ }
+#domInspector li > span:first-child:hover {
+ opacity: 1;
+ }
+#domInspector li > *:last-child {
+ margin-right: 0;
+ }
+#domInspector li > span:first-child:before {
+ content: '\a0';
+ }
+#domInspector li.branch > span:first-child:before {
+ content: '\25b8';
+ visibility: visible;
+ }
+#domInspector li.branch.show > span:first-child:before {
+ content: '\25be';
+ }
+#domInspector li.branch.hasCosmeticHide > span:first-child:before {
+ color: red;
+ }
+#domInspector li > code {
+ cursor: pointer;
+ font-family: monospace;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+#domInspector li > code.off {
+ text-decoration: line-through;
+ }
+#domInspector li > code.filter {
+ color: var(--cm-negative);
+ }
+
+#domInspector li > ul {
+ display: block;
+ }
+#domInspector li:not(.hasCosmeticHide):not(.isCosmeticHide):not(.show) > ul {
+ display: none;
+ }
+
+#domInspector li:not(.hasCosmeticHide):not(.isCosmeticHide):not(.show) {
+ display: none;
+ }
+#domInspector #domTree > li {
+ display: block;
+ }
+#domInspector:not(.vExpanded) ul {
+ display: block;
+ }
+#domInspector li > ul > li:not(.hasCosmeticHide):not(.isCosmeticHide) {
+ display: none;
+ }
+#domInspector li.show > ul > li:not(.hasCosmeticHide):not(.isCosmeticHide) {
+ display: block;
+ }
+#domInspector li:not(.hasCosmeticHide):not(.isCosmeticHide) {
+ display: block;
+ }
+#domInspector.hCompact li > code:first-of-type {
+ max-width: 12em;
+ }
+
+#cosmeticFilteringDialog .dialog {
+ text-align: center;
+ }
+#cosmeticFilteringDialog .dialog textarea {
+ height: 40vh;
+ white-space: pre;
+ word-wrap: normal;
+ }
diff --git a/src/css/logger-ui.css b/src/css/logger-ui.css
new file mode 100644
index 0000000..8e5065c
--- /dev/null
+++ b/src/css/logger-ui.css
@@ -0,0 +1,985 @@
+body {
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ overflow: hidden;
+ width: 100vw;
+ }
+textarea {
+ box-sizing: border-box;
+ direction: ltr;
+ min-height: 6rem;
+ resize: vertical;
+ width: 100%;
+ }
+.permatoolbar {
+ background-color: var(--surface-1);
+ border: 0;
+ box-sizing: border-box;
+ display: flex;
+ flex-shrink: 0;
+ font-size: 120%;
+ justify-content: space-between;
+ margin: 0;
+ padding: 0.25em;
+ }
+.permatoolbar > div {
+ display: flex;
+ }
+.permatoolbar button.iconified {
+ padding-left: var(--default-gap-xsmall);
+ padding-right: var(--default-gap-xsmall);
+ }
+.permatoolbar button.active {
+ fill: rgb(var(--primary-50));
+ }
+.permatoolbar button > .fa-icon {
+ font-size: 180%;
+ }
+#pageSelector {
+ min-width: 10em;
+ padding: 0.25em 0;
+ width: 50vw;
+ }
+#showpopup {
+ display: inline-flex;
+ align-items: center;
+ }
+#showpopup img {
+ filter: grayscale(100%);
+ height: auto;
+ width: 1em;
+ }
+#info {
+ fill: #ccc;
+ }
+#info:hover {
+ fill: #000;
+ }
+
+/*
+ https://github.com/gorhill/uBlock/issues/3293
+ => https://devhints.io/css-system-font-stack
+*/
+#inspectors {
+ flex-grow: 1;
+ font-family: "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
+ position: relative;
+ }
+.inspector {
+ border-top: 1px solid #ccc;
+ display: flex;
+ flex-direction: column;
+ }
+.vscrollable {
+ direction: ltr;
+ flex-grow: 1;
+ font-size: var(--font-size-smaller);
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+#domInspector button.vExpandToggler > .fa-icon {
+ transform: scaleY(1)
+ }
+.inspector:not(.vExpanded) button.vCompactToggler > .fa-icon {
+ transform: scaleY(-1)
+ }
+.hCompact button.hCompactToggler > .fa-icon {
+ transform: scaleX(-1)
+ }
+
+#inspectors.dom #netInspector {
+ display: none;
+ }
+
+#netInspector #pause > .fa-icon[data-i18n-title="loggerUnpauseTip"] {
+ display: none;
+}
+#netInspector.paused #pause > .fa-icon[data-i18n-title="loggerPauseTip"] {
+ display: none;
+}
+#netInspector.paused #pause > .fa-icon[data-i18n-title="loggerUnpauseTip"] {
+ display: inline-flex;
+ fill: #5F9EA0;
+}
+#netInspector #filterExprGroup {
+ display: flex;
+ margin: 0 1em;
+ position: relative;
+ }
+#netInspector #filterButton {
+ opacity: 0.25;
+ }
+#netInspector.f #filterButton {
+ opacity: 1;
+ }
+#netInspector #filterInput {
+ border: 1px solid gray;
+ display: inline-flex;
+ }
+#netInspector #filterInput > input {
+ border: 0;
+ min-width: 16em;
+ }
+#netInspector #filterExprButton {
+ transform: scaleY(-1);
+ }
+#netInspector #filterExprButton:hover {
+ background-color: transparent;
+ }
+#netInspector #filterExprButton.expanded {
+ transform: scaleY(1);
+ }
+#netInspector #filterExprPicker {
+ background-color: var(--surface-0);
+ border: 1px solid gray;
+ display: none;
+ position: absolute;
+ flex-direction: column;
+ font-size: small;
+ top: 100%;
+ z-index: 100;
+ }
+body[dir="ltr"] #netInspector #filterExprPicker {
+ right: 0;
+ }
+body[dir="rtl"] #netInspector #filterExprPicker {
+ left: 0;
+ }
+
+#netInspector #filterExprGroup:hover #filterExprButton.expanded ~ #filterExprPicker {
+ display: flex;
+ }
+#netInspector #filterExprPicker > div {
+ border: 1px dotted #ddd;
+ border-left: 0;
+ border-right: 0;
+ display: flex;
+ padding: 0.5em;
+ }
+#netInspector #filterExprPicker > div:first-of-type {
+ border-top: 0;
+ }
+#netInspector #filterExprPicker > div:last-of-type {
+ border-bottom: 0;
+ }
+#netInspector #filterExprPicker div {
+ display: flex;
+ }
+#netInspector #filterExprPicker span[data-filtex] {
+ align-items: center;
+ border: 1px solid transparent;
+ cursor: pointer;
+ display: inline-flex;
+ margin: 0 0.5em 0 0;
+ padding: 0.25em;
+ white-space: nowrap;
+ }
+#netInspector #filterExprPicker span[data-filtex]:last-of-type {
+ margin: 0;
+ }
+#netInspector #filterExprPicker span[data-filtex]:hover {
+ background-color: rgb(var(--primary-70) / 25%);
+ border: 1px solid rgb(var(--primary-70));
+ }
+#netInspector #filterExprPicker span.on[data-filtex],
+#filterExprButton.active {
+ background-color: rgb(var(--primary-70) / 40%);
+ }
+#netInspector #filterExprPicker span.on[data-filtex] {
+ border: 1px solid rgb(var(--primary-70));
+ }
+
+#netInspector .vscrollable {
+ overflow: hidden;
+ }
+#vwRenderer {
+ box-sizing: border-box;
+ height: 100%;
+ overflow: hidden;
+ position: relative;
+ width: 100%;
+ }
+#vwRenderer #vwScroller {
+ height: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+ position: absolute;
+ width: 100%;
+ }
+#vwRenderer #vwScroller #vwVirtualContent {
+ overflow: hidden;
+ }
+#vwRenderer #vwContent {
+ left: 0;
+ overflow: hidden;
+ position: absolute;
+ width: 100%;
+ }
+#vwRenderer .logEntry {
+ display: block;
+ left: 0;
+ overflow: hidden;
+ position: absolute;
+ width: 100%;
+ }
+#vwRenderer .logEntry:empty {
+ display: none;
+ }
+#vwRenderer .logEntry > div {
+ height: 100%;
+ white-space: nowrap;
+ }
+#vwRenderer .logEntry > div[data-status="1"],
+.netFilteringDialog > .panes > .details > div[data-status="1"] {
+ background-color: rgb(var(--popup-cell-block-surface-rgb) / 50%);
+ }
+#vwRenderer .logEntry > div[data-status="1"][data-modifier],
+.netFilteringDialog > .panes > .details > div[data-status="1"][data-modifier] {
+ background-color: var(--logger-modified-surface);
+ }
+#vwRenderer .logEntry > div[data-status="3"] {
+ background-color: rgba(108, 108, 108, 0.1);
+ }
+:root.colorBlind #vwRenderer .logEntry > div[data-status="3"] {
+ background-color: rgba(96, 96, 96, 0.1);
+ }
+#vwRenderer .logEntry > div[data-status="2"],
+.netFilteringDialog > .panes > .details > div[data-status="2"] {
+ background-color: rgb(var(--popup-cell-allow-surface-rgb) / 50%);
+ }
+#vwRenderer .logEntry > div[data-tabid="-1"] {
+ text-shadow: 0 0.2em 0.4em #aaa;
+ }
+#vwRenderer .logEntry > div.extendedRealm,
+#vwRenderer .logEntry > div.redirect {
+ background-color: var(--logger-redirected-surface);
+ }
+#vwRenderer .logEntry > div.extendedRealm.scriptlet {
+ background-color: var(--logger-scriptlet-surface);
+ }
+:root.colorBlind #vwRenderer .logEntry > div.extendedRealm,
+:root.colorBlind #vwRenderer .logEntry > div.redirect {
+ background-color: rgba(0, 19, 110, 0.1);
+ }
+#vwRenderer .logEntry > div[data-aliasid] {
+ color: var(--popup-cell-cname-ink);
+ }
+#vwRenderer .logEntry > div[data-type="tabLoad"] {
+ background-color: #666;
+ color: white;
+ }
+#vwRenderer .logEntry > div[data-type="error"] {
+ color: var(--sf-error-ink);
+ }
+#vwRenderer .logEntry > div[data-type="info"] {
+ color: var(--sf-def-ink);
+ }
+#vwRenderer .logEntry > div.voided {
+ opacity: 0.5;
+ }
+#vwRenderer .logEntry > div.voided:hover {
+ opacity: 0.7;
+ }
+
+#vwRenderer .logEntry > div > span {
+ border: 1px dotted var(--border-1);
+ border-top: 0;
+ border-right: 0;
+ box-sizing: border-box;
+ display: inline-block;
+ height: 100%;
+ overflow: hidden;
+ padding: 0.2em;
+ vertical-align: middle;
+ white-space: nowrap;
+ word-break: break-all;
+ }
+#vwRenderer .logEntry > div.canDetails:hover > span {
+ background-color: rgba(0,0,0,0.04);
+ }
+body[dir="ltr"] #vwRenderer .logEntry > div > span:first-child {
+ border-left: 0;
+ }
+body[dir="rtl"] #vwRenderer .logEntry > div > span:first-child {
+ border-right: 0;
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(1) {
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(2) {
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(2) {
+ text-overflow: ellipsis;
+ }
+#vwRenderer .logEntry > div.messageRealm > span:nth-of-type(2) ~ span {
+ display: none;
+ }
+.vExpanded #vwRenderer #vwContent .logEntry > div > span:nth-of-type(2) {
+ overflow-y: auto;
+ white-space: pre-line;
+ }
+#vwRenderer .logEntry > div.messageRealm[data-type="tabLoad"] > span:nth-of-type(2) {
+ text-align: center;
+ }
+#vwRenderer .logEntry > div.extendedRealm > span:nth-of-type(2) > span:first-of-type {
+ display: none;
+ }
+#vwRenderer .logEntry > div.extendedRealm > span:nth-of-type(2) > span:last-of-type {
+ pointer-events: none;
+ }
+#vwRenderer .logEntry > div.extendedRealm.isException > span:nth-of-type(2) > span:last-of-type {
+ text-decoration: line-through rgba(0,0,255,0.7);
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(3) {
+ font-family: monospace;
+ padding-left: 0.3em;
+ padding-right: 0.3em;
+ text-align: center;
+ }
+#vwRenderer .logEntry > div.canDetails:hover > span:not(:nth-of-type(4)):not(:nth-of-type(8)) {
+ background: rgba(0, 0, 255, 0.1);
+ cursor: zoom-in;
+ }
+#netInspector:not(.vExpanded) #vwRenderer .logEntry > div > span:nth-of-type(4) {
+ direction: rtl;
+ text-align: right;
+ unicode-bidi: plaintext;
+ }
+#vwRenderer #vwContent .logEntry > div > span:nth-of-type(4) {
+ text-overflow: ellipsis;
+ }
+.vExpanded #vwRenderer #vwContent .logEntry > div > span:nth-of-type(4) {
+ overflow-y: auto;
+ text-overflow: clip;
+ white-space: pre-line;
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(5) {
+ text-align: center;
+ }
+/* visual for tabless network requests */
+#vwRenderer .logEntry > div > span:nth-of-type(5) {
+ position: relative;
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(7) {
+ }
+#vwRenderer #vwContent .logEntry > div > span:nth-of-type(7) {
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(8) {
+ position: relative;
+ }
+#vwRenderer #vwContent .logEntry > div > span:nth-of-type(8) {
+ text-overflow: ellipsis;
+ }
+.vExpanded #vwRenderer #vwContent .logEntry > div > span:nth-of-type(8) {
+ overflow-y: auto;
+ white-space: pre-line;
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(8) b {
+ font-weight: bold;
+ }
+#vwRenderer .logEntry > div[data-status="1"] > span:nth-of-type(8) b,
+.netFilteringDialog > .panes > .details > div[data-status="1"] b {
+ background-color: rgb(var(--popup-cell-block-surface-rgb) / 100%);
+ }
+#vwRenderer .logEntry > div[data-status="1"][data-modifier] > span:nth-of-type(8) b,
+.netFilteringDialog > .panes > .details > div[data-status="1"][data-modifier] b {
+ background-color: var(--logger-modified-em-surface);
+ }
+#vwRenderer .logEntry > div[data-status="3"] > span:nth-of-type(8) b {
+ background-color: rgba(108, 108, 108, 0.2);
+ }
+:root.colorBlind #vwRenderer .logEntry > div[data-status="3"] > span:nth-of-type(8) b {
+ background-color: rgba(96, 96, 96, 0.2);
+ }
+#vwRenderer .logEntry > div[data-status="2"] > span:nth-of-type(8) b,
+.netFilteringDialog > .panes > .details > div[data-status="2"] b {
+ background-color: rgb(var(--popup-cell-allow-surface-rgb) / 100%);
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(8) a {
+ align-items: center;
+ background-color: dimgray;
+ color: white;
+ display: none;
+ height: 100%;
+ justify-content: center;
+ padding: 0 0.25em;
+ opacity: 0.4;
+ position: absolute;
+ right: 0;
+ text-decoration: none;
+ top: 0;
+ width: 2rem;
+ }
+#netInspector.vExpanded #vwRenderer .logEntry > div > span:nth-of-type(8) a {
+ bottom: 0px;
+ height: unset;
+ padding: 0.25em;
+ top: unset;
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(8) a::after {
+ content: '\2197';
+ }
+#vwRenderer .logEntry > div.networkRealm > span:nth-of-type(8):hover a {
+ display: inline-flex;
+ }
+#vwRenderer .logEntry > div > span:nth-of-type(8) a:hover {
+ opacity: 1;
+ }
+
+#vwRenderer #vwBottom {
+ background-color: #00F;
+ height: 0;
+ overflow: hidden;
+ width: 100%;
+ }
+#vwRenderer #vwLineSizer {
+ left: 0;
+ pointer-events: none;
+ position: absolute;
+ top: 0;
+ visibility: hidden;
+ width: 100%;
+ }
+
+#netInspector .entryTools {
+ background-color: var(--surface-0);
+ filter: drop-shadow(2px 4px 6px black);
+ max-width: 640px;
+ min-width: min(100%, 640px);
+ position: absolute;
+ }
+#netInspector .entryTools:empty {
+ display: none;
+ }
+#netInspector .entryTools .dialogControls {
+ display: flex;
+ justify-content: stretch;
+ }
+
+.closeButton {
+ stroke: var(--ink-1);
+ stroke-width: 3px;
+ width: 1.6em;
+ height: 1.6em;
+ bottom: calc(100% + 2px);
+ }
+body[dir="ltr"] .closeButton {
+ right: 0;
+ }
+body[dir="rtl"] .closeButton {
+ left: 0;
+ }
+.closeButton:hover {
+ background-color: var(--surface-2) !important;
+ }
+.closeButton > * {
+ pointer-events: none;
+ }
+.moveBand {
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAFElEQVQI12NgwAfKy8v/M5ANYLoBshgEyQo6H9UAAAAASUVORK5CYII=');
+ cursor: grab;
+ flex-grow: 1;
+ opacity: 0.5;
+ }
+.moving .moveBand {
+ cursor: grabbing;
+}
+
+#popupContainer {
+ background-color: var(--surface-1);
+ border: 1px solid gray;
+ bottom: 0;
+ display: none;
+ max-height: min(800px, calc(100vh - 2rem));
+ min-width: 360px;
+ overflow: hidden;
+ position: fixed;
+ right: 0;
+ z-index: 200;
+ }
+#inspectors.popupOn #popupContainer {
+ display: block;
+ }
+
+#modalOverlay {
+ align-items: center;
+ background-color: rgba(0, 0, 0, 0.5);
+ border: 0;
+ bottom: 0;
+ display: none;
+ justify-content: center;
+ left: 0;
+ margin: 0;
+ position: fixed;
+ right: 0;
+ top: 0;
+ z-index: 400;
+ }
+#modalOverlay.on {
+ display: flex;
+ }
+#modalOverlay > div {
+ position: relative;
+ }
+#modalOverlay .closeButton {
+ background-color: var(--surface-1);
+ position: absolute;
+ }
+
+#modalOverlayContainer {
+ background-color: var(--surface-1);
+ border: 0;
+ box-sizing: border-box;
+ padding: 1em;
+ max-height: 90vh;
+ overflow-y: auto;
+ width: 90vw;
+ }
+
+.netFilteringDialog {
+ font-size: var(--font-size-smaller);
+ }
+.netFilteringDialog a {
+ text-decoration: none;
+ }
+.netFilteringDialog select {
+ max-width: 50vw;
+ outline: none;
+ text-overflow: ellipsis;
+}
+.netFilteringDialog > .preview {
+ align-items: center;
+ /* http://lea.verou.me/css3patterns/ */
+ background-color: #aaa;
+ background-image:
+ linear-gradient(
+ 45deg,
+ #666 25%,
+ transparent 25%,
+ transparent 75%,
+ #666 75%,
+ #666
+ ),
+ linear-gradient(
+ 45deg,
+ #666 25%,
+ transparent 25%,
+ transparent 75%,
+ #666 75%,
+ #666
+ );
+ background-position:0 0, 9px 9px;
+ background-size: 18px 18px;
+ display: flex;
+ justify-content: center;
+ margin-bottom: 1em;
+ padding: 0.5em;
+ text-align: center;
+ }
+.netFilteringDialog > .preview > * {
+ max-width: 100%;
+ max-height: 20vh;
+ }
+.netFilteringDialog > .preview > span {
+ background-color: var(--surface-3);
+ cursor: pointer;
+ padding: 1em;
+ }
+
+.netFilteringDialog > .headers {
+ align-items: center;
+ border-bottom: 1px solid var(--border-4);
+ display: flex;
+ line-height: 2;
+ }
+.netFilteringDialog > .headers > .header {
+ border: 1px solid var(--border-2);
+ border-bottom: 1px solid var(--border-4);
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ color: var(--border-2);
+ cursor: pointer;
+ display: inline-block;
+ margin-inline-end: 4px;
+ padding: 0 1em;
+ position: relative;
+ top: 1px;
+ }
+.netFilteringDialog[data-pane="details"] > .headers > [data-pane="details"],
+.netFilteringDialog[data-pane="dynamic"] > .headers > [data-pane="dynamic"],
+.netFilteringDialog[data-pane="static"] > .headers > [data-pane="static"] {
+ background-color: var(--surface-0);
+ border-color: var(--border-4);
+ border-bottom: 1px solid transparent;
+ color: var(--ink-1);
+ }
+.netFilteringDialog > .headers > .tools {
+ bottom: 0;
+ display: flex;
+ height: 100%;
+ margin-inline-start: 2rem;
+ }
+.netFilteringDialog > .headers > .tools > span {
+ color: var(--ink-3);
+ fill: var(--ink-3);
+ cursor: pointer;
+ font-size: 1.5em;
+ padding: 0 0.25em;
+ text-align: center;
+ }
+.netFilteringDialog > .headers > .tools > span:hover {
+ color: var(--ink-1);
+ fill: var(--ink-1);
+ }
+.netFilteringDialog.extendedRealm > .headers > .dynamic,
+.netFilteringDialog.extendedRealm > .panes > .dynamic {
+ display: none;
+ }
+.netFilteringDialog.extendedRealm > .headers > .static,
+.netFilteringDialog.extendedRealm > .panes > .static {
+ display: none;
+ }
+.netFilteringDialog > div.panes {
+ overflow: hidden;
+ overflow-y: auto;
+ padding-top: 1em;
+ }
+.netFilteringDialog > div.panes > div {
+ display: none;
+ }
+.netFilteringDialog[data-pane="details"] > .panes > [data-pane="details"],
+.netFilteringDialog[data-pane="dynamic"] > .panes > [data-pane="dynamic"],
+.netFilteringDialog[data-pane="static"] > .panes > [data-pane="static"] {
+ display: flex;
+ flex-direction: column;
+ padding: 0 var(--default-gap-xsmall) var(--default-gap-xsmall) var(--default-gap-xsmall);
+ }
+.netFilteringDialog > .panes > .details > div {
+ align-items: stretch;
+ background-color: var(--surface-2);
+ border: 0;
+ border-bottom: 1px solid var(--surface-0);
+ display: flex;
+ }
+.netFilteringDialog > .panes > .details > div > span {
+ padding: 0.5em;
+ }
+.netFilteringDialog > .panes > .details > div > span:nth-of-type(1) {
+ border: 0;
+ flex-grow: 0;
+ flex-shrink: 0;
+ text-align: right;
+ width: 8em;
+ }
+body[dir="ltr"] .netFilteringDialog > .panes > .details > div > span:nth-of-type(1) {
+ border-right: 1px solid var(--surface-0);
+ }
+body[dir="rtl"] .netFilteringDialog > .panes > .details > div > span:nth-of-type(1) {
+ border-left: 1px solid var(--surface-0);
+ }
+.netFilteringDialog > .panes > .details > div > span:nth-of-type(2) {
+ flex-grow: 1;
+ max-height: 10vh;
+ overflow: hidden auto;
+ white-space: pre-line
+ }
+.netFilteringDialog > .panes > .details > div > span:nth-of-type(2):not(.prose) {
+ word-break: break-all;
+ }
+.netFilteringDialog > .panes > .details > div > span:nth-of-type(2) .listEntry {
+ display: inline-flex;
+ }
+.netFilteringDialog > .panes > .details > div > span:nth-of-type(2) .fa-icon {
+ font-size: 110%;
+ opacity: 0.5;
+ }
+.netFilteringDialog > .panes > .details > div > span:nth-of-type(2) .fa-icon:hover {
+ opacity: 1;
+ }
+.netFilteringDialog > .panes > .details .exceptor {
+ align-items: center;
+ border-left: 1px solid var(--surface-0);
+ cursor: pointer;
+ display: inline-flex;
+ font-family: monospace;
+ opacity: 0.8;
+ }
+.netFilteringDialog > .panes > .details .exceptor:hover {
+ opacity: 1;
+ }
+.netFilteringDialog > .panes > .details .exceptored .filter {
+ text-decoration: line-through;
+ }
+.netFilteringDialog > .panes > .details .exceptored .exceptor {
+ background-color: rgb(var(--primary-50) / 50%);
+ }
+.netFilteringDialog > .panes > .details .exceptor::before {
+ content: '@@';
+ }
+.netFilteringDialog.extendedRealm > .panes > .details .exceptor::before {
+ content: '#@#';
+ }
+.netFilteringDialog > div.panes > .dynamic > .toolbar {
+ padding-bottom: 1em;
+ }
+.netFilteringDialog > div.panes > .dynamic .row {
+ display: flex;
+ min-height: 2.2em;
+ }
+.netFilteringDialog > div.panes > .dynamic .row > span:nth-of-type(1) {
+ align-self: stretch;
+ border: 0;
+ display: inline-flex;
+ flex-grow: 0;
+ flex-shrink: 0;
+ text-align: center;
+ width: 4.5em;
+ }
+body[dir="ltr"] .netFilteringDialog > div.panes > .dynamic .row > span:nth-of-type(1) {
+ border-right: 1px solid var(--surface-0);
+ }
+body[dir="rtl"] .netFilteringDialog > div.panes > .dynamic .row > span:nth-of-type(1) {
+ border-left: 1px solid var(--surface-0);
+ }
+.netFilteringDialog > div.panes > .dynamic .row > span:nth-of-type(2) {
+ align-self: center;
+ padding: 0 0.5em;
+ }
+.netFilteringDialog > div.panes > .dynamic > .toolbar #saveRules {
+ background-color: #ffe;
+ border: 1px solid #ddc;
+ border-radius: 4px;
+ fill: #888;
+ cursor: pointer;
+ font-size: 2em;
+ visibility: hidden;
+ width: 100%;
+ }
+body.dirty .netFilteringDialog > div.panes > .dynamic > .toolbar #saveRules {
+ visibility: visible;
+ }
+.netFilteringDialog > div.panes > .dynamic > .toolbar #saveRules:hover {
+ fill: black;
+ }
+.netFilteringDialog > div.panes > .dynamic > .toolbar .entry {
+ display: none;
+ }
+.netFilteringDialog > div.panes > .dynamic .entry {
+ background-color: var(--surface-2);
+ border: 0;
+ border-bottom: 1px solid var(--surface-0);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry:hover {
+ background-color: var(--surface-3);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action {
+ background-color: transparent;
+ border: 0;
+ cursor: pointer;
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action > span {
+ background-color: transparent;
+ border: 0;
+ display: inline-block;
+ height: 100%;
+ opacity: 0.2;
+ visibility: hidden;
+ width: 33.33%;
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action.allow {
+ background-color: rgba(0, 160, 0, 0.3);
+ }
+:root.colorBlind .netFilteringDialog > div.panes > .dynamic .entry > .action.allow {
+ background-color: rgba(255, 194, 57, 0.4);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action.noop {
+ background-color: rgba(108, 108, 108, 0.3);
+ }
+:root.colorBlind .netFilteringDialog > div.panes > .dynamic .entry > .action.noop {
+ background-color: rgba(96, 96, 96, 0.4);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action.block {
+ background-color: rgba(192, 0, 0, 0.3);
+ }
+:root.colorBlind .netFilteringDialog > div.panes > .dynamic .entry > .action.block {
+ background-color: rgba(0, 19, 110, 0.4);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action.own.allow {
+ background-color: rgba(0, 160, 0, 1);
+ }
+:root.colorBlind .netFilteringDialog > div.panes > .dynamic .entry > .action.own.allow {
+ background-color: rgba(255, 194, 57, 1);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action.own.noop,
+:root.colorBlind .netFilteringDialog > div.panes > .dynamic .entry > .action.own.noop {
+ background-color: rgba(108, 108, 108, 1);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action.own.block {
+ background-color: rgba(192, 0, 0, 1);
+ }
+:root.colorBlind .netFilteringDialog > div.panes > .dynamic .entry > .action.own.block {
+ background-color: rgba(0, 19, 110, 1);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action:not(.own):hover > span {
+ opacity: 0.2;
+ visibility: visible;
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action:not(.own):hover > span:hover {
+ opacity: 0.75;
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action > .allow {
+ background-color: rgb(0, 160, 0);
+ }
+:root.colorBlind .netFilteringDialog > div.panes > .dynamic .entry > .action > .allow {
+ background-color: rgb(255, 194, 57);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action > .noop {
+ background-color: rgb(108, 108, 108);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .action > .block {
+ background-color: rgb(192, 0, 0);
+ }
+:root.colorBlind .netFilteringDialog > div.panes > .dynamic .entry > .action > .block {
+ background-color: rgb(0, 19, 110);
+ }
+.netFilteringDialog > div.panes > .dynamic .entry > .url {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+.netFilteringDialog > div.panes > div.static > div {
+ line-height: 2;
+ }
+.netFilteringDialog > div.panes > div.static textarea {
+ height: 6em;
+ max-height: 20vh;
+ min-height: 10vh;
+ word-break: break-all;
+ }
+.netFilteringDialog > div.panes > div.static > div:nth-of-type(2) {
+ text-align: center;
+ }
+
+#filterFinderDialog {
+ word-break: break-all;
+ }
+#filterFinderDialog code {
+ background: #eee;
+ font-size: 85%;
+ padding: 3px;
+ unicode-bidi: plaintext;
+ white-space: pre-wrap;
+ }
+#filterFinderDialog ul {
+ font-size: larger;
+ }
+#filterFinderDialog .filterFinderListEntry {
+ align-items: flex-end;
+ display: flex;
+ }
+#filterFinderDialog .filterFinderListEntry a {
+ text-decoration: none;
+ }
+#filterFinderDialog .filterFinderListEntry a.fa-icon {
+ margin: 0 0.5em;
+ opacity: 0.6;
+ }
+#filterFinderDialog .filterFinderListEntry a.fa-icon:hover {
+ opacity: 1;
+ }
+#filterFinderDialog .filterFinderListEntry a.fa-icon[href=""] {
+ display: none;
+ }
+#filterFinderDialog > *:first-child {
+ margin-top: 0;
+ }
+#filterFinderDialog > *:last-child {
+ margin-bottom: 0;
+ }
+
+#loggerStatsDialog .sortedEntries {
+ display: flex;
+ flex-direction: column;
+ font-size: smaller;
+ }
+#loggerStatsDialog .sortedEntries > div {
+ display: flex;
+ }
+#loggerStatsDialog .sortedEntries > div > span:first-of-type {
+ flex-grow: 0;
+ flex-shrink: 0;
+ padding: 0 2em 0 0;
+ text-align: right;
+ width: 3em;
+ }
+#loggerStatsDialog .sortedEntries > div > span:last-of-type {
+ flex-grow: 1;
+ flex-shrink: 1;
+ white-space: pre;
+ }
+
+#loggerExportDialog {
+ display: flex;
+ flex-direction: column;
+ }
+#loggerExportDialog .options {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 1em;
+ }
+#loggerExportDialog .options > div {
+ display: inline-flex;
+ }
+#loggerExportDialog .options span[data-i18n] {
+ border: 1px solid rgb(var(--primary-70));
+ cursor: pointer;
+ font-size: 90%;
+ margin: 0;
+ padding: 0.5em;
+ white-space: nowrap;
+ }
+#loggerExportDialog .options span[data-i18n]:hover {
+ background-color: rgb(var(--primary-70) / 40%);
+ }
+#loggerExportDialog .options span.on[data-i18n],
+#loggerExportDialog .options span.pushbutton:active {
+ background-color: rgb(var(--primary-70) / 40%);
+ }
+#loggerExportDialog .output {
+ font: smaller mono;
+ height: 60vh;
+ padding: 0.5em;
+ white-space: pre;
+ }
+
+#loggerSettingsDialog {
+ display: flex;
+ flex-direction: column;
+ }
+#loggerSettingsDialog > div {
+ padding-bottom: 1em;
+ }
+#loggerSettingsDialog > div:last-of-type {
+ padding-bottom: 0;
+ }
+#loggerSettingsDialog ul {
+ padding: 0;
+ }
+body[dir="ltr"] #loggerSettingsDialog ul {
+ padding-left: 2em;
+ }
+body[dir="rtl"] #loggerSettingsDialog ul {
+ padding-right: 2em;
+ }
+#loggerSettingsDialog li {
+ list-style-type: none;
+ margin: 0.5em 0 0 0;
+ }
+#loggerSettingsDialog input {
+ max-width: 6em;
+ }
+
+.hide {
+ display: none !important;
+ }
diff --git a/src/css/popup-fenix.css b/src/css/popup-fenix.css
new file mode 100644
index 0000000..252e371
--- /dev/null
+++ b/src/css/popup-fenix.css
@@ -0,0 +1,778 @@
+ /* External CSS values override */
+.fa-icon.fa-icon-badged > .fa-icon-badge {
+ bottom: auto;
+ top: -20%;
+ }
+
+/* Internal CSS values */
+:root body {
+ overflow: hidden;
+ }
+:root body,
+:root.mobile body {
+ --font-size: 14px;
+ --popup-gap: var(--font-size);
+ --popup-gap-thin: calc(0.5 * var(--popup-gap));
+ --popup-gap-extra-thin: calc(0.25 * var(--popup-gap));
+ --popup-main-min-width: 18em;
+ --popup-firewall-min-width: 30em;
+ --popup-rule-cell-width: 5em;
+ font-size: var(--font-size);
+ line-height: 20px;
+ }
+:root body.loading {
+ opacity: 0;
+ }
+a {
+ color: var(--ink-1);
+ fill: var(--ink-1);
+ text-decoration: none;
+ }
+:focus {
+ outline: 0;
+ }
+
+#panes {
+ align-items: stretch;
+ display: flex;
+ flex-direction: row-reverse;
+ padding: 0;
+ position: relative;
+ }
+#main {
+ align-self: flex-start;
+ max-width: 340px;
+ min-width: var(--popup-main-min-width);
+ }
+:root.portrait #main {
+ align-self: inherit;
+ }
+hr {
+ border: 0;
+ border-top: 1px solid var(--hr-ink);
+ margin: 0;
+ padding: 0;
+ }
+
+#sticky {
+ background-color: var(--surface-1);
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ }
+#stickyTools {
+ align-items: stretch;
+ display: flex;
+ justify-content: space-between;
+ margin: var(--popup-gap-extra-thin) 0;
+ }
+#switch {
+ color: var(--popup-power-ink);
+ cursor: pointer;
+ display: flex;
+ fill: var(--popup-power-ink);
+ flex-grow: 1;
+ font-size: 96px;
+ justify-content: center;
+ margin: var(--popup-gap) 0;
+ padding: 0;
+ stroke: none;
+ stroke-width: 64;
+ }
+body.off #switch {
+ fill: var(--surface-1);
+ stroke: var(--checkbox-ink);
+ }
+.rulesetTools {
+ background-color: transparent;
+ border: 0;
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ width: 25%;
+ }
+.rulesetTools [id] {
+ background-color: var(--popup-ruleset-tool-surface);
+ border-radius: 4px;
+ cursor: pointer;
+ fill: var(--popup-ruleset-tool-ink);
+ flex-grow: 1;
+ font-size: 2.2em;
+ padding: 0;
+ visibility: hidden;
+ }
+.rulesetTools [id]:not(:first-of-type) {
+ margin-block-start: 1px;
+ }
+.rulesetTools [id] > svg {
+ fill: var(--ink-4);
+ }
+body.needReload #refresh,
+body.needSave #saveRules,
+body.needSave #revertRules {
+ visibility: visible;
+ }
+#hostname {
+ background-color: var(--popup-toolbar-surface);
+ margin: 0;
+ padding: var(--popup-gap-thin) 0;
+ text-align: center;
+ white-space: normal;
+
+ }
+#hostname > span {
+ word-break: break-all;
+ }
+#hostname > span + span {
+ font-weight: 600;
+ }
+
+#basicStats {
+ column-gap: var(--popup-gap);
+ display: grid;
+ grid-template: auto / auto;
+ margin: var(--popup-gap) var(--popup-gap) var(--popup-gap-thin) var(--popup-gap);
+ }
+#basicStats > span {
+ justify-self: center;
+ white-space: nowrap;
+ }
+#basicStats > [data-i18n] {
+ font-size: 95%;
+ }
+#basicStats > [data-i18n] + span {
+ font-size: 105%;
+ margin-bottom: var(--popup-gap-thin);
+ }
+:root.portrait #basicStats {
+ grid-template: auto / auto auto;
+ margin-bottom: 0;
+ }
+:root.portrait #basicStats > span {
+ font-size: inherit;
+ justify-self: stretch;
+ margin-bottom: var(--popup-gap);
+ white-space: unset;
+ }
+:root.portrait #basicStats > [data-i18n] {
+ }
+:root.portrait #basicStats > [data-i18n] + span {
+ text-align: end;
+ }
+
+.itemRibbon {
+ column-gap: var(--popup-gap);
+ display: grid;
+ grid-auto-columns: 1fr;
+ grid-auto-flow: column;
+ grid-template: auto / 1fr 1fr;
+ margin: var(--popup-gap);
+ }
+.itemRibbon > span + span {
+ text-align: end;
+ }
+
+.toolRibbon {
+ align-items: start;
+ background-color: var(--popup-toolbar-surface);
+ display: grid;
+ grid-auto-columns: 1fr;
+ grid-auto-flow: column;
+ grid-template: auto / repeat(4, 1fr);
+ justify-items: center;
+ margin: 0;
+ white-space: normal;
+ }
+.toolRibbon .tool {
+ cursor: pointer;
+ display: flex;
+ flex-direction: column;
+ font-size: 1.4em;
+ min-width: 32px;
+ padding: var(--popup-gap)
+ var(--popup-gap-thin);
+ unicode-bidi: embed;
+ visibility: hidden;
+ }
+.toolRibbon .tool:hover {
+ color: var(--ink-1);
+ fill: var(--ink-1);
+ }
+.toolRibbon .tool.enabled {
+ visibility: visible;
+ }
+.toolRibbon .tool .caption {
+ font: 10px/12px sans-serif;
+ margin-top: 6px;
+ text-align: center;
+ }
+:root.mobile.no-tooltips .toolRibbon .tool {
+ font-size: 1.6em;
+ }
+
+#basicTools:not(.canPick) .needPick {
+ visibility: hidden;
+ }
+
+#extraTools .fa-icon {
+ align-self: center;
+ position: relative;
+ }
+#extraTools .fa-icon > .nope {
+ height: 1.1em;
+ left: 50%;
+ position: absolute;
+ stroke: var(--popup-icon-x-ink);
+ stroke-width: 2;
+ transform: translateX(-50%);
+ visibility: hidden;
+ width: 1.1em;
+ }
+#extraTools > span.on .fa-icon >.nope {
+ visibility: visible;
+ }
+
+#unprocessedRequestWarning {
+ align-items: center;
+ background-color: #fc0;
+ color: rgb(var(--ink-80));
+ stroke: rgb(var(--ink-80));
+ display: none;
+ font-size: var(--font-size-smaller);
+ padding: var(--popup-gap-thin);
+ }
+:root.warn #unprocessedRequestWarning {
+ display: flex;
+ }
+#unprocessedRequestWarning > .dismiss {
+ flex-shrink: 0;
+ width: calc(var(--font-size) - 2px);
+ }
+#unprocessedRequestWarning > .dismiss > svg {
+ width: 100%;
+ }
+
+#moreOrLess {
+ column-gap: 0;
+ display: grid;
+ grid-template: auto / 1fr 1fr;
+ justify-items: stretch;
+ margin: 1px 0 0 0;
+ }
+#moreOrLess > span {
+ cursor: pointer;
+ margin: 0;
+ padding: var(--popup-gap-thin) var(--popup-gap);
+ user-select: none;
+ white-space: nowrap;
+ }
+:root.mobile #moreOrLess > span {
+ padding: var(--popup-gap);
+ }
+#moreButton .fa-icon {
+ transform: rotate(180deg);
+ }
+#lessButton {
+ border-inline-start: 1px solid var(--surface-1);
+ text-align: end;
+ }
+#moreButton.disabled,
+#lessButton.disabled {
+ pointer-events: none;
+ visibility: hidden;
+ }
+
+#firewall {
+ border: 0;
+ flex-shrink: 1;
+ font-size: 90%;
+ margin: 0;
+ max-height: 600px;
+ max-width: 460px;
+ min-width: var(--popup-firewall-min-width);
+ padding: 0;
+ position: relative;
+ overflow-y: auto;
+ }
+:root.desktop #firewall {
+ margin-inline-start: 1px;
+ }
+:root.desktop body.vMin #firewall {
+ max-height: 100vh;
+ }
+#firewall > * {
+ direction: ltr;
+ }
+#firewall > section {
+ align-items: flex-start;
+ display: flex;
+ left: 0;
+ position: absolute;
+ z-index: 50;
+ }
+#firewall > section .fa-icon {
+ color: var(--ink-4);
+ fill: var(--ink-4);
+ font-size: 150%;
+ padding: var(--popup-gap-thin);
+ }
+#firewall > section:hover .fa-icon {
+ color: var(--ink-1);
+ fill: var(--ink-1);
+ }
+#firewall.showBlocked > section .fa-icon,
+#firewall.showAllowed > section .fa-icon,
+#firewall.hideBlocked > section .fa-icon,
+#firewall.hideAllowed > section .fa-icon,
+#firewall.show3pScript > section .fa-icon,
+#firewall.show3pFrame > section .fa-icon,
+#firewall.hide3pScript > section .fa-icon,
+#firewall.hide3pFrame > section .fa-icon {
+ color: rgb(var(--primary-70));
+ fill: rgb(var(--primary-70));
+ }
+#firewall > section .filterExpressions {
+ background-color: var(--surface-0);
+ border: 1px solid var(--border-4);
+ display: none;
+ }
+#firewall > section:hover .filterExpressions {
+ display: flex;
+ flex-direction: column;
+ }
+#firewall > section .filterExpressions div {
+ border-bottom: 1px dotted #ddd;
+ padding: 0.25em;
+ }
+#firewall > section .filterExpressions div:last-of-type {
+ border-bottom: 0;
+ }
+#firewall > section .filterExpressions span {
+ cursor: default;
+ display: inline-flex;
+ margin: 0 0.25em 0 0;
+ padding: 0.5em;
+ white-space: nowrap;
+ border: 1px solid var(--surface-0);
+ }
+#firewall > section .filterExpressions span:last-of-type {
+ margin: 0;
+ }
+:root:not(.mobile) #firewall > section .filterExpressions span:not(.on):hover {
+ background-color: rgb(var(--primary-70) / 15%);
+ border: 1px solid rgb(var(--primary-70));
+ }
+#firewall > section .filterExpressions span.on {
+ background-color: rgb(var(--primary-70) / 40%);
+ border: 1px solid rgb(var(--primary-70));
+ }
+#firewall > div {
+ border: 0;
+ display: flex;
+ margin: 0;
+ margin-top: 1px;
+ padding: 0;
+ }
+#firewall > div:first-of-type {
+ margin-top: 0;
+ }
+#firewall > div:first-of-type ~ div[data-des="*"] {
+ display: none;
+ }
+#firewall:not(.expanded) > div.isSubdomain:not(.expandException):not(.isRootContext),
+#firewall.expanded > div.isSubdomain.expandException:not(.isRootContext) {
+ display: none;
+ }
+#firewall > div > span,
+#actionSelector > #dynaCounts {
+ background-color: var(--popup-cell-surface);
+ border: none;
+ box-sizing: border-box;
+ display: inline-flex;
+ padding: 0.4em 0;
+ position: relative;
+ }
+#firewall > div:first-of-type span[data-i18n] {
+ cursor: pointer;
+ flex-direction: unset;
+ flex-grow: 1;
+ }
+#firewall > div:first-of-type span[data-i18n]::before {
+ color: var(--ink-3);
+ content: '+';
+ padding-right: 0.25em;
+ }
+#firewall.expanded > div:first-of-type span[data-i18n]::before {
+ content: '\2012';
+ }
+#firewall > div > span:first-of-type {
+ flex-direction: column;
+ flex-grow: 1;
+ justify-content: flex-end;
+ padding-right: 2px;
+ text-align: right;
+ white-space: normal;
+ width: calc(100% - var(--popup-rule-cell-width));
+ word-break: break-word;
+ }
+#firewall > div[data-des="*"] > span:first-of-type {
+ flex-direction: row;
+ }
+#firewall.show3pScript:not(.show3pFrame) > div:not([data-des="*"]).is3p:not(.hasScript),
+#firewall.show3pFrame:not(.show3pScript) > div:not([data-des="*"]).is3p:not(.hasFrame),
+#firewall.show3pScript.show3pFrame > div:not([data-des="*"]).is3p:not(.hasScript):not(.hasFrame),
+#firewall.hide3pScript > div:not([data-des="*"]).is3p.hasScript,
+#firewall.hide3pFrame > div:not([data-des="*"]).is3p.hasFrame,
+#firewall.showBlocked > div:not([data-des="*"]).is3p:not(.totalBlocked):not(.blocked),
+#firewall.showAllowed > div:not([data-des="*"]).is3p:not(.totalAllowed):not(.allowed),
+#firewall.hideBlocked > div:not([data-des="*"]).is3p.totalBlocked,
+#firewall.hideBlocked > div:not([data-des="*"]).is3p.blocked,
+#firewall.hideAllowed > div:not([data-des="*"]).is3p.totalAllowed,
+#firewall.hideAllowed > div:not([data-des="*"]).is3p.allowed {
+ max-height: 4px;
+ overflow-y: hidden;
+ pointer-events: none;
+ user-select: none;
+ }
+#firewall.show3pScript:not(.show3pFrame) > div:not([data-des="*"]).is3p:not(.hasScript) *,
+#firewall.show3pFrame:not(.show3pScript) > div:not([data-des="*"]).is3p:not(.hasFrame) *,
+#firewall.show3pScript.show3pFrame > div:not([data-des="*"]).is3p:not(.hasScript):not(.hasFrame) *,
+#firewall.hide3pScript > div:not([data-des="*"]).is3p.hasScript *,
+#firewall.hide3pFrame > div:not([data-des="*"]).is3p.hasFrame *,
+#firewall.showBlocked > div:not([data-des="*"]).is3p:not(.totalBlocked):not(.blocked) *,
+#firewall.showAllowed > div:not([data-des="*"]).is3p:not(.totalAllowed):not(.allowed) *,
+#firewall.hideBlocked > div:not([data-des="*"]).is3p.totalBlocked *,
+#firewall.hideBlocked > div:not([data-des="*"]).is3p.blocked *,
+#firewall.hideAllowed > div:not([data-des="*"]).is3p.totalAllowed *,
+#firewall.hideAllowed > div:not([data-des="*"]).is3p.allowed * {
+ color: transparent !important;
+ }
+#firewall > div.isCname > span:first-of-type {
+ color: var(--popup-cell-cname-ink);
+ }
+#firewall > div > span:first-of-type > sub {
+ display: inline-block;
+ font-size: 85%;
+ font-weight: normal;
+ padding: 0.25em 0 0 0;
+ }
+#firewall > div > span:first-of-type > sub:empty {
+ display: none;
+ }
+#firewall > div > span:first-of-type ~ span {
+ flex-shrink: 0;
+ margin-left: 1px;
+ width: var(--popup-rule-cell-width);
+ }
+#firewall > div > span:nth-of-type(2) {
+ display: none;
+ }
+#firewall > div > span:nth-of-type(3),
+#firewall > div > span:nth-of-type(4) {
+ color: var(--ink-2);
+ display: none;
+ font-family: monospace;
+ text-align: center;
+ }
+#firewall > div.isDomain > span:first-of-type > span {
+ pointer-events: none;
+ }
+#firewall > div.isDomain > span:first-of-type > span > span {
+ font-weight: 600;
+ pointer-events: auto;
+ }
+#firewall > div.isDomain.hasSubdomains > span:first-of-type > span::before {
+ content: '\2026\A0';
+ opacity: 0.6;
+ }
+#firewall > div[data-des="*"] > span:nth-of-type(3),
+#firewall > div.isSubdomain > span:nth-of-type(3),
+#firewall > div.isSubdomain.isRootContext > span:nth-of-type(3),
+#firewall.expanded > div:not(.expandException) > span:nth-of-type(3),
+#firewall:not(.expanded) > div.expandException > span:nth-of-type(3),
+#firewall:not(.expanded) > div.isDomain:not(.expandException) > span:nth-of-type(4),
+#firewall.expanded > div.isDomain.expandException > span:nth-of-type(4),
+#actionSelector > #dynaCounts {
+ display: inline-flex;
+ justify-content: space-between;
+ }
+#firewall > div > span[data-acount]::before,
+#firewall > div > span[data-bcount]::after,
+#firewall > div > span[data-acount] > #actionSelector > #dynaCounts::before,
+#firewall > div > span[data-acount] > #actionSelector > #dynaCounts::after {
+ content: ' ';
+ }
+#firewall > div > span[data-acount]::before,
+#firewall > div > span[data-acount] > #actionSelector > #dynaCounts::before {
+ padding-left: 0.1em;
+ }
+#firewall > div > span[data-acount="1"]::before,
+#firewall > div > span[data-acount="1"] > #actionSelector > #dynaCounts::before {
+ content: '+';
+ }
+#firewall > div > span[data-acount="2"]::before,
+#firewall > div > span[data-acount="2"] > #actionSelector > #dynaCounts::before {
+ content: '++';
+ }
+#firewall > div > span[data-acount="3"]::before,
+#firewall > div > span[data-acount="3"] > #actionSelector > #dynaCounts::before {
+ content: '+++';
+ }
+#firewall > div > span[data-bcount]::after,
+#firewall > div > span[data-bcount] > #actionSelector > #dynaCounts::after {
+ padding-right: 0.1em;
+ }
+#firewall > div > span[data-bcount="1"]::after,
+#firewall > div > span[data-bcount="1"] > #actionSelector > #dynaCounts::after {
+ content: '\2212';
+ }
+#firewall > div > span[data-bcount="2"]::after,
+#firewall > div > span[data-bcount="2"] > #actionSelector > #dynaCounts::after {
+ content: '\2212\2212';
+ }
+#firewall > div > span[data-bcount="3"]::after,
+#firewall > div > span[data-bcount="3"] > #actionSelector > #dynaCounts::after {
+ content: '\2212\2212\2212';
+ }
+
+body.advancedUser #firewall > div > span:first-of-type {
+ width: calc(100% - 2 * var(--popup-rule-cell-width));
+ }
+body.advancedUser #firewall > div > span:nth-of-type(2) {
+ display: inline-flex;
+ }
+body.advancedUser #firewall > div:first-of-type ~ div[data-des="*"] {
+ display: flex;
+ }
+body.advancedUser #firewall > div > span:first-of-type ~ span {
+ cursor: pointer;
+ }
+
+/**
+ Small coloured label at the left of a row
+ */
+#firewall > div.isRootContext > span:first-of-type::before,
+#firewall > div.allowed > span:first-of-type::before,
+#firewall > div.blocked > span:first-of-type::before,
+#firewall:not(.expanded) > div.isDomain.totalAllowed:not(.expandException) > span:first-of-type::before,
+#firewall:not(.expanded) > div.isDomain.totalBlocked:not(.expandException) > span:first-of-type::before,
+#firewall.expanded > div.isDomain.totalAllowed.expandException > span:first-of-type::before,
+#firewall.expanded > div.isDomain.totalBlocked.expandException > span:first-of-type::before {
+ box-sizing: border-box;
+ content: '';
+ display: inline-block;
+ filter: var(--popup-cell-label-filter);
+ height: 100%;
+ left: 0;
+ position: absolute;
+ top: 0;
+ width: 7px;
+ }
+#firewall > div.isRootContext > span:first-of-type::before {
+ background: var(--ink-3);
+ width: 14px !important;
+ }
+#firewall > div.allowed > span:first-of-type::before,
+#firewall > div.isDomain.totalAllowed > span:first-of-type::before {
+ background: var(--popup-cell-allow-own-surface);
+ }
+#firewall > div.blocked > span:first-of-type::before,
+#firewall > div.isDomain.totalBlocked > span:first-of-type::before {
+ background: var(--popup-cell-block-own-surface);
+ }
+#firewall > div.allowed.blocked > span:first-of-type::before,
+#firewall > div.isDomain.totalAllowed.totalBlocked > span:first-of-type::before {
+ background: var(--popup-cell-label-mixed-surface);
+ }
+/* Rule cells */
+body.advancedUser #firewall > div > span.allowRule,
+#actionSelector > #dynaAllow {
+ background: var(--popup-cell-allow-surface);
+ }
+body.advancedUser #firewall > div > span.blockRule,
+#actionSelector > #dynaBlock {
+ background: var(--popup-cell-block-surface);
+ }
+body.advancedUser #firewall > div > span.noopRule,
+#actionSelector > #dynaNoop {
+ background: var(--popup-cell-noop-surface);
+ }
+body.advancedUser #firewall > div > span.ownRule,
+#firewall > div > span.ownRule {
+ color: var(--surface-1);
+ }
+body.advancedUser #firewall > div > span.allowRule.ownRule,
+:root:not(.mobile) #actionSelector > #dynaAllow:hover {
+ background: var(--popup-cell-allow-own-surface);
+ }
+body.advancedUser #firewall > div > span.blockRule.ownRule,
+:root:not(.mobile) #actionSelector > #dynaBlock:hover {
+ background: var(--popup-cell-block-own-surface);
+ }
+body.advancedUser #firewall > div > span.noopRule.ownRule,
+:root:not(.mobile) #actionSelector > #dynaNoop:hover {
+ background: var(--popup-cell-noop-own-surface);
+ }
+
+#actionSelector {
+ box-sizing: border-box;
+ display: flex;
+ height: 100%;
+ justify-items: stretch;
+ left: 0;
+ overflow: hidden;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ z-index: 1;
+ }
+#actionSelector > span {
+ display: inline-block;
+ flex-grow: 1;
+ }
+#actionSelector > #dynaAllow {
+ display: none;
+ }
+body.godMode #actionSelector > #dynaAllow {
+ display: inline-block;
+ }
+#actionSelector > #dynaNoop {
+ }
+#actionSelector > #dynaBlock {
+ }
+#actionSelector > #dynaCounts {
+ background-color: transparent;
+ height: 100%;
+ left: 0;
+ pointer-events: none;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ }
+
+/* configurable UI elements */
+:root:not(.mobile) .toolRibbon .caption,
+:root.mobile body.no-tooltips .toolRibbon .caption,
+:root.mobile body[data-ui~="-captions"] .toolRibbon .caption {
+ display: none;
+ }
+:root.mobile .toolRibbon .caption,
+:root:not(.mobile) body[data-ui~="+captions"] .toolRibbon .caption {
+ display: inherit;
+ }
+:root:not(.mobile) .toolRibbon .tool,
+:root.mobile body.no-tooltips .toolRibbon .tool,
+:root.mobile body[data-ui~="-captions"] .toolRibbon .tool {
+ padding: var(--popup-gap) var(--popup-gap-thin);
+ }
+:root.mobile #no-popups,
+:root body[data-ui~="-no-popups"] #no-popups {
+ display: none;
+ }
+:root:not(.mobile) #no-popups,
+:root body[data-ui~="+no-popups"] #no-popups {
+ display: flex;
+ }
+:root.mobile [href="logger-ui.html#_"],
+:root body[data-ui~="-logger"] [href="logger-ui.html#_"] {
+ display: none;
+ }
+:root:not(.mobile) [href="logger-ui.html#_"],
+:root body[data-ui~="+logger"] [href="logger-ui.html#_"] {
+ display: flex;
+ }
+body:not([data-more*="a"]) [data-more="a"],
+body:not([data-more*="b"]) [data-more="b"],
+body:not([data-more*="c"]) [data-more="c"],
+body:not([data-more*="d"]) [data-more="d"],
+body:not([data-more*="f"]) [data-more="f"] {
+ height: 0;
+ margin-bottom: 0 !important;
+ margin-top: 0 !important;
+ overflow-y: hidden;
+ visibility: hidden;
+ }
+body[data-more*="d"] hr[data-more="a"] {
+ display: none;
+ }
+body[data-more*="c"] hr[data-more="f"] {
+ display: none;
+ }
+body[data-more*="c"]:not([data-more*="f"]) hr[data-more="g"] {
+ display: none;
+ }
+body:not([data-more*="e"]) [data-more="e"] {
+ display: none;
+ }
+
+:root #firewall-vspacer {
+ display: none;
+ height: calc(6 * var(--popup-gap));
+ }
+
+/* popup-in-tab mode, useful for screenshots */
+:root.desktop.intab body {
+ overflow: auto;
+ }
+:root.desktop.intab #firewall {
+ max-height: none;
+ }
+
+/* horizontally-constrained viewport */
+:root.portrait:not(.desktop) body {
+ overflow-y: auto;
+ width: 100%;
+ }
+:root.portrait #panes {
+ flex-direction: column;
+ }
+:root.portrait #main {
+ max-width: unset;
+ }
+:root.portrait #firewall {
+ max-height: unset;
+ max-width: unset;
+ min-width: unset;
+ overflow-y: hidden;
+ }
+:root.portrait body[data-more*="e"] #firewall-vspacer {
+ display: block;
+ }
+
+/* touch-driven devices */
+:root.mobile #firewall {
+ line-height: 20px;
+ }
+
+/* mouse-driven devices */
+:root.desktop {
+ display: flex;
+ justify-content: flex-end;
+ }
+:root.desktop body {
+ --popup-gap: calc(var(--font-size) * 0.875);
+ }
+:root.desktop body:not(.off) #switch:hover {
+ fill: rgb(var(--popup-power-ink-rgb) / 90%);
+ }
+:root.desktop body.off #switch:hover {
+ stroke: var(--popup-power-ink);
+ }
+:root.desktop .rulesetTools [id]:hover {
+ background-color: var(--popup-ruleset-tool-surface-hover);
+ }
+:root.desktop .rulesetTools [id]:hover > svg {
+ fill: var(--ink-2);
+ }
+:root.desktop #firewall {
+ direction: rtl;
+ line-height: 1.4;
+ }
+:root.desktop .tool:hover {
+ background-color: var(--popup-toolbar-surface-hover);
+ }
+:root.desktop #moreOrLess > span:hover {
+ background-color: var(--surface-2);
+ /* background-color: var(--popup-toolbar-surface-hover); */
+ }
diff --git a/src/css/settings.css b/src/css/settings.css
new file mode 100644
index 0000000..61a8c0e
--- /dev/null
+++ b/src/css/settings.css
@@ -0,0 +1,74 @@
+body {
+ margin-bottom: 6rem;
+ }
+
+.synopsis {
+ color: var(--ink-0);
+ font-size: var(--font-size-smaller);
+ opacity: var(--medium-em);
+ }
+
+/* surface/ink */
+#themeMood {
+ align-items: stretch;
+ align-self: stretch;
+ display: inline-flex;
+ justify-content: stretch;
+ user-select: none;
+ }
+#themeMood > span {
+ border: 1px solid var(--ink-1);
+ color: var(--ink-1);
+ display: inline-flex;
+ background-color: var(--surface-1);
+ display: inline-block;
+ padding: 0 0.5em;
+ text-align: center;
+ user-select: none;
+ }
+
+/* primary color */
+#themePrimary {
+ align-items: stretch;
+ align-self: stretch;
+ display: inline-flex;
+ justify-content: stretch;
+ position: relative;
+ }
+#themePrimary > span {
+ background-color: rgb(var(--primary-50));
+ display: inline-flex;
+ width: 2em;
+ }
+
+[href="advanced-settings.html"] {
+ display: none;
+ }
+body.advancedUser [href="advanced-settings.html"] {
+ display: inline-flex;
+ }
+
+#localData > div {
+ margin-bottom: var(--default-gap-small);
+ }
+#localData > div:last-of-type {
+ align-items: flex-start;
+ display: flex;
+ flex-direction: column;
+ }
+#localData > div:last-of-type > button {
+ margin-bottom: var(--default-gap-small);
+ min-width: 280px;
+ }
+
+/* Mobile devices */
+
+:root.mobile #localData {
+ max-width: 100vw;
+ }
+:root.mobile #localData > div:last-of-type {
+ align-items: stretch;
+ }
+:root.mobile #localData > div:last-of-type > button {
+ min-width: unset;
+ }
diff --git a/src/css/support.css b/src/css/support.css
new file mode 100644
index 0000000..0afd740
--- /dev/null
+++ b/src/css/support.css
@@ -0,0 +1,110 @@
+@keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+ }
+
+body {
+ margin-bottom: 6rem;
+ }
+
+.body > div {
+ max-width: 800px;
+ }
+h3 {
+ color: var(--fieldset-header-ink);
+ margin-bottom: 0;
+ }
+.supportEntry {
+ display: flex;
+ margin-block: 1em;
+ }
+:root.mobile .supportEntry {
+ flex-direction: column;
+ }
+.supportEntry > * {
+ min-width: 6em;
+ }
+.supportEntry > div:first-of-type {
+ flex-grow: 1;
+ }
+:root:not(.mobile) .supportEntry > div:first-of-type {
+ margin-inline-end: 2em;
+ }
+.supportEntry h3 {
+ margin: 1em 0;
+ }
+
+.e > .supportEntry {
+ flex-direction: column;
+ }
+.e > .supportEntry > div:not(:first-of-type) {
+ margin-top: 1em;
+ }
+.e > .supportEntry select {
+ min-width: 50%;
+ max-width: calc(100% - 1em);
+ }
+body:not(.filterIssue) .body > div.e {
+ display: none;
+}
+body.filterIssue .body > div:not(.e) {
+ display: none;
+}
+body.filterIssue #moreButton {
+ display: none;
+}
+
+body[data-should-update-lists]:not(.updated) .e .createEntry {
+ opacity: 0.25;
+ pointer-events: none;
+}
+
+body:not([data-should-update-lists]) .shouldUpdate {
+ display: none;
+ }
+body.updating {
+ pointer-events: none;
+ }
+body.updating button {
+ filter: grayscale(1);
+ opacity: 0.5;
+ }
+body.updated .shouldUpdate button {
+ display: none;
+ }
+body.updating .shouldUpdate button .fa-icon svg {
+ animation: spin 1s linear infinite;
+ transform-origin: 50%;
+ }
+body .shouldUpdate .updated {
+ align-self: center;
+ }
+body:not(.updated) .shouldUpdate .updated {
+ display: none;
+ }
+
+button {
+ align-self: center;
+ }
+span[data-url] {
+ color: var(--link-ink);
+ cursor: pointer;
+ }
+
+#showSupportInfo {
+ cursor: pointer;
+ }
+
+body.redacted #redactButton {
+ display: none;
+ }
+#unredactButton {
+ display: none;
+ }
+body.redacted #unredactButton {
+ display: inline;
+ }
+
+.cm-string.cm-property {
+ color: black;
+ }
diff --git a/src/css/themes/default.css b/src/css/themes/default.css
new file mode 100644
index 0000000..c37bd28
--- /dev/null
+++ b/src/css/themes/default.css
@@ -0,0 +1,526 @@
+/**
+
+ References:
+ https://protocol.mozilla.org/
+ https://material.io/
+
+ Color names from:
+ https://protocol.mozilla.org/docs/fundamentals/color.html
+
+ Tools:
+ Lightness validator: https://www.hsluv.org/
+ Contrast validator: https://bernaferrari.github.io/color-studio/#/
+*/
+:root {
+ --blue-5: 170 242 255;
+ --blue-10: 128 235 255;
+ --blue-20: 0 221 255;
+ --blue-30: 0 179 244;
+ --blue-40: 0 144 237;
+ --blue-50: 0 96 223;
+ --blue-60: 2 80 187;
+ --blue-70: 5 64 150;
+ --blue-80: 7 48 114;
+ --blue-90: 9 32 77;
+ --dark-gray-10: 82 82 94;
+ --dark-gray-20: 74 74 85;
+ --dark-gray-30: 66 65 77;
+ --dark-gray-40: 58 57 68;
+ --dark-gray-50: 50 49 60;
+ --dark-gray-60: 43 42 51;
+ --dark-gray-70: 35 34 43;
+ --dark-gray-80: 28 27 34;
+ --dark-gray-90: 21 20 26;
+ --green-30: 136 255 209;
+ --green-40: 84 255 189;
+ --green-50: 63 225 176;
+ --green-60: 42 195 162;
+ --green-65: 21 165 149;
+ --green-70: 0 135 135;
+ --green-80: 0 94 94;
+ --ink-10: 57 52 115;
+ --ink-80: 32 18 58;
+ --light-gray-10: 249 249 251;
+ --light-gray-20: 240 240 244;
+ --light-gray-30: 224 224 230;
+ --light-gray-40: 207 207 216;
+ --light-gray-50: 191 191 201;
+ --light-gray-60: 175 175 186;
+ --light-gray-70: 159 159 173;
+ --light-gray-80: 143 143 158;
+ --light-gray-90: 128 128 143;
+ --orange-5: 255 244 222;
+ --orange-10: 255 213 178;
+ --orange-20: 255 181 135;
+ --orange-30: 255 162 102;
+ --orange-40: 255 138 80;
+ --orange-50: 255 113 57;
+ --orange-60: 226 89 32;
+ --orange-70: 204 61 0;
+ --orange-80: 158 40 11;
+ --orange-90: 124 21 4;
+ --purple-5: 247 226 255;
+ --purple-10: 246 184 255;
+ --purple-20: 246 143 255;
+ --purple-30: 247 112 255;
+ --purple-40: 215 76 240;
+ --purple-50: 184 51 225;
+ --purple-60: 149 43 185;
+ --purple-70: 114 34 145;
+ --purple-80: 78 26 105;
+ --purple-90: 43 17 65;
+ --red-20: 255 154 162;
+ --red-30: 255 132 139;
+ --red-40: 255 106 117;
+ --red-50: 255 79 94;
+ --red-60: 226 40 80;
+ --red-70: 197 0 66;
+ --violet-5: 231 223 255;
+ --violet-10: 217 191 255;
+ --violet-20: 203 158 255;
+ --violet-30: 198 137 255;
+ --violet-40: 171 113 255;
+ --violet-50: 144 89 255;
+ --violet-60: 117 66 229;
+ --violet-70: 89 42 203;
+ --violet-80: 69 39 141;
+ --violet-90: 50 28 100;
+ --yellow-5: 255 255 204;
+ --yellow-10: 255 255 152;
+ --yellow-20: 255 234 128;
+ --yellow-30: 255 213 103;
+ --yellow-40: 255 189 79;
+ --yellow-50: 255 164 54;
+ --yellow-60: 226 127 46;
+ --yellow-70: 196 90 39;
+ --yellow-80: 167 52 31;
+ --yellow-90: 150 14 24;
+
+ /*
+ * Reference gray: -light-gray-90, then calibrated with hsluv.org, where
+ * the number is Luv.
+ *
+ * */
+ --gray-5: 16 16 22;
+ --gray-10: 27 27 35;
+ --gray-15: 37 37 47;
+ --gray-20: 47 47 59;
+ --gray-25: 58 58 72;
+ --gray-30: 69 69 85;
+ --gray-35: 81 81 98;
+ --gray-40: 93 93 110;
+ --gray-45: 105 105 121;
+ --gray-50: 118 118 133;
+ --gray-55: 131 131 145;
+ --gray-60: 144 144 156;
+ --gray-65: 157 157 168;
+ --gray-70: 170 170 180;
+ --gray-75: 184 184 192;
+ --gray-80: 198 198 204;
+ --gray-85: 212 212 217;
+ --gray-90: 226 226 229;
+ --gray-95: 240 240 242;
+}
+
+/*
+ * Font
+ *
+ * */
+:root {
+ --font-size: 14px;
+ --font-size-smaller: calc(var(--font-size) - 1px);
+ --font-size-xsmall: calc(var(--font-size) - 3px);
+ --font-size-larger: 15px;
+ --font-family: Inter, sans-serif;
+ --monospace-size: 12px;
+}
+
+:root.mobile {
+ --font-size: 16px;
+ --font-size-smaller: 14px;
+ --monospace-size: 13px;
+}
+
+/*
+ * Default color theme
+ *
+ * Tool: hsluv.org
+ *
+ * */
+:root /* h255 */ {
+ --primary-5: 3 16 40; /* S:90 Luv:5 */
+ --primary-10: 5 27 59; /* S:90 Luv:10 */
+ --primary-20: 14 47 95; /* S:90 Luv:20 */
+ --primary-30: 24 69 134; /* S:90 Luv:30 */
+ --primary-40: 34 93 176; /* S:90 Luv:40 */
+ --primary-50: 45 117 219; /* S:90 Luv:50 */
+ --primary-60: 86 143 244; /* S:90 Luv:60 */
+ --primary-70: 137 170 247; /* S:90 Luv:70 */
+ --primary-80: 179 198 250; /* S:90 Luv:80 */
+ --primary-90: 218 226 252; /* S:90 Luv:90 */
+ --primary-95: 236 240 254; /* S:90 Luv:95 */
+ }
+
+/*
+ * Default dark theme starts here
+ *
+ * https://github.com/uBlockOrigin/uBlock-issues/issues/1027#issuecomment-629641072
+ * Assign a default background color if dark mode is enabled -- hopefully
+ * this will avoid flashes of white background until the document's own CSS
+ * overrides the default color value below.
+ *
+ * */
+@media (prefers-color-scheme: light) {
+ :root {
+ --surface-0-rgb: 255 255 255;
+ --surface-1: rgb(var(--gray-95));
+ --surface-2: rgb(var(--gray-90));
+ --surface-3: rgb(var(--gray-80));
+ }
+}
+@media (prefers-color-scheme: dark) {
+ :root {
+ --surface-0-rgb: 0 0 0;
+ --surface-1: rgb(var(--gray-10));
+ --surface-2: rgb(var(--gray-20));
+ --surface-3: rgb(var(--gray-30));
+ }
+}
+
+:root.light {
+ --surface-0-rgb: 255 255 255;
+ --surface-1: rgb(var(--gray-95));
+ --surface-2: rgb(var(--gray-90));
+ --surface-3: rgb(var(--gray-80));
+}
+
+:root.dark {
+ --surface-0-rgb: 0 0 0;
+ --surface-1: rgb(var(--gray-10));
+ --surface-2: rgb(var(--gray-20));
+ --surface-3: rgb(var(--gray-30));
+}
+
+/*
+ * Components
+ *
+ * */
+:root {
+ --font-size: 14px;
+
+ --ubo-red: #800000;
+
+ --elevation-up-surface: black;
+ --elevation-up1-opacity: 4%;
+ --elevation-up2-opacity: 8%;
+ --elevation-down-surface: white;
+ --elevation-down1-opacity: 16%;
+ --elevation-down2-opacity: 32%;
+
+ /* https://material.io/design/color/text-legibility.html#text-backgrounds */
+ --ink-rgb: var(--ink-80);
+ --ink-0: black;
+ --ink-100: white;
+
+ --border-1: rgb(var(--gray-75));
+ --border-2: rgb(var(--gray-70));
+ --border-3: rgb(var(--gray-65));
+ --border-4: rgb(var(--gray-60));
+
+ --accent-ink-3: var(--ink-1);
+ --accent-surface-1: rgb(var(--primary-40));
+
+ --link-ink: rgb(var(--primary-40));
+ --link-hover-ink: rgb(var(--primary-30));
+
+ /* buttons */
+ --button-surface-rgb: var(--gray-80);
+
+ --dashboard-tab-active-ink-rgb: var(--primary-40);
+ --dashboard-tab-focus-surface-rgb: var(--primary-90);
+ --dashboard-highlight-surface-rgb: var(--primary-90);
+
+ --dashboard-happy-green: rgb(var(--green-65));
+
+ /* popup panel */
+ --popup-cell-cname-ink: #0054d7; /* h260 S:100 Luv:40 */;
+ --popup-cell-label-mixed-surface: #c29100; /* TODO: fix */
+ --popup-icon-x-ink: rgb(var(--red-60));
+ --popup-power-ink-rgb: var(--primary-50);
+
+ /* horizontal line separator */
+ --hr-ink: var(--surface-2);
+
+ /* cloud widget */
+ --cloud-total-used-surface: rgb(var(--violet-60) / 25%);
+ --cloud-used-surface: rgb(var(--violet-60));
+
+ /* misc */
+ --error-surface: #c00004; /* h:12 S:100 Luv:40 */
+
+ /* codemirror */
+ --cm-active-line: rgb(var(--gray-90));
+ --cm-cursor: var(--ink-0);
+ --cm-foldmarker-ink: rgb(var(--blue-40));
+ --cm-gutter-border: var(--surface-1);
+ --cm-gutter-ink: var(--ink-3);
+ --cm-gutter-surface: var(--surface-2);
+ --cm-matchingbracket: rgb(var(--green-30));
+ --cm-merge-copy-ink: rgb(var(--blue-50));
+ --cm-merge-chunk-border: rgb(var(--surface-0-rgb) / 40%);
+ --cm-merge-chunk-surface: rgb(var(--surface-0-rgb) / 40%);
+ --cm-negative: #e32f00; /* h:15 S:100 Luv:50 */
+ --cm-positive: #008a21; /* h:130 S:100 Luv:50 */
+ --cm-selection-surface: rgb(var(--gray-80));
+ --cm-selection-focused-surface: rgb(var(--primary-80));
+ --cm-searching-ink: black;
+ --cm-searching-surface: #fee300cc /* h75 S:100 Luv:90 a:80% */;
+ --cm-search-match-surface: rgb(var(--yellow-40) / 50%);
+
+ /* syntax highlight: static filtering */
+ --sf-comment-ink: var(--ink-3);
+ --sf-def-ink: #3c3aff; /* h:266 S:100 Luv:40 */
+ --sf-directive-ink: var(--ink-1);
+ --sf-error-ink: #ff8981; /* h15 S:100 Luv:70 */
+ --sf-error-surface: #ff898133; /* h15 S:100 Luv:70 @ 20% */
+ --sf-keyword-ink: #9b00ca; /* h:290 S:100 Luv:40 */
+ --sf-notice-ink: var(--ink-4);
+ --sf-readonly-ink: var(--ink-3);
+ --sf-tag-ink: #006e2e /* h:135 S:100 Luv:40 */;
+ --sf-unicode-ink: var(--ink-1);
+ --sf-value-ink: #974900 /* h:30 S:100 Luv:40 */;
+ --sf-variable-ink: var(--ink-1);
+ --sf-warning-ink: #e49d00; /* h:50 S:100 Luv:70 */
+ --sf-warning-surface: #e49d0033; /* h:50 S:100 Luv:70 @ 20% */
+
+ /* syntax highlight: dynamic filtering */
+ --df-allow-ink: var(--cm-positive);
+ --df-block-ink: var(--cm-negative);
+ --df-noop-ink: rgb(var(--dark-gray-10));
+
+ /* logger */
+ --logger-modified-surface: #0000c010;
+ --logger-modified-em-surface: #0000c028;
+ --logger-redirected-surface: rgb(var(--yellow-5) / 50%);
+ --logger-scriptlet-surface: rgb(var(--yellow-30) / 50%);
+}
+
+/* https://material.io/design/color/dark-theme.html */
+:root.dark {
+ --elevation-down-surface: black;
+ --elevation-down1-opacity: 16%;
+ --elevation-down2-opacity: 32%;
+ --elevation-up-surface: white;
+ --elevation-up1-opacity: 12%;
+ --elevation-up2-opacity: 24%;
+
+ --ink-rgb: var(--gray-95);
+ --ink-0: white;
+ --ink-100: black;
+
+ --border-1: rgb(var(--gray-35));
+ --border-2: rgb(var(--gray-40));
+ --border-3: rgb(var(--gray-45));
+ --border-4: rgb(var(--gray-50));
+
+ --accent-surface-1: rgb(var(--primary-70));
+
+ --link-ink: rgb(var(--primary-70));
+ --link-hover-ink: rgb(var(--primary-80));
+
+ /* buttons */
+ --button-surface-rgb: var(--gray-30);
+
+ --dashboard-tab-active-ink-rgb: var(--primary-70);
+ --dashboard-tab-focus-surface-rgb: var(--primary-20);
+ --dashboard-highlight-surface-rgb: var(--primary-20);
+
+ /* popup panel */
+ --popup-cell-cname-ink: #93a6ff; /* h260 S:100 Luv:70 */;
+ --popup-cell-label-mixed-surface: hsla(45, 100%, 38%, 1); /* TODO: fix */
+ --popup-icon-x-ink: rgb(var(--red-50));
+ --popup-power-ink-rgb: var(--primary-60);
+
+ /* cloud widget */
+ --cloud-total-used-surface: rgb(var(--violet-20) / 25%);
+ --cloud-used-surface: rgb(var(--violet-20));
+
+ /* misc */
+ --error-surface: #ff5354; /* h:12 S:100 Luv:60 */
+
+ /* codemirror */
+ --cm-active-line: rgb(var(--gray-20));
+ --cm-merge-copy-ink: rgb(var(--blue-30));
+ --cm-foldmarker-ink: rgb(var(--blue-20));
+ --cm-matchingbracket: rgb(var(--green-30) / 50%);
+ --cm-negative: #ff8982; /* h:15 S:100 Luv:70 */
+ --cm-positive: #00c634; /* h:130 S:100 Luv:70 */
+ --cm-selection-surface: rgb(var(--gray-40));
+ --cm-selection-focused-surface: rgb(var(--primary-40));
+ --cm-searching-ink: black;
+ --cm-searching-surface: #fee300cc /* h75 S:100 Luv:90 a:80% */;
+
+ /* syntax highlight: static filtering */
+ --sf-comment-ink: var(--ink-3);
+ --sf-def-ink: #a2a2ff; /* h:266 S:100 Luv:70 */
+ --sf-error-ink: #ff8981; /* h15 S:100 Luv:70 */
+ --sf-error-surface: #ff898166; /* h15 S:100 Luv:70 @ 40% */
+ --sf-keyword-ink: #d78dff; /* h:290 S:100 Luv:70 */
+ --sf-tag-ink: #00c559 /* h:135 S:100 Luv:70 */;
+ --sf-value-ink: #ff8d48 /* h:30 S:100 Luv:70 */;
+ --sf-variable-ink: var(--ink-1);
+ --sf-warning-ink: #e49d00; /* h:50 S:100 Luv:70 */
+ --sf-warning-surface: #e49d0066; /* h:50 S:100 Luv:50 @ 40% */
+
+ /* syntax highlight: dynamic filtering */
+ --df-noop-ink: var(--ink-3);
+
+ /* logger */
+ --logger-modified-surface: #663efd60;
+ --logger-redirected-surface: rgb(var(--yellow-5) / 40%);
+ --logger-scriptlet-surface: rgb(var(--yellow-30) / 40%);
+}
+
+:root.dark input,
+:root.dark select,
+:root.dark textarea {
+ color-scheme: dark;
+}
+
+/*
+ * Shared declarations
+ * */
+:root {
+ --high-em: 87%;
+ --medium-em: 60%;
+ --low-em: 38%;
+
+ --surface-0: rgb(var(--surface-0-rgb));
+
+ --ink-1: rgb(var(--ink-rgb));
+ --ink-2: rgb(var(--ink-rgb) / var(--high-em));
+ --ink-3: rgb(var(--ink-rgb) / var(--medium-em));
+ --ink-4: rgb(var(--ink-rgb) / var(--low-em));
+
+ --accent-ink-1: var(--surface-0);
+ --accent-ink-3: var(--ink-1);
+
+ --subtil-ink: var(--accent-surface-1);
+
+ --fieldset-header-surface: transparent;
+ --fieldset-header-ink: var(--ink-2);
+
+ --button-ink: var(--ink-1);
+ --button-surface: rgb(var(--button-surface-rgb));
+ --button-border-radius: 5px;
+ --button-preferred-ink: var(--accent-ink-1);
+ --button-preferred-surface: var(--accent-surface-1);
+ --button-disabled-surface: var(--surface-3);
+ --button-disabled-filter: opacity(50%);
+
+ --checkbox-size: calc(var(--font-size) + 2px);
+ --checkbox-ink: var(--ink-3);
+ --checkbox-checked-ink: var(--accent-surface-1);
+ --checkbox-disabled-filter: opacity(50%);
+ --checkbox-margin-end: calc(var(--font-size) * 0.75);
+
+ --notice-ink: var(--accent-ink-1);
+ --notice-surface: var(--accent-surface-1);
+ --notice-surface-shadow: #000 0 2px 8px;
+
+ --dashboard-tab-ink: var(--ink-1);
+ --dashboard-tab-active-ink: rgb(var(--dashboard-tab-active-ink-rgb));
+ --dashboard-tab-active-surface: transparent;
+ --dashboard-tab-focus-surface: rgb(var(--dashboard-tab-focus-surface-rgb));
+ --dashboard-tab-hover-surface: var(--surface-2);
+ --dashboard-tab-hover-border: var(--surface-3);
+
+ /* info levels: normal, fyi, warn, error -- we want same Luv */
+ --info0-ink-rgb: 119 119 119; /* h: 0 S: 0 Luv:60 */
+ --info1-ink-rgb: 72 143 255; /* h:255 S:100 Luv:60 */
+ --info2-ink-rgb: 208 125 0; /* h: 40 S:100 Luv:60 */
+ --info3-ink-rgb: 255 82 94; /* h: 10 S:100 Luv:60 */
+ --info0-ink: rgb(var(--info0-ink-rgb));
+ --info1-ink: rgb(var(--info1-ink-rgb));
+ --info2-ink: rgb(var(--info2-ink-rgb));
+ --info3-ink: rgb(var(--info3-ink-rgb));
+
+ --popup-cell-surface: var(--surface-2);
+ --popup-cell-label-filter: opacity(40%);
+ --popup-cell-allow-own-surface: rgb(var(--popup-cell-allow-own-surface-rgb));
+ --popup-cell-allow-surface: rgb(var(--popup-cell-allow-surface-rgb));
+ --popup-cell-noop-own-surface: rgb(var(--popup-cell-noop-own-surface-rgb));
+ --popup-cell-noop-surface: rgb(var(--popup-cell-noop-surface-rgb));
+ --popup-cell-block-own-surface: rgb(var(--popup-cell-block-own-surface-rgb));
+ --popup-cell-block-surface: rgb(var(--popup-cell-block-surface-rgb));
+ --popup-power-ink: rgb(var(--popup-power-ink-rgb));
+ --popup-toolbar-surface: rgb(var(--primary-80) / 15%);
+ --popup-toolbar-surface-hover: rgb(var(--primary-80) / 20%);
+ --popup-ruleset-tool-ink: var(--ink-1);
+ --popup-ruleset-tool-surface: rgb(var(--primary-80) / 15%);
+ --popup-ruleset-tool-surface-hover: rgb(var(--primary-80) / 20%);
+ --popup-ruleset-tool-shadow: transparent;
+}
+
+/*
+ * Rule colors
+ * */
+:root:not(.dark):not(.colorBlind) {
+ --popup-cell-allow-own-surface-rgb: 0 127 0; /* h:127.7 S:100 Luv:45 */
+ --popup-cell-allow-surface-rgb: 129 202 129; /* h:127.7 S:50 Luv:75 */
+ --popup-cell-block-own-surface-rgb: 216 0 0; /* h:12.2 S:100 Luv:45 */
+ --popup-cell-block-surface-rgb: 224 172 172; /* h:12.2 S:50 Luv:75 */
+ --popup-cell-noop-own-surface-rgb: 107 107 107; /* h:0 S:0 Luv:45 */
+ --popup-cell-noop-surface-rgb: 185 185 185; /* h:0 S:0 Luv:75 */
+}
+
+:root.dark:not(.colorBlind) {
+ --popup-cell-allow-own-surface-rgb: 0 153 0; /* h:127.7 S:100 Luv:55 */
+ --popup-cell-allow-surface-rgb: 73 117 73; /* h:127.7 S:50 Luv:45 */
+ --popup-cell-block-own-surface-rgb: 255 40 40; /* h:12.2 S:100 Luv:55 */
+ --popup-cell-block-surface-rgb: 175 74 74; /* h:12.2 S:50 Luv:45 */
+ --popup-cell-noop-own-surface-rgb: 132 132 132; /* h:0 S:0 Luv:55 */
+ --popup-cell-noop-surface-rgb: 94 94 94; /* h:0 S:0 Luv:40 */
+}
+
+/*
+ * Source for color-blind color scheme:
+ * https://davidmathlogic.com/colorblind/
+ * First pair in "Accessible palettes"
+ *
+ * */
+:root.colorBlind {
+ --popup-cell-allow-own-surface-rgb: 151 113 0; /* h:58.5 S:100 Luv:50 */
+ --popup-cell-block-own-surface-rgb: 0 120 216; /* h:252 S:100 Luv:50 */
+ --popup-cell-noop-own-surface-rgb: 119 119 119; /* h:0 S:0 Luv:50 */
+ --popup-cell-label-mixed-surface: #ff6a00; /* TODO: fix */
+}
+:root.colorBlind:not(.dark) {
+ --popup-cell-allow-surface-rgb: 223 178 92; /* h:58.5 S:75 Luv:75 */
+ --popup-cell-block-surface-rgb: 159 185 238; /* h:252 S:75 Luv:75 */
+ --popup-cell-noop-surface-rgb: 185 185 185; /* h:0 S:0 Luv:75 */
+}
+:root.dark.colorBlind {
+ --popup-cell-allow-surface-rgb: 115 91 44; /* h:58.5 S:75 Luv:40 */
+ --popup-cell-block-surface-rgb: 53 95 154; /* h:252 S:75 Luv:40 */
+ --popup-cell-noop-surface-rgb: 94 94 94; /* h:0 S:0 Luv:40 */
+}
+
+:root.classic:not(.dark) {
+ --notice-ink: rgb(var(--ink-80));
+ --notice-surface: rgb(var(--yellow-5));
+ --popup-power-ink-rgb: 0 110 254;
+ --popup-ruleset-tool-ink: var(--ink-1);
+ --popup-ruleset-tool-surface: rgb(var(--yellow-5) / 50%);
+ --popup-ruleset-tool-surface-hover: rgb(var(--yellow-5) / 75%);
+ --popup-ruleset-tool-shadow: rgb(var(--gray-85));
+}
+
+/*
+ * Experiment: use Firefox for Android dark theme colors
+:root.mobile.dark {
+ --gray-10: 43 42 51;
+ --gray-20: 66 65 77;
+ --ink-rgb: 251 251 254;
+}
+*/
diff --git a/src/css/whitelist.css b/src/css/whitelist.css
new file mode 100644
index 0000000..715c964
--- /dev/null
+++ b/src/css/whitelist.css
@@ -0,0 +1,22 @@
+html {
+ height: 100vh;
+ overflow: hidden;
+ width: 100vw;
+ }
+body {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ justify-content: stretch;
+ overflow: hidden;
+ width: 100%;
+ }
+.body {
+ flex-shrink: 0;
+ }
+.codeMirrorContainer {
+ flex-grow: 1;
+ }
+#whitelist {
+ text-align: left;
+ }