mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Add comments to Sass variables and tweak main window (#2137)
* Prevent multiple inclusion of variables in CSS files * Use dict instead of tuple for variables * Add comments to variables * Improve appearance of main window * Tweak main window styles * Use json.dumps over pprint.format * Make study button primary * Improve header margin * Make bottom toolbar slimmer * Make congrats page more balanced * Fix type issue * Replace day/night with light/dark * Exclude top-level-drag-row from hover effect * Create dataclass for variables * Run formatter * Apply CSS variables from Python side Why go full-circle with the Sass variables? This way we only need one interface for add-on authors to interact with. It also makes it easier for us to apply additional themes in the future. * Fix typing * Fix rgba values in Qt * Darken button background * Fix palette not being applied in light theme For some odd reason this problem arose much later than #2016. * Tweak default button look * Reformat * Apply CSS vars to ts pages * Include elevation in button_mixins_lib * Cast opacity to int * Add some margin to studiedToday info * Tweak light theme button gradient * Tweak highlight-bg for light theme * Add back default button color as it made the browser sidebar tool icons dark in light theme. * Reformat * Tweak light theme buttons once more Sorry for the back-and-forth. Sass only compiles when there are changes in user files, not when I only change the vars. * Fix bottom toolbar button indicators * Make buttons more clicky * Fix button padding * Handle macOS separately again * Decrease elevation effect for main window buttons to 1 * Imitate box-shadow for Qt elements * Adjust shadow vars * Adjust primary border color because the save button in the deck options had a lighter color than its background gradient. * Boost box-shadow color of primary buttons * Format * Adjust Qt box-shadow imitation and shadow colors * Use more subtle default shadow color * Add some more padding to top toolbar * Revert "Apply CSS vars to ts pages" This reverts commit5d8e7f6b7f
. * Revert "Apply CSS variables from Python side" This reverts commit87db774412
. * Better match the standard macOS buttons In the dark theme the standard color is a lighter grey, but at least the size/shape is similar again. This doesn't work for the editor buttons. * Reduce the top margin of the congrats screen * Fix illegible buttons when changing theme on macOS; match dark button style
This commit is contained in:
parent
95d0c78b78
commit
0c340c4f74
40 changed files with 691 additions and 405 deletions
|
@ -14,7 +14,7 @@ genrule(
|
|||
genrule(
|
||||
name = "extract_sass_vars",
|
||||
srcs = [
|
||||
"//sass:_vars.css",
|
||||
"//sass:_root-vars.css",
|
||||
],
|
||||
outs = [
|
||||
"colors.py",
|
||||
|
|
|
@ -49,7 +49,7 @@ class CellRow:
|
|||
) -> None:
|
||||
self.refreshed_at: float = time.time()
|
||||
self.cells: tuple[Cell, ...] = tuple(Cell(*cell) for cell in cells)
|
||||
self.color: tuple[str, str] | None = backend_color_to_aqt_color(color)
|
||||
self.color: dict[str, str] | None = backend_color_to_aqt_color(color)
|
||||
self.font_name: str = font_name or "arial"
|
||||
self.font_size: int = font_size if font_size > 0 else 12
|
||||
|
||||
|
@ -76,7 +76,7 @@ class CellRow:
|
|||
return row
|
||||
|
||||
|
||||
def backend_color_to_aqt_color(color: BrowserRow.Color.V) -> tuple[str, str] | None:
|
||||
def backend_color_to_aqt_color(color: BrowserRow.Color.V) -> dict[str, str] | None:
|
||||
temp_color = None
|
||||
|
||||
if color == BrowserRow.COLOR_MARKED:
|
||||
|
@ -101,12 +101,11 @@ def backend_color_to_aqt_color(color: BrowserRow.Color.V) -> tuple[str, str] | N
|
|||
return adjusted_bg_color(temp_color)
|
||||
|
||||
|
||||
def adjusted_bg_color(color: tuple[str, str]) -> tuple[str, str]:
|
||||
def adjusted_bg_color(color: dict[str, str]) -> dict[str, str]:
|
||||
if color:
|
||||
return (
|
||||
QColor(color[0]).lighter(150).name(),
|
||||
QColor(color[1]).darker(150).name(),
|
||||
)
|
||||
color["light"] = QColor(color["light"]).lighter(150).name()
|
||||
color["dark"] = QColor(color["dark"]).darker(150).name()
|
||||
return color
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
|
@ -37,11 +37,13 @@ with open(input_svg, "r") as f:
|
|||
elif f"{prefix}-dark.svg" in path:
|
||||
dark_svg = path
|
||||
|
||||
for (idx, filename) in enumerate((light_svg, dark_svg)):
|
||||
data = svg_data
|
||||
def substitute(data: str, filename: str, mode: str) -> None:
|
||||
if "fill" in data:
|
||||
data = re.sub(r"fill=\"#.+?\"", f'fill="{color[idx]}"', data)
|
||||
data = re.sub(r"fill=\"#.+?\"", f'fill="{color[mode]}"', data)
|
||||
else:
|
||||
data = re.sub(r"<svg", f'<svg fill="{color[idx]}"', data, 1)
|
||||
data = re.sub(r"<svg", f'<svg fill="{color[mode]}"', data, 1)
|
||||
with open(filename, "w") as f:
|
||||
f.write(data)
|
||||
|
||||
substitute(svg_data, light_svg, "light")
|
||||
substitute(svg_data, dark_svg, "dark")
|
||||
|
|
|
@ -9,7 +9,7 @@ compile_sass(
|
|||
group = "css_local",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//sass:vars_lib",
|
||||
"//sass:base_lib",
|
||||
"//sass:buttons_lib",
|
||||
"//sass:card_counts_lib",
|
||||
"//sass:scrollbar_lib",
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* Copyright: Ankitects Pty Ltd and contributors
|
||||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||
|
||||
@use "sass/vars";
|
||||
@use "root-vars";
|
||||
@use "sass/vars" as *;
|
||||
@use "sass/card-counts";
|
||||
|
||||
a.deck {
|
||||
color: var(--fg);
|
||||
color: color(fg);
|
||||
text-decoration: none;
|
||||
min-width: 5em;
|
||||
display: inline-block;
|
||||
|
@ -15,8 +15,13 @@ a.deck:hover {
|
|||
text-decoration: underline;
|
||||
}
|
||||
|
||||
th {
|
||||
border-bottom: 1px solid color(border-subtle);
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
tr.deck td {
|
||||
border-bottom: 1px solid var(--border-faint);
|
||||
padding: 5px 12px;
|
||||
}
|
||||
|
||||
tr.top-level-drag-row td {
|
||||
|
@ -28,16 +33,30 @@ td {
|
|||
}
|
||||
|
||||
tr.drag-hover td {
|
||||
border-bottom: 1px solid var(--border);
|
||||
border-bottom: 1px solid color(border);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 1em;
|
||||
margin: 2em 1em 1em 1em;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.current {
|
||||
background-color: var(--shadow-subtle);
|
||||
.current,
|
||||
tr:hover:not(.top-level-drag-row) {
|
||||
td {
|
||||
background: color(canvas-inset);
|
||||
&:first-child {
|
||||
border-top-left-radius: prop(border-radius-large);
|
||||
border-bottom-left-radius: prop(border-radius-large);
|
||||
}
|
||||
&:last-child {
|
||||
border-top-right-radius: prop(border-radius-large);
|
||||
border-bottom-right-radius: prop(border-radius-large);
|
||||
}
|
||||
.gears {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.decktd {
|
||||
|
@ -56,14 +75,14 @@ body {
|
|||
}
|
||||
|
||||
.collapse {
|
||||
color: var(--fg);
|
||||
color: color(fg);
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.filtered {
|
||||
color: var(--accent-link) !important;
|
||||
color: color(fg-link) !important;
|
||||
}
|
||||
|
||||
.gears {
|
||||
|
@ -72,6 +91,7 @@ body {
|
|||
opacity: 0.5;
|
||||
padding-top: 0.2em;
|
||||
cursor: pointer;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.nightMode {
|
||||
|
@ -81,7 +101,7 @@ body {
|
|||
}
|
||||
|
||||
.callout {
|
||||
background: var(--border);
|
||||
background: color(border);
|
||||
padding: 1em;
|
||||
margin: 1em;
|
||||
|
||||
|
@ -89,3 +109,7 @@ body {
|
|||
margin: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
#studiedToday {
|
||||
margin: 2em 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
/* Copyright: Ankitects Pty Ltd and contributors
|
||||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||
|
||||
@use "root-vars";
|
||||
@use "sass/vars" as *;
|
||||
@use "sass/card-counts";
|
||||
@use "sass/button-mixins" as button;
|
||||
|
||||
.smallLink {
|
||||
font-size: 10px;
|
||||
|
@ -13,7 +16,7 @@ h3 {
|
|||
|
||||
.descfont {
|
||||
padding: 1em;
|
||||
color: var(--fg-subtle);
|
||||
color: color(fg-subtle);
|
||||
}
|
||||
|
||||
.description {
|
||||
|
@ -33,3 +36,7 @@ h3 {
|
|||
.dyn {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#study {
|
||||
@include button.base($primary: true);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
/* Copyright: Ankitects Pty Ltd and contributors
|
||||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||
|
||||
@use "vars";
|
||||
@use "root-vars";
|
||||
@use "sass/vars" as *;
|
||||
@use "sass/card-counts";
|
||||
|
||||
:root {
|
||||
--focus-color: #{vars.palette-of(button-focus)};
|
||||
--focus-color: #{palette-of(border-focus)};
|
||||
|
||||
.isMac {
|
||||
--focus-color: rgba(0 103 244 / 0.247);
|
||||
|
@ -17,6 +18,15 @@ body {
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
#innertable {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
#middle td[align="center"] {
|
||||
padding-top: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
button {
|
||||
min-width: 60px;
|
||||
white-space: nowrap;
|
||||
|
@ -28,7 +38,7 @@ button {
|
|||
}
|
||||
|
||||
.stat {
|
||||
padding-top: 5px;
|
||||
padding-top: 10px;
|
||||
|
||||
@media (max-width: 583px) {
|
||||
display: none;
|
||||
|
@ -36,13 +46,11 @@ button {
|
|||
}
|
||||
|
||||
.stat2 {
|
||||
padding-top: 3px;
|
||||
padding-top: 10px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.stattxt {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
@ -51,18 +59,17 @@ button {
|
|||
}
|
||||
|
||||
:focus {
|
||||
outline: 1px auto var(--focus-color);
|
||||
|
||||
.nightMode & {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px var(--focus-color);
|
||||
}
|
||||
border-color: color(border-focus);
|
||||
}
|
||||
|
||||
.nobold {
|
||||
.nobold,
|
||||
.stattxt {
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-weight: normal;
|
||||
display: inline-block;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
|
@ -74,13 +81,13 @@ button {
|
|||
}
|
||||
|
||||
#outer {
|
||||
border-top: 1px solid var(--border);
|
||||
border-top: 1px solid color(border);
|
||||
/* Better compatibility with graphics pad/touchscreen */
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.nightMode {
|
||||
#outer {
|
||||
border-top-color: var(--border-subtle);
|
||||
border-top-color: color(border-subtle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,23 @@
|
|||
/* Copyright: Ankitects Pty Ltd and contributors
|
||||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||
|
||||
@use "root-vars";
|
||||
@use "sass/vars" as *;
|
||||
@use "sass/elevation";
|
||||
@use "sass/button-mixins" as button;
|
||||
|
||||
#header {
|
||||
padding: 3px;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.tdcenter {
|
||||
white-space: nowrap;
|
||||
border-radius: prop(border-radius);
|
||||
border-bottom-left-radius: prop(border-radius-large);
|
||||
border-bottom-right-radius: prop(border-radius-large);
|
||||
@include button.base($with-hover: false);
|
||||
@include elevation.elevation(2);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
|
@ -23,28 +32,25 @@ body {
|
|||
}
|
||||
|
||||
.hitem {
|
||||
padding-right: 12px;
|
||||
padding-left: 12px;
|
||||
font-weight: bold;
|
||||
padding: 8px 14px;
|
||||
text-decoration: none;
|
||||
color: var(--fg);
|
||||
color: color(fg);
|
||||
display: inline-block;
|
||||
@include button.base($elevation: 0);
|
||||
border: none;
|
||||
&:first-child {
|
||||
padding-left: 18px;
|
||||
}
|
||||
&:last-child {
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.hitem:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hitem:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.nightMode #header {
|
||||
border-bottom-color: var(--border-subtle);
|
||||
}
|
||||
|
||||
.isMac.nightMode #header {
|
||||
border-bottom-color: var(--canvas-elevated);
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
|
@ -55,25 +61,27 @@ body {
|
|||
}
|
||||
|
||||
.spin {
|
||||
width: 16px;
|
||||
animation: spin;
|
||||
animation-duration: 2s;
|
||||
animation-iteration-count: infinite;
|
||||
display: inline-block;
|
||||
visibility: visible !important;
|
||||
animation-timing-function: linear;
|
||||
transition: all 0.2s ease-in;
|
||||
}
|
||||
|
||||
#sync-spinner {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-bottom: -3px;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.normal-sync {
|
||||
color: var(--state-new);
|
||||
color: color(state-new);
|
||||
}
|
||||
|
||||
.full-sync {
|
||||
color: var(--state-learn);
|
||||
color: color(state-learn);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ body {
|
|||
}
|
||||
|
||||
a {
|
||||
color: var(--accent-link);
|
||||
color: var(--fg-link);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ class FilteredDeckConfigDialog(QDialog):
|
|||
qconnect(self.form.search_button.clicked, self.on_search_button)
|
||||
qconnect(self.form.search_button_2.clicked, self.on_search_button_2)
|
||||
qconnect(self.form.hint_button.clicked, self.on_hint_button)
|
||||
blue = theme_manager.var(colors.ACCENT_LINK)
|
||||
blue = theme_manager.var(colors.FG_LINK)
|
||||
grey = theme_manager.var(colors.FG_DISABLED)
|
||||
self.setStyleSheet(
|
||||
f"""QPushButton[label] {{ padding: 0; border: 0 }}
|
||||
|
|
|
@ -663,12 +663,11 @@ class Reviewer:
|
|||
<table id=innertable width=100%% cellspacing=0 cellpadding=0>
|
||||
<tr>
|
||||
<td align=left width=50 valign=top class=stat>
|
||||
<br>
|
||||
<button title="%(editkey)s" onclick="pycmd('edit');">%(edit)s</button></td>
|
||||
<td align=center valign=top id=middle>
|
||||
</td>
|
||||
<td width=50 align=right valign=top class=stat><span id=time class=stattxt>
|
||||
</span><br>
|
||||
</span>
|
||||
<button onclick="pycmd('more');">%(more)s %(downArrow)s</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -688,7 +687,7 @@ time = %(time)d;
|
|||
|
||||
def _showAnswerButton(self) -> None:
|
||||
middle = """
|
||||
<span class=stattxt>{}</span><br>
|
||||
<span class=stattxt>{}</span>
|
||||
<button title="{}" id="ansbut" onclick='pycmd("ans");'>{}</button>""".format(
|
||||
self._remaining(),
|
||||
tr.actions_shortcut_key(val=tr.studying_space()),
|
||||
|
@ -805,7 +804,7 @@ time = %(time)d;
|
|||
txt = v3_labels[i - 1]
|
||||
else:
|
||||
txt = self.mw.col.sched.nextIvlStr(self.card, i, True) or " "
|
||||
return f"<span class=nobold>{txt}</span><br>"
|
||||
return f"<span class=nobold>{txt}</span>"
|
||||
|
||||
# Leeches
|
||||
##########################################################################
|
||||
|
|
|
@ -4,12 +4,13 @@ from aqt import colors, props
|
|||
from aqt.theme import ThemeManager
|
||||
|
||||
|
||||
def button_gradient(start: str, end: str) -> str:
|
||||
def button_gradient(start: str, end: str, shadow: str) -> str:
|
||||
return f"""
|
||||
qlineargradient(
|
||||
spread:pad, x1:0.5, y1:0, x2:0.5, y2:1.25,
|
||||
spread:pad, x1:0.5, y1:0, x2:0.5, y2:1,
|
||||
stop:0 {start},
|
||||
stop:1 {end}
|
||||
stop:0.94 {end}
|
||||
stop:1 {shadow}
|
||||
);
|
||||
"""
|
||||
|
||||
|
@ -62,7 +63,7 @@ QSpinBox {{
|
|||
def menu_styles(tm: ThemeManager) -> str:
|
||||
return f"""
|
||||
QMenuBar {{
|
||||
border-bottom: 1px solid {tm.var(colors.BORDER_FAINT)};
|
||||
border-bottom: 1px solid {tm.var(colors.BORDER_SUBTLE)};
|
||||
}}
|
||||
QMenuBar::item {{
|
||||
background-color: transparent;
|
||||
|
@ -111,9 +112,11 @@ QComboBox:!editable {{
|
|||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_GRADIENT_END),
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
};
|
||||
border-bottom: 1px solid {tm.var(colors.SHADOW)};
|
||||
}}
|
||||
QPushButton:hover,
|
||||
QTabBar::tab:hover,
|
||||
|
@ -121,18 +124,19 @@ QComboBox:!editable:hover {{
|
|||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_END),
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
};
|
||||
}}
|
||||
QPushButton:pressed,
|
||||
QComboBox:!editable:pressed {{
|
||||
border: 1px solid {tm.var(colors.BUTTON_PRESSED_BORDER)};
|
||||
border: 1px solid {tm.var(colors.BORDER_STRONG)};
|
||||
background: {
|
||||
button_pressed_gradient(
|
||||
tm.var(colors.BUTTON_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_GRADIENT_END),
|
||||
tm.var(colors.BUTTON_PRESSED_SHADOW)
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
};
|
||||
}}
|
||||
|
@ -190,7 +194,7 @@ QComboBox::drop-down {{
|
|||
padding: 2px;
|
||||
width: 16px;
|
||||
subcontrol-position: top right;
|
||||
border: 1px solid {tm.var(colors.BUTTON_BORDER)};
|
||||
border: 1px solid {tm.var(colors.BORDER_SUBTLE)};
|
||||
border-top-{tm.right()}-radius: {tm.var(props.BORDER_RADIUS)};
|
||||
border-bottom-{tm.right()}-radius: {tm.var(props.BORDER_RADIUS)};
|
||||
}}
|
||||
|
@ -201,17 +205,21 @@ QComboBox::drop-down {{
|
|||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_GRADIENT_END),
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
};
|
||||
border-bottom: 1px solid {tm.var(colors.SHADOW)};
|
||||
}}
|
||||
QComboBox::drop-down:hover {{
|
||||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_END),
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
};
|
||||
border-bottom: 1px solid {tm.var(colors.SHADOW)};
|
||||
}}
|
||||
"""
|
||||
|
||||
|
@ -239,6 +247,7 @@ QTabBar::tab {{
|
|||
}}
|
||||
QTabBar::tab {{
|
||||
border: 1px solid {tm.var(colors.BORDER_SUBTLE)};
|
||||
border-bottom-color: {tm.var(colors.SHADOW)};
|
||||
}}
|
||||
QTabBar::tab:first {{
|
||||
border-top-{tm.left()}-radius: {tm.var(props.BORDER_RADIUS)};
|
||||
|
@ -256,7 +265,8 @@ QTabBar::tab:selected {{
|
|||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_PRIMARY_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_PRIMARY_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_PRIMARY_GRADIENT_END),
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
};
|
||||
}}
|
||||
|
@ -268,8 +278,8 @@ def table_styles(tm: ThemeManager) -> str:
|
|||
QTableView {{
|
||||
border-radius: {tm.var(props.BORDER_RADIUS)};
|
||||
gridline-color: {tm.var(colors.BORDER_SUBTLE)};
|
||||
selection-background-color: {tm.var(colors.SELECTION_BG)};
|
||||
selection-color: {tm.var(colors.SELECTION_FG)};
|
||||
selection-background-color: {tm.var(colors.SELECTED_BG)};
|
||||
selection-color: {tm.var(colors.SELECTED_FG)};
|
||||
}}
|
||||
QHeaderView {{
|
||||
background: {tm.var(colors.CANVAS)};
|
||||
|
@ -279,18 +289,19 @@ QHeaderView::section {{
|
|||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_GRADIENT_END),
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
};
|
||||
}}
|
||||
QHeaderView::section:pressed,
|
||||
QHeaderView::section:pressed:!first {{
|
||||
border: 1px solid {tm.var(colors.BUTTON_PRESSED_BORDER)};
|
||||
border: 1px solid {tm.var(colors.BORDER_STRONG)};
|
||||
background: {
|
||||
button_pressed_gradient(
|
||||
tm.var(colors.BUTTON_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_GRADIENT_END),
|
||||
tm.var(colors.BUTTON_PRESSED_SHADOW)
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
}
|
||||
}}
|
||||
|
@ -298,7 +309,8 @@ QHeaderView::section:hover {{
|
|||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_END),
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
};
|
||||
}}
|
||||
|
@ -339,22 +351,23 @@ QSpinBox::up-button,
|
|||
QSpinBox::down-button {{
|
||||
subcontrol-origin: border;
|
||||
width: 16px;
|
||||
border: 1px solid {tm.var(colors.BUTTON_BORDER)};
|
||||
border: 1px solid {tm.var(colors.BORDER_SUBTLE)};
|
||||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_GRADIENT_END),
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
};
|
||||
}}
|
||||
QSpinBox::up-button:pressed,
|
||||
QSpinBox::down-button:pressed {{
|
||||
border: 1px solid {tm.var(colors.BUTTON_PRESSED_BORDER)};
|
||||
border: 1px solid {tm.var(colors.BORDER_STRONG)};
|
||||
background: {
|
||||
button_pressed_gradient(
|
||||
tm.var(colors.BUTTON_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_GRADIENT_END),
|
||||
tm.var(colors.BUTTON_PRESSED_SHADOW)
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
}
|
||||
}}
|
||||
|
@ -363,7 +376,8 @@ QSpinBox::down-button:hover {{
|
|||
background: {
|
||||
button_gradient(
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_START),
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_END)
|
||||
tm.var(colors.BUTTON_HOVER_GRADIENT_END),
|
||||
tm.var(colors.SHADOW)
|
||||
)
|
||||
};
|
||||
}}
|
||||
|
@ -418,7 +432,7 @@ QRadioButton {{
|
|||
QCheckBox::indicator,
|
||||
QRadioButton::indicator,
|
||||
QMenu::indicator {{
|
||||
border: 1px solid {tm.var(colors.BUTTON_BORDER)};
|
||||
border: 1px solid {tm.var(colors.BORDER_SUBTLE)};
|
||||
border-radius: {tm.var(props.BORDER_RADIUS)};
|
||||
background: {tm.var(colors.CANVAS_INSET)};
|
||||
width: 16px;
|
||||
|
|
|
@ -19,8 +19,8 @@ class Switch(QAbstractButton):
|
|||
radius: int = 10,
|
||||
left_label: str = "",
|
||||
right_label: str = "",
|
||||
left_color: tuple[str, str] = colors.ACCENT_CARD,
|
||||
right_color: tuple[str, str] = colors.ACCENT_NOTE,
|
||||
left_color: dict[str, str] = colors.ACCENT_CARD | {},
|
||||
right_color: dict[str, str] = colors.ACCENT_NOTE | {},
|
||||
parent: QWidget = None,
|
||||
) -> None:
|
||||
super().__init__(parent=parent)
|
||||
|
|
|
@ -30,16 +30,15 @@ from aqt.qt import (
|
|||
@dataclass
|
||||
class ColoredIcon:
|
||||
path: str
|
||||
# (day, night)
|
||||
color: tuple[str, str]
|
||||
color: dict[str, str]
|
||||
|
||||
def current_color(self, night_mode: bool) -> str:
|
||||
if night_mode:
|
||||
return self.color[1]
|
||||
return self.color.get("dark", "")
|
||||
else:
|
||||
return self.color[0]
|
||||
return self.color.get("light", "")
|
||||
|
||||
def with_color(self, color: tuple[str, str]) -> ColoredIcon:
|
||||
def with_color(self, color: dict[str, str]) -> ColoredIcon:
|
||||
return ColoredIcon(path=self.path, color=color)
|
||||
|
||||
|
||||
|
@ -177,12 +176,22 @@ class ThemeManager:
|
|||
"Returns body classes used when showing a card."
|
||||
return f"card card{card_ord+1} {self.body_class(night_mode)}"
|
||||
|
||||
def var(self, vars: tuple[str, str]) -> str:
|
||||
def var(self, vars: dict[str, str]) -> str:
|
||||
"""Given day/night colors/props, return the correct one for the current theme."""
|
||||
idx = 1 if self.night_mode else 0
|
||||
return vars[idx]
|
||||
return vars["dark" if self.night_mode else "light"]
|
||||
|
||||
def qcolor(self, colors: tuple[str, str]) -> QColor:
|
||||
def qcolor(self, colors: dict[str, str]) -> QColor:
|
||||
"""Create QColor instance from CSS string for the current theme."""
|
||||
|
||||
if m := re.match(
|
||||
r"rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+\.*\d+?)\)", self.var(colors)
|
||||
):
|
||||
return QColor(
|
||||
int(m.group(1)),
|
||||
int(m.group(2)),
|
||||
int(m.group(3)),
|
||||
int(255 * float(m.group(4))),
|
||||
)
|
||||
return QColor(self.var(colors))
|
||||
|
||||
def _determine_night_mode(self) -> bool:
|
||||
|
@ -257,7 +266,7 @@ class ThemeManager:
|
|||
def _apply_palette(self, app: QApplication) -> None:
|
||||
set_macos_dark_mode(self.night_mode)
|
||||
|
||||
if not self.night_mode:
|
||||
if is_mac:
|
||||
app.setStyle(QStyleFactory.create(self._default_style)) # type: ignore
|
||||
self.default_palette.setColor(
|
||||
QPalette.ColorRole.Window, self.qcolor(colors.CANVAS)
|
||||
|
@ -265,11 +274,9 @@ class ThemeManager:
|
|||
app.setPalette(self.default_palette)
|
||||
return
|
||||
|
||||
if not self.macos_dark_mode():
|
||||
app.setStyle(QStyleFactory.create("fusion")) # type: ignore
|
||||
|
||||
palette = QPalette()
|
||||
|
||||
text = self.qcolor(colors.FG)
|
||||
palette.setColor(QPalette.ColorRole.WindowText, text)
|
||||
palette.setColor(QPalette.ColorRole.ToolTipText, text)
|
||||
|
@ -277,7 +284,6 @@ class ThemeManager:
|
|||
palette.setColor(QPalette.ColorRole.ButtonText, text)
|
||||
|
||||
hlbg = self.qcolor(colors.HIGHLIGHT_BG)
|
||||
hlbg.setAlpha(64)
|
||||
palette.setColor(
|
||||
QPalette.ColorRole.HighlightedText, self.qcolor(colors.HIGHLIGHT_FG)
|
||||
)
|
||||
|
@ -287,11 +293,13 @@ class ThemeManager:
|
|||
palette.setColor(QPalette.ColorRole.Window, canvas)
|
||||
palette.setColor(QPalette.ColorRole.AlternateBase, canvas)
|
||||
|
||||
palette.setColor(QPalette.ColorRole.Button, QColor("#454545"))
|
||||
palette.setColor(
|
||||
QPalette.ColorRole.Button, self.qcolor(colors.BUTTON_GRADIENT_START)
|
||||
)
|
||||
|
||||
canvas_inset = self.qcolor(colors.CANVAS_INSET)
|
||||
palette.setColor(QPalette.ColorRole.Base, canvas_inset)
|
||||
palette.setColor(QPalette.ColorRole.ToolTipBase, canvas_inset)
|
||||
input_base = self.qcolor(colors.CANVAS_CODE)
|
||||
palette.setColor(QPalette.ColorRole.Base, input_base)
|
||||
palette.setColor(QPalette.ColorRole.ToolTipBase, input_base)
|
||||
|
||||
palette.setColor(
|
||||
QPalette.ColorRole.PlaceholderText, self.qcolor(colors.FG_SUBTLE)
|
||||
|
@ -310,7 +318,7 @@ class ThemeManager:
|
|||
disabled_color,
|
||||
)
|
||||
|
||||
palette.setColor(QPalette.ColorRole.Link, self.qcolor(colors.ACCENT_LINK))
|
||||
palette.setColor(QPalette.ColorRole.Link, self.qcolor(colors.FG_LINK))
|
||||
|
||||
palette.setColor(QPalette.ColorRole.BrightText, Qt.GlobalColor.red)
|
||||
|
||||
|
|
|
@ -196,7 +196,7 @@ class Toolbar:
|
|||
|
||||
_body = """
|
||||
<center id=outer>
|
||||
<table id=header width=100%%>
|
||||
<table id=header>
|
||||
<tr>
|
||||
<td class=tdcenter align=center>%s</td>
|
||||
</tr></table>
|
||||
|
|
|
@ -412,30 +412,32 @@ class AnkiWebView(QWebEngineView):
|
|||
family = tr.qt_misc_segoe_ui()
|
||||
button_style = f"""
|
||||
button {{ font-family: {family}; }}
|
||||
button:focus {{ outline: 5px auto {color_hl}; }}"""
|
||||
"""
|
||||
font = f"font-size:12px;font-family:{family};"
|
||||
elif is_mac:
|
||||
family = "Helvetica"
|
||||
font = f'font-size:15px;font-family:"{family}";'
|
||||
color = ""
|
||||
if not theme_manager.night_mode:
|
||||
color = "background: #fff; border: 1px solid #ccc;"
|
||||
button_style = (
|
||||
font = f'font-size:14px;font-family:"{family}";'
|
||||
button_style = """
|
||||
button {
|
||||
--canvas: #fff;
|
||||
-webkit-appearance: none;
|
||||
background: var(--canvas);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 3px 12px;
|
||||
border: 0.5px solid var(--border);
|
||||
box-shadow: 0px 1px 3px var(--border-subtle);
|
||||
font-family: Helvetica
|
||||
}
|
||||
.night-mode button { --canvas: #606060; --fg: #eee; }
|
||||
"""
|
||||
button { -webkit-appearance: none; %s
|
||||
border-radius:5px; font-family: Helvetica }"""
|
||||
% color
|
||||
)
|
||||
else:
|
||||
family = self.font().family()
|
||||
color_hl_txt = palette.color(QPalette.ColorRole.HighlightedText).name()
|
||||
font = f'font-size:14px;font-family:"{family}", sans-serif;'
|
||||
button_style = """
|
||||
/* Buttons */
|
||||
button{{
|
||||
font-family:"{family}", sans-serif; }}
|
||||
button:focus{{ border-color: {color_hl} }}
|
||||
button:active, button:active:hover {{ background-color: {color_hl}; color: {color_hl_txt};}}
|
||||
font-family: "{family}", sans-serif;
|
||||
}}
|
||||
/* Input field focus outline */
|
||||
textarea:focus, input:focus, input[type]:focus, .uneditable-input:focus,
|
||||
div[contenteditable="true"]:focus {{
|
||||
|
@ -444,7 +446,6 @@ div[contenteditable="true"]:focus {{
|
|||
}}""".format(
|
||||
family=family,
|
||||
color_hl=color_hl,
|
||||
color_hl_txt=color_hl_txt,
|
||||
)
|
||||
|
||||
zoom = self.app_zoom_factor()
|
||||
|
@ -453,8 +454,8 @@ div[contenteditable="true"]:focus {{
|
|||
body {{ zoom: {zoom}; background-color: var(--canvas); }}
|
||||
html {{ {font} }}
|
||||
{button_style}
|
||||
:root {{ --canvas: {colors.CANVAS[0]} }}
|
||||
:root[class*=night-mode] {{ --canvas: {colors.CANVAS[1]} }}
|
||||
:root {{ --canvas: {colors.CANVAS["light"]} }}
|
||||
:root[class*=night-mode] {{ --canvas: {colors.CANVAS["dark"]} }}
|
||||
"""
|
||||
|
||||
def stdHtml(
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright: Ankitects Pty Ltd and contributors
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
# bazel genrule "srcs"
|
||||
vars_css = sys.argv[1]
|
||||
root_vars_css = sys.argv[1]
|
||||
|
||||
# bazel genrule "outs"
|
||||
colors_py = sys.argv[2]
|
||||
|
@ -16,14 +15,19 @@ props_py = sys.argv[3]
|
|||
colors = {}
|
||||
props = {}
|
||||
reached_props = False
|
||||
comment = ""
|
||||
|
||||
for line in re.split(r"[;\{\}]", open(vars_css).read()):
|
||||
for line in re.split(r"[;\{\}]|\*\/", open(root_vars_css).read()):
|
||||
line = line.strip()
|
||||
|
||||
if not line:
|
||||
continue
|
||||
if line.startswith("/*!"):
|
||||
if "props" in line:
|
||||
reached_props = True
|
||||
else:
|
||||
comment = re.match(r"\/\*!\s*(.*)$", line)[1]
|
||||
continue
|
||||
|
||||
m = re.match(r"--(.+):(.+)$", line)
|
||||
|
||||
|
@ -38,39 +42,47 @@ for line in re.split(r"[;\{\}]", open(vars_css).read()):
|
|||
print("failed to match", line)
|
||||
continue
|
||||
|
||||
var = m.group(1)
|
||||
var = m.group(1).replace("-", "_").upper()
|
||||
val = m.group(2)
|
||||
|
||||
if reached_props:
|
||||
props.setdefault(var, []).append(val)
|
||||
if not var in props:
|
||||
props.setdefault(var, {})["comment"] = comment
|
||||
props[var]["light"] = val
|
||||
else:
|
||||
colors.setdefault(var, []).append(val)
|
||||
props[var]["dark"] = val
|
||||
else:
|
||||
if not var in colors:
|
||||
colors.setdefault(var, {})["comment"] = comment
|
||||
colors[var]["light"] = val
|
||||
else:
|
||||
colors[var]["dark"] = val
|
||||
|
||||
comment = ""
|
||||
|
||||
|
||||
copyright_notice = """\
|
||||
# Copyright: Ankitects Pty Ltd and contributors
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html\n
|
||||
"""
|
||||
|
||||
with open(colors_py, "w") as buf:
|
||||
buf.write(copyright_notice)
|
||||
buf.write("# this file is auto-generated from _vars.scss and _colors.scss\n")
|
||||
buf.write("# This file was automatically generated from _root-vars.scss\n")
|
||||
|
||||
for color, val in colors.items():
|
||||
day = val[0]
|
||||
night = val[1] if len(val) > 1 else day
|
||||
if not "dark" in val:
|
||||
val["dark"] = val.light
|
||||
|
||||
color = color.replace("-", "_").upper()
|
||||
buf.write(f'{color} = ("{day}", "{night}")\n')
|
||||
buf.write(re.sub(r"\"\n", '",\n', f"{color} = {json.dumps(val, indent=4)}\n"))
|
||||
|
||||
|
||||
with open(props_py, "w") as buf:
|
||||
buf.write(copyright_notice)
|
||||
buf.write("# this file is auto-generated from _vars.scss\n")
|
||||
buf.write("# This file was automatically generated from _root-vars.scss\n")
|
||||
|
||||
for prop, val in props.items():
|
||||
day = val[0]
|
||||
night = val[1] if len(val) > 1 else day
|
||||
if not "dark" in val:
|
||||
val["dark"] = val.light
|
||||
|
||||
prop = prop.replace("-", "_").upper()
|
||||
buf.write(f'{prop} = ("{day}", "{night}")\n')
|
||||
buf.write(re.sub(r"\"\n", '",\n', f"{prop} = {json.dumps(val, indent=4)}\n"))
|
||||
|
|
|
@ -17,7 +17,7 @@ sass_library(
|
|||
sass_library(
|
||||
name = "vars_lib",
|
||||
srcs = [
|
||||
"_colors.scss",
|
||||
"_color-palette.scss",
|
||||
"_functions.scss",
|
||||
"_vars.scss",
|
||||
],
|
||||
|
@ -104,7 +104,7 @@ sass_library(
|
|||
)
|
||||
|
||||
compile_sass(
|
||||
srcs = ["_vars.scss"],
|
||||
srcs = ["_root-vars.scss"],
|
||||
group = "vars_css",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||
@use "vars";
|
||||
@use "sass:color";
|
||||
@use "sass/elevation" as *;
|
||||
|
||||
@import "bootstrap/scss/functions";
|
||||
@import "bootstrap/scss/variables";
|
||||
|
||||
@mixin impressed-shadow($intensity) {
|
||||
box-shadow: inset 0 calc(var(--buttons-size) / 15) calc(var(--buttons-size) / 5)
|
||||
rgba(black, $intensity);
|
||||
box-shadow: inset 0 calc(var(--buttons-size, 10px) / 15)
|
||||
calc(var(--buttons-size, 10px) / 5) rgba(black, $intensity);
|
||||
}
|
||||
|
||||
@mixin border-radius {
|
||||
|
@ -19,13 +20,14 @@
|
|||
border-bottom-right-radius: var(--border-right-radius);
|
||||
}
|
||||
|
||||
@mixin background($primary: false) {
|
||||
@mixin background($primary: false, $elevation: 1, $hover: true) {
|
||||
@if $primary {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
var(--button-primary-gradient-start) 0%,
|
||||
var(--button-primary-gradient-end) 100%
|
||||
);
|
||||
@if $hover {
|
||||
&:hover {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
|
@ -34,12 +36,17 @@
|
|||
);
|
||||
border-color: var(--button-hover-border);
|
||||
}
|
||||
}
|
||||
@if $elevation != 0 {
|
||||
@include elevation($elevation, 0.2);
|
||||
}
|
||||
} @else {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
var(--button-gradient-start) 0%,
|
||||
var(--button-gradient-end) 100%
|
||||
);
|
||||
@if $hover {
|
||||
&:hover {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
|
@ -49,6 +56,10 @@
|
|||
border-color: var(--button-hover-border);
|
||||
}
|
||||
}
|
||||
@if $elevation != 0 {
|
||||
@include elevation($elevation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin base(
|
||||
|
@ -57,16 +68,21 @@
|
|||
$with-hover: true,
|
||||
$with-active: true,
|
||||
$active-class: "",
|
||||
$with-disabled: true
|
||||
$with-disabled: true,
|
||||
$elevation: 1
|
||||
) {
|
||||
-webkit-appearance: none;
|
||||
cursor: pointer;
|
||||
@if $border {
|
||||
border: 1px solid var(--button-border);
|
||||
@if $primary {
|
||||
border: none;
|
||||
} @else {
|
||||
border: 1px solid var(--border-subtle);
|
||||
}
|
||||
} @else {
|
||||
border: none;
|
||||
}
|
||||
@include background($primary);
|
||||
@include background($primary, $elevation, $hover: $with-hover);
|
||||
|
||||
@if ($primary) {
|
||||
color: white;
|
||||
|
@ -77,12 +93,12 @@
|
|||
@if ($with-active) {
|
||||
&:active {
|
||||
@include impressed-shadow(0.35);
|
||||
border-color: var(--button-border);
|
||||
border-color: var(--border-subtle);
|
||||
}
|
||||
@if ($active-class != "") {
|
||||
&.#{$active-class} {
|
||||
@include impressed-shadow(0.35);
|
||||
border-color: var(--button-border);
|
||||
border-color: var(--border);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* custom gray, rest from Tailwind CSS v3 palette
|
||||
* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
|
||||
|
||||
$colors: (
|
||||
$color-palette: (
|
||||
lightgray: (
|
||||
0: #fcfcfc,
|
||||
1: #fafafa,
|
||||
|
@ -26,7 +26,7 @@ $colors: (
|
|||
4: #363636,
|
||||
5: #2c2c2c,
|
||||
6: #252525,
|
||||
7: #1f1f1f,
|
||||
7: #202020,
|
||||
8: #141414,
|
||||
9: #020202,
|
||||
),
|
|
@ -6,7 +6,17 @@
|
|||
|
||||
@function create-vars-from-map($map, $theme, $name: "-", $output: ()) {
|
||||
@each $key, $value in $map {
|
||||
@if $key == $theme {
|
||||
@if $key ==
|
||||
$theme or
|
||||
(
|
||||
$key ==
|
||||
"default" and
|
||||
type-of($value) !=
|
||||
"map" and
|
||||
type-of($value) !=
|
||||
"list"
|
||||
)
|
||||
{
|
||||
@return map.set($output, $name, map.get($map, $key));
|
||||
}
|
||||
@if type-of($value) == "map" {
|
||||
|
@ -21,8 +31,24 @@
|
|||
create-vars-from-map($value, $theme, #{$name}-#{$key}, $output)
|
||||
);
|
||||
}
|
||||
} @else if $key == "default" {
|
||||
@return map.set($output, $name, map.get($map, $key));
|
||||
} @else if type-of($value) == "list" and list.length($value) > 1 {
|
||||
$next-name: #{$name}-#{$key};
|
||||
@if $key == "default" {
|
||||
$next-name: $name;
|
||||
}
|
||||
$output: map-merge(
|
||||
$output,
|
||||
(#{"comment"}#{$next-name}: list.nth($value, 1))
|
||||
);
|
||||
$output: map-merge(
|
||||
$output,
|
||||
create-vars-from-map(
|
||||
list.nth($value, 2),
|
||||
$theme,
|
||||
#{$next-name},
|
||||
$output
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@return $output;
|
||||
|
@ -30,8 +56,12 @@
|
|||
|
||||
@function map-deep-get($map, $keys) {
|
||||
@each $key in $keys {
|
||||
@if type-of($map) == "list" and list.length($map) > 1 {
|
||||
$map: map-get(list.nth($map, 2), $key);
|
||||
} @else {
|
||||
$map: map-get($map, $key);
|
||||
}
|
||||
}
|
||||
@return $map;
|
||||
}
|
||||
|
||||
|
|
50
sass/_root-vars.scss
Normal file
50
sass/_root-vars.scss
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* Copyright: Ankitects Pty Ltd and contributors
|
||||
* License: GNU AGPL, version 3 or later, http://www.gnu.org/licenses/agpl.html */
|
||||
|
||||
@use "sass:map";
|
||||
@use "vars" as *;
|
||||
@use "functions" as *;
|
||||
|
||||
/*! colors */
|
||||
:root {
|
||||
$colors: map.get($vars, colors);
|
||||
@each $name, $val in create-vars-from-map($colors, light) {
|
||||
@if str-index($name, "comment") == 1 {
|
||||
/*! #{$val} */
|
||||
} @else {
|
||||
#{$name}: #{$val};
|
||||
}
|
||||
}
|
||||
color-scheme: light;
|
||||
&.night-mode {
|
||||
@each $name, $val in create-vars-from-map($colors, dark) {
|
||||
@if str-index($name, "comment") == 1 {
|
||||
/*! #{$val} */
|
||||
} @else {
|
||||
#{$name}: #{$val};
|
||||
}
|
||||
}
|
||||
color-scheme: dark;
|
||||
}
|
||||
}
|
||||
|
||||
/*! props */
|
||||
:root {
|
||||
$props: map.get($vars, props);
|
||||
@each $name, $val in create-vars-from-map($props, light) {
|
||||
@if str-index($name, "comment") == 1 {
|
||||
/*! #{$val} */
|
||||
} @else {
|
||||
#{$name}: #{$val};
|
||||
}
|
||||
}
|
||||
&.night-mode {
|
||||
@each $name, $val in create-vars-from-map($props, dark) {
|
||||
@if str-index($name, "comment") == 1 {
|
||||
/*! #{$val} */
|
||||
} @else {
|
||||
#{$name}: #{$val};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
291
sass/_vars.scss
291
sass/_vars.scss
|
@ -4,296 +4,439 @@
|
|||
@use "sass:map";
|
||||
@use "sass:color";
|
||||
@use "functions" as *;
|
||||
@use "colors" as *;
|
||||
@use "color-palette" as *;
|
||||
|
||||
@function palette($key, $shade) {
|
||||
$color: map.get($colors, $key);
|
||||
$color: map.get($color-palette, $key);
|
||||
@return map.get($color, $shade);
|
||||
}
|
||||
|
||||
$vars: (
|
||||
props: (
|
||||
border-radius: (
|
||||
default: (
|
||||
"Used to round corners of various UI elements",
|
||||
(
|
||||
default: 5px,
|
||||
),
|
||||
),
|
||||
large: (
|
||||
"Used for big centered buttons",
|
||||
(
|
||||
default: 15px,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
colors: (
|
||||
white: (
|
||||
default: white,
|
||||
),
|
||||
black: (
|
||||
default: black,
|
||||
),
|
||||
fg: (
|
||||
default: (
|
||||
"Default text/icon color",
|
||||
(
|
||||
light: palette(darkgray, 9),
|
||||
dark: palette(lightgray, 0),
|
||||
),
|
||||
),
|
||||
subtle: (
|
||||
"Placeholder text, icons in idle state",
|
||||
(
|
||||
light: palette(darkgray, 6),
|
||||
dark: palette(lightgray, 3),
|
||||
),
|
||||
),
|
||||
disabled: (
|
||||
"Foreground color of disabled UI elements",
|
||||
(
|
||||
light: palette(lightgray, 9),
|
||||
dark: palette(darkgray, 0),
|
||||
),
|
||||
),
|
||||
faint: (
|
||||
"Foreground color that barely stands out against canvas",
|
||||
(
|
||||
light: palette(lightgray, 7),
|
||||
dark: palette(darkgray, 2),
|
||||
),
|
||||
),
|
||||
link: (
|
||||
"Hyperlink foreground color",
|
||||
(
|
||||
light: palette(blue, 7),
|
||||
dark: palette(blue, 2),
|
||||
),
|
||||
),
|
||||
),
|
||||
canvas: (
|
||||
default: (
|
||||
light: palette(lightgray, 3),
|
||||
"Window background",
|
||||
(
|
||||
light: palette(lightgray, 2),
|
||||
dark: palette(darkgray, 5),
|
||||
),
|
||||
),
|
||||
elevated: (
|
||||
"Slightly brighter than window background",
|
||||
(
|
||||
light: white,
|
||||
dark: palette(darkgray, 4),
|
||||
),
|
||||
),
|
||||
inset: (
|
||||
light: palette(lightgray, 4),
|
||||
"Slightly darker than window background",
|
||||
(
|
||||
light: palette(lightgray, 3),
|
||||
dark: palette(darkgray, 6),
|
||||
),
|
||||
),
|
||||
overlay: (
|
||||
"Background of floating elements (menus, tooltips)",
|
||||
(
|
||||
light: palette(lightgray, 0),
|
||||
dark: palette(darkgray, 5),
|
||||
),
|
||||
),
|
||||
code: (
|
||||
"Background of code editors",
|
||||
(
|
||||
light: white,
|
||||
dark: palette(darkgray, 6),
|
||||
),
|
||||
),
|
||||
),
|
||||
border: (
|
||||
default: (
|
||||
"Border color with medium contrast against window background",
|
||||
(
|
||||
light: palette(lightgray, 6),
|
||||
dark: palette(darkgray, 4),
|
||||
),
|
||||
strong: (
|
||||
light: palette(lightgray, 9),
|
||||
dark: palette(darkgray, 1),
|
||||
),
|
||||
subtle: (
|
||||
light: palette(lightgray, 5),
|
||||
dark: palette(darkgray, 7),
|
||||
),
|
||||
faint: (
|
||||
),
|
||||
subtle: (
|
||||
"Border color with low contrast against window background",
|
||||
(
|
||||
light: palette(lightgray, 4),
|
||||
dark: palette(darkgray, 6),
|
||||
),
|
||||
focus: (
|
||||
light: palette(blue, 5),
|
||||
dark: palette(blue, 5),
|
||||
),
|
||||
),
|
||||
button: (
|
||||
border: (
|
||||
light: palette(lightgray, 6),
|
||||
dark: palette(darkgray, 6),
|
||||
),
|
||||
focus: (
|
||||
light: palette(cyan, 3),
|
||||
dark: palette(cyan, 4),
|
||||
),
|
||||
pressed: (
|
||||
shadow: (
|
||||
light: palette(lightgray, 7),
|
||||
dark: palette(darkgray, 7),
|
||||
),
|
||||
border: (
|
||||
strong: (
|
||||
"Border color with high contrast against window background",
|
||||
(
|
||||
light: palette(lightgray, 9),
|
||||
dark: palette(darkgray, 9),
|
||||
),
|
||||
),
|
||||
focus: (
|
||||
"Border color of focused input elements",
|
||||
(
|
||||
light: palette(blue, 5),
|
||||
dark: palette(blue, 5),
|
||||
),
|
||||
),
|
||||
),
|
||||
button: (
|
||||
disabled: (
|
||||
"Background color of disabled buttons",
|
||||
(
|
||||
light: color.scale(palette(lightgray, 5), $alpha: -50%),
|
||||
dark: color.scale(palette(darkgray, 3), $alpha: -50%),
|
||||
),
|
||||
),
|
||||
gradient: (
|
||||
start: (
|
||||
"Start value of default button gradient",
|
||||
(
|
||||
light: white,
|
||||
dark: palette(darkgray, 3),
|
||||
dark: palette(darkgray, 4),
|
||||
),
|
||||
),
|
||||
end: (
|
||||
light: palette(lightgray, 1),
|
||||
dark: palette(darkgray, 4),
|
||||
"End value of default button gradient",
|
||||
(
|
||||
light: palette(lightgray, 3),
|
||||
dark: palette(darkgray, 5),
|
||||
),
|
||||
),
|
||||
),
|
||||
hover: (
|
||||
gradient: (
|
||||
start: (
|
||||
"Start value of default button gradient in hover state",
|
||||
(
|
||||
light: palette(lightgray, 1),
|
||||
dark: palette(darkgray, 2),
|
||||
),
|
||||
end: (
|
||||
light: palette(lightgray, 4),
|
||||
dark: palette(darkgray, 3),
|
||||
),
|
||||
),
|
||||
end: (
|
||||
"End value of default button gradient in hover state",
|
||||
(
|
||||
light: palette(lightgray, 2),
|
||||
dark: palette(darkgray, 4),
|
||||
),
|
||||
),
|
||||
),
|
||||
border: (
|
||||
"Border color of default button in hover state",
|
||||
(
|
||||
light: palette(lightgray, 8),
|
||||
dark: palette(darkgray, 8),
|
||||
),
|
||||
),
|
||||
),
|
||||
primary: (
|
||||
gradient: (
|
||||
start: (
|
||||
"Start value of primary button gradient",
|
||||
(
|
||||
light: palette(blue, 4),
|
||||
dark: color.scale(palette(blue, 6), $saturation: -10%),
|
||||
),
|
||||
),
|
||||
end: (
|
||||
"End value of primary button gradient",
|
||||
(
|
||||
light: palette(blue, 6),
|
||||
dark: color.scale(palette(blue, 8), $saturation: -10%),
|
||||
),
|
||||
),
|
||||
),
|
||||
hover: (
|
||||
gradient: (
|
||||
start: (
|
||||
"Start value of primary button gradient in hover state",
|
||||
(
|
||||
light: palette(blue, 3),
|
||||
dark: color.scale(palette(blue, 5), $saturation: -10%),
|
||||
),
|
||||
),
|
||||
end: (
|
||||
"End value of primary button gradient in hover state",
|
||||
(
|
||||
light: palette(blue, 5),
|
||||
dark: color.scale(palette(blue, 7), $saturation: -10%),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
disabled: (
|
||||
"Background of primary button in disabled state",
|
||||
(
|
||||
light: palette(blue, 3),
|
||||
dark: color.scale(palette(blue, 5), $saturation: -10%),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
scrollbar: (
|
||||
bg: (
|
||||
default: (
|
||||
"Background of scrollbar in idle state (Win/Lin only)",
|
||||
(
|
||||
light: palette(lightgray, 5),
|
||||
dark: palette(darkgray, 4),
|
||||
),
|
||||
),
|
||||
hover: (
|
||||
"Background of scrollbar in hover state (Win/Lin only)",
|
||||
(
|
||||
light: palette(lightgray, 6),
|
||||
dark: palette(darkgray, 3),
|
||||
),
|
||||
),
|
||||
active: (
|
||||
"Background of scrollbar in pressed state (Win/Lin only)",
|
||||
(
|
||||
light: palette(lightgray, 7),
|
||||
dark: palette(darkgray, 1),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
shadow: (
|
||||
default: (
|
||||
light: palette(lightgray, 8),
|
||||
"Default box-shadow color",
|
||||
(
|
||||
light: palette(lightgray, 6),
|
||||
dark: palette(darkgray, 7),
|
||||
),
|
||||
),
|
||||
inset: (
|
||||
light: palette(lightgray, 9),
|
||||
"Inset box-shadow color",
|
||||
(
|
||||
light: palette(darkgray, 3),
|
||||
dark: palette(darkgray, 7),
|
||||
),
|
||||
),
|
||||
subtle: (
|
||||
light: palette(lightgray, 5),
|
||||
dark: palette(darkgray, 6),
|
||||
"Box-shadow color with lower contrast against window background",
|
||||
(
|
||||
light: palette(darkgray, 0),
|
||||
dark: palette(darkgray, 4),
|
||||
),
|
||||
),
|
||||
focus: (
|
||||
"Box-shadow color for elements in focused state",
|
||||
(
|
||||
default: palette(indigo, 5),
|
||||
),
|
||||
),
|
||||
),
|
||||
accent: (
|
||||
card: (
|
||||
"Accent color for cards",
|
||||
(
|
||||
light: palette(blue, 4),
|
||||
dark: palette(blue, 3),
|
||||
),
|
||||
),
|
||||
note: (
|
||||
"Accent color for notes",
|
||||
(
|
||||
light: palette(green, 5),
|
||||
dark: palette(green, 4),
|
||||
),
|
||||
link: (
|
||||
light: palette(blue, 7),
|
||||
dark: palette(blue, 2),
|
||||
),
|
||||
danger: (
|
||||
"Saturated accent color to grab attention",
|
||||
(
|
||||
light: palette(red, 5),
|
||||
dark: palette(red, 4),
|
||||
),
|
||||
),
|
||||
),
|
||||
flag: (
|
||||
1: (
|
||||
"Flag 1 (red)",
|
||||
(
|
||||
light: palette(red, 5),
|
||||
dark: palette(red, 4),
|
||||
),
|
||||
),
|
||||
2: (
|
||||
"Flag 2 (orange)",
|
||||
(
|
||||
light: palette(orange, 4),
|
||||
dark: palette(orange, 3),
|
||||
),
|
||||
),
|
||||
3: (
|
||||
"Flag 3 (green)",
|
||||
(
|
||||
light: palette(green, 4),
|
||||
dark: palette(green, 3),
|
||||
),
|
||||
),
|
||||
4: (
|
||||
"Flag 4 (blue)",
|
||||
(
|
||||
light: palette(blue, 5),
|
||||
dark: palette(blue, 4),
|
||||
),
|
||||
),
|
||||
5: (
|
||||
"Flag 5 (pink)",
|
||||
(
|
||||
light: palette(fuchsia, 4),
|
||||
dark: palette(fuchsia, 3),
|
||||
),
|
||||
),
|
||||
6: (
|
||||
"Flag 6 (turquoise)",
|
||||
(
|
||||
light: palette(teal, 4),
|
||||
dark: palette(teal, 3),
|
||||
),
|
||||
),
|
||||
7: (
|
||||
"Flag 7 (purple)",
|
||||
(
|
||||
light: palette(purple, 5),
|
||||
dark: palette(purple, 4),
|
||||
),
|
||||
),
|
||||
),
|
||||
state: (
|
||||
new: (
|
||||
"Accent color for new cards",
|
||||
(
|
||||
light: palette(blue, 5),
|
||||
dark: palette(blue, 3),
|
||||
),
|
||||
),
|
||||
learn: (
|
||||
"Accent color for cards in learning state",
|
||||
(
|
||||
light: palette(red, 6),
|
||||
dark: palette(red, 4),
|
||||
),
|
||||
),
|
||||
review: (
|
||||
"Accent color for cards in review state",
|
||||
(
|
||||
light: palette(green, 6),
|
||||
dark: palette(green, 5),
|
||||
),
|
||||
),
|
||||
buried: (
|
||||
"Accent color for buried cards",
|
||||
(
|
||||
light: palette(amber, 5),
|
||||
dark: palette(amber, 8),
|
||||
),
|
||||
),
|
||||
suspended: (
|
||||
"Accent color for suspended cards",
|
||||
(
|
||||
light: palette(yellow, 4),
|
||||
dark: palette(yellow, 1),
|
||||
),
|
||||
),
|
||||
marked: (
|
||||
"Accent color for marked cards",
|
||||
(
|
||||
light: palette(indigo, 2),
|
||||
dark: palette(purple, 5),
|
||||
),
|
||||
),
|
||||
),
|
||||
highlight: (
|
||||
bg: (
|
||||
light: color.scale(palette(blue, 3), $alpha: -33%),
|
||||
dark: color.scale(palette(blue, 4), $alpha: -33%),
|
||||
"Background color of highlighted items",
|
||||
(
|
||||
light: color.scale(palette(blue, 6), $alpha: -50%),
|
||||
dark: color.scale(palette(blue, 3), $alpha: -50%),
|
||||
),
|
||||
),
|
||||
fg: (
|
||||
"Foreground color of highlighted items",
|
||||
(
|
||||
light: black,
|
||||
dark: white,
|
||||
),
|
||||
),
|
||||
selection: (
|
||||
),
|
||||
selected: (
|
||||
bg: (
|
||||
"Background color of selected text",
|
||||
(
|
||||
light: color.scale(palette(lightgray, 5), $alpha: -50%),
|
||||
dark: color.scale(palette(blue, 3), $alpha: -50%),
|
||||
),
|
||||
),
|
||||
fg: (
|
||||
"Foreground color of selected text",
|
||||
(
|
||||
light: black,
|
||||
dark: white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@function prop($keyword) {
|
||||
@return var(--#{$keyword});
|
||||
}
|
||||
|
||||
@function color($keyword) {
|
||||
@return var(--#{$keyword});
|
||||
}
|
||||
|
@ -302,41 +445,3 @@ $vars: (
|
|||
$colors: map.get($vars, colors);
|
||||
@return get-value-from-map($colors, $keyword, $theme);
|
||||
}
|
||||
|
||||
@function prop($keyword) {
|
||||
@return var(--#{$keyword});
|
||||
}
|
||||
|
||||
/*! colors */
|
||||
:root {
|
||||
$colors: map.get($vars, colors);
|
||||
@each $name, $val in create-vars-from-map($colors, light) {
|
||||
#{$name}: #{$val};
|
||||
}
|
||||
color-scheme: light;
|
||||
&.night-mode {
|
||||
@each $name, $val in create-vars-from-map($colors, dark) {
|
||||
#{$name}: #{$val};
|
||||
}
|
||||
color-scheme: dark;
|
||||
}
|
||||
}
|
||||
|
||||
/*! props */
|
||||
:root {
|
||||
$props: map.get($vars, props);
|
||||
@each $name, $val in create-vars-from-map($props, default) {
|
||||
#{$name}: #{$val};
|
||||
}
|
||||
@each $name, $val in create-vars-from-map($props, light) {
|
||||
#{$name}: #{$val};
|
||||
}
|
||||
&.night-mode {
|
||||
@each $name, $val in create-vars-from-map($props, default) {
|
||||
#{$name}: #{$val};
|
||||
}
|
||||
@each $name, $val in create-vars-from-map($props, dark) {
|
||||
#{$name}: #{$val};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
@use "vars";
|
||||
@use "vars" as *;
|
||||
@use "root-vars";
|
||||
@use "scrollbar";
|
||||
@use "button-mixins" as button;
|
||||
|
||||
$body-color: var(--fg);
|
||||
$body-bg: var(--canvas);
|
||||
$body-color: color(fg);
|
||||
$body-bg: color(canvas);
|
||||
|
||||
$link-hover-color: var(--accent-link);
|
||||
$link-hover-color: color(fg-link);
|
||||
$link-hover-decoration: none;
|
||||
|
||||
$utilities: (
|
||||
|
@ -53,6 +54,7 @@ body {
|
|||
button {
|
||||
/* override transition for instant hover response */
|
||||
transition: color 0.15s ease-in-out, box-shadow 0.15s ease-in-out !important;
|
||||
border-radius: prop(border-radius);
|
||||
}
|
||||
|
||||
pre,
|
||||
|
@ -82,12 +84,12 @@ samp {
|
|||
}
|
||||
.form-select:focus {
|
||||
outline: none;
|
||||
border: 1px solid var(--border-focus);
|
||||
border: 1px solid color(border-focus);
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.night-mode .form-select:disabled {
|
||||
background-color: var(--fg-disabled);
|
||||
background-color: color(fg-disabled);
|
||||
}
|
||||
|
||||
.reduced-motion * {
|
||||
|
@ -104,10 +106,10 @@ select {
|
|||
|
||||
&:focus,
|
||||
&.focus {
|
||||
border: 1px solid var(--border-focus);
|
||||
border: 1px solid color(border-focus);
|
||||
}
|
||||
option {
|
||||
background: var(--canvas-elevated);
|
||||
color: var(--fg);
|
||||
background: color(canvas-elevated);
|
||||
color: color(fg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
@use "vars";
|
||||
@use "button-mixins" as button;
|
||||
@use "elevation" as *;
|
||||
|
||||
:root {
|
||||
--focus-color: #{vars.palette-of(shadow-focus)};
|
||||
|
@ -22,7 +23,11 @@
|
|||
}
|
||||
|
||||
button {
|
||||
outline: none !important;
|
||||
@include button.base;
|
||||
border-radius: var(--border-radius);
|
||||
padding: 5px 10px;
|
||||
@include elevation(1);
|
||||
border-radius: var(--border-radius-large);
|
||||
padding: 8px 10px;
|
||||
font-weight: 500;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@ body {
|
|||
}
|
||||
|
||||
a {
|
||||
color: var(--accent-link);
|
||||
color: var(--fg-link);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Heavily inspired by https://github.com/material-components/material-components-web/tree/master/packages/mdc-elevation
|
||||
@use "sass:color";
|
||||
@use "sass:map";
|
||||
@use "sass:list";
|
||||
|
||||
|
@ -64,21 +65,23 @@ $ambient-opacity: 0.12;
|
|||
$penumbra-z-value: map.get($penumbra-map, $level);
|
||||
$ambient-z-value: map.get($ambient-map, $level);
|
||||
|
||||
$umbra-color: rgba($color, $umbra-opacity + $opacity-boost);
|
||||
$penumbra-color: rgba($color, $penumbra-opacity + $opacity-boost);
|
||||
$ambient-color: rgba($color, $ambient-opacity + $opacity-boost);
|
||||
$umbra-color: color.adjust(rgba($color, $umbra-opacity), $alpha: $opacity-boost);
|
||||
$penumbra-color: color.adjust(
|
||||
rgba($color, $penumbra-opacity),
|
||||
$alpha: $opacity-boost
|
||||
);
|
||||
$ambient-color: color.adjust(
|
||||
rgba($color, $ambient-opacity),
|
||||
$alpha: $opacity-boost
|
||||
);
|
||||
|
||||
@return (
|
||||
#{"#{$umbra-z-value} #{$umbra-color}"},
|
||||
#{"#{$penumbra-z-value} #{$penumbra-color}"},
|
||||
#{$umbra-z-value} $umbra-color,
|
||||
#{$penumbra-z-value} $penumbra-color,
|
||||
#{$ambient-z-value} $ambient-color
|
||||
);
|
||||
}
|
||||
|
||||
@mixin elevation($level, $opacity-boost: 0, $color: black) {
|
||||
@mixin elevation($level, $opacity-boost: 0, $color: #141414) {
|
||||
box-shadow: box-shadow($level, $opacity-boost, $color);
|
||||
}
|
||||
|
||||
@mixin elevation-transition() {
|
||||
transition: box-shadow 80ms cubic-bezier(0.33, 1, 0.68, 1);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
@use "sass/vars";
|
||||
@use "sass/bootstrap-dark";
|
||||
|
||||
@import "sass/base";
|
||||
|
|
|
@ -20,10 +20,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@use "sass/vars";
|
||||
@use "sass/vars" as *;
|
||||
.popover {
|
||||
border-radius: 5px;
|
||||
background-color: var(--canvas-elevated);
|
||||
background-color: color(canvas-elevated);
|
||||
min-width: var(--popover-width, 1rem);
|
||||
max-width: 95vw;
|
||||
|
||||
|
@ -31,20 +31,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
padding: var(--popover-padding-block, 6px) var(--popover-padding-inline, 6px);
|
||||
|
||||
font-size: 1rem;
|
||||
color: var(--fg);
|
||||
color: color(fg);
|
||||
|
||||
/* outer border */
|
||||
border: 1px solid vars.palette(lightgray, 6);
|
||||
border: 1px solid palette(lightgray, 6);
|
||||
|
||||
&.dark {
|
||||
border-color: vars.palette(darkgray, 9);
|
||||
border-color: palette(darkgray, 9);
|
||||
}
|
||||
|
||||
/* inner border */
|
||||
box-shadow: inset 0 0 0 1px vars.palette(lightgray, 3);
|
||||
box-shadow: inset 0 0 0 1px palette(lightgray, 3);
|
||||
|
||||
&.dark {
|
||||
box-shadow: inset 0 0 0 1px vars.palette(darkgray, 2);
|
||||
box-shadow: inset 0 0 0 1px palette(darkgray, 2);
|
||||
}
|
||||
&.scrollable {
|
||||
max-height: 80vh;
|
||||
|
|
|
@ -75,13 +75,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
.chevron {
|
||||
position: absolute;
|
||||
inset: 0 0 0 auto;
|
||||
border-left: 1px solid var(--button-border);
|
||||
border-left: 1px solid var(--border-subtle);
|
||||
}
|
||||
:global([dir="rtl"]) {
|
||||
.chevron {
|
||||
inset: 0 auto 0 0;
|
||||
border-left: none;
|
||||
border-right: 1px solid var(--button-border);
|
||||
border-right: 1px solid var(--border-subtle);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -102,6 +102,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
input {
|
||||
width: 100%;
|
||||
padding: 0.2rem 1.5rem 0.2rem 0.75rem;
|
||||
background: var(--canvas-elevated);
|
||||
color: var(--fg);
|
||||
border: none;
|
||||
outline: none;
|
||||
text-align: center;
|
||||
|
@ -120,7 +122,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
button {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
@include button.base($border: false);
|
||||
@include button.base($border: false, $elevation: 0);
|
||||
|
||||
&.left {
|
||||
inset: 0 auto 0 0;
|
||||
|
|
|
@ -29,7 +29,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
<Container --gutter-block="1rem" --gutter-inline="2px" breakpoint="sm">
|
||||
<Col --col-justify="center">
|
||||
<div class="congrats">
|
||||
<h3>{congrats}</h3>
|
||||
<h1>{congrats}</h1>
|
||||
|
||||
<p>{nextLearnMsg}</p>
|
||||
|
||||
|
@ -66,17 +66,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
<style lang="scss">
|
||||
.congrats {
|
||||
margin-top: 2em;
|
||||
max-width: 30em;
|
||||
font-size: var(--base-font-size);
|
||||
|
||||
:global(a) {
|
||||
color: var(--accent-link);
|
||||
color: var(--fg-link);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@use "sass/root-vars";
|
||||
@import "sass/base";
|
||||
|
||||
@import "sass/bootstrap/scss/containers";
|
||||
|
|
|
@ -118,7 +118,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
border-radius: 5px;
|
||||
border: 1px solid var(--border);
|
||||
|
||||
@include elevation-transition;
|
||||
@include elevation(1);
|
||||
|
||||
&:focus-within {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* Copyright: Ankitects Pty Ltd and contributors
|
||||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||
@use "sass/vars";
|
||||
@use "sass:color";
|
||||
@use "sass/button-mixins" as button;
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
@use "sass/vars";
|
||||
@use "sass/bootstrap-dark";
|
||||
|
||||
@import "sass/base";
|
||||
|
|
|
@ -143,7 +143,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
.search-link:hover {
|
||||
cursor: pointer;
|
||||
color: var(--accent-link);
|
||||
color: var(--fg-link);
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@use "sass/base";
|
||||
@use "root-vars";
|
||||
@use "sass/button-mixins" as button;
|
||||
|
||||
label,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
@use "sass/vars";
|
||||
@use "sass/bootstrap-dark";
|
||||
|
||||
@import "sass/base";
|
||||
|
|
|
@ -33,7 +33,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@use "sass/vars";
|
||||
@use "sass/button-mixins" as button;
|
||||
|
||||
.autocomplete-item {
|
||||
|
|
Loading…
Reference in a new issue