mirror of
https://github.com/pepaskopec-blip/Graduately.git
synced 2026-10-27 15:14:35 +00:00
moved the css to an external file
This commit is contained in:
parent
b35ade2957
commit
4cc68e3e46
5 changed files with 804 additions and 769 deletions
|
|
@ -60,3 +60,10 @@ else()
|
|||
target_compile_options(maturita PRIVATE
|
||||
-Wall -Wextra -Wno-deprecated-declarations)
|
||||
endif()
|
||||
|
||||
# The GTK stylesheet is loaded at runtime from the working directory, so keep
|
||||
# a copy next to the built binary as well.
|
||||
add_custom_command(TARGET maturita POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/style.css
|
||||
$<TARGET_FILE_DIR:maturita>/style.css)
|
||||
|
|
|
|||
1
Makefile
1
Makefile
|
|
@ -46,6 +46,7 @@ bundle: $(TARGET)
|
|||
@rm -rf dist
|
||||
@mkdir -p dist
|
||||
@cp $(TARGET) dist/
|
||||
@cp style.css dist/
|
||||
@ldd $(TARGET) | grep -Ei '/(ucrt64|mingw64)/bin/' | awk '{print $$3}' \
|
||||
| xargs -r -I{} cp -f {} dist/
|
||||
@echo "Bundled into dist/ - run dist/$(TARGET)"
|
||||
|
|
|
|||
22
README.md
22
README.md
|
|
@ -300,6 +300,7 @@ saved per unit to `progress/unit1.conf` / `progress/unit2.conf` /
|
|||
|
||||
```
|
||||
maturita.c entire application (UI, navigation, themes, exercises)
|
||||
style.css GTK stylesheet (palette colors are injected at runtime)
|
||||
Makefile build & run targets (Linux, macOS, MSYS2); `make bundle` on Windows
|
||||
CMakeLists.txt optional CMake build (Linux / macOS)
|
||||
build-windows.bat legacy MSVC build (requires Visual Studio + gvsbuild GTK)
|
||||
|
|
@ -317,12 +318,13 @@ progress/ created at runtime
|
|||
|
||||
The app ships with ten palettes – Catppuccin, Nord, Dracula, Rose Pine, Ocean,
|
||||
Gruvbox, Solarized, Everforest, Monokai and One Dark – each available in dark
|
||||
and light mode. Colors are defined as theme palettes in `maturita.c` and
|
||||
applied through a generated CSS stylesheet (plus matching Cairo colors for the
|
||||
roadmap rails and icons).
|
||||
and light mode. Colors are defined as theme palettes in `maturita.c`, injected
|
||||
as `@define-color` bindings, and combined with the rules in the external
|
||||
`style.css` stylesheet (plus matching Cairo colors for the roadmap rails and
|
||||
icons).
|
||||
|
||||
Change the look from the in-app settings panel, or edit the palette tables /
|
||||
`build_theme_css()` in `maturita.c` and rebuild.
|
||||
Change the look from the in-app settings panel, or edit the palette tables in
|
||||
`maturita.c` / the rules in `style.css` and rebuild.
|
||||
|
||||
### Languages
|
||||
|
||||
|
|
@ -647,6 +649,7 @@ prvním dokončení).
|
|||
|
||||
```
|
||||
maturita.c celá aplikace (UI, navigace, témata, cvičení)
|
||||
style.css GTK styl (barvy palety se vkládají za běhu)
|
||||
Makefile build & run (Linux, macOS, MSYS2); `make bundle` na Windows
|
||||
CMakeLists.txt volitelný CMake build (Linux / macOS)
|
||||
build-windows.bat legacy MSVC build (vyžaduje Visual Studio + gvsbuild GTK)
|
||||
|
|
@ -664,11 +667,12 @@ progress/ vzniká za běhu
|
|||
|
||||
Aplikace má deset palet – Catppuccin, Nord, Dracula, Rose Pine, Ocean, Gruvbox,
|
||||
Solarized, Everforest, Monokai a One Dark – každou ve světlém i tmavém režimu.
|
||||
Barvy jsou v `maturita.c` a aplikují se přes generované CSS (a Cairo barvy pro
|
||||
koleje a ikony na mapě).
|
||||
Barvy jsou v `maturita.c`, vkládají se jako `@define-color` a spojují se s
|
||||
pravidly v externím souboru `style.css` (a Cairo barvy pro koleje a ikony na
|
||||
mapě).
|
||||
|
||||
Vzhled změníte v nastavení, nebo upravte tabulky palet / `build_theme_css()` v
|
||||
`maturita.c` a znovu zkompilujte.
|
||||
Vzhled změníte v nastavení, nebo upravte tabulky palet v `maturita.c` / pravidla
|
||||
v `style.css` a znovu zkompilujte.
|
||||
|
||||
### Jazyky
|
||||
|
||||
|
|
|
|||
804
maturita.c
804
maturita.c
|
|
@ -10,6 +10,7 @@
|
|||
#define NUM_SUBJECTS 13
|
||||
#define NET_SUBJ 1 /* index of "Správa počítačových sítí" */
|
||||
|
||||
#define CSS_FILE "style.css"
|
||||
#define PROGRESS_DIR "progress"
|
||||
#define PROGRESS_U1 "progress/unit1.conf"
|
||||
#define PROGRESS_U2 "progress/unit2.conf"
|
||||
|
|
@ -1058,771 +1059,54 @@ static void apply_language(void) {
|
|||
net_slide_apply();
|
||||
}
|
||||
|
||||
static char *read_css_file(void) {
|
||||
gchar *contents = NULL;
|
||||
GError *err = NULL;
|
||||
|
||||
if (!g_file_get_contents(CSS_FILE, &contents, NULL, &err)) {
|
||||
g_warning("Could not load stylesheet '%s': %s", CSS_FILE,
|
||||
err ? err->message : "unknown error");
|
||||
if (err)
|
||||
g_error_free(err);
|
||||
return g_strdup("");
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
|
||||
/* The palette is data-driven, so its @define-color bindings are generated
|
||||
* here and prepended to the rules loaded from the external stylesheet. */
|
||||
static char *build_theme_css(const ThemePalette *p) {
|
||||
return g_strdup_printf(
|
||||
"@define-color bg_crust #%06x;"
|
||||
"@define-color bg_base #%06x;"
|
||||
"@define-color bg_mantle #%06x;"
|
||||
"@define-color bg_surface0 #%06x;"
|
||||
"@define-color bg_surface1 #%06x;"
|
||||
"@define-color bg_surface2 #%06x;"
|
||||
"@define-color fg_overlay #%06x;"
|
||||
"@define-color fg_text #%06x;"
|
||||
"@define-color fg_subtext #%06x;"
|
||||
"@define-color accent #%06x;"
|
||||
"@define-color accent2 #%06x;"
|
||||
"@define-color accent3 #%06x;"
|
||||
"@define-color success #%06x;"
|
||||
"@define-color success2 #%06x;"
|
||||
"@define-color warning #%06x;"
|
||||
"@define-color error #%06x;"
|
||||
"@define-color on_accent #%06x;"
|
||||
"@define-color node_bg #%06x;"
|
||||
"@define-color locked_bg #%06x;"
|
||||
"@define-color locked_border #%06x;"
|
||||
"window {"
|
||||
" background-color: @bg_base;"
|
||||
" background-image: linear-gradient(160deg, @bg_crust 0%%, @bg_base 40%%, @bg_surface0 100%%);"
|
||||
"}"
|
||||
"button {"
|
||||
" background-image: none;"
|
||||
"}"
|
||||
".app-title {"
|
||||
" color: @fg_text;"
|
||||
" font-weight: 700;"
|
||||
" font-size: 14px;"
|
||||
"}"
|
||||
".settings-btn,"
|
||||
".settings-btn:hover,"
|
||||
".settings-btn:active,"
|
||||
".settings-btn:checked,"
|
||||
".settings-btn:focus,"
|
||||
".settings-btn:focus-visible {"
|
||||
" min-width: 34px;"
|
||||
" min-height: 34px;"
|
||||
" padding: 0;"
|
||||
" border-radius: 999px;"
|
||||
" background: transparent;"
|
||||
" background-color: transparent;"
|
||||
" background-image: none;"
|
||||
" border: none;"
|
||||
" outline: none;"
|
||||
" box-shadow: none;"
|
||||
" color: @fg_text;"
|
||||
"}"
|
||||
".settings-btn:hover {"
|
||||
" color: @accent;"
|
||||
" background-color: alpha(@bg_surface0, 0.55);"
|
||||
"}"
|
||||
".settings-btn:active {"
|
||||
" color: @accent;"
|
||||
" background-color: alpha(@bg_surface1, 0.4);"
|
||||
"}"
|
||||
"popover,"
|
||||
"popover.background,"
|
||||
".settings-popover {"
|
||||
" background: @bg_mantle;"
|
||||
" background-color: @bg_mantle;"
|
||||
" color: @fg_text;"
|
||||
" border: 1px solid @bg_surface1;"
|
||||
" border-radius: 18px;"
|
||||
" box-shadow: 0 18px 40px alpha(@bg_crust, 0.45);"
|
||||
"}"
|
||||
"popover > contents,"
|
||||
".settings-popover > contents {"
|
||||
" background: transparent;"
|
||||
" background-color: transparent;"
|
||||
" border: none;"
|
||||
" border-radius: 18px;"
|
||||
" box-shadow: none;"
|
||||
" padding: 0;"
|
||||
"}"
|
||||
".settings-box {"
|
||||
" background-color: transparent;"
|
||||
" color: @fg_text;"
|
||||
" min-width: 292px;"
|
||||
" padding: 16px 16px 14px 16px;"
|
||||
"}"
|
||||
".settings-title {"
|
||||
" color: @fg_text;"
|
||||
" font-size: 17px;"
|
||||
" font-weight: 800;"
|
||||
" letter-spacing: -0.2px;"
|
||||
"}"
|
||||
".settings-label {"
|
||||
" color: @fg_overlay;"
|
||||
" font-size: 11px;"
|
||||
" font-weight: 700;"
|
||||
" letter-spacing: 0.8px;"
|
||||
"}"
|
||||
".settings-seg {"
|
||||
" background-color: alpha(@bg_surface0, 0.55);"
|
||||
" border: none;"
|
||||
" border-radius: 12px;"
|
||||
" padding: 3px;"
|
||||
"}"
|
||||
".mode-chip {"
|
||||
" background-image: none;"
|
||||
" background-color: transparent;"
|
||||
" color: @fg_subtext;"
|
||||
" border: none;"
|
||||
" border-radius: 10px;"
|
||||
" padding: 9px 12px;"
|
||||
" font-size: 13px;"
|
||||
" font-weight: 600;"
|
||||
" min-width: 0;"
|
||||
" box-shadow: none;"
|
||||
" transition: background-color 140ms ease, color 140ms ease,"
|
||||
" box-shadow 140ms ease;"
|
||||
"}"
|
||||
".mode-chip:hover {"
|
||||
" background-color: alpha(@bg_surface1, 0.28);"
|
||||
" color: @fg_text;"
|
||||
"}"
|
||||
".mode-chip:checked {"
|
||||
" background-image: linear-gradient(135deg, @accent 0%%, @accent2 100%%);"
|
||||
" color: @on_accent;"
|
||||
" font-weight: 800;"
|
||||
" box-shadow: 0 4px 12px alpha(@accent, 0.25);"
|
||||
"}"
|
||||
".mode-chip:checked:hover {"
|
||||
" background-image: linear-gradient(135deg, @accent 0%%, @accent2 100%%);"
|
||||
" color: @on_accent;"
|
||||
"}"
|
||||
".theme-grid {"
|
||||
" background-color: transparent;"
|
||||
" border: none;"
|
||||
" padding: 0;"
|
||||
"}"
|
||||
"flowboxchild {"
|
||||
" padding: 0;"
|
||||
" margin: 0;"
|
||||
" background: transparent;"
|
||||
" border: none;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
".theme-card {"
|
||||
" background-image: none;"
|
||||
" background-color: transparent;"
|
||||
" color: @fg_text;"
|
||||
" border: none;"
|
||||
" border-radius: 12px;"
|
||||
" padding: 6px 4px;"
|
||||
" min-width: 0;"
|
||||
" box-shadow: none;"
|
||||
" transition: background-color 140ms ease;"
|
||||
"}"
|
||||
".theme-card:hover {"
|
||||
" background-color: alpha(@bg_surface0, 0.45);"
|
||||
"}"
|
||||
".theme-card:checked {"
|
||||
" background-color: transparent;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
".theme-card:checked:hover {"
|
||||
" background-color: alpha(@bg_surface0, 0.35);"
|
||||
"}"
|
||||
".theme-card-name {"
|
||||
" color: @fg_subtext;"
|
||||
" font-size: 11px;"
|
||||
" font-weight: 600;"
|
||||
"}"
|
||||
".theme-card:checked .theme-card-name {"
|
||||
" color: @fg_text;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
"headerbar,"
|
||||
"headerbar.titlebar,"
|
||||
".titlebar {"
|
||||
" background-color: @bg_base;"
|
||||
" background-image: none;"
|
||||
" color: @fg_text;"
|
||||
" box-shadow: none;"
|
||||
" border: none;"
|
||||
"}"
|
||||
"windowcontrols button:not(:hover) {"
|
||||
" color: @fg_text;"
|
||||
"}"
|
||||
"windowcontrols button:not(:hover) image {"
|
||||
" color: @fg_text;"
|
||||
"}"
|
||||
".heading {"
|
||||
" color: @fg_text;"
|
||||
" font-size: 32px;"
|
||||
" font-weight: 800;"
|
||||
"}"
|
||||
".card {"
|
||||
" background-color: alpha(@bg_surface0, 0.92);"
|
||||
" border: 1px solid @bg_surface1;"
|
||||
" border-radius: 18px;"
|
||||
" padding: 30px 34px;"
|
||||
" color: @fg_text;"
|
||||
" font-size: 16px;"
|
||||
"}"
|
||||
".btn-primary {"
|
||||
" background-image: linear-gradient(135deg, @accent 0%%, @accent2 100%%);"
|
||||
" color: @on_accent;"
|
||||
" font-size: 16px;"
|
||||
" font-weight: 700;"
|
||||
" padding: 12px 40px;"
|
||||
" border: none;"
|
||||
" border-radius: 999px;"
|
||||
" box-shadow: 0 6px 18px alpha(@accent, 0.25);"
|
||||
" transition: box-shadow 150ms ease, background-image 150ms ease;"
|
||||
"}"
|
||||
".btn-primary:hover {"
|
||||
" box-shadow: 0 8px 24px alpha(@accent, 0.45);"
|
||||
" background-image: linear-gradient(135deg, @accent2 0%%, @accent3 100%%);"
|
||||
"}"
|
||||
".btn-primary:active {"
|
||||
" box-shadow: 0 3px 10px alpha(@accent, 0.35);"
|
||||
"}"
|
||||
".roadmap-title {"
|
||||
" color: @fg_text;"
|
||||
" font-size: 28px;"
|
||||
" font-weight: 800;"
|
||||
"}"
|
||||
".roadmap-sub {"
|
||||
" color: @fg_subtext;"
|
||||
" font-size: 14px;"
|
||||
"}"
|
||||
".back-btn {"
|
||||
" min-width: 42px;"
|
||||
" min-height: 42px;"
|
||||
" padding: 0;"
|
||||
" border-radius: 999px;"
|
||||
" background-color: alpha(@bg_surface0, 0.9);"
|
||||
" border: 1px solid @bg_surface1;"
|
||||
" color: @fg_text;"
|
||||
" box-shadow: 0 4px 14px alpha(@bg_crust, 0.35);"
|
||||
" transition: background-color 150ms ease, color 150ms ease,"
|
||||
" border-color 150ms ease, box-shadow 150ms ease;"
|
||||
"}"
|
||||
".back-btn:hover {"
|
||||
" background-color: @bg_surface1;"
|
||||
" border-color: @bg_surface2;"
|
||||
" color: @accent;"
|
||||
" box-shadow: 0 6px 20px alpha(@accent, 0.35);"
|
||||
"}"
|
||||
".back-btn:active {"
|
||||
" background-color: @bg_surface0;"
|
||||
" box-shadow: 0 2px 8px alpha(@bg_crust, 0.35);"
|
||||
"}"
|
||||
".unit-node {"
|
||||
" background-image: none;"
|
||||
" background-color: @node_bg;"
|
||||
" color: @fg_text;"
|
||||
" border: 2px solid @locked_border;"
|
||||
" border-radius: 999px;"
|
||||
" padding: 0;"
|
||||
" box-shadow: 0 4px 14px alpha(@bg_crust, 0.35);"
|
||||
" transition: transform 150ms ease, box-shadow 150ms ease,"
|
||||
" border-color 150ms ease;"
|
||||
"}"
|
||||
".unit-node.done {"
|
||||
" background-image: linear-gradient(135deg, @success 0%%, @success2 100%%);"
|
||||
" border-color: @success;"
|
||||
" color: @on_accent;"
|
||||
" box-shadow: 0 4px 16px alpha(@success, 0.35);"
|
||||
"}"
|
||||
".unit-node.current {"
|
||||
" background-image: linear-gradient(135deg, @accent 0%%, @accent2 55%%, @accent3 100%%);"
|
||||
" border-color: @accent;"
|
||||
" color: @on_accent;"
|
||||
" box-shadow: 0 4px 18px alpha(@accent, 0.5),"
|
||||
" 0 0 0 4px alpha(@bg_base, 0.9),"
|
||||
" 0 0 0 7px alpha(@accent, 0.45);"
|
||||
"}"
|
||||
".unit-node.done:hover,"
|
||||
".unit-node.current:hover {"
|
||||
" transition: box-shadow 150ms ease, border-color 150ms ease;"
|
||||
"}"
|
||||
".unit-node.done:hover {"
|
||||
" box-shadow: 0 8px 22px alpha(@success, 0.5);"
|
||||
"}"
|
||||
".unit-node.current:hover {"
|
||||
" box-shadow: 0 8px 26px alpha(@accent, 0.65),"
|
||||
" 0 0 0 4px alpha(@bg_base, 0.9),"
|
||||
" 0 0 0 7px alpha(@accent, 0.55);"
|
||||
"}"
|
||||
".unit-node.locked {"
|
||||
" background-image: none;"
|
||||
" background-color: @locked_bg;"
|
||||
" border: 2px solid @locked_border;"
|
||||
" color: @fg_overlay;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
".unit-node.locked:hover {"
|
||||
" transform: none;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
".unit-node.finish {"
|
||||
" background-color: transparent;"
|
||||
" background-image: none;"
|
||||
" border: none;"
|
||||
" color: @fg_overlay;"
|
||||
" box-shadow: 0 4px 14px alpha(@bg_crust, 0.35);"
|
||||
"}"
|
||||
".unit-node.finish:hover {"
|
||||
" transform: none;"
|
||||
" box-shadow: 0 4px 14px alpha(@bg_crust, 0.35);"
|
||||
"}"
|
||||
".unit-node:focus,"
|
||||
".unit-node:focus-visible,"
|
||||
".unit-node:hover {"
|
||||
" outline: none;"
|
||||
"}"
|
||||
".unit-number {"
|
||||
" font-size: 24px;"
|
||||
" font-weight: 800;"
|
||||
"}"
|
||||
".unit-node.done .unit-number,"
|
||||
".unit-node.current .unit-number {"
|
||||
" color: @on_accent;"
|
||||
"}"
|
||||
".unit-node.locked .unit-number {"
|
||||
" color: @fg_overlay;"
|
||||
"}"
|
||||
".state-icon {"
|
||||
" color: @on_accent;"
|
||||
"}"
|
||||
".unit-node.locked .lock-icon {"
|
||||
" color: @bg_surface2;"
|
||||
"}"
|
||||
".unit-name {"
|
||||
" color: @fg_text;"
|
||||
" font-size: 13px;"
|
||||
" font-weight: 600;"
|
||||
"}"
|
||||
".unit-name-locked {"
|
||||
" color: @fg_overlay;"
|
||||
"}"
|
||||
".ex-bubble {"
|
||||
" min-width: 64px;"
|
||||
" min-height: 64px;"
|
||||
" padding: 0;"
|
||||
" border-radius: 999px;"
|
||||
" background-color: @node_bg;"
|
||||
" color: @fg_text;"
|
||||
" border: 2px solid @locked_border;"
|
||||
" box-shadow: 0 4px 14px alpha(@bg_crust, 0.35);"
|
||||
" transition: border-color 150ms ease, box-shadow 150ms ease;"
|
||||
"}"
|
||||
".ex-bubble:hover {"
|
||||
" background-image: none;"
|
||||
" border-color: @accent;"
|
||||
" box-shadow: 0 6px 20px alpha(@accent, 0.35);"
|
||||
"}"
|
||||
".ex-bubble.done {"
|
||||
" background-image: linear-gradient(135deg, @success 0%%, @success2 100%%);"
|
||||
" border-color: @success;"
|
||||
" color: @on_accent;"
|
||||
" box-shadow: 0 4px 16px alpha(@success, 0.35);"
|
||||
"}"
|
||||
".ex-bubble.done:hover {"
|
||||
" box-shadow: 0 8px 22px alpha(@success, 0.5);"
|
||||
"}"
|
||||
".ex-bubble:focus,"
|
||||
".ex-bubble:focus-visible {"
|
||||
" outline: none;"
|
||||
"}"
|
||||
".bubble-number {"
|
||||
" font-size: 22px;"
|
||||
" font-weight: 800;"
|
||||
"}"
|
||||
".ex-bubble.done .bubble-number {"
|
||||
" color: @on_accent;"
|
||||
"}"
|
||||
".bubble-icon {"
|
||||
" color: @on_accent;"
|
||||
"}"
|
||||
".ex-label {"
|
||||
" color: @fg_text;"
|
||||
" font-size: 12px;"
|
||||
" font-weight: 600;"
|
||||
"}"
|
||||
".ex-prompt {"
|
||||
" color: @fg_text;"
|
||||
" font-size: 16px;"
|
||||
" font-weight: 500;"
|
||||
"}"
|
||||
".ex-sub {"
|
||||
" color: @fg_subtext;"
|
||||
" font-size: 13px;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
".hint {"
|
||||
" color: @fg_subtext;"
|
||||
" font-size: 13px;"
|
||||
" font-style: italic;"
|
||||
"}"
|
||||
".meaning {"
|
||||
" color: @fg_subtext;"
|
||||
" font-size: 13px;"
|
||||
" font-style: italic;"
|
||||
"}"
|
||||
".u3-answer {"
|
||||
" color: @success;"
|
||||
" font-size: 13px;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
".notes-card {"
|
||||
" background-color: alpha(@bg_surface0, 0.9);"
|
||||
" border: 1px solid @bg_surface1;"
|
||||
" border-radius: 24px;"
|
||||
" padding: 24px 34px;"
|
||||
" box-shadow: 0 10px 30px alpha(@bg_crust, 0.20);"
|
||||
"}"
|
||||
".notes-kicker {"
|
||||
" color: @accent2;"
|
||||
" font-weight: 800;"
|
||||
" letter-spacing: 2px;"
|
||||
"}"
|
||||
".notes-title {"
|
||||
" color: @fg_text;"
|
||||
" font-weight: 800;"
|
||||
"}"
|
||||
".notes-body {"
|
||||
" color: @fg_text;"
|
||||
"}"
|
||||
".notes-tip {"
|
||||
" color: @success2;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
".dlg-speaker {"
|
||||
" color: @accent;"
|
||||
" font-weight: 700;"
|
||||
" font-size: 15px;"
|
||||
"}"
|
||||
".number-big {"
|
||||
" color: @warning;"
|
||||
" font-size: 26px;"
|
||||
" font-weight: 800;"
|
||||
"}"
|
||||
".hm-word {"
|
||||
" color: @fg_text;"
|
||||
" font-family: monospace;"
|
||||
" font-size: 30px;"
|
||||
" font-weight: 800;"
|
||||
"}"
|
||||
".chain {"
|
||||
" color: @warning;"
|
||||
" font-size: 20px;"
|
||||
" font-weight: 700;"
|
||||
" letter-spacing: 1px;"
|
||||
"}"
|
||||
"entry {"
|
||||
" background-color: @bg_mantle;"
|
||||
" color: @fg_text;"
|
||||
" border: 1px solid @bg_surface1;"
|
||||
" border-radius: 10px;"
|
||||
" padding: 8px 12px;"
|
||||
" font-size: 15px;"
|
||||
" caret-color: @accent;"
|
||||
"}"
|
||||
"entry:focus {"
|
||||
" border-color: @accent;"
|
||||
"}"
|
||||
"combobox {"
|
||||
" background-color: @bg_mantle;"
|
||||
" color: @fg_text;"
|
||||
"}"
|
||||
"combobox button {"
|
||||
" background-image: none;"
|
||||
" background-color: @bg_mantle;"
|
||||
" color: @fg_text;"
|
||||
" border: 1px solid @bg_surface1;"
|
||||
" border-radius: 10px;"
|
||||
" padding: 4px 10px;"
|
||||
"}"
|
||||
"combobox button:hover {"
|
||||
" background-image: none;"
|
||||
" border-color: @accent;"
|
||||
"}"
|
||||
"combobox.answer-ok button {"
|
||||
" border-color: @success;"
|
||||
" background-color: alpha(@success, 0.12);"
|
||||
"}"
|
||||
"combobox.answer-wrong button {"
|
||||
" border-color: @error;"
|
||||
" background-color: alpha(@error, 0.12);"
|
||||
"}"
|
||||
"entry.answer-ok {"
|
||||
" border-color: @success;"
|
||||
" background-color: alpha(@success, 0.08);"
|
||||
"}"
|
||||
"entry.answer-wrong {"
|
||||
" border-color: @error;"
|
||||
" background-color: alpha(@error, 0.08);"
|
||||
"}"
|
||||
".pill {"
|
||||
" background-image: none;"
|
||||
" background-color: @node_bg;"
|
||||
" color: @fg_text;"
|
||||
" border: 2px solid @locked_border;"
|
||||
" border-radius: 999px;"
|
||||
" padding: 6px 18px;"
|
||||
" font-size: 15px;"
|
||||
" transition: border-color 150ms ease, box-shadow 150ms ease;"
|
||||
"}"
|
||||
".pill:hover {"
|
||||
" background-image: none;"
|
||||
" background-color: @node_bg;"
|
||||
" border-color: @accent;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
".pill:active {"
|
||||
" background-image: none;"
|
||||
" background-color: @bg_surface1;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
".pill:checked {"
|
||||
" background-image: linear-gradient(135deg, @accent 0%%, @accent2 100%%);"
|
||||
" color: @on_accent;"
|
||||
" border-color: @accent;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
".pill.ok {"
|
||||
" border-color: @success;"
|
||||
" box-shadow: 0 0 0 2px alpha(@success, 0.4);"
|
||||
"}"
|
||||
".pill.wrong {"
|
||||
" border-color: @error;"
|
||||
" box-shadow: 0 0 0 2px alpha(@error, 0.4);"
|
||||
"}"
|
||||
".pill.hm-key {"
|
||||
" padding: 4px 5px;"
|
||||
" min-width: 32px;"
|
||||
" font-size: 13px;"
|
||||
"}"
|
||||
".chip {"
|
||||
" background-image: none;"
|
||||
" background-color: @bg_surface1;"
|
||||
" color: @fg_text;"
|
||||
" border: 1px solid @bg_surface2;"
|
||||
" border-radius: 999px;"
|
||||
" padding: 6px 14px;"
|
||||
" font-size: 14px;"
|
||||
" font-weight: 600;"
|
||||
" transition: background-color 150ms ease, border-color 150ms ease;"
|
||||
"}"
|
||||
".chip:hover {"
|
||||
" background-image: none;"
|
||||
" background-color: @bg_surface2;"
|
||||
" border-color: @accent;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
".chip:active {"
|
||||
" background-image: none;"
|
||||
" background-color: @bg_surface2;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
".chip.ghost-host {"
|
||||
" opacity: 0;"
|
||||
"}"
|
||||
".group-btn {"
|
||||
" background-image: none;"
|
||||
" background-color: @node_bg;"
|
||||
" color: @fg_text;"
|
||||
" border: 2px solid @locked_border;"
|
||||
" border-radius: 12px;"
|
||||
" padding: 8px 18px;"
|
||||
" font-size: 14px;"
|
||||
" font-weight: 700;"
|
||||
" transition: border-color 150ms ease, box-shadow 150ms ease;"
|
||||
"}"
|
||||
".group-btn:hover {"
|
||||
" background-image: none;"
|
||||
" background-color: @node_bg;"
|
||||
" border-color: @accent;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
".group-btn:active {"
|
||||
" background-image: none;"
|
||||
" background-color: @bg_surface1;"
|
||||
" box-shadow: none;"
|
||||
"}"
|
||||
".group-btn:checked {"
|
||||
" background-image: linear-gradient(135deg, @accent3 0%%, @success2 100%%);"
|
||||
" color: @on_accent;"
|
||||
" border-color: @accent3;"
|
||||
"}"
|
||||
".group-panel {"
|
||||
" background-color: alpha(@bg_surface0, 0.5);"
|
||||
" border: 2px dashed @bg_surface1;"
|
||||
" border-radius: 14px;"
|
||||
" padding: 10px;"
|
||||
"}"
|
||||
".group-panel-label {"
|
||||
" color: @fg_subtext;"
|
||||
" font-size: 13px;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
".sent-group {"
|
||||
" background-color: alpha(@bg_surface0, 0.5);"
|
||||
" border: 1px solid @bg_surface1;"
|
||||
" border-radius: 14px;"
|
||||
" padding: 12px;"
|
||||
"}"
|
||||
".sent-group.ok {"
|
||||
" border-color: @success;"
|
||||
"}"
|
||||
".sent-group.wrong {"
|
||||
" border-color: @error;"
|
||||
"}"
|
||||
".feedback-ok {"
|
||||
" color: @success;"
|
||||
" font-size: 15px;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
".feedback-err {"
|
||||
" color: @error;"
|
||||
" font-size: 15px;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
".stats-page {"
|
||||
" padding: 8px 28px 24px 28px;"
|
||||
"}"
|
||||
".stats-summary {"
|
||||
" margin-top: 8px;"
|
||||
" margin-bottom: 18px;"
|
||||
"}"
|
||||
".stats-metric {"
|
||||
" background-color: alpha(@bg_surface0, 0.92);"
|
||||
" border: 1px solid @bg_surface1;"
|
||||
" border-radius: 16px;"
|
||||
" padding: 16px 18px;"
|
||||
" min-width: 120px;"
|
||||
"}"
|
||||
".stats-metric-value {"
|
||||
" color: @fg_text;"
|
||||
" font-size: 26px;"
|
||||
" font-weight: 800;"
|
||||
" letter-spacing: -0.4px;"
|
||||
"}"
|
||||
".stats-metric-label {"
|
||||
" color: @fg_overlay;"
|
||||
" font-size: 11px;"
|
||||
" font-weight: 700;"
|
||||
" letter-spacing: 0.8px;"
|
||||
" margin-top: 4px;"
|
||||
"}"
|
||||
".stats-overall-bar,"
|
||||
".stats-overall-bar trough,"
|
||||
".stats-unit-bar,"
|
||||
".stats-unit-bar trough {"
|
||||
" min-height: 10px;"
|
||||
" border-radius: 999px;"
|
||||
" background-color: alpha(@bg_surface1, 0.85);"
|
||||
" border: none;"
|
||||
" padding: 0;"
|
||||
"}"
|
||||
".stats-overall-bar {"
|
||||
" margin-bottom: 22px;"
|
||||
" min-height: 12px;"
|
||||
"}"
|
||||
".stats-overall-bar progress,"
|
||||
".stats-unit-bar progress {"
|
||||
" min-height: 10px;"
|
||||
" border-radius: 999px;"
|
||||
" background-image: linear-gradient(90deg, @accent 0%%, @accent2 100%%);"
|
||||
" background-color: @accent;"
|
||||
" border: none;"
|
||||
"}"
|
||||
".stats-unit-bar.done progress {"
|
||||
" background-image: linear-gradient(90deg, @success 0%%, @success2 100%%);"
|
||||
" background-color: @success;"
|
||||
"}"
|
||||
".stats-section {"
|
||||
" color: @fg_overlay;"
|
||||
" font-size: 11px;"
|
||||
" font-weight: 700;"
|
||||
" letter-spacing: 0.8px;"
|
||||
" margin-bottom: 10px;"
|
||||
"}"
|
||||
".stats-subject {"
|
||||
" margin-bottom: 20px;"
|
||||
"}"
|
||||
".stats-subject-name {"
|
||||
" color: @fg_text;"
|
||||
" font-size: 16px;"
|
||||
" font-weight: 800;"
|
||||
"}"
|
||||
".stats-subject-count {"
|
||||
" color: @fg_subtext;"
|
||||
" font-size: 13px;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
".stats-subject-count.locked {"
|
||||
" color: @fg_overlay;"
|
||||
"}"
|
||||
".stats-subject-bar,"
|
||||
".stats-subject-bar trough {"
|
||||
" min-height: 12px;"
|
||||
" border-radius: 999px;"
|
||||
" background-color: alpha(@bg_surface1, 0.85);"
|
||||
" border: none;"
|
||||
" padding: 0;"
|
||||
"}"
|
||||
".stats-subject-bar {"
|
||||
" margin: 4px 0 0 0;"
|
||||
"}"
|
||||
".stats-subject-bar progress {"
|
||||
" min-height: 10px;"
|
||||
" border-radius: 999px;"
|
||||
" background-image: linear-gradient(90deg, @accent 0%%, @accent2 100%%);"
|
||||
" background-color: @accent;"
|
||||
" border: none;"
|
||||
"}"
|
||||
".stats-units {"
|
||||
" margin-top: 8px;"
|
||||
" border-left: 2px solid alpha(@fg_overlay, 0.22);"
|
||||
" padding-left: 12px;"
|
||||
"}"
|
||||
".stats-unit-row {"
|
||||
" background-color: alpha(@bg_surface0, 0.72);"
|
||||
" border: 1px solid @bg_surface1;"
|
||||
" border-radius: 14px;"
|
||||
" padding: 12px 14px;"
|
||||
" margin-bottom: 8px;"
|
||||
"}"
|
||||
".stats-unit-row.locked {"
|
||||
" opacity: 0.55;"
|
||||
"}"
|
||||
".stats-unit-row.done {"
|
||||
" border-color: alpha(@success, 0.55);"
|
||||
"}"
|
||||
".stats-unit-index {"
|
||||
" color: @fg_overlay;"
|
||||
" font-size: 13px;"
|
||||
" font-weight: 700;"
|
||||
" min-width: 22px;"
|
||||
"}"
|
||||
".stats-unit-name {"
|
||||
" color: @fg_text;"
|
||||
" font-size: 15px;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
".stats-unit-count {"
|
||||
" color: @fg_subtext;"
|
||||
" font-size: 13px;"
|
||||
" font-weight: 600;"
|
||||
"}"
|
||||
".stats-unit-badge {"
|
||||
" color: @success;"
|
||||
" font-size: 12px;"
|
||||
" font-weight: 700;"
|
||||
"}"
|
||||
"tooltip {"
|
||||
" background-color: @bg_mantle;"
|
||||
" border: 1px solid @bg_surface1;"
|
||||
" border-radius: 10px;"
|
||||
" color: @fg_text;"
|
||||
"}",
|
||||
char *palette = g_strdup_printf(
|
||||
"@define-color bg_crust #%06x;\n"
|
||||
"@define-color bg_base #%06x;\n"
|
||||
"@define-color bg_mantle #%06x;\n"
|
||||
"@define-color bg_surface0 #%06x;\n"
|
||||
"@define-color bg_surface1 #%06x;\n"
|
||||
"@define-color bg_surface2 #%06x;\n"
|
||||
"@define-color fg_overlay #%06x;\n"
|
||||
"@define-color fg_text #%06x;\n"
|
||||
"@define-color fg_subtext #%06x;\n"
|
||||
"@define-color accent #%06x;\n"
|
||||
"@define-color accent2 #%06x;\n"
|
||||
"@define-color accent3 #%06x;\n"
|
||||
"@define-color success #%06x;\n"
|
||||
"@define-color success2 #%06x;\n"
|
||||
"@define-color warning #%06x;\n"
|
||||
"@define-color error #%06x;\n"
|
||||
"@define-color on_accent #%06x;\n"
|
||||
"@define-color node_bg #%06x;\n"
|
||||
"@define-color locked_bg #%06x;\n"
|
||||
"@define-color locked_border #%06x;\n",
|
||||
p->crust, p->base, p->mantle, p->surface0, p->surface1, p->surface2,
|
||||
p->overlay, p->text, p->subtext, p->accent, p->accent2, p->accent3,
|
||||
p->success, p->success2, p->warning, p->error, p->on_accent,
|
||||
p->node, p->locked_bg, p->locked_border);
|
||||
char *rules = read_css_file();
|
||||
char *css = g_strconcat(palette, rules, NULL);
|
||||
|
||||
g_free(palette);
|
||||
g_free(rules);
|
||||
return css;
|
||||
}
|
||||
|
||||
static void save_settings(void) {
|
||||
|
|
|
|||
739
style.css
Normal file
739
style.css
Normal file
|
|
@ -0,0 +1,739 @@
|
|||
window {
|
||||
background-color: @bg_base;
|
||||
background-image: linear-gradient(160deg, @bg_crust 0%, @bg_base 40%, @bg_surface0 100%);
|
||||
}
|
||||
button {
|
||||
background-image: none;
|
||||
}
|
||||
.app-title {
|
||||
color: @fg_text;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
}
|
||||
.settings-btn,
|
||||
.settings-btn:hover,
|
||||
.settings-btn:active,
|
||||
.settings-btn:checked,
|
||||
.settings-btn:focus,
|
||||
.settings-btn:focus-visible {
|
||||
min-width: 34px;
|
||||
min-height: 34px;
|
||||
padding: 0;
|
||||
border-radius: 999px;
|
||||
background: transparent;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
color: @fg_text;
|
||||
}
|
||||
.settings-btn:hover {
|
||||
color: @accent;
|
||||
background-color: alpha(@bg_surface0, 0.55);
|
||||
}
|
||||
.settings-btn:active {
|
||||
color: @accent;
|
||||
background-color: alpha(@bg_surface1, 0.4);
|
||||
}
|
||||
popover,
|
||||
popover.background,
|
||||
.settings-popover {
|
||||
background: @bg_mantle;
|
||||
background-color: @bg_mantle;
|
||||
color: @fg_text;
|
||||
border: 1px solid @bg_surface1;
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 18px 40px alpha(@bg_crust, 0.45);
|
||||
}
|
||||
popover > contents,
|
||||
.settings-popover > contents {
|
||||
background: transparent;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
border-radius: 18px;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
}
|
||||
.settings-box {
|
||||
background-color: transparent;
|
||||
color: @fg_text;
|
||||
min-width: 292px;
|
||||
padding: 16px 16px 14px 16px;
|
||||
}
|
||||
.settings-title {
|
||||
color: @fg_text;
|
||||
font-size: 17px;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.2px;
|
||||
}
|
||||
.settings-label {
|
||||
color: @fg_overlay;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.8px;
|
||||
}
|
||||
.settings-seg {
|
||||
background-color: alpha(@bg_surface0, 0.55);
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
padding: 3px;
|
||||
}
|
||||
.mode-chip {
|
||||
background-image: none;
|
||||
background-color: transparent;
|
||||
color: @fg_subtext;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
padding: 9px 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
min-width: 0;
|
||||
box-shadow: none;
|
||||
transition: background-color 140ms ease, color 140ms ease,
|
||||
box-shadow 140ms ease;
|
||||
}
|
||||
.mode-chip:hover {
|
||||
background-color: alpha(@bg_surface1, 0.28);
|
||||
color: @fg_text;
|
||||
}
|
||||
.mode-chip:checked {
|
||||
background-image: linear-gradient(135deg, @accent 0%, @accent2 100%);
|
||||
color: @on_accent;
|
||||
font-weight: 800;
|
||||
box-shadow: 0 4px 12px alpha(@accent, 0.25);
|
||||
}
|
||||
.mode-chip:checked:hover {
|
||||
background-image: linear-gradient(135deg, @accent 0%, @accent2 100%);
|
||||
color: @on_accent;
|
||||
}
|
||||
.theme-grid {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
flowboxchild {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.theme-card {
|
||||
background-image: none;
|
||||
background-color: transparent;
|
||||
color: @fg_text;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
padding: 6px 4px;
|
||||
min-width: 0;
|
||||
box-shadow: none;
|
||||
transition: background-color 140ms ease;
|
||||
}
|
||||
.theme-card:hover {
|
||||
background-color: alpha(@bg_surface0, 0.45);
|
||||
}
|
||||
.theme-card:checked {
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.theme-card:checked:hover {
|
||||
background-color: alpha(@bg_surface0, 0.35);
|
||||
}
|
||||
.theme-card-name {
|
||||
color: @fg_subtext;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.theme-card:checked .theme-card-name {
|
||||
color: @fg_text;
|
||||
font-weight: 700;
|
||||
}
|
||||
headerbar,
|
||||
headerbar.titlebar,
|
||||
.titlebar {
|
||||
background-color: @bg_base;
|
||||
background-image: none;
|
||||
color: @fg_text;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
windowcontrols button:not(:hover) {
|
||||
color: @fg_text;
|
||||
}
|
||||
windowcontrols button:not(:hover) image {
|
||||
color: @fg_text;
|
||||
}
|
||||
.heading {
|
||||
color: @fg_text;
|
||||
font-size: 32px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.card {
|
||||
background-color: alpha(@bg_surface0, 0.92);
|
||||
border: 1px solid @bg_surface1;
|
||||
border-radius: 18px;
|
||||
padding: 30px 34px;
|
||||
color: @fg_text;
|
||||
font-size: 16px;
|
||||
}
|
||||
.btn-primary {
|
||||
background-image: linear-gradient(135deg, @accent 0%, @accent2 100%);
|
||||
color: @on_accent;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
padding: 12px 40px;
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
box-shadow: 0 6px 18px alpha(@accent, 0.25);
|
||||
transition: box-shadow 150ms ease, background-image 150ms ease;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
box-shadow: 0 8px 24px alpha(@accent, 0.45);
|
||||
background-image: linear-gradient(135deg, @accent2 0%, @accent3 100%);
|
||||
}
|
||||
.btn-primary:active {
|
||||
box-shadow: 0 3px 10px alpha(@accent, 0.35);
|
||||
}
|
||||
.roadmap-title {
|
||||
color: @fg_text;
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.roadmap-sub {
|
||||
color: @fg_subtext;
|
||||
font-size: 14px;
|
||||
}
|
||||
.back-btn {
|
||||
min-width: 42px;
|
||||
min-height: 42px;
|
||||
padding: 0;
|
||||
border-radius: 999px;
|
||||
background-color: alpha(@bg_surface0, 0.9);
|
||||
border: 1px solid @bg_surface1;
|
||||
color: @fg_text;
|
||||
box-shadow: 0 4px 14px alpha(@bg_crust, 0.35);
|
||||
transition: background-color 150ms ease, color 150ms ease,
|
||||
border-color 150ms ease, box-shadow 150ms ease;
|
||||
}
|
||||
.back-btn:hover {
|
||||
background-color: @bg_surface1;
|
||||
border-color: @bg_surface2;
|
||||
color: @accent;
|
||||
box-shadow: 0 6px 20px alpha(@accent, 0.35);
|
||||
}
|
||||
.back-btn:active {
|
||||
background-color: @bg_surface0;
|
||||
box-shadow: 0 2px 8px alpha(@bg_crust, 0.35);
|
||||
}
|
||||
.unit-node {
|
||||
background-image: none;
|
||||
background-color: @node_bg;
|
||||
color: @fg_text;
|
||||
border: 2px solid @locked_border;
|
||||
border-radius: 999px;
|
||||
padding: 0;
|
||||
box-shadow: 0 4px 14px alpha(@bg_crust, 0.35);
|
||||
transition: transform 150ms ease, box-shadow 150ms ease,
|
||||
border-color 150ms ease;
|
||||
}
|
||||
.unit-node.done {
|
||||
background-image: linear-gradient(135deg, @success 0%, @success2 100%);
|
||||
border-color: @success;
|
||||
color: @on_accent;
|
||||
box-shadow: 0 4px 16px alpha(@success, 0.35);
|
||||
}
|
||||
.unit-node.current {
|
||||
background-image: linear-gradient(135deg, @accent 0%, @accent2 55%, @accent3 100%);
|
||||
border-color: @accent;
|
||||
color: @on_accent;
|
||||
box-shadow: 0 4px 18px alpha(@accent, 0.5),
|
||||
0 0 0 4px alpha(@bg_base, 0.9),
|
||||
0 0 0 7px alpha(@accent, 0.45);
|
||||
}
|
||||
.unit-node.done:hover,
|
||||
.unit-node.current:hover {
|
||||
transition: box-shadow 150ms ease, border-color 150ms ease;
|
||||
}
|
||||
.unit-node.done:hover {
|
||||
box-shadow: 0 8px 22px alpha(@success, 0.5);
|
||||
}
|
||||
.unit-node.current:hover {
|
||||
box-shadow: 0 8px 26px alpha(@accent, 0.65),
|
||||
0 0 0 4px alpha(@bg_base, 0.9),
|
||||
0 0 0 7px alpha(@accent, 0.55);
|
||||
}
|
||||
.unit-node.locked {
|
||||
background-image: none;
|
||||
background-color: @locked_bg;
|
||||
border: 2px solid @locked_border;
|
||||
color: @fg_overlay;
|
||||
box-shadow: none;
|
||||
}
|
||||
.unit-node.locked:hover {
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.unit-node.finish {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
border: none;
|
||||
color: @fg_overlay;
|
||||
box-shadow: 0 4px 14px alpha(@bg_crust, 0.35);
|
||||
}
|
||||
.unit-node.finish:hover {
|
||||
transform: none;
|
||||
box-shadow: 0 4px 14px alpha(@bg_crust, 0.35);
|
||||
}
|
||||
.unit-node:focus,
|
||||
.unit-node:focus-visible,
|
||||
.unit-node:hover {
|
||||
outline: none;
|
||||
}
|
||||
.unit-number {
|
||||
font-size: 24px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.unit-node.done .unit-number,
|
||||
.unit-node.current .unit-number {
|
||||
color: @on_accent;
|
||||
}
|
||||
.unit-node.locked .unit-number {
|
||||
color: @fg_overlay;
|
||||
}
|
||||
.state-icon {
|
||||
color: @on_accent;
|
||||
}
|
||||
.unit-node.locked .lock-icon {
|
||||
color: @bg_surface2;
|
||||
}
|
||||
.unit-name {
|
||||
color: @fg_text;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.unit-name-locked {
|
||||
color: @fg_overlay;
|
||||
}
|
||||
.ex-bubble {
|
||||
min-width: 64px;
|
||||
min-height: 64px;
|
||||
padding: 0;
|
||||
border-radius: 999px;
|
||||
background-color: @node_bg;
|
||||
color: @fg_text;
|
||||
border: 2px solid @locked_border;
|
||||
box-shadow: 0 4px 14px alpha(@bg_crust, 0.35);
|
||||
transition: border-color 150ms ease, box-shadow 150ms ease;
|
||||
}
|
||||
.ex-bubble:hover {
|
||||
background-image: none;
|
||||
border-color: @accent;
|
||||
box-shadow: 0 6px 20px alpha(@accent, 0.35);
|
||||
}
|
||||
.ex-bubble.done {
|
||||
background-image: linear-gradient(135deg, @success 0%, @success2 100%);
|
||||
border-color: @success;
|
||||
color: @on_accent;
|
||||
box-shadow: 0 4px 16px alpha(@success, 0.35);
|
||||
}
|
||||
.ex-bubble.done:hover {
|
||||
box-shadow: 0 8px 22px alpha(@success, 0.5);
|
||||
}
|
||||
.ex-bubble:focus,
|
||||
.ex-bubble:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
.bubble-number {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.ex-bubble.done .bubble-number {
|
||||
color: @on_accent;
|
||||
}
|
||||
.bubble-icon {
|
||||
color: @on_accent;
|
||||
}
|
||||
.ex-label {
|
||||
color: @fg_text;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.ex-prompt {
|
||||
color: @fg_text;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.ex-sub {
|
||||
color: @fg_subtext;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.hint {
|
||||
color: @fg_subtext;
|
||||
font-size: 13px;
|
||||
font-style: italic;
|
||||
}
|
||||
.meaning {
|
||||
color: @fg_subtext;
|
||||
font-size: 13px;
|
||||
font-style: italic;
|
||||
}
|
||||
.u3-answer {
|
||||
color: @success;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.notes-card {
|
||||
background-color: alpha(@bg_surface0, 0.9);
|
||||
border: 1px solid @bg_surface1;
|
||||
border-radius: 24px;
|
||||
padding: 24px 34px;
|
||||
box-shadow: 0 10px 30px alpha(@bg_crust, 0.20);
|
||||
}
|
||||
.notes-kicker {
|
||||
color: @accent2;
|
||||
font-weight: 800;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
.notes-title {
|
||||
color: @fg_text;
|
||||
font-weight: 800;
|
||||
}
|
||||
.notes-body {
|
||||
color: @fg_text;
|
||||
}
|
||||
.notes-tip {
|
||||
color: @success2;
|
||||
font-weight: 700;
|
||||
}
|
||||
.dlg-speaker {
|
||||
color: @accent;
|
||||
font-weight: 700;
|
||||
font-size: 15px;
|
||||
}
|
||||
.number-big {
|
||||
color: @warning;
|
||||
font-size: 26px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.hm-word {
|
||||
color: @fg_text;
|
||||
font-family: monospace;
|
||||
font-size: 30px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.chain {
|
||||
color: @warning;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
entry {
|
||||
background-color: @bg_mantle;
|
||||
color: @fg_text;
|
||||
border: 1px solid @bg_surface1;
|
||||
border-radius: 10px;
|
||||
padding: 8px 12px;
|
||||
font-size: 15px;
|
||||
caret-color: @accent;
|
||||
}
|
||||
entry:focus {
|
||||
border-color: @accent;
|
||||
}
|
||||
combobox {
|
||||
background-color: @bg_mantle;
|
||||
color: @fg_text;
|
||||
}
|
||||
combobox button {
|
||||
background-image: none;
|
||||
background-color: @bg_mantle;
|
||||
color: @fg_text;
|
||||
border: 1px solid @bg_surface1;
|
||||
border-radius: 10px;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
combobox button:hover {
|
||||
background-image: none;
|
||||
border-color: @accent;
|
||||
}
|
||||
combobox.answer-ok button {
|
||||
border-color: @success;
|
||||
background-color: alpha(@success, 0.12);
|
||||
}
|
||||
combobox.answer-wrong button {
|
||||
border-color: @error;
|
||||
background-color: alpha(@error, 0.12);
|
||||
}
|
||||
entry.answer-ok {
|
||||
border-color: @success;
|
||||
background-color: alpha(@success, 0.08);
|
||||
}
|
||||
entry.answer-wrong {
|
||||
border-color: @error;
|
||||
background-color: alpha(@error, 0.08);
|
||||
}
|
||||
.pill {
|
||||
background-image: none;
|
||||
background-color: @node_bg;
|
||||
color: @fg_text;
|
||||
border: 2px solid @locked_border;
|
||||
border-radius: 999px;
|
||||
padding: 6px 18px;
|
||||
font-size: 15px;
|
||||
transition: border-color 150ms ease, box-shadow 150ms ease;
|
||||
}
|
||||
.pill:hover {
|
||||
background-image: none;
|
||||
background-color: @node_bg;
|
||||
border-color: @accent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.pill:active {
|
||||
background-image: none;
|
||||
background-color: @bg_surface1;
|
||||
box-shadow: none;
|
||||
}
|
||||
.pill:checked {
|
||||
background-image: linear-gradient(135deg, @accent 0%, @accent2 100%);
|
||||
color: @on_accent;
|
||||
border-color: @accent;
|
||||
font-weight: 700;
|
||||
}
|
||||
.pill.ok {
|
||||
border-color: @success;
|
||||
box-shadow: 0 0 0 2px alpha(@success, 0.4);
|
||||
}
|
||||
.pill.wrong {
|
||||
border-color: @error;
|
||||
box-shadow: 0 0 0 2px alpha(@error, 0.4);
|
||||
}
|
||||
.pill.hm-key {
|
||||
padding: 4px 5px;
|
||||
min-width: 32px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.chip {
|
||||
background-image: none;
|
||||
background-color: @bg_surface1;
|
||||
color: @fg_text;
|
||||
border: 1px solid @bg_surface2;
|
||||
border-radius: 999px;
|
||||
padding: 6px 14px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
transition: background-color 150ms ease, border-color 150ms ease;
|
||||
}
|
||||
.chip:hover {
|
||||
background-image: none;
|
||||
background-color: @bg_surface2;
|
||||
border-color: @accent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.chip:active {
|
||||
background-image: none;
|
||||
background-color: @bg_surface2;
|
||||
box-shadow: none;
|
||||
}
|
||||
.chip.ghost-host {
|
||||
opacity: 0;
|
||||
}
|
||||
.group-btn {
|
||||
background-image: none;
|
||||
background-color: @node_bg;
|
||||
color: @fg_text;
|
||||
border: 2px solid @locked_border;
|
||||
border-radius: 12px;
|
||||
padding: 8px 18px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
transition: border-color 150ms ease, box-shadow 150ms ease;
|
||||
}
|
||||
.group-btn:hover {
|
||||
background-image: none;
|
||||
background-color: @node_bg;
|
||||
border-color: @accent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.group-btn:active {
|
||||
background-image: none;
|
||||
background-color: @bg_surface1;
|
||||
box-shadow: none;
|
||||
}
|
||||
.group-btn:checked {
|
||||
background-image: linear-gradient(135deg, @accent3 0%, @success2 100%);
|
||||
color: @on_accent;
|
||||
border-color: @accent3;
|
||||
}
|
||||
.group-panel {
|
||||
background-color: alpha(@bg_surface0, 0.5);
|
||||
border: 2px dashed @bg_surface1;
|
||||
border-radius: 14px;
|
||||
padding: 10px;
|
||||
}
|
||||
.group-panel-label {
|
||||
color: @fg_subtext;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.sent-group {
|
||||
background-color: alpha(@bg_surface0, 0.5);
|
||||
border: 1px solid @bg_surface1;
|
||||
border-radius: 14px;
|
||||
padding: 12px;
|
||||
}
|
||||
.sent-group.ok {
|
||||
border-color: @success;
|
||||
}
|
||||
.sent-group.wrong {
|
||||
border-color: @error;
|
||||
}
|
||||
.feedback-ok {
|
||||
color: @success;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.feedback-err {
|
||||
color: @error;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.stats-page {
|
||||
padding: 8px 28px 24px 28px;
|
||||
}
|
||||
.stats-summary {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.stats-metric {
|
||||
background-color: alpha(@bg_surface0, 0.92);
|
||||
border: 1px solid @bg_surface1;
|
||||
border-radius: 16px;
|
||||
padding: 16px 18px;
|
||||
min-width: 120px;
|
||||
}
|
||||
.stats-metric-value {
|
||||
color: @fg_text;
|
||||
font-size: 26px;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.4px;
|
||||
}
|
||||
.stats-metric-label {
|
||||
color: @fg_overlay;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.8px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.stats-overall-bar,
|
||||
.stats-overall-bar trough,
|
||||
.stats-unit-bar,
|
||||
.stats-unit-bar trough {
|
||||
min-height: 10px;
|
||||
border-radius: 999px;
|
||||
background-color: alpha(@bg_surface1, 0.85);
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
.stats-overall-bar {
|
||||
margin-bottom: 22px;
|
||||
min-height: 12px;
|
||||
}
|
||||
.stats-overall-bar progress,
|
||||
.stats-unit-bar progress {
|
||||
min-height: 10px;
|
||||
border-radius: 999px;
|
||||
background-image: linear-gradient(90deg, @accent 0%, @accent2 100%);
|
||||
background-color: @accent;
|
||||
border: none;
|
||||
}
|
||||
.stats-unit-bar.done progress {
|
||||
background-image: linear-gradient(90deg, @success 0%, @success2 100%);
|
||||
background-color: @success;
|
||||
}
|
||||
.stats-section {
|
||||
color: @fg_overlay;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.stats-subject {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.stats-subject-name {
|
||||
color: @fg_text;
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.stats-subject-count {
|
||||
color: @fg_subtext;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.stats-subject-count.locked {
|
||||
color: @fg_overlay;
|
||||
}
|
||||
.stats-subject-bar,
|
||||
.stats-subject-bar trough {
|
||||
min-height: 12px;
|
||||
border-radius: 999px;
|
||||
background-color: alpha(@bg_surface1, 0.85);
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
.stats-subject-bar {
|
||||
margin: 4px 0 0 0;
|
||||
}
|
||||
.stats-subject-bar progress {
|
||||
min-height: 10px;
|
||||
border-radius: 999px;
|
||||
background-image: linear-gradient(90deg, @accent 0%, @accent2 100%);
|
||||
background-color: @accent;
|
||||
border: none;
|
||||
}
|
||||
.stats-units {
|
||||
margin-top: 8px;
|
||||
border-left: 2px solid alpha(@fg_overlay, 0.22);
|
||||
padding-left: 12px;
|
||||
}
|
||||
.stats-unit-row {
|
||||
background-color: alpha(@bg_surface0, 0.72);
|
||||
border: 1px solid @bg_surface1;
|
||||
border-radius: 14px;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.stats-unit-row.locked {
|
||||
opacity: 0.55;
|
||||
}
|
||||
.stats-unit-row.done {
|
||||
border-color: alpha(@success, 0.55);
|
||||
}
|
||||
.stats-unit-index {
|
||||
color: @fg_overlay;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
min-width: 22px;
|
||||
}
|
||||
.stats-unit-name {
|
||||
color: @fg_text;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.stats-unit-count {
|
||||
color: @fg_subtext;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.stats-unit-badge {
|
||||
color: @success;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
tooltip {
|
||||
background-color: @bg_mantle;
|
||||
border: 1px solid @bg_surface1;
|
||||
border-radius: 10px;
|
||||
color: @fg_text;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue