2024-04-12 10:22:57 +00:00
|
|
|
@use 'sass:color';
|
|
|
|
@use "sass:map";
|
2023-10-20 16:05:57 +00:00
|
|
|
//
|
|
|
|
// Mixins
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
|
|
|
@mixin compact {
|
|
|
|
$selector: &;
|
|
|
|
@at-root [zoteroUIDensity="compact"] {
|
|
|
|
@if $selector {
|
|
|
|
#{$selector} {
|
|
|
|
@content;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@else {
|
|
|
|
@content;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@mixin comfortable {
|
|
|
|
$selector: &;
|
|
|
|
@at-root [zoteroUIDensity="comfortable"] {
|
|
|
|
@if $selector {
|
|
|
|
#{$selector} {
|
|
|
|
@content;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@else {
|
|
|
|
@content;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-10-24 06:36:56 +00:00
|
|
|
|
|
|
|
// @NOTE: this mixin uses `state` mixin, therefore must be used in a selector nested
|
|
|
|
// underneath selectors listed in arguments, e.g., .virtualized-table .row
|
|
|
|
// by default. See `state` mixin for more details.
|
|
|
|
@mixin focus-states(
|
2023-11-15 09:07:54 +00:00
|
|
|
$selectedState: '.row.selected',
|
|
|
|
$focused: '.virtualized-table:focus-within'
|
|
|
|
) {
|
|
|
|
@media (prefers-color-scheme: light) {
|
|
|
|
@content("light");
|
|
|
|
|
|
|
|
@include state($selectedState) {
|
|
|
|
@include state($focused) {
|
|
|
|
@content("white");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
|
|
@content("dark");
|
|
|
|
|
|
|
|
@include state($selectedState) {
|
|
|
|
@include state($focused) {
|
|
|
|
@content("white");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-10-24 06:36:56 +00:00
|
|
|
|
2023-11-15 09:07:54 +00:00
|
|
|
// An implementation of Firefox light-dark() CSS mixin, which is not supported in 102
|
|
|
|
@mixin light-dark($prop, $light-color, $dark-color) {
|
|
|
|
@media (prefers-color-scheme: light) {
|
|
|
|
#{$prop}: $light-color;
|
|
|
|
}
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
|
|
#{$prop}: $dark-color;
|
|
|
|
}
|
2023-10-24 06:36:56 +00:00
|
|
|
}
|
2023-10-27 13:00:21 +00:00
|
|
|
|
|
|
|
@mixin color-scheme {
|
|
|
|
@media (prefers-color-scheme: light) {
|
|
|
|
@content("light");
|
|
|
|
}
|
|
|
|
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
|
|
@content("dark");
|
|
|
|
}
|
2023-11-28 10:58:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@mixin clicky-item {
|
|
|
|
display: flex;
|
|
|
|
align-items: flex-start;
|
|
|
|
gap: 4px;
|
|
|
|
padding-inline-start: 4px;
|
|
|
|
overflow: hidden;
|
2023-12-24 06:26:30 +00:00
|
|
|
border-radius: 5px;
|
2023-11-28 10:58:59 +00:00
|
|
|
|
2023-12-24 06:26:30 +00:00
|
|
|
&:not([disabled]):hover {
|
2023-11-28 10:58:59 +00:00
|
|
|
background-color: var(--fill-quinary);
|
|
|
|
}
|
2023-12-24 06:26:30 +00:00
|
|
|
|
|
|
|
&:not([disabled]):active {
|
|
|
|
background-color: var(--fill-quarternary);
|
|
|
|
}
|
2023-11-28 10:58:59 +00:00
|
|
|
|
2024-01-17 20:04:29 +00:00
|
|
|
.icon {
|
|
|
|
height: calc(1.3333333333 * var(--zotero-font-size));
|
|
|
|
}
|
|
|
|
|
2023-11-28 10:58:59 +00:00
|
|
|
.label {
|
|
|
|
display: -webkit-box;
|
|
|
|
-webkit-box-orient: vertical;
|
|
|
|
-webkit-line-clamp: 10;
|
|
|
|
width: 0; // Needed to allow the label to shrink for some reason
|
|
|
|
flex: 1;
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
|
2023-12-01 16:11:02 +00:00
|
|
|
.icon, .label {
|
|
|
|
padding-block: 2px;
|
2023-11-28 10:58:59 +00:00
|
|
|
}
|
|
|
|
}
|
2023-12-01 07:43:43 +00:00
|
|
|
|
2024-01-13 02:16:08 +00:00
|
|
|
@mixin meta-table {
|
|
|
|
display: grid;
|
|
|
|
grid-template-columns: max-content 1fr;
|
2024-01-13 02:31:54 +00:00
|
|
|
column-gap: 8px;
|
2024-01-13 02:16:08 +00:00
|
|
|
row-gap: 2px;
|
|
|
|
width: inherit;
|
|
|
|
|
|
|
|
.show-on-hover {
|
|
|
|
visibility: hidden;
|
|
|
|
&.no-display {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.meta-row {
|
|
|
|
display: grid;
|
|
|
|
grid-template-columns: subgrid;
|
|
|
|
grid-column: span 2;
|
|
|
|
|
2024-01-13 13:50:24 +00:00
|
|
|
&[hidden] {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
|
2024-01-13 02:16:08 +00:00
|
|
|
// On hover of the meta-row, reveal all hidden icons
|
|
|
|
// unless there's .noHover class which keeps everything hidden
|
|
|
|
&:not(.noHover):hover .show-on-hover,
|
|
|
|
&:focus-within .show-on-hover {
|
|
|
|
visibility: visible;
|
2024-01-25 21:29:51 +00:00
|
|
|
display: revert;
|
2024-01-13 02:16:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.meta-data {
|
|
|
|
width: 0;
|
|
|
|
min-width: 100%;
|
|
|
|
display: flex;
|
|
|
|
toolbarbutton {
|
|
|
|
margin-inline-start: 4px;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
editable-text {
|
|
|
|
flex: 1; // stretch value field as much as possible
|
|
|
|
max-width: 100%; // stay within .meta-data when the itemBox is narrow
|
|
|
|
.input {
|
|
|
|
// allow input to be shrunk by other elements when the itemBox is narrow
|
|
|
|
min-width: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.meta-label {
|
|
|
|
display: flex;
|
|
|
|
font-weight: normal;
|
|
|
|
text-align: end;
|
|
|
|
color: var(--fill-secondary);
|
|
|
|
|
|
|
|
&[fieldname^="creator"] {
|
|
|
|
justify-content: space-between;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
> label {
|
|
|
|
margin-top: 2px;
|
|
|
|
@include comfortable {
|
|
|
|
margin-top: 3px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.key {
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
toolbarbutton {
|
|
|
|
@include focus-ring;
|
|
|
|
|
|
|
|
// needed to have the outline appear on all platforms
|
|
|
|
appearance: none;
|
|
|
|
-moz-appearance: none;
|
|
|
|
align-self: center;
|
|
|
|
// Make all buttons tigher to not stretch the rows
|
|
|
|
height: auto;
|
|
|
|
width: auto;
|
|
|
|
padding: 1px;
|
|
|
|
border-radius: 2px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-01 07:43:43 +00:00
|
|
|
|
|
|
|
/* Hide icons on macOS. We use :is() to work around weird behavior in Fx101 where a regular child
|
|
|
|
selector doesn't match the first time the menu is opened. */
|
|
|
|
@mixin macOS-hide-menu-icons {
|
|
|
|
$selector: &;
|
|
|
|
@at-root {
|
|
|
|
@media (-moz-platform: macos) {
|
|
|
|
// Yes, every single one of these :is-es is necessary!
|
|
|
|
:is(:is(#{$selector}) .menuitem-iconic, :is(#{$selector}) .menu-iconic) {
|
|
|
|
list-style-image: none !important;
|
|
|
|
|
|
|
|
.menu-iconic-left {
|
|
|
|
display: none !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-20 11:29:28 +00:00
|
|
|
|
|
|
|
@mixin macOS-inactive-opacity {
|
|
|
|
$selector: &;
|
|
|
|
@at-root {
|
|
|
|
@media (-moz-platform: macos) {
|
|
|
|
#{$selector} {
|
|
|
|
&:-moz-window-inactive {
|
|
|
|
opacity: 0.6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-21 14:15:48 +00:00
|
|
|
/*
|
|
|
|
This mixin replaces the default focus-rings - those are platform-specific, do not show up on some
|
|
|
|
components (e.g. toolbarbutton) and sometimes are too wide (e.g. around textfield on macOS).
|
|
|
|
Box-shadow is used to be able to set the radius.
|
|
|
|
*/
|
2024-03-02 07:51:55 +00:00
|
|
|
@mixin focus-ring($thin: false, $selector: focus-visible) {
|
|
|
|
&:#{$selector} {
|
|
|
|
@media (-moz-platform: windows) {
|
|
|
|
outline: var(--color-focus-outer-border) solid var(--width-focus-outer-border);
|
|
|
|
outline-offset: var(--width-focus-border);
|
|
|
|
box-shadow: 0 0 0 var(--width-focus-border) var(--color-focus-border);
|
|
|
|
}
|
|
|
|
|
|
|
|
@media not (-moz-platform: windows) {
|
2024-04-17 09:30:05 +00:00
|
|
|
// fx115: Necessary to hide default focus ring
|
|
|
|
outline: none;
|
2024-03-02 07:51:55 +00:00
|
|
|
box-shadow: 0 0 0 var(--width-focus-border) var(--color-focus-border);
|
|
|
|
|
|
|
|
@if $thin {
|
|
|
|
--width-focus-border: 1px;
|
|
|
|
--color-focus-border: var(--color-accent);
|
|
|
|
}
|
|
|
|
}
|
2023-12-21 14:15:48 +00:00
|
|
|
}
|
2024-03-02 07:51:55 +00:00
|
|
|
}
|
2024-04-12 10:22:57 +00:00
|
|
|
|
|
|
|
@mixin derive-colors($colors) {
|
|
|
|
@each $name, $color in $colors {
|
|
|
|
--#{$name}: #{$color};
|
|
|
|
}
|
|
|
|
|
|
|
|
// composite (opaque) colors
|
|
|
|
--color-quinary-on-background: #{color.mix(
|
|
|
|
map.get($colors, "color-background"), color.change(map.get($colors, "fill-quinary"), $alpha: 1), 100% * (1 - color.alpha(map.get($colors, "fill-quinary")))
|
|
|
|
)};
|
|
|
|
--color-quarternary-on-background: #{color.mix(
|
|
|
|
map.get($colors, "color-background"), color.change(map.get($colors, "fill-quarternary"), $alpha: 1), 100% * (1 - color.alpha(map.get($colors, "fill-quarternary")))
|
|
|
|
)};
|
|
|
|
--color-quinary-on-sidepane: #{color.mix(
|
|
|
|
map.get($colors, "color-sidepane"), color.change(map.get($colors, "fill-quinary"), $alpha: 1), 100% * (1 - color.alpha(map.get($colors, "fill-quinary")))
|
|
|
|
)};
|
|
|
|
--color-quarternary-on-sidepane: #{color.mix(
|
|
|
|
map.get($colors, "color-sidepane"), color.change(map.get($colors, "fill-quarternary"), $alpha: 1), 100% * (1 - color.alpha(map.get($colors, "fill-quarternary")))
|
|
|
|
)};
|
|
|
|
--color-stripe-on-background: #{color.mix(
|
|
|
|
map.get($colors, "color-background"), color.change(map.get($colors, "color-stripe"), $alpha: 1), 100% * (1 - color.alpha(map.get($colors, "color-stripe")))
|
|
|
|
)};
|
|
|
|
--color-menu-opaque: rgb(
|
|
|
|
#{color.alpha(map.get($colors, "color-menu")) * color.red(map.get($colors, "color-menu"))},
|
|
|
|
#{color.alpha(map.get($colors, "color-menu")) * color.green(map.get($colors, "color-menu"))},
|
|
|
|
#{color.alpha(map.get($colors, "color-menu")) * color.blue(map.get($colors, "color-menu"))}
|
|
|
|
);
|
|
|
|
|
|
|
|
// background materials
|
|
|
|
--material-background: var(--color-background);
|
|
|
|
--material-background50: var(--color-background50);
|
|
|
|
--material-background70: var(--color-background70);
|
|
|
|
--material-button: var(--color-button);
|
|
|
|
--material-control: var(--color-control);
|
|
|
|
--material-menu: var(--color-menu);
|
|
|
|
--material-sidepane: var(--color-sidepane);
|
|
|
|
--material-tabbar: var(--color-tabbar);
|
|
|
|
--material-toolbar: var(--color-toolbar);
|
|
|
|
--material-mix-quinary: var(--color-quinary-on-background);
|
|
|
|
--material-mix-quarternary: var(--color-quarternary-on-background);
|
|
|
|
--material-stripe: var(--color-stripe-on-background);
|
|
|
|
|
|
|
|
// border materials
|
|
|
|
--material-border-transparent: 1px solid transparent;
|
|
|
|
--material-border: 1px solid var(--color-border);
|
|
|
|
--material-border50: 1px solid var(--color-border50);
|
|
|
|
--material-panedivider: 1px solid var(--color-panedivider);
|
|
|
|
--material-border-quinary: 1px solid var(--fill-quinary);
|
|
|
|
--material-border-quarternary: 1px solid var(--fill-quarternary);
|
2024-04-22 19:02:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@mixin contain-richlistbox {
|
|
|
|
// richlistbox elements are crazy and will expand beyond the window size
|
|
|
|
// unless all/most elements in the hierarchy that contain that
|
|
|
|
// richlistbox have a min-height: 0 set
|
|
|
|
vbox, hbox {
|
|
|
|
min-height: 0;
|
|
|
|
}
|
|
|
|
}
|