@use 'variables' as *; @use 'mixins' as *; // Media cards & grid .media-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: $space-6; } .media-card { background: $bg-2; border: 1px solid $border; border-radius: $radius; overflow: hidden; cursor: pointer; transition: border-color 0.12s, box-shadow 0.12s; position: relative; &:hover { border-color: $border-strong; box-shadow: $shadow-sm; } &.selected { border-color: $accent; box-shadow: 0 0 0 1px $accent; } } .card-checkbox { position: absolute; top: 6px; left: 6px; z-index: 2; opacity: 0; transition: opacity $transition-base; input[type='checkbox'] { width: 16px; height: 16px; cursor: pointer; filter: drop-shadow(0 1px 2px $drop-shadow); } } .media-card:hover .card-checkbox, .media-card.selected .card-checkbox { opacity: 1; } .card-thumbnail { width: 100%; aspect-ratio: 1; background: $bg-0; @include flex-center; overflow: hidden; position: relative; img, .card-thumb-img { width: 100%; height: 100%; object-fit: cover; position: absolute; top: 0; left: 0; z-index: 1; } } .card-type-icon { font-size: 32px; opacity: 0.4; @include flex-center; width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 0; } .card-info { padding: $space-4 $space-5; } .card-name { font-size: $font-size-md; font-weight: $font-weight-medium; color: $text-0; @include text-truncate; margin-bottom: $space-2; } .card-title, .card-artist { font-size: $font-size-sm; @include text-truncate; line-height: $line-height-base; } .card-meta { @include flex(row, flex-start, center, 6px); font-size: $font-size-sm; } .card-size { color: $text-2; font-size: $font-size-sm; } // Table thumbnails .table-thumb-cell { width: 36px; padding: $space-2 6px !important; position: relative; } .table-thumb { width: 28px; height: 28px; object-fit: cover; border-radius: 3px; display: block; } .table-thumb-overlay { position: absolute; top: $space-2; left: 6px; z-index: 1; } .table-type-icon { @include flex-center; width: 28px; height: 28px; font-size: 14px; opacity: 0.5; border-radius: 3px; background: $bg-0; z-index: 0; } // Type badges .type-badge { display: inline-block; padding: 1px $space-3; border-radius: $radius-sm; font-size: $font-size-sm; font-weight: $font-weight-semibold; @include text-uppercase; &.type-audio { background: $type-audio-bg; color: $type-audio-text; } &.type-video { background: $type-video-bg; color: $type-video-text; } &.type-image { background: $type-image-bg; color: $type-image-text; } &.type-document { background: $type-document-bg; color: $type-document-text; } &.type-text { background: $type-text-bg; color: $type-text-text; } &.type-other { background: $type-other-bg; color: $text-2; } } // Tag badges .tag-list { display: flex; flex-wrap: wrap; gap: $space-2; } .tag-badge { display: inline-flex; align-items: center; gap: $space-2; padding: $space-1 $space-5; background: $accent-dim; color: $accent-text; border-radius: 12px; font-size: $font-size-base; font-weight: $font-weight-medium; &.selected { background: $accent; color: white; cursor: pointer; } &:not(.selected) { cursor: pointer; } .tag-remove { cursor: pointer; opacity: 0.4; font-size: $font-size-lg; line-height: 1; transition: opacity $transition-base; &:hover { opacity: 1; } } } // Tag hierarchy .tag-group { margin-bottom: 6px; } .tag-children { margin-left: $space-8; margin-top: $space-2; display: flex; flex-wrap: wrap; gap: $space-2; } .tag-confirm-delete { display: inline-flex; align-items: center; gap: $space-2; font-size: $font-size-sm; color: $text-1; } .tag-confirm-yes { cursor: pointer; color: $error; font-weight: $font-weight-semibold; &:hover { text-decoration: underline; } } .tag-confirm-no { cursor: pointer; color: $text-2; font-weight: $font-weight-medium; &:hover { text-decoration: underline; } } // Detail view .detail-actions { display: flex; gap: 6px; margin-bottom: $space-8; } .detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: $space-4; } .detail-field { padding: $space-5 $space-6; background: $bg-0; border-radius: $radius-sm; border: 1px solid $border-subtle; &.full-width { grid-column: 1 / -1; } input[type='text'], textarea, select { width: 100%; margin-top: $space-2; } textarea { min-height: 64px; resize: vertical; } } .detail-label { font-size: $font-size-sm; font-weight: $font-weight-semibold; color: $text-2; @include text-uppercase($letter-spacing-wider); margin-bottom: $space-1; } .detail-value { font-size: $font-size-lg; color: $text-0; word-break: break-all; &.mono { font-family: $font-family-mono; font-size: $font-size-base; color: $text-1; } } .detail-preview { margin-bottom: $space-8; background: $bg-0; border: 1px solid $border-subtle; border-radius: $radius; overflow: hidden; text-align: center; &:has(.markdown-viewer) { max-height: none; overflow-y: auto; text-align: left; } &:not(:has(.markdown-viewer)) { max-height: 450px; } img { max-width: 100%; max-height: 400px; object-fit: contain; display: block; margin: 0 auto; } audio { width: 100%; padding: $space-8; } video { max-width: 100%; max-height: 400px; display: block; margin: 0 auto; } } .detail-no-preview { padding: $space-8 $space-8; text-align: center; @include flex(column, center, center, $space-5); } // Frontmatter .frontmatter-card { max-width: 800px; background: $bg-2; border: 1px solid $border; border-radius: $radius; padding: $space-6 $space-8; margin-bottom: $space-8; } .frontmatter-fields { display: grid; grid-template-columns: auto 1fr; gap: $space-2 $space-6; margin: 0; dt { font-weight: $font-weight-semibold; font-size: $font-size-md; color: $text-1; text-transform: capitalize; } dd { font-size: $font-size-lg; color: $text-0; margin: 0; } } // Empty state .empty-state { text-align: center; padding: 48px $space-6; color: $text-2; .empty-icon { font-size: $font-size-7xl; margin-bottom: $space-6; opacity: 0.3; } } .empty-title { font-size: $font-size-2xl; font-weight: $font-weight-semibold; color: $text-1; margin-bottom: $space-2; } .empty-subtitle { font-size: $font-size-md; max-width: 320px; margin: 0 auto; line-height: $line-height-relaxed; } // Toast .toast-container { position: fixed; bottom: $space-8; right: $space-8; z-index: $z-toast; display: flex; flex-direction: column-reverse; gap: 6px; align-items: flex-end; .toast { position: static; transform: none; } } .toast { position: fixed; bottom: $space-8; right: $space-8; padding: $space-5 $space-8; border-radius: $radius; background: $bg-3; border: 1px solid $border; color: $text-0; font-size: $font-size-md; box-shadow: $shadow; z-index: $z-toast; animation: slide-up 0.15s ease-out; max-width: 420px; &.success { border-left: 3px solid $success; } &.error { border-left: 3px solid $error; } } // Banners .offline-banner, .error-banner { background: $error-bg; border: 1px solid $error-border; border-radius: $radius-sm; padding: $space-5 $space-6; margin-bottom: $space-6; font-size: $font-size-md; color: $error-text; @include flex(row, flex-start, center, $space-4); .offline-icon, .error-icon { font-size: 14px; flex-shrink: 0; } } .error-banner { padding: 10px 14px; } .readonly-banner { @include flex(row, flex-start, center, $space-4); padding: $space-5 $space-6; background: $warning-bg; border: 1px solid $warning-border; border-radius: $radius-sm; margin-bottom: $space-8; font-size: $font-size-md; color: $warning; } .batch-actions { @include flex(row, flex-start, center, $space-4); padding: $space-4 $space-5; background: $accent-dim; border: 1px solid $accent-border; border-radius: $radius-sm; margin-bottom: $space-6; font-size: $font-size-md; font-weight: $font-weight-medium; color: $accent-text; } .select-all-banner { @include flex(row, center, center, $space-4); padding: $space-5 $space-8; background: $info-bg; border-radius: 6px; margin-bottom: $space-4; font-size: 0.85rem; color: $text-1; button { background: none; border: none; color: $accent; cursor: pointer; font-weight: $font-weight-semibold; text-decoration: underline; font-size: 0.85rem; padding: 0; &:hover { color: $text-0; } } } // Import status .import-status-panel { background: $bg-2; border: 1px solid $accent; border-radius: $radius; padding: $space-6 $space-8; margin-bottom: $space-8; } .import-status-header { @include flex(row, flex-start, center, $space-4); margin-bottom: $space-4; font-size: $font-size-lg; color: $text-0; } .import-current-file { @include flex(row, flex-start, center, $space-1); margin-bottom: 6px; font-size: $font-size-md; overflow: hidden; } .import-file-label { color: $text-2; flex-shrink: 0; } .import-file-name { color: $text-0; @include text-truncate; font-family: monospace; font-size: $font-size-base; } .import-queue-indicator { @include flex(row, flex-start, center, $space-1); margin-bottom: $space-4; font-size: $font-size-base; } .import-queue-badge { @include flex-center; min-width: 18px; height: 18px; padding: 0 6px; background: $accent-dim; color: $accent-text; border-radius: 9px; font-weight: $font-weight-semibold; font-size: $font-size-sm; } .import-queue-text { color: $text-2; } .import-tabs { display: flex; gap: 0; margin-bottom: $space-8; border-bottom: 1px solid $border; } .import-tab { padding: $space-5 $space-8; background: none; border: none; border-bottom: 2px solid transparent; color: $text-2; font-size: $font-size-md; font-weight: $font-weight-medium; cursor: pointer; transition: color $transition-base, border-color $transition-base; &:hover { color: $text-0; } &.active { color: $accent-text; border-bottom-color: $accent; } } // Queue panel .queue-panel { @include flex(column); border-left: 1px solid $border; background: $bg-1; min-width: 280px; max-width: 320px; } .queue-header { @include flex-between; padding: $space-6 $space-8; border-bottom: 1px solid $border-subtle; h3 { margin: 0; font-size: 0.9rem; color: $text-0; } } .queue-controls { display: flex; gap: $space-1; } .queue-list { overflow-y: auto; flex: 1; } .queue-item { @include flex(row, flex-start, center); padding: $space-4 $space-8; cursor: pointer; border-bottom: 1px solid $border-subtle; transition: background $transition-slow; &:hover { background: $bg-2; .queue-item-remove { opacity: 1; } } &-active { background: $accent-dim; border-left: 3px solid $accent; } } .queue-item-info { flex: 1; min-width: 0; } .queue-item-title { display: block; font-size: 0.85rem; color: $text-0; @include text-truncate; } .queue-item-artist { display: block; font-size: 0.75rem; color: $text-2; } .queue-item-remove { opacity: 0; transition: opacity $transition-slow; } .queue-empty { padding: $space-8 $space-8; text-align: center; color: $text-2; font-size: 0.85rem; }