mirror of
https://github.com/philemonchiro/obsidian-notekeeper.git
synced 2026-07-22 06:51:40 +00:00
The bigger half is the new "wall" view: a sticky-note styled, vertically-scrolled, curated subset of your notes. - New density modes 'wall' and 'wall-compact' selectable from the toolbar. Wall is now the default density on fresh installs. - Per-card sticky-note look: deterministic 1-3 degree rotation seeded by file path, paper-style drop shadow, hover lift to 0deg. - Eight wall backgrounds (cork, whiteboard, slate, paper, graph, blueprint, linen, chalkboard) chosen from the settings tab. Default: slate. - Walls are curated, not auto-filled. The wall starts empty; users add notes via the floating + button (FuzzySuggestModal picker) or via the empty state's "Fill from current view" shortcut (only offered when the current filter has <= 200 notes). - Right-click any card on the wall: "Remove from wall". - Command "Clear wall" (palette) wipes the current wall. - The freeform-canvas prototype was scrapped in favor of the column layout after testing showed dragging cards onto a giant scattered canvas was unusable at vault scale. Bot fixes: - async onClose / async render / async make-trash arrow had no awaits. Made onClose and onOpen non-async (return Promise.resolve) to match Obsidian's signature; render is now sync; the trash arrow is sync too (its body's awaits are inside a ConfirmModal callback). - Switched view content access from this.containerEl.children[1] to this.contentEl. Fixes a tab-switching ghosting bug — newer Obsidian versions can wrap views in extra layers, shifting the children index, so renders were occasionally landing on the wrong element. Per the developer docs, contentEl is the stable getter. - The wall FAB moved from position: fixed to position: absolute inside the body container, so it disappears with its tab instead of bleeding across panes. - Added @typescript-eslint/require-await to the local eslint config so the next round of these doesn't slip past.
1341 lines
28 KiB
CSS
1341 lines
28 KiB
CSS
/* ========== root ========== */
|
|
.keep-cards-root {
|
|
padding: 0 !important;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
/* ========== header ========== */
|
|
.keep-cards-header {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 14px;
|
|
flex-shrink: 0;
|
|
background: var(--background-primary);
|
|
padding: 12px 16px 12px;
|
|
border-bottom: 1px solid var(--background-modifier-border);
|
|
}
|
|
|
|
.keep-cards-header-top {
|
|
display: flex;
|
|
gap: 12px;
|
|
align-items: center;
|
|
}
|
|
|
|
.keep-cards-header-capture {
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
/* search */
|
|
.keep-cards-search-wrap {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
border-radius: 8px;
|
|
border: 1px solid var(--background-modifier-border);
|
|
background: var(--background-secondary);
|
|
overflow: hidden;
|
|
height: 36px;
|
|
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
|
}
|
|
|
|
.keep-cards-search-wrap:focus-within {
|
|
border-color: var(--text-accent);
|
|
}
|
|
|
|
.keep-cards-search-icon {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0 10px 0 12px;
|
|
color: var(--text-faint);
|
|
}
|
|
|
|
.keep-cards-search-icon svg,
|
|
.keep-cards-search-icon .svg-icon {
|
|
width: 15px;
|
|
height: 15px;
|
|
}
|
|
|
|
.keep-cards-search {
|
|
flex: 1;
|
|
padding: 0 12px 0 0;
|
|
border: none;
|
|
background: transparent;
|
|
color: var(--text-normal);
|
|
font-size: 13px;
|
|
height: 100%;
|
|
outline: none;
|
|
}
|
|
|
|
/* sort button */
|
|
.keep-cards-sort-btn {
|
|
background: var(--background-secondary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
color: var(--text-muted);
|
|
width: 36px;
|
|
height: 36px;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
padding: 0;
|
|
transition: background 0.12s ease, color 0.12s ease;
|
|
}
|
|
|
|
.keep-cards-sort-btn:hover {
|
|
background: var(--background-modifier-hover);
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.keep-cards-sort-btn.is-active {
|
|
background: var(--background-modifier-hover);
|
|
color: var(--text-accent);
|
|
border-color: var(--text-accent);
|
|
}
|
|
|
|
/* active filter chip */
|
|
.keep-cards-active-filter {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 2px;
|
|
padding: 0 4px 0 12px;
|
|
height: 28px;
|
|
background: var(--background-modifier-hover);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 14px;
|
|
color: var(--text-normal);
|
|
font-size: 12px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.keep-cards-active-filter-label {
|
|
white-space: nowrap;
|
|
max-width: 180px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.keep-cards-active-filter-x {
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text-muted);
|
|
width: 20px;
|
|
height: 20px;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0;
|
|
margin-left: 2px;
|
|
}
|
|
|
|
.keep-cards-active-filter-x:hover {
|
|
background: var(--background-modifier-active-hover, var(--background-modifier-border));
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.keep-cards-active-filter-x svg,
|
|
.keep-cards-active-filter-x .svg-icon {
|
|
width: 12px;
|
|
height: 12px;
|
|
}
|
|
|
|
.keep-cards-sort-btn svg,
|
|
.keep-cards-sort-btn .svg-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
|
|
/* toolbar — segmented control */
|
|
.keep-cards-toolbar {
|
|
display: inline-flex;
|
|
align-items: stretch;
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
background: var(--background-secondary);
|
|
height: 36px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.keep-cards-tb-btn {
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text-muted);
|
|
width: 38px;
|
|
height: 100%;
|
|
border-radius: 0;
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0;
|
|
border-right: 1px solid var(--background-modifier-border);
|
|
transition: background 0.12s ease, color 0.12s ease;
|
|
}
|
|
|
|
.keep-cards-tb-btn:last-child {
|
|
border-right: none;
|
|
}
|
|
|
|
.keep-cards-tb-btn:hover {
|
|
background: var(--background-modifier-hover);
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.keep-cards-tb-btn.is-active {
|
|
background: var(--background-modifier-hover);
|
|
color: var(--text-accent);
|
|
}
|
|
|
|
.keep-cards-tb-btn svg,
|
|
.keep-cards-tb-btn .svg-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
|
|
/* capture */
|
|
.keep-cards-capture-wrap {
|
|
width: 100%;
|
|
max-width: 600px;
|
|
display: flex;
|
|
align-items: stretch;
|
|
border-radius: 10px;
|
|
border: 1px solid var(--background-modifier-border);
|
|
background: var(--background-secondary);
|
|
overflow: hidden;
|
|
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
|
}
|
|
|
|
.keep-cards-capture-wrap:focus-within {
|
|
border-color: var(--background-modifier-border-hover, var(--background-modifier-border));
|
|
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.25);
|
|
}
|
|
|
|
.keep-cards-capture {
|
|
flex: 1;
|
|
padding: 12px 16px;
|
|
border: none;
|
|
background: transparent;
|
|
color: var(--text-normal);
|
|
font-size: 14px;
|
|
resize: none;
|
|
font-family: inherit;
|
|
line-height: 1.5;
|
|
outline: none;
|
|
}
|
|
|
|
.keep-cards-capture::placeholder {
|
|
color: var(--text-faint);
|
|
}
|
|
|
|
/* shared icon sizing across buttons */
|
|
.keep-card-action svg,
|
|
.keep-card-action .svg-icon,
|
|
.keep-cards-bulk-btn svg,
|
|
.keep-cards-bulk-btn .svg-icon,
|
|
.keep-modal-action-btn svg,
|
|
.keep-modal-action-btn .svg-icon,
|
|
.keep-sidebar-icon svg,
|
|
.keep-sidebar-icon .svg-icon,
|
|
.keep-sidebar-edit svg,
|
|
.keep-sidebar-edit .svg-icon,
|
|
.keep-sidebar-more svg,
|
|
.keep-sidebar-more .svg-icon,
|
|
.keep-card-backlinks-icon svg,
|
|
.keep-card-backlinks-icon .svg-icon,
|
|
.keep-empty-icon svg,
|
|
.keep-empty-icon .svg-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
|
|
.keep-empty-icon svg,
|
|
.keep-empty-icon .svg-icon {
|
|
width: 32px;
|
|
height: 32px;
|
|
}
|
|
|
|
/* ========== body row ========== */
|
|
.keep-cards-body {
|
|
display: flex;
|
|
gap: 16px;
|
|
align-items: stretch;
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
padding: 12px 16px 16px;
|
|
position: relative;
|
|
}
|
|
|
|
/* ========== sidebar ========== */
|
|
.keep-cards-sidebar {
|
|
width: 220px;
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
padding-top: 4px;
|
|
padding-bottom: 12px;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
align-self: stretch;
|
|
min-height: 0;
|
|
}
|
|
|
|
.keep-sidebar-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 8px 12px;
|
|
border-radius: 0 24px 24px 0;
|
|
cursor: pointer;
|
|
color: var(--text-muted);
|
|
font-size: 13px;
|
|
user-select: none;
|
|
position: relative;
|
|
}
|
|
|
|
.keep-sidebar-item:hover {
|
|
background: var(--background-modifier-hover);
|
|
}
|
|
|
|
.keep-sidebar-item.is-active {
|
|
background: var(--background-modifier-active-hover, var(--background-modifier-hover));
|
|
color: var(--text-normal);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.keep-sidebar-item.is-drop-target {
|
|
outline: 2px dashed var(--text-accent);
|
|
outline-offset: -2px;
|
|
}
|
|
|
|
.keep-sidebar-icon {
|
|
display: inline-flex;
|
|
width: 16px;
|
|
height: 16px;
|
|
}
|
|
|
|
.keep-sidebar-color-dot {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.keep-sidebar-label {
|
|
flex: 1;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.keep-sidebar-more {
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text-muted);
|
|
padding: 0;
|
|
width: 22px;
|
|
height: 22px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
opacity: 0;
|
|
}
|
|
|
|
.keep-sidebar-item:hover .keep-sidebar-more {
|
|
opacity: 1;
|
|
}
|
|
|
|
.keep-sidebar-more:hover {
|
|
background: var(--background-modifier-hover);
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.keep-sidebar-divider {
|
|
height: 1px;
|
|
background: var(--background-modifier-border);
|
|
margin: 8px 0;
|
|
}
|
|
|
|
.keep-sidebar-heading {
|
|
font-size: 11px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
color: var(--text-faint);
|
|
padding: 4px 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.keep-sidebar-edit {
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text-faint);
|
|
padding: 0;
|
|
width: 18px;
|
|
height: 18px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.keep-sidebar-edit:hover {
|
|
color: var(--text-muted);
|
|
background: var(--background-modifier-hover);
|
|
}
|
|
|
|
/* ========== grid + sections ========== */
|
|
.keep-cards-grid {
|
|
flex: 1;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 24px;
|
|
overflow-y: auto;
|
|
align-self: stretch;
|
|
min-height: 0;
|
|
padding-bottom: 12px;
|
|
}
|
|
|
|
.keep-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.keep-section-header {
|
|
font-size: 11px;
|
|
letter-spacing: 0.08em;
|
|
color: var(--text-faint);
|
|
text-transform: uppercase;
|
|
padding-left: 4px;
|
|
}
|
|
|
|
.keep-section-cols {
|
|
display: flex;
|
|
gap: 16px;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.keep-col {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
min-width: 0;
|
|
}
|
|
|
|
/* ========== card ========== */
|
|
.keep-card {
|
|
position: relative;
|
|
border-radius: 10px;
|
|
border: 1px solid var(--background-modifier-border);
|
|
background: var(--background-secondary);
|
|
cursor: pointer;
|
|
transition: box-shadow 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.keep-card:hover {
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
.keep-card.is-focused {
|
|
outline: 2px solid var(--text-accent);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.keep-card.is-selected {
|
|
outline: 2px solid var(--text-accent);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.keep-card.is-dragging {
|
|
opacity: 0.4;
|
|
}
|
|
|
|
.keep-card.is-drop-target {
|
|
border-color: var(--text-accent);
|
|
box-shadow: 0 0 0 2px var(--text-accent);
|
|
}
|
|
|
|
.keep-card--pinned {
|
|
border-color: var(--text-accent);
|
|
}
|
|
|
|
.keep-card-checkbox {
|
|
position: absolute;
|
|
top: 8px;
|
|
left: 8px;
|
|
z-index: 2;
|
|
opacity: 0;
|
|
margin: 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.keep-card:hover .keep-card-checkbox,
|
|
.keep-card.is-selected .keep-card-checkbox {
|
|
opacity: 1;
|
|
}
|
|
|
|
.keep-card-image {
|
|
width: 100%;
|
|
max-height: 220px;
|
|
object-fit: cover;
|
|
display: block;
|
|
}
|
|
|
|
.keep-card-title {
|
|
font-weight: 600;
|
|
font-size: 15px;
|
|
padding: 12px 14px 4px;
|
|
color: var(--text-normal);
|
|
word-wrap: break-word;
|
|
}
|
|
|
|
.keep-card-body {
|
|
padding: 0 14px 8px;
|
|
font-size: 13px;
|
|
color: var(--text-muted);
|
|
line-height: 1.5;
|
|
word-wrap: break-word;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.keep-card-body p {
|
|
margin: 0 0 8px;
|
|
}
|
|
|
|
.keep-card-body p:last-child { margin-bottom: 0; }
|
|
|
|
.keep-card-body ul,
|
|
.keep-card-body ol {
|
|
margin: 0 0 8px;
|
|
padding-left: 20px;
|
|
}
|
|
|
|
.keep-card-body h1,
|
|
.keep-card-body h2,
|
|
.keep-card-body h3,
|
|
.keep-card-body h4 {
|
|
margin: 8px 0 4px;
|
|
font-size: 14px;
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.keep-card-body code {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.keep-card-body pre {
|
|
font-size: 12px;
|
|
overflow-x: auto;
|
|
max-height: 120px;
|
|
}
|
|
|
|
.keep-card-body img {
|
|
max-width: 100%;
|
|
height: auto;
|
|
}
|
|
|
|
.keep-card-body a.tag {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.keep-card-body input[type="checkbox"] {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.keep-card-tags {
|
|
margin-top: 4px;
|
|
padding: 0 14px 8px;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
}
|
|
|
|
.keep-card-tag {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 12px;
|
|
background: var(--background-modifier-hover);
|
|
color: var(--text-muted);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.keep-card-tag:hover {
|
|
background: var(--background-modifier-active-hover, var(--background-modifier-hover));
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.keep-card-meta {
|
|
padding: 0 14px;
|
|
display: flex;
|
|
gap: 8px;
|
|
font-size: 11px;
|
|
color: var(--text-faint);
|
|
align-items: center;
|
|
min-height: 0;
|
|
}
|
|
|
|
.keep-card-backlinks {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
.keep-card-backlinks-icon {
|
|
display: inline-flex;
|
|
width: 12px;
|
|
height: 12px;
|
|
}
|
|
|
|
.keep-card-actions {
|
|
display: flex;
|
|
gap: 2px;
|
|
padding: 4px 6px 6px;
|
|
opacity: 0;
|
|
transition: opacity 0.12s ease;
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
.keep-card:hover .keep-card-actions,
|
|
.keep-card.is-focused .keep-card-actions {
|
|
opacity: 1;
|
|
}
|
|
|
|
.keep-card-action {
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text-muted);
|
|
width: 28px;
|
|
height: 28px;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0;
|
|
}
|
|
|
|
.keep-card-action:hover {
|
|
background: var(--background-modifier-hover);
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
/* ========== inline editor ========== */
|
|
.keep-card-editor {
|
|
width: 100%;
|
|
margin: 0;
|
|
padding: 0 14px 8px;
|
|
border: none;
|
|
background: transparent;
|
|
color: var(--text-normal);
|
|
font-family: inherit;
|
|
font-size: 13px;
|
|
line-height: 1.5;
|
|
resize: none;
|
|
outline: none;
|
|
min-height: 60px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.keep-card.is-editing-card {
|
|
cursor: default;
|
|
outline: 2px solid var(--text-accent);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* ========== color picker ========== */
|
|
.keep-color-picker {
|
|
position: absolute;
|
|
bottom: 44px;
|
|
left: 6px;
|
|
display: grid;
|
|
grid-template-columns: repeat(6, 1fr);
|
|
gap: 6px;
|
|
padding: 8px;
|
|
border-radius: 10px;
|
|
background: var(--background-primary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
|
|
z-index: 5;
|
|
}
|
|
|
|
.keep-color-swatch {
|
|
width: 22px;
|
|
height: 22px;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
border: 1px solid var(--background-modifier-border);
|
|
}
|
|
|
|
.keep-color-swatch:hover {
|
|
outline: 2px solid var(--text-accent);
|
|
outline-offset: 1px;
|
|
}
|
|
|
|
.keep-color-swatch--default {
|
|
background:
|
|
linear-gradient(45deg, transparent 45%, var(--text-muted) 45%, var(--text-muted) 55%, transparent 55%),
|
|
var(--background-primary);
|
|
}
|
|
|
|
/* ========== skeleton shimmer ========== */
|
|
.keep-card.is-skeleton .keep-card-body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
padding: 6px 14px 14px;
|
|
}
|
|
|
|
.keep-shimmer {
|
|
height: 10px;
|
|
border-radius: 4px;
|
|
background: linear-gradient(
|
|
90deg,
|
|
var(--background-modifier-border) 0%,
|
|
var(--background-modifier-hover) 50%,
|
|
var(--background-modifier-border) 100%
|
|
);
|
|
background-size: 200% 100%;
|
|
animation: keep-shimmer 1.6s infinite;
|
|
}
|
|
|
|
.keep-shimmer:nth-child(2) { width: 80%; }
|
|
.keep-shimmer:nth-child(3) { width: 60%; }
|
|
|
|
@keyframes keep-shimmer {
|
|
0% { background-position: 200% 0; }
|
|
100% { background-position: -200% 0; }
|
|
}
|
|
|
|
/* ========== empty state ========== */
|
|
.keep-cards-empty {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 80px 16px;
|
|
color: var(--text-muted);
|
|
text-align: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.keep-empty-icon {
|
|
display: inline-flex;
|
|
width: 48px;
|
|
height: 48px;
|
|
color: var(--text-faint);
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.keep-empty-title {
|
|
font-size: 16px;
|
|
color: var(--text-normal);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.keep-empty-sub {
|
|
font-size: 13px;
|
|
}
|
|
|
|
/* ========== bulk actions bar ========== */
|
|
.keep-cards-bulk {
|
|
position: fixed;
|
|
bottom: 24px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
background: var(--background-primary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 32px;
|
|
padding: 6px 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
|
|
z-index: 100;
|
|
}
|
|
|
|
.keep-cards-bulk-count {
|
|
padding: 0 8px;
|
|
color: var(--text-normal);
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.keep-cards-bulk-btn {
|
|
background: transparent;
|
|
border: none;
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 50%;
|
|
color: var(--text-muted);
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.keep-cards-bulk-btn:hover {
|
|
background: var(--background-modifier-hover);
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
/* ========== undo toast ========== */
|
|
.keep-undo-toast {
|
|
position: fixed;
|
|
bottom: 24px;
|
|
right: 24px;
|
|
background: var(--background-primary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 8px;
|
|
padding: 10px 14px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
|
|
color: var(--text-normal);
|
|
z-index: 100;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.keep-undo-btn {
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text-accent);
|
|
cursor: pointer;
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
padding: 0;
|
|
}
|
|
|
|
/* ========== density: list ========== */
|
|
.density-list .keep-section-cols {
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.density-list .keep-col {
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.density-list .keep-card {
|
|
flex-direction: row;
|
|
align-items: stretch;
|
|
max-height: 120px;
|
|
}
|
|
|
|
.density-list .keep-card-image {
|
|
width: 120px;
|
|
height: auto;
|
|
max-height: 120px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.density-list .keep-card-body {
|
|
-webkit-line-clamp: 3;
|
|
display: -webkit-box;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.density-list .keep-card-actions {
|
|
flex-direction: column;
|
|
padding: 4px;
|
|
}
|
|
|
|
/* ========== density: compact ========== */
|
|
.density-compact .keep-card-title {
|
|
font-size: 13px;
|
|
padding: 8px 10px 2px;
|
|
}
|
|
|
|
.density-compact .keep-card-body {
|
|
font-size: 12px;
|
|
padding: 0 10px 6px;
|
|
}
|
|
|
|
.density-compact .keep-card-tags {
|
|
padding: 0 10px 6px;
|
|
}
|
|
|
|
.density-compact .keep-card-image {
|
|
max-height: 140px;
|
|
}
|
|
|
|
/* ========== reduced motion ========== */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.keep-card,
|
|
.keep-card-actions,
|
|
.keep-shimmer {
|
|
transition: none !important;
|
|
animation: none !important;
|
|
}
|
|
}
|
|
|
|
/* ========== note preview modal ========== */
|
|
.keep-note-modal {
|
|
width: min(900px, 92vw);
|
|
max-height: 88vh;
|
|
}
|
|
|
|
.keep-note-modal .modal-title {
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.keep-modal-titlerow {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
width: 100%;
|
|
}
|
|
|
|
.keep-modal-title {
|
|
flex: 1;
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
text-align: left;
|
|
}
|
|
|
|
.keep-modal-actions {
|
|
display: flex;
|
|
gap: 2px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.keep-modal-action-btn {
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text-muted);
|
|
width: 30px;
|
|
height: 30px;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0;
|
|
}
|
|
|
|
.keep-modal-action-btn:hover {
|
|
background: var(--background-modifier-hover);
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.keep-modal-tags {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.keep-modal-body {
|
|
max-height: 65vh;
|
|
overflow-y: auto;
|
|
padding: 4px 4px 8px;
|
|
}
|
|
|
|
.keep-modal-md {
|
|
font-size: 14px;
|
|
line-height: 1.6;
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.keep-modal-md p { margin: 0 0 12px; }
|
|
.keep-modal-md p:last-child { margin-bottom: 0; }
|
|
.keep-modal-md h1, .keep-modal-md h2, .keep-modal-md h3 { margin-top: 16px; }
|
|
.keep-modal-md ul, .keep-modal-md ol { padding-left: 24px; margin: 0 0 12px; }
|
|
.keep-modal-md img { max-width: 100%; border-radius: 6px; }
|
|
.keep-modal-md pre { padding: 10px; border-radius: 6px; background: var(--background-secondary); overflow-x: auto; }
|
|
.keep-modal-md blockquote { border-left: 3px solid var(--background-modifier-border); padding-left: 12px; margin: 0 0 12px; color: var(--text-muted); }
|
|
|
|
.keep-modal-meta {
|
|
display: flex;
|
|
gap: 16px;
|
|
align-items: center;
|
|
margin-top: 16px;
|
|
padding-top: 12px;
|
|
border-top: 1px solid var(--background-modifier-border);
|
|
font-size: 11px;
|
|
color: var(--text-faint);
|
|
}
|
|
|
|
.keep-modal-path {
|
|
font-family: var(--font-monospace);
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
flex: 1;
|
|
}
|
|
|
|
.keep-modal-editor {
|
|
width: 100%;
|
|
min-height: 60vh;
|
|
padding: 14px;
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 6px;
|
|
background: var(--background-primary);
|
|
color: var(--text-normal);
|
|
font-family: inherit;
|
|
font-size: 14px;
|
|
line-height: 1.6;
|
|
resize: vertical;
|
|
outline: none;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.keep-modal-editor:focus {
|
|
border-color: var(--text-accent);
|
|
}
|
|
|
|
/* ========== shared modal helpers ========== */
|
|
.keep-modal-stack {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.keep-modal-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 4px 0;
|
|
}
|
|
|
|
.keep-modal-spacer {
|
|
flex: 1;
|
|
}
|
|
|
|
.keep-modal-input {
|
|
width: 100%;
|
|
}
|
|
|
|
.keep-modal-buttons {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 8px;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
.keep-modal-hint {
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
margin-top: 8px;
|
|
}
|
|
|
|
.keep-modal-color-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(6, 1fr);
|
|
gap: 8px;
|
|
margin-top: 8px;
|
|
}
|
|
|
|
.keep-modal-color-swatch {
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
border: 1px solid var(--background-modifier-border);
|
|
}
|
|
|
|
.keep-tag-dot {
|
|
width: 12px;
|
|
height: 12px;
|
|
border-radius: 50%;
|
|
border: 1px solid var(--background-modifier-border);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.keep-confirm-message {
|
|
margin: 8px 0 4px;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
/* ========== wall view ========== */
|
|
.keep-cards-wall-switcher {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
height: 36px;
|
|
padding: 0 10px 0 14px;
|
|
background: var(--background-secondary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 8px;
|
|
color: var(--text-normal);
|
|
cursor: pointer;
|
|
font-size: 13px;
|
|
font-family: inherit;
|
|
flex-shrink: 0;
|
|
max-width: 220px;
|
|
}
|
|
|
|
.keep-cards-wall-switcher:hover {
|
|
background: var(--background-modifier-hover);
|
|
}
|
|
|
|
.keep-cards-wall-switcher-name {
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
max-width: 160px;
|
|
}
|
|
|
|
.keep-cards-wall-switcher-chev {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.keep-cards-wall-switcher-chev svg,
|
|
.keep-cards-wall-switcher-chev .svg-icon {
|
|
width: 14px;
|
|
height: 14px;
|
|
}
|
|
|
|
.keep-cards-grid.is-wall {
|
|
position: relative;
|
|
background-color: var(--background-secondary);
|
|
padding: 16px;
|
|
}
|
|
|
|
/* Backgrounds */
|
|
|
|
/* Cork: layered dot textures + warm noise */
|
|
.keep-cards-grid.wall-cork {
|
|
background-color: #8a5f3a;
|
|
background-image:
|
|
radial-gradient(rgba(255, 240, 220, 0.04) 0.7px, transparent 0.7px),
|
|
radial-gradient(rgba(40, 20, 0, 0.18) 1.2px, transparent 1.2px),
|
|
radial-gradient(rgba(60, 30, 5, 0.10) 1.6px, transparent 1.6px);
|
|
background-size: 5px 5px, 11px 11px, 19px 19px;
|
|
background-position: 0 0, 2px 3px, 5px 1px;
|
|
}
|
|
|
|
/* Whiteboard: clean light with crisp grid + a hairline major grid */
|
|
.keep-cards-grid.wall-whiteboard {
|
|
background-color: #fafaf7;
|
|
background-image:
|
|
linear-gradient(rgba(0, 0, 0, 0.035) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(0, 0, 0, 0.035) 1px, transparent 1px),
|
|
linear-gradient(rgba(0, 0, 0, 0.06) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(0, 0, 0, 0.06) 1px, transparent 1px);
|
|
background-size: 24px 24px, 24px 24px, 120px 120px, 120px 120px;
|
|
}
|
|
|
|
/* Slate: deep neutral with subtle grid */
|
|
.keep-cards-grid.wall-slate {
|
|
background-color: #1f2227;
|
|
background-image:
|
|
linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px),
|
|
linear-gradient(rgba(255, 255, 255, 0.06) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(255, 255, 255, 0.06) 1px, transparent 1px);
|
|
background-size: 24px 24px, 24px 24px, 120px 120px, 120px 120px;
|
|
}
|
|
|
|
/* Paper: warm beige, soft noise */
|
|
.keep-cards-grid.wall-paper {
|
|
background-color: #fbf6e8;
|
|
background-image:
|
|
radial-gradient(rgba(102, 70, 30, 0.07) 1px, transparent 1.4px),
|
|
radial-gradient(rgba(102, 70, 30, 0.05) 0.8px, transparent 1.2px);
|
|
background-size: 14px 14px, 7px 7px;
|
|
background-position: 0 0, 3px 4px;
|
|
}
|
|
|
|
/* Graph paper: minor + major grid in a soft blue, white field */
|
|
.keep-cards-grid.wall-graph {
|
|
background-color: #f6f9ff;
|
|
background-image:
|
|
linear-gradient(rgba(60, 110, 200, 0.08) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(60, 110, 200, 0.08) 1px, transparent 1px),
|
|
linear-gradient(rgba(60, 110, 200, 0.18) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(60, 110, 200, 0.18) 1px, transparent 1px);
|
|
background-size: 12px 12px, 12px 12px, 60px 60px, 60px 60px;
|
|
}
|
|
|
|
/* Blueprint: dark navy with crisp white grid (architect / maker) */
|
|
.keep-cards-grid.wall-blueprint {
|
|
background-color: #163a5f;
|
|
background-image:
|
|
linear-gradient(rgba(255, 255, 255, 0.08) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(255, 255, 255, 0.08) 1px, transparent 1px),
|
|
linear-gradient(rgba(255, 255, 255, 0.18) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(255, 255, 255, 0.18) 1px, transparent 1px);
|
|
background-size: 14px 14px, 14px 14px, 70px 70px, 70px 70px;
|
|
}
|
|
|
|
/* Linen: cross-hatched fabric weave */
|
|
.keep-cards-grid.wall-linen {
|
|
background-color: #ede4d3;
|
|
background-image:
|
|
repeating-linear-gradient(45deg, rgba(80, 60, 30, 0.05) 0 1px, transparent 1px 4px),
|
|
repeating-linear-gradient(-45deg, rgba(80, 60, 30, 0.05) 0 1px, transparent 1px 4px),
|
|
radial-gradient(rgba(80, 60, 30, 0.04) 0.6px, transparent 0.8px);
|
|
background-size: auto, auto, 8px 8px;
|
|
}
|
|
|
|
/* Chalkboard: dark green with chalk dust + faint major grid */
|
|
.keep-cards-grid.wall-chalkboard {
|
|
background-color: #2d3a2d;
|
|
background-image:
|
|
radial-gradient(rgba(255, 255, 255, 0.025) 0.8px, transparent 1.2px),
|
|
radial-gradient(rgba(255, 255, 255, 0.015) 0.5px, transparent 1px),
|
|
linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
|
|
background-size: 6px 6px, 3px 3px, 80px 80px, 80px 80px;
|
|
background-position: 0 0, 2px 1px, 0 0, 0 0;
|
|
}
|
|
|
|
/* Cards on a wall: paper-feeling stickies in the masonry flow */
|
|
.keep-cards-grid.is-wall .keep-card {
|
|
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.35);
|
|
transition: box-shadow 0.18s ease, transform 0.18s ease;
|
|
transform-origin: 50% 50%;
|
|
}
|
|
|
|
.keep-cards-grid.is-wall .keep-card:hover {
|
|
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.42);
|
|
transform: rotate(0deg) translateY(-2px) !important;
|
|
z-index: 5;
|
|
}
|
|
|
|
/* Light wall backgrounds: lighter shadow against the lighter surface */
|
|
.keep-cards-grid.wall-whiteboard .keep-card,
|
|
.keep-cards-grid.wall-paper .keep-card,
|
|
.keep-cards-grid.wall-graph .keep-card,
|
|
.keep-cards-grid.wall-linen .keep-card {
|
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18);
|
|
}
|
|
|
|
.keep-cards-grid.wall-whiteboard .keep-card:hover,
|
|
.keep-cards-grid.wall-paper .keep-card:hover,
|
|
.keep-cards-grid.wall-graph .keep-card:hover,
|
|
.keep-cards-grid.wall-linen .keep-card:hover {
|
|
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.24);
|
|
}
|
|
|
|
/* Empty state */
|
|
.keep-wall-empty {
|
|
position: absolute;
|
|
inset: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 10px;
|
|
text-align: center;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.keep-wall-empty-title {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.keep-wall-empty-sub {
|
|
font-size: 13px;
|
|
color: var(--text-muted);
|
|
max-width: 420px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.keep-wall-empty-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
margin-top: 8px;
|
|
pointer-events: auto;
|
|
}
|
|
|
|
/* Floating action buttons (bottom-right of wall — anchored to body, not viewport) */
|
|
.keep-wall-fab {
|
|
position: absolute;
|
|
right: 28px;
|
|
bottom: 28px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
z-index: 5;
|
|
pointer-events: auto;
|
|
}
|
|
|
|
.keep-wall-fab-btn {
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: 50%;
|
|
background: var(--background-secondary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
color: var(--text-muted);
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0;
|
|
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
|
|
transition: background 0.12s ease, color 0.12s ease, transform 0.1s ease;
|
|
}
|
|
|
|
.keep-wall-fab-btn:hover {
|
|
background: var(--background-modifier-hover);
|
|
color: var(--text-normal);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.keep-wall-fab-btn svg,
|
|
.keep-wall-fab-btn .svg-icon {
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
|
|
.keep-wall-fab-add {
|
|
background: var(--interactive-accent);
|
|
color: var(--text-on-accent);
|
|
border-color: transparent;
|
|
width: 48px;
|
|
height: 48px;
|
|
}
|
|
|
|
.keep-wall-fab-add svg,
|
|
.keep-wall-fab-add .svg-icon {
|
|
width: 22px;
|
|
height: 22px;
|
|
}
|
|
|
|
.keep-wall-fab-add:hover {
|
|
background: var(--interactive-accent-hover);
|
|
color: var(--text-on-accent);
|
|
}
|
|
|
|
/* ========== batch sentinel ========== */
|
|
.keep-batch-sentinel {
|
|
height: 1px;
|
|
width: 100%;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* ========== narrow widths ========== */
|
|
@media (max-width: 700px) {
|
|
.keep-cards-sidebar { display: none; }
|
|
.keep-cards-search { width: 160px; }
|
|
}
|