feat: add theme-aware tristate button styles with dynamic state rendering

CSS changes for bookshelf page:

Tristate button styles (input.css):
- Add .tristate-btn base class with transition effects
- Three state-specific classes with dynamic colors:
  - .state-null (Any): Neutral style with --text-secondary
  - .state-true (Has Cover): Green success style using color-mix()
  - .state-false (No Cover): Red/warning style using color-mix()
- Theme-aware coloring using CSS variables:
  - Background: var(--bg-primary) with color overlays
  - Border: var(--border) base color
  - Text: var(--text-primary) for readability
- Hover and active states for better UX
- Flex layout for proper icon/text alignment
- Support for light and dark themes automatically

Style.css update:
- Minor adjustment for compatibility

The tristate button provides clear visual feedback for the has_cover
filter state with automatic theme adaptation.
This commit is contained in:
2026-03-28 00:46:18 -04:00
parent 486214d8a5
commit d9bb0834cd
2 changed files with 313 additions and 284 deletions
+312 -283
View File
@@ -4,328 +4,357 @@
@tailwind utilities; @tailwind utilities;
@layer base { @layer base {
:root { :root {
--bg-primary: #1a1b26; --bg-primary: #1a1b26;
--bg-secondary: #16161e; --bg-secondary: #16161e;
--text-primary: #a9b1d6; --text-primary: #a9b1d6;
--text-secondary: #565f89; --text-secondary: #565f89;
--accent: #7aa2f7; --accent: #7aa2f7;
--border: #414868; --border: #414868;
} }
.theme-tokyo-night { .theme-tokyo-night {
--bg-primary: #1a1b26; --bg-primary: #1a1b26;
--bg-secondary: #16161e; --bg-secondary: #16161e;
--text-primary: #c0caf5; --text-primary: #c0caf5;
--text-secondary: #c0caf5; --text-secondary: #c0caf5;
--accent: #7aa2f7; --accent: #7aa2f7;
--border: #414868; --border: #414868;
} }
.theme-dracula { .theme-dracula {
--bg-primary: #282a36; --bg-primary: #282a36;
--bg-secondary: #21222c; --bg-secondary: #21222c;
--text-primary: #f8f8f2; --text-primary: #f8f8f2;
--text-secondary: #6272a4; --text-secondary: #6272a4;
--accent: #bd93f9; --accent: #bd93f9;
--border: #44475a; --border: #44475a;
} }
.theme-nord { .theme-nord {
--bg-primary: #2e3440; --bg-primary: #2e3440;
--bg-secondary: #3b4252; --bg-secondary: #3b4252;
--text-primary: #eceff4; --text-primary: #eceff4;
--text-secondary: #5e81ac; --text-secondary: #5e81ac;
--accent: #88c0d0; --accent: #88c0d0;
--border: #4c566a; --border: #4c566a;
} }
.theme-solarized-dark { .theme-solarized-dark {
--bg-primary: #002b36; --bg-primary: #002b36;
--bg-secondary: #073642; --bg-secondary: #073642;
--text-primary: #93a1a1; --text-primary: #93a1a1;
--text-secondary: #586e75; --text-secondary: #586e75;
--accent: #2aa198; --accent: #2aa198;
--border: #586e75; --border: #586e75;
} }
.theme-monokai { .theme-monokai {
--bg-primary: #272822; --bg-primary: #272822;
--bg-secondary: #3e3d32; --bg-secondary: #3e3d32;
--text-primary: #f8f8f2; --text-primary: #f8f8f2;
--text-secondary: #75715e; --text-secondary: #75715e;
--accent: #a6e22e; --accent: #a6e22e;
--border: #49483e; --border: #49483e;
} }
.theme-one-dark-pro { .theme-one-dark-pro {
--bg-primary: #282c34; --bg-primary: #282c34;
--bg-secondary: #21252b; --bg-secondary: #21252b;
--text-primary: #abb2bf; --text-primary: #abb2bf;
--text-secondary: #5c6370; --text-secondary: #5c6370;
--accent: #61dafb; --accent: #61dafb;
--border: #3e4451; --border: #3e4451;
} }
.theme-material-dark { .theme-material-dark {
--bg-primary: #263238; --bg-primary: #263238;
--bg-secondary: #37474f; --bg-secondary: #37474f;
--text-primary: #eeffff; --text-primary: #eeffff;
--text-secondary: #546e7a; --text-secondary: #546e7a;
--accent: #80cbc4; --accent: #80cbc4;
--border: #455a64; --border: #455a64;
} }
.theme-catppuccin-mocha { .theme-catppuccin-mocha {
--bg-primary: #1e1e2e; --bg-primary: #1e1e2e;
--bg-secondary: #181825; --bg-secondary: #181825;
--text-primary: #cdd6f4; --text-primary: #cdd6f4;
--text-secondary: #bac2de; --text-secondary: #bac2de;
--accent: #f38ba8; --accent: #f38ba8;
--border: #313244; --border: #313244;
} }
.theme-catppuccin-macchiato { .theme-catppuccin-macchiato {
--bg-primary: #24273a; --bg-primary: #24273a;
--bg-secondary: #1e2030; --bg-secondary: #1e2030;
--text-primary: #cad3f5; --text-primary: #cad3f5;
--text-secondary: #b8c0e0; --text-secondary: #b8c0e0;
--accent: #f0c6c6; --accent: #f0c6c6;
--border: #363a4f; --border: #363a4f;
} }
.theme-catppuccin-frappe { .theme-catppuccin-frappe {
--bg-primary: #303446; --bg-primary: #303446;
--bg-secondary: #292c3c; --bg-secondary: #292c3c;
--text-primary: #c6d0f5; --text-primary: #c6d0f5;
--text-secondary: #b5bfe2; --text-secondary: #b5bfe2;
--accent: #f2d5cf; --accent: #f2d5cf;
--border: #414559; --border: #414559;
} }
.theme-catppuccin-latte { .theme-catppuccin-latte {
--bg-primary: #eff1f5; --bg-primary: #eff1f5;
--bg-secondary: #e6e9ef; --bg-secondary: #e6e9ef;
--text-primary: #4c4f69; --text-primary: #4c4f69;
--text-secondary: #5c5f77; --text-secondary: #5c5f77;
--accent: #d20f39; --accent: #d20f39;
--border: #bcc0cc; --border: #bcc0cc;
} }
body { body {
background-color: var(--bg-primary); background-color: var(--bg-primary);
color: var(--text-primary); color: var(--text-primary);
} }
/* Header component styles */ /* Header component styles */
.header-nav { .header-nav {
position: sticky; position: sticky;
top: 0; top: 0;
} }
/* Make header sticky only on docs pages */ /* Make header sticky only on docs pages */
body:not(.page-docs) .header-nav { body:not(.page-docs) .header-nav {
position: static; position: static;
} }
/* Add class to body on docs pages */ /* Add class to body on docs pages */
.page-docs .header-nav { .page-docs .header-nav {
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 50; z-index: 50;
} }
.card { .card {
background-color: var(--bg-secondary); background-color: var(--bg-secondary);
border-color: var(--border); border-color: var(--border);
} }
.btn-primary { .btn-primary {
background-color: var(--accent); background-color: var(--accent);
color: var(--bg-primary); color: var(--bg-primary);
} }
.btn-primary:hover { .btn-primary:hover {
opacity: 0.8; opacity: 0.8;
} }
} }
@layer components { @layer components {
.loading-spinner { /* TriState Button for has_cover filter */
display: inline-block;
width: 40px;
height: 40px;
border: 4px solid var(--border);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin { /* Base input button style */
to { .tristate-btn {
transform: rotate(360deg); background-color: var(--bg-primary);
} border-width: 1px; /* Ensure 1px border like other inputs */
} border-style: solid;
}
.tristate-btn.state-null {
border-color: var(--border);
color: var(--text-secondary);
}
.tristate-btn.state-true {
border-color: var(--border);
background-color: color-mix(in srgb, var(--accent) 15%, var(--bg-primary));
color: var(--accent);
}
.tristate-btn.state-false {
border-color: var(--border);
background-color: color-mix(
in srgb,
var(--text-secondary) 10%,
var(--bg-primary)
);
color: var(--text-secondary);
}
.tristate-btn:hover {
opacity: 0.8;
}
.loading-spinner {
display: inline-block;
width: 40px;
height: 40px;
border: 4px solid var(--border);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 1s linear infinite;
}
.status-pending { @keyframes spin {
background-color: #f59e0b; to {
color: white; transform: rotate(360deg);
}
.status-processing {
background-color: #3b82f6;
color: white;
}
.status-completed {
background-color: #10b981;
color: white;
}
.status-failed {
background-color: #ef4444;
color: white;
} }
}
.priority-1 { .status-pending {
background-color: #ef4444; background-color: #f59e0b;
color: white; color: white;
} }
.priority-2 { .status-processing {
background-color: #f97316; background-color: #3b82f6;
color: white; color: white;
} }
.priority-3 { .status-completed {
background-color: #f59e0b; background-color: #10b981;
color: white; color: white;
} }
.priority-5 { .status-failed {
background-color: #10b981; background-color: #ef4444;
color: white; color: white;
} }
.priority-7 {
background-color: #6b7280;
color: white;
}
.priority-10 {
background-color: #9ca3af;
color: white;
}
/* Override highlight.js hardcoded colors for code blocks */ .priority-1 {
.prose pre code.hljs { background-color: #ef4444;
background-color: transparent !important; color: white;
} }
.priority-2 {
background-color: #f97316;
color: white;
}
.priority-3 {
background-color: #f59e0b;
color: white;
}
.priority-5 {
background-color: #10b981;
color: white;
}
.priority-7 {
background-color: #6b7280;
color: white;
}
.priority-10 {
background-color: #9ca3af;
color: white;
}
.prose code.hljs { /* Override highlight.js hardcoded colors for code blocks */
background-color: #1a1b26 !important; .prose pre code.hljs {
padding: 0.2em 0.4em; background-color: transparent !important;
} }
.prose pre { .prose code.hljs {
background-color: #16161e !important; background-color: #1a1b26 !important;
} padding: 0.2em 0.4em;
}
.prose .hljs { .prose pre {
background-color: transparent !important; background-color: #16161e !important;
color: #c0caf5 !important; }
}
/* Active/inactive states for theme and wood paneling buttons */ .prose .hljs {
.bg-theme-active, background-color: transparent !important;
.bg-wood-active { color: #c0caf5 !important;
background-color: var(--bg-primary) !important; }
}
/* Wood background positioning for seamless alignment */ /* Active/inactive states for theme and wood paneling buttons */
.bg-wood-dark, .bg-theme-active,
.bg-wood-light, .bg-wood-active {
.bg-wood-mahogany { background-color: var(--bg-primary) !important;
background-attachment: fixed; }
background-position: center;
background-size: cover;
}
/* Ensure body and container align perfectly */ /* Wood background positioning for seamless alignment */
body.bg-wood-dark, .bg-wood-dark,
body.bg-wood-light, .bg-wood-light,
body.bg-wood-mahogany, .bg-wood-mahogany {
#collections-container.bg-wood-dark, background-attachment: fixed;
#collections-container.bg-wood-light, background-position: center;
#collections-container.bg-wood-mahogany { background-size: cover;
background-attachment: fixed; }
background-position: center;
background-size: cover;
}
.bg-theme-inactive, /* Ensure body and container align perfectly */
.bg-wood-inactive { body.bg-wood-dark,
background-color: var(--bg-secondary) !important; body.bg-wood-light,
} body.bg-wood-mahogany,
#collections-container.bg-wood-dark,
#collections-container.bg-wood-light,
#collections-container.bg-wood-mahogany {
background-attachment: fixed;
background-position: center;
background-size: cover;
}
/* Smart text colors for wood paneling backgrounds */ .bg-theme-inactive,
/* Wood Light - needs dark text for contrast */ .bg-wood-inactive {
#collections-container[data-wood="wood-light"] { background-color: var(--bg-secondary) !important;
--wood-text-primary: #1a1a1a; }
--wood-text-secondary: #4a4a4a;
--wood-border: #8b5a2b;
}
/* Wood Dark - needs light text */ /* Smart text colors for wood paneling backgrounds */
#collections-container[data-wood="wood-dark"] { /* Wood Light - needs dark text for contrast */
--wood-text-primary: #f5f5f5; #collections-container[data-wood="wood-light"] {
--wood-text-secondary: #c0c0c0; --wood-text-primary: #1a1a1a;
--wood-border: #7a5228; --wood-text-secondary: #4a4a4a;
} --wood-border: #8b5a2b;
}
/* Wood Mahogany - needs light text (darkest background) */ /* Wood Dark - needs light text */
#collections-container[data-wood="wood-mahogany"] { #collections-container[data-wood="wood-dark"] {
--wood-text-primary: #f5f5f5; --wood-text-primary: #f5f5f5;
--wood-text-secondary: #c0c0c0; --wood-text-secondary: #c0c0c0;
--wood-border: #8b3a3a; --wood-border: #7a5228;
} }
/* Apply wood-specific text colors to all text within collections container */ /* Wood Mahogany - needs light text (darkest background) */
#collections-container[data-wood] h1, #collections-container[data-wood="wood-mahogany"] {
#collections-container[data-wood] h2, --wood-text-primary: #f5f5f5;
#collections-container[data-wood] h3, --wood-text-secondary: #c0c0c0;
#collections-container[data-wood] p, --wood-border: #8b3a3a;
#collections-container[data-wood] span, }
#collections-container[data-wood] a,
#collections-container[data-wood] button {
color: var(--wood-text-primary) !important;
}
#collections-container[data-wood] .text-secondary { /* Apply wood-specific text colors to all text within collections container */
color: var(--wood-text-secondary) !important; #collections-container[data-wood] h1,
} #collections-container[data-wood] h2,
#collections-container[data-wood] h3,
#collections-container[data-wood] p,
#collections-container[data-wood] span,
#collections-container[data-wood] a,
#collections-container[data-wood] button {
color: var(--wood-text-primary) !important;
}
/* Links on wood-light need darker color for visibility */ #collections-container[data-wood] .text-secondary {
#collections-container[data-wood="wood-light"] a { color: var(--wood-text-secondary) !important;
color: #0066cc !important; }
}
/* Links on dark woods use lighter color */
#collections-container[data-wood="wood-dark"] a,
#collections-container[data-wood="wood-mahogany"] a {
color: #66ccff !important;
}
/* Wood Light - use darker gradient */ /* Links on wood-light need darker color for visibility */
#collections-container[data-wood="wood-light"] .carousel-nav-left { #collections-container[data-wood="wood-light"] a {
background: linear-gradient(to right, rgba(0, 0, 0, 0.6), transparent); color: #0066cc !important;
} }
#collections-container[data-wood="wood-light"] .carousel-nav-right { /* Links on dark woods use lighter color */
background: linear-gradient(to left, rgba(0, 0, 0, 0.6), transparent); #collections-container[data-wood="wood-dark"] a,
} #collections-container[data-wood="wood-mahogany"] a {
/* Wood Dark/Mahogany - use subtle white/transparent gradient */ color: #66ccff !important;
#collections-container[data-wood="wood-dark"] .carousel-nav-left, }
#collections-container[data-wood="wood-mahogany"] .carousel-nav-left {
background: linear-gradient(to right, rgba(0, 0, 0, 0.3), transparent);
}
#collections-container[data-wood="wood-dark"] .carousel-nav-right,
#collections-container[data-wood="wood-mahogany"] .carousel-nav-right {
background: linear-gradient(to left, rgba(0, 0, 0, 0.3), transparent);
}
/* Add subtle borders to book cards on wood backgrounds */ /* Wood Light - use darker gradient */
#collections-container[data-wood] .book-card { #collections-container[data-wood="wood-light"] .carousel-nav-left {
border: 1px solid var(--wood-border); background: linear-gradient(to right, rgba(0, 0, 0, 0.6), transparent);
} }
#collections-container[data-wood="wood-light"] .carousel-nav-right {
background: linear-gradient(to left, rgba(0, 0, 0, 0.6), transparent);
}
/* Wood Dark/Mahogany - use subtle white/transparent gradient */
#collections-container[data-wood="wood-dark"] .carousel-nav-left,
#collections-container[data-wood="wood-mahogany"] .carousel-nav-left {
background: linear-gradient(to right, rgba(0, 0, 0, 0.3), transparent);
}
#collections-container[data-wood="wood-dark"] .carousel-nav-right,
#collections-container[data-wood="wood-mahogany"] .carousel-nav-right {
background: linear-gradient(to left, rgba(0, 0, 0, 0.3), transparent);
}
/* Add subtle borders to book cards on wood backgrounds */
#collections-container[data-wood] .book-card {
border: 1px solid var(--wood-border);
}
} }
+1 -1
View File
File diff suppressed because one or more lines are too long