diff --git a/index.html b/index.html
index 0d5e597e..9ebd6a62 100644
--- a/index.html
+++ b/index.html
@@ -7,6 +7,11 @@
laputa-scaffold
+
diff --git a/src/components/CreateNoteDialog.css b/src/components/CreateNoteDialog.css
index be4f51e8..24855621 100644
--- a/src/components/CreateNoteDialog.css
+++ b/src/components/CreateNoteDialog.css
@@ -4,7 +4,7 @@
left: 0;
right: 0;
bottom: 0;
- background: rgba(0, 0, 0, 0.6);
+ background: var(--shadow-overlay);
display: flex;
align-items: center;
justify-content: center;
@@ -12,20 +12,20 @@
}
.create-dialog {
- background: #1e1e3a;
- border: 1px solid #2a2a4a;
+ background: var(--bg-dialog);
+ border: 1px solid var(--border-primary);
border-radius: 12px;
padding: 24px;
width: 420px;
max-width: 90vw;
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 8px 32px var(--shadow-dialog);
}
.create-dialog__title {
margin: 0 0 20px 0;
font-size: 16px;
font-weight: 600;
- color: #e0e0e0;
+ color: var(--text-primary);
}
.create-dialog__field {
@@ -35,7 +35,7 @@
.create-dialog__label {
display: block;
font-size: 12px;
- color: #888;
+ color: var(--text-tertiary);
margin-bottom: 6px;
text-transform: uppercase;
letter-spacing: 0.5px;
@@ -44,21 +44,21 @@
.create-dialog__input {
width: 100%;
padding: 8px 12px;
- background: #16162a;
- border: 1px solid #2a2a4a;
+ background: var(--bg-input);
+ border: 1px solid var(--border-primary);
border-radius: 6px;
- color: #e0e0e0;
+ color: var(--text-primary);
font-size: 14px;
outline: none;
box-sizing: border-box;
}
.create-dialog__input:focus {
- border-color: #4a9eff;
+ border-color: var(--accent-blue);
}
.create-dialog__input::placeholder {
- color: #555;
+ color: var(--text-faint);
}
.create-dialog__types {
@@ -70,23 +70,23 @@
.create-dialog__type-btn {
padding: 4px 12px;
font-size: 12px;
- border: 1px solid #2a2a4a;
+ border: 1px solid var(--border-primary);
border-radius: 14px;
background: transparent;
- color: #888;
+ color: var(--text-tertiary);
cursor: pointer;
transition: all 0.15s;
}
.create-dialog__type-btn:hover {
- background: #2a2a4a;
- color: #e0e0e0;
+ background: var(--bg-button);
+ color: var(--text-primary);
}
.create-dialog__type-btn--active {
- background: #4a9eff;
+ background: var(--accent-blue);
color: #fff;
- border-color: #4a9eff;
+ border-color: var(--accent-blue);
}
.create-dialog__actions {
@@ -107,22 +107,22 @@
.create-dialog__btn--cancel {
background: transparent;
- color: #888;
- border: 1px solid #2a2a4a;
+ color: var(--text-tertiary);
+ border: 1px solid var(--border-primary);
}
.create-dialog__btn--cancel:hover {
- background: #2a2a4a;
- color: #e0e0e0;
+ background: var(--bg-button);
+ color: var(--text-primary);
}
.create-dialog__btn--create {
- background: #4a9eff;
+ background: var(--accent-blue);
color: #fff;
}
.create-dialog__btn--create:hover {
- background: #3a8eef;
+ background: var(--accent-blue-hover);
}
.create-dialog__btn--create:disabled {
diff --git a/src/components/Editor.css b/src/components/Editor.css
index a36744b0..159dabdf 100644
--- a/src/components/Editor.css
+++ b/src/components/Editor.css
@@ -1,6 +1,6 @@
.editor {
- background: #0f0f1a;
- color: #e0e0e0;
+ background: var(--bg-primary);
+ color: var(--text-primary);
display: flex;
flex-direction: column;
flex: 1;
@@ -15,7 +15,7 @@
justify-content: center;
height: 100%;
text-align: center;
- color: #444;
+ color: var(--text-muted);
gap: 8px;
}
@@ -26,7 +26,7 @@
.editor__placeholder-hint {
font-size: 12px;
- color: #383858;
+ color: var(--text-faint);
}
/* Drag strip for frameless window (shown when no tabs are open) */
@@ -40,8 +40,8 @@
/* Tab bar */
.editor__tab-bar {
display: flex;
- background: #16162a;
- border-bottom: 1px solid #2a2a4a;
+ background: var(--bg-card);
+ border-bottom: 1px solid var(--border-primary);
overflow-x: auto;
flex-shrink: 0;
-webkit-app-region: drag;
@@ -58,9 +58,9 @@
gap: 6px;
padding: 7px 14px;
font-size: 12px;
- color: #777;
+ color: var(--text-tertiary);
cursor: pointer;
- border-right: 1px solid #2a2a4a;
+ border-right: 1px solid var(--border-primary);
white-space: nowrap;
max-width: 180px;
flex-shrink: 0;
@@ -70,14 +70,14 @@
}
.editor__tab:hover {
- background: #1a1a35;
- color: #bbb;
+ background: var(--bg-hover-subtle);
+ color: var(--text-secondary);
}
.editor__tab--active {
- background: #0f0f1a;
- color: #e0e0e0;
- border-bottom: 2px solid #4a9eff;
+ background: var(--bg-primary);
+ color: var(--text-primary);
+ border-bottom: 2px solid var(--accent-blue);
}
.editor__tab-title {
@@ -88,7 +88,7 @@
.editor__tab-close {
background: none;
border: none;
- color: #666;
+ color: var(--text-muted);
cursor: pointer;
font-size: 14px;
padding: 0 2px;
@@ -104,8 +104,8 @@
}
.editor__tab-close:hover {
- background: #3a3a5a;
- color: #e0e0e0;
+ background: var(--bg-hover);
+ color: var(--text-primary);
}
/* CodeMirror container */
diff --git a/src/components/Inspector.css b/src/components/Inspector.css
index f969f4e9..27d8cf3d 100644
--- a/src/components/Inspector.css
+++ b/src/components/Inspector.css
@@ -1,10 +1,10 @@
.inspector {
- background: #1a1a2e;
- color: #e0e0e0;
+ background: var(--bg-sidebar);
+ color: var(--text-primary);
display: flex;
flex-direction: column;
overflow-y: auto;
- border-left: 1px solid #2a2a4a;
+ border-left: 1px solid var(--border-primary);
transition: width 0.2s ease;
}
@@ -15,7 +15,7 @@
.inspector__header {
padding: 14px 12px;
- border-bottom: 1px solid #2a2a4a;
+ border-bottom: 1px solid var(--border-primary);
display: flex;
align-items: center;
gap: 8px;
@@ -34,20 +34,20 @@
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
- color: #999;
+ color: var(--text-tertiary);
}
.inspector__toggle {
background: none;
border: none;
- color: #888;
+ color: var(--text-tertiary);
cursor: pointer;
padding: 4px;
font-size: 12px;
}
.inspector__toggle:hover {
- color: #fff;
+ color: var(--text-heading);
}
.inspector__content {
@@ -62,13 +62,13 @@
margin: 0 0 8px;
font-size: 12px;
text-transform: uppercase;
- color: #888;
+ color: var(--text-tertiary);
letter-spacing: 0.5px;
}
.inspector__empty {
font-size: 13px;
- color: #555;
+ color: var(--text-faint);
margin: 0;
}
@@ -87,12 +87,15 @@
}
.inspector__prop-label {
- color: #888;
+ color: var(--text-tertiary);
flex-shrink: 0;
+ display: flex;
+ align-items: center;
+ gap: 4px;
}
.inspector__prop-value {
- color: #ccc;
+ color: var(--text-secondary);
text-align: right;
}
@@ -104,13 +107,13 @@
}
.inspector__prop-value--editable:hover {
- background-color: rgba(255, 255, 255, 0.1);
+ background-color: var(--bg-hover);
}
.inspector__edit-input {
- background: #2a2a4a;
- border: 1px solid #4a4a6a;
- color: #fff;
+ background: var(--bg-button);
+ border: 1px solid var(--border-dialog);
+ color: var(--text-heading);
padding: 4px 8px;
border-radius: 4px;
font-size: 13px;
@@ -120,21 +123,13 @@
.inspector__edit-input:focus {
outline: none;
- border-color: #7eb8da;
-}
-
-.inspector__prop-label {
- color: #888;
- flex-shrink: 0;
- display: flex;
- align-items: center;
- gap: 4px;
+ border-color: var(--link-color);
}
.inspector__prop-delete {
background: none;
border: none;
- color: #666;
+ color: var(--text-muted);
cursor: pointer;
padding: 0;
font-size: 14px;
@@ -148,7 +143,7 @@
}
.inspector__prop-delete:hover {
- color: #f44336;
+ color: var(--accent-red);
}
.inspector__status-pill {
@@ -171,8 +166,8 @@
.inspector__bool-toggle {
background: none;
- border: 1px solid #444;
- color: #ccc;
+ border: 1px solid var(--border-primary);
+ color: var(--text-secondary);
padding: 2px 8px;
border-radius: 4px;
cursor: pointer;
@@ -181,8 +176,8 @@
}
.inspector__bool-toggle:hover {
- background: rgba(255, 255, 255, 0.1);
- border-color: #666;
+ background: var(--bg-hover);
+ border-color: var(--text-muted);
}
/* List editor */
@@ -201,7 +196,7 @@
.inspector__list-item-text {
flex: 1;
- color: #ccc;
+ color: var(--text-secondary);
font-size: 13px;
cursor: pointer;
padding: 2px 4px;
@@ -213,13 +208,13 @@
}
.inspector__list-item-text:hover {
- background-color: rgba(255, 255, 255, 0.1);
+ background-color: var(--bg-hover);
}
.inspector__list-item-delete {
background: none;
border: none;
- color: #666;
+ color: var(--text-muted);
cursor: pointer;
padding: 0 4px;
font-size: 14px;
@@ -233,13 +228,13 @@
}
.inspector__list-item-delete:hover {
- color: #f44336;
+ color: var(--accent-red);
}
.inspector__list-add {
background: none;
border: none;
- color: #666;
+ color: var(--text-muted);
font-size: 12px;
padding: 4px 0;
cursor: pointer;
@@ -247,14 +242,14 @@
}
.inspector__list-add:hover {
- color: #888;
+ color: var(--text-tertiary);
}
.inspector__add-prop {
margin-top: 12px;
background: none;
- border: 1px dashed #444;
- color: #666;
+ border: 1px dashed var(--border-primary);
+ color: var(--text-muted);
padding: 6px 12px;
border-radius: 6px;
cursor: pointer;
@@ -264,8 +259,8 @@
}
.inspector__add-prop:hover:not(:disabled) {
- border-color: #7eb8da;
- color: #7eb8da;
+ border-color: var(--link-color);
+ color: var(--link-color);
}
.inspector__add-prop:disabled {
@@ -280,9 +275,9 @@
flex-direction: column;
gap: 8px;
padding: 12px;
- background: #2a2a4a;
+ background: var(--bg-button);
border-radius: 6px;
- border: 1px solid #4a4a6a;
+ border: 1px solid var(--border-dialog);
}
.inspector__add-dialog-buttons {
@@ -292,9 +287,9 @@
}
.inspector__add-dialog-buttons button {
- background: #3a3a5a;
+ background: var(--bg-hover);
border: none;
- color: #ccc;
+ color: var(--text-secondary);
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
@@ -303,16 +298,17 @@
}
.inspector__add-dialog-buttons button:hover:not(:disabled) {
- background: #4a4a6a;
- color: #fff;
+ background: var(--border-dialog);
+ color: var(--text-heading);
}
.inspector__add-dialog-buttons button:first-child {
- background: #4a6a8a;
+ background: var(--accent-blue);
+ color: #fff;
}
.inspector__add-dialog-buttons button:first-child:hover:not(:disabled) {
- background: #5a7a9a;
+ background: var(--accent-blue-hover);
}
.inspector__add-dialog-buttons button:disabled {
@@ -328,7 +324,7 @@
.inspector__rel-label {
display: block;
font-size: 11px;
- color: #666;
+ color: var(--text-muted);
margin-bottom: 4px;
}
@@ -341,7 +337,7 @@
.inspector__rel-link {
background: none;
border: none;
- color: #7eb8da;
+ color: var(--link-color);
font-size: 13px;
padding: 2px 0;
cursor: pointer;
@@ -349,14 +345,14 @@
}
.inspector__rel-link:hover {
- color: #a8d8f0;
+ color: var(--link-hover);
text-decoration: underline;
}
/* Backlinks */
.inspector__count {
font-size: 11px;
- color: #666;
+ color: var(--text-muted);
font-weight: 400;
margin-left: 4px;
}
@@ -373,7 +369,7 @@
align-items: center;
background: none;
border: none;
- color: #7eb8da;
+ color: var(--link-color);
font-size: 13px;
padding: 4px 0;
cursor: pointer;
@@ -382,7 +378,7 @@
}
.inspector__backlink:hover {
- color: #a8d8f0;
+ color: var(--link-hover);
}
.inspector__backlink-title {
@@ -394,7 +390,7 @@
.inspector__backlink-type {
font-size: 11px;
- color: #555;
+ color: var(--text-faint);
flex-shrink: 0;
}
@@ -406,7 +402,7 @@
}
.inspector__commit {
- border-left: 2px solid #333;
+ border-left: 2px solid var(--border-primary);
padding-left: 10px;
}
@@ -420,17 +416,17 @@
.inspector__commit-hash {
font-family: 'SF Mono', 'Menlo', monospace;
font-size: 11px;
- color: #7eb8da;
+ color: var(--link-color);
}
.inspector__commit-date {
font-size: 11px;
- color: #666;
+ color: var(--text-muted);
}
.inspector__commit-msg {
font-size: 12px;
- color: #aaa;
+ color: var(--text-secondary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -440,12 +436,12 @@
margin-top: 10px;
background: none;
border: none;
- color: #666;
+ color: var(--text-muted);
font-size: 12px;
padding: 4px 0;
cursor: not-allowed;
}
.inspector__view-all:hover {
- color: #888;
+ color: var(--text-tertiary);
}
diff --git a/src/components/NoteList.css b/src/components/NoteList.css
index d8575e3c..87dddf7e 100644
--- a/src/components/NoteList.css
+++ b/src/components/NoteList.css
@@ -1,15 +1,15 @@
.note-list {
- background: #16162a;
- color: #e0e0e0;
+ background: var(--bg-card);
+ color: var(--text-primary);
display: flex;
flex-direction: column;
overflow-y: auto;
- border-right: 1px solid #2a2a4a;
+ border-right: 1px solid var(--border-primary);
}
.note-list__header {
padding: 14px 16px;
- border-bottom: 1px solid #2a2a4a;
+ border-bottom: 1px solid var(--border-primary);
display: flex;
align-items: center;
justify-content: space-between;
@@ -41,8 +41,8 @@
.note-list__count {
font-size: 11px;
- color: #777;
- background: #2a2a4a;
+ color: var(--text-tertiary);
+ background: var(--bg-button);
padding: 2px 8px;
border-radius: 10px;
}
@@ -52,8 +52,8 @@
height: 24px;
border: none;
border-radius: 6px;
- background: #2a2a4a;
- color: #888;
+ background: var(--bg-button);
+ color: var(--text-tertiary);
font-size: 16px;
line-height: 1;
cursor: pointer;
@@ -65,23 +65,23 @@
}
.note-list__add-btn:hover {
- background: #4a9eff;
+ background: var(--accent-blue);
color: #fff;
}
/* Search */
.note-list__search {
padding: 8px 12px;
- border-bottom: 1px solid #2a2a4a;
+ border-bottom: 1px solid var(--border-primary);
}
.note-list__search-input {
width: 100%;
padding: 7px 10px;
- background: #1e1e3a;
- border: 1px solid #2a2a4a;
+ background: var(--bg-input);
+ border: 1px solid var(--border-input);
border-radius: 6px;
- color: #e0e0e0;
+ color: var(--text-primary);
font-size: 13px;
outline: none;
box-sizing: border-box;
@@ -89,11 +89,11 @@
}
.note-list__search-input::placeholder {
- color: #555;
+ color: var(--text-faint);
}
.note-list__search-input:focus {
- border-color: #4a9eff;
+ border-color: var(--accent-blue);
}
/* Type filter pills */
@@ -101,25 +101,25 @@
display: flex;
gap: 4px;
padding: 8px 12px;
- border-bottom: 1px solid #2a2a4a;
+ border-bottom: 1px solid var(--border-primary);
flex-wrap: wrap;
}
.note-list__pill {
padding: 3px 10px;
font-size: 11px;
- border: 1px solid #2a2a4a;
+ border: 1px solid var(--border-primary);
border-radius: 12px;
background: transparent;
- color: #777;
+ color: var(--text-tertiary);
cursor: pointer;
white-space: nowrap;
transition: all 0.15s;
}
.note-list__pill:hover {
- background: #2a2a4a;
- color: #ccc;
+ background: var(--bg-button);
+ color: var(--text-secondary);
}
.note-list__pill-count {
@@ -129,9 +129,9 @@
}
.note-list__pill--active {
- background: #4a9eff22;
- color: #4a9eff;
- border-color: #4a9eff44;
+ background: var(--accent-blue-bg);
+ color: var(--accent-blue);
+ border-color: var(--accent-blue-bg);
}
.note-list__pill--active .note-list__pill-count {
@@ -145,7 +145,7 @@
.note-list__empty {
padding: 32px 16px;
- color: #555;
+ color: var(--text-faint);
font-size: 13px;
text-align: center;
}
@@ -153,13 +153,13 @@
/* Note items */
.note-list__item {
padding: 10px 16px;
- border-bottom: 1px solid rgba(42, 42, 74, 0.5);
+ border-bottom: 1px solid var(--border-subtle);
cursor: pointer;
transition: background 0.1s;
}
.note-list__item:hover {
- background: #1e1e3a;
+ background: var(--bg-hover-subtle);
}
.note-list__item-top {
@@ -172,7 +172,7 @@
.note-list__title {
font-size: 13px;
font-weight: 600;
- color: #e0e0e0;
+ color: var(--text-primary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -182,14 +182,14 @@
.note-list__date {
font-size: 11px;
- color: #555;
+ color: var(--text-faint);
flex-shrink: 0;
white-space: nowrap;
}
.note-list__snippet {
font-size: 12px;
- color: #666;
+ color: var(--text-muted);
margin-top: 3px;
overflow: hidden;
text-overflow: ellipsis;
@@ -201,7 +201,7 @@
display: flex;
gap: 6px;
font-size: 11px;
- color: #888;
+ color: var(--text-tertiary);
margin-top: 5px;
}
@@ -255,30 +255,30 @@
}
.note-list__status {
- color: #4caf50;
+ color: var(--accent-green);
font-size: 10px;
}
/* Selected & pinned states */
.note-list__item--selected {
- background: #24244a;
- border-left: 3px solid #4a9eff;
+ background: var(--bg-selected);
+ border-left: 3px solid var(--accent-blue);
padding-left: 13px;
}
.note-list__item--selected:hover {
- background: #28284e;
+ background: var(--bg-selected);
}
.note-list__item--pinned {
- background: #1e1e3a;
- border-left: 3px solid #4caf50;
+ background: var(--bg-hover-subtle);
+ border-left: 3px solid var(--accent-green);
padding-left: 13px;
}
/* Relationship groups */
.note-list__group {
- border-top: 1px solid rgba(42, 42, 74, 0.5);
+ border-top: 1px solid var(--border-subtle);
}
.note-list__group-header {
@@ -293,13 +293,13 @@
font-weight: 600;
letter-spacing: 0.05em;
text-transform: uppercase;
- color: #666;
+ color: var(--text-muted);
}
.note-list__group-count {
font-size: 10px;
- color: #555;
- background: #2a2a4a;
+ color: var(--text-faint);
+ background: var(--bg-button);
padding: 1px 6px;
border-radius: 8px;
}
diff --git a/src/components/QuickOpenPalette.css b/src/components/QuickOpenPalette.css
index 9a23c1f8..500e6ede 100644
--- a/src/components/QuickOpenPalette.css
+++ b/src/components/QuickOpenPalette.css
@@ -4,7 +4,7 @@
left: 0;
right: 0;
bottom: 0;
- background: rgba(0, 0, 0, 0.5);
+ background: var(--shadow-dialog);
display: flex;
justify-content: center;
padding-top: 15vh;
@@ -15,10 +15,10 @@
width: 500px;
max-width: 90vw;
max-height: 400px;
- background: #1e1e3a;
- border: 1px solid #3a3a5a;
+ background: var(--bg-dialog);
+ border: 1px solid var(--border-dialog);
border-radius: 10px;
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
+ box-shadow: 0 8px 32px var(--shadow-dialog);
display: flex;
flex-direction: column;
overflow: hidden;
@@ -29,14 +29,14 @@
padding: 12px 16px;
background: transparent;
border: none;
- border-bottom: 1px solid #2a2a4a;
- color: #e0e0e0;
+ border-bottom: 1px solid var(--border-primary);
+ color: var(--text-primary);
font-size: 15px;
outline: none;
}
.palette__input::placeholder {
- color: #555;
+ color: var(--text-faint);
}
.palette__results {
@@ -47,7 +47,7 @@
.palette__empty {
padding: 16px;
- color: #666;
+ color: var(--text-muted);
font-size: 13px;
text-align: center;
}
@@ -63,26 +63,26 @@
.palette__item:hover,
.palette__item--selected {
- background: #2a2a4a;
+ background: var(--bg-button);
}
.palette__item--selected {
- background: #3a3a5a;
+ background: var(--bg-hover);
}
.palette__item-title {
font-size: 14px;
- color: #e0e0e0;
+ color: var(--text-primary);
}
.palette__item-type {
font-size: 11px;
- color: #888;
- background: #2a2a4a;
+ color: var(--text-tertiary);
+ background: var(--bg-button);
padding: 2px 8px;
border-radius: 4px;
}
.palette__item--selected .palette__item-type {
- background: #4a4a6a;
+ background: var(--border-dialog);
}
diff --git a/src/components/ResizeHandle.css b/src/components/ResizeHandle.css
index 5d29c2df..28ea5ea8 100644
--- a/src/components/ResizeHandle.css
+++ b/src/components/ResizeHandle.css
@@ -7,5 +7,5 @@
}
.resize-handle:hover {
- background: #4a4a6a;
+ background: var(--border-dialog);
}
diff --git a/src/components/Sidebar.css b/src/components/Sidebar.css
index 4378c628..a2332353 100644
--- a/src/components/Sidebar.css
+++ b/src/components/Sidebar.css
@@ -1,6 +1,6 @@
.sidebar {
- background: #1a1a2e;
- color: #e0e0e0;
+ background: var(--bg-sidebar);
+ color: var(--text-primary);
display: flex;
flex-direction: column;
overflow-y: auto;
@@ -10,17 +10,20 @@
.sidebar__header {
padding: 12px 16px;
padding-left: 78px; /* space for macOS traffic light buttons */
- border-bottom: 1px solid #2a2a4a;
+ border-bottom: 1px solid var(--border-primary);
flex-shrink: 0;
-webkit-app-region: drag;
app-region: drag;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
}
.sidebar__header h2 {
margin: 0;
font-size: 17px;
font-weight: 700;
- color: #ffffff;
+ color: var(--text-heading);
letter-spacing: -0.01em;
}
@@ -29,6 +32,26 @@
app-region: no-drag;
}
+.sidebar__theme-toggle {
+ background: none;
+ border: none;
+ color: var(--text-tertiary);
+ cursor: pointer;
+ font-size: 16px;
+ padding: 4px 6px;
+ border-radius: 6px;
+ line-height: 1;
+ transition: all 0.15s;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.sidebar__theme-toggle:hover {
+ background: var(--bg-hover);
+ color: var(--text-heading);
+}
+
.sidebar__nav {
padding: 8px 0;
flex: 1;
@@ -39,7 +62,7 @@
.sidebar__filters {
padding: 4px 0;
margin-bottom: 8px;
- border-bottom: 1px solid #2a2a4a;
+ border-bottom: 1px solid var(--border-primary);
}
.sidebar__filter-item {
@@ -49,17 +72,17 @@
border-radius: 6px;
margin: 1px 6px;
transition: all 0.12s;
- color: #aaa;
+ color: var(--text-secondary);
}
.sidebar__filter-item:hover {
- background: #252545;
- color: #ddd;
+ background: var(--bg-hover);
+ color: var(--text-primary);
}
.sidebar__filter-item--active {
- background: #4a9eff18;
- color: #4a9eff;
+ background: var(--accent-blue-bg);
+ color: var(--accent-blue);
font-weight: 500;
}
@@ -78,18 +101,18 @@
font-size: 11px;
font-weight: 600;
letter-spacing: 0.05em;
- color: #888;
+ color: var(--text-tertiary);
user-select: none;
}
.sidebar__section-header:hover {
- background: #2a2a4a;
- color: #bbb;
+ background: var(--bg-button);
+ color: var(--text-secondary);
}
.sidebar__section-header--active {
- background: #2a2a4a;
- color: #ffffff;
+ background: var(--bg-button);
+ color: var(--text-heading);
}
.sidebar__collapse-btn {
@@ -110,14 +133,14 @@
.sidebar__section-count {
font-size: 10px;
- color: #666;
+ color: var(--text-muted);
margin-right: 4px;
}
.sidebar__add-btn {
background: none;
border: none;
- color: #666;
+ color: var(--text-muted);
font-size: 14px;
cursor: pointer;
padding: 0 2px;
@@ -132,8 +155,8 @@
}
.sidebar__add-btn:hover {
- color: #ffffff;
- background: #3a3a5a;
+ color: var(--text-heading);
+ background: var(--bg-hover);
}
/* Section items (entity list) */
@@ -150,18 +173,18 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
- color: #bbb;
+ color: var(--text-secondary);
transition: all 0.12s;
}
.sidebar__item:hover {
- background: #252545;
- color: #ddd;
+ background: var(--bg-hover);
+ color: var(--text-primary);
}
.sidebar__item--active {
- background: #4a9eff18;
- color: #4a9eff;
+ background: var(--accent-blue-bg);
+ color: var(--accent-blue);
font-weight: 500;
}
@@ -169,7 +192,7 @@
.sidebar__topics {
margin-top: 8px;
padding-top: 8px;
- border-top: 1px solid #2a2a4a;
+ border-top: 1px solid var(--border-primary);
}
.sidebar__topics-header {
@@ -177,7 +200,7 @@
font-size: 11px;
font-weight: 600;
letter-spacing: 0.05em;
- color: #888;
+ color: var(--text-tertiary);
user-select: none;
}
@@ -190,17 +213,17 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
- color: #bbb;
+ color: var(--text-secondary);
transition: all 0.12s;
}
.sidebar__topic-item:hover {
- background: #252545;
- color: #ddd;
+ background: var(--bg-hover);
+ color: var(--text-primary);
}
.sidebar__topic-item--active {
- background: #4a9eff18;
- color: #4a9eff;
+ background: var(--accent-blue-bg);
+ color: var(--accent-blue);
font-weight: 500;
}
diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx
index 4fb724bd..80fade58 100644
--- a/src/components/Sidebar.tsx
+++ b/src/components/Sidebar.tsx
@@ -1,4 +1,4 @@
-import { useState } from 'react'
+import { useState, useEffect } from 'react'
import type { VaultEntry, SidebarSelection } from '../types'
import './Sidebar.css'
@@ -26,6 +26,26 @@ const SECTION_GROUPS = [
export function Sidebar({ entries, selection, onSelect, onSelectNote }: SidebarProps) {
const [collapsed, setCollapsed] = useState>({})
+ const [theme, setTheme] = useState<'dark' | 'light'>(() => {
+ try {
+ return (localStorage.getItem('laputa-theme') as 'dark' | 'light') || 'dark'
+ } catch {
+ return 'dark'
+ }
+ })
+
+ useEffect(() => {
+ document.documentElement.setAttribute('data-theme', theme)
+ try {
+ localStorage.setItem('laputa-theme', theme)
+ } catch {
+ // localStorage unavailable (e.g. in tests)
+ }
+ }, [theme])
+
+ const toggleTheme = () => {
+ setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'))
+ }
const toggleSection = (type: string) => {
setCollapsed((prev) => ({ ...prev, [type]: !prev[type] }))
@@ -44,6 +64,13 @@ export function Sidebar({ entries, selection, onSelect, onSelectNote }: SidebarP