@use 'variables' as *; @use 'mixins' as *; // Buttons .btn { @include button-base; &-primary { @include button-variant($accent, white, null, $accent-hover); } &-secondary { @include button-variant($bg-3, $text-0, $border); &:hover { border-color: $border-strong; background: $btn-secondary-hover; } } &-danger { @include button-variant(transparent, $error, $error-border-light); &:hover { background: $btn-danger-hover; } } &-ghost { @include button-ghost; color: $text-1; padding: 5px $space-4; &:hover { color: $text-0; background: $btn-ghost-hover; } } &-sm { padding: 3px $space-4; font-size: $font-size-base; } &-icon { padding: $space-2; border-radius: $radius-sm; background: transparent; border: none; color: $text-2; cursor: pointer; transition: color $transition-base; font-size: $font-size-lg; &:hover { color: $text-0; } } &:disabled, &[disabled] { @include disabled-state(0.4); } &.btn-disabled-hint:disabled { opacity: 0.6; border-style: dashed; pointer-events: auto; cursor: help; } } // Cards .card { @include card; &-header { @include card-header; } &-title { font-size: $font-size-xl; font-weight: $font-weight-semibold; } } // Tables .data-table { width: 100%; border-collapse: collapse; background: $bg-2; border: 1px solid $border; border-radius: $radius; overflow: hidden; thead th { padding: $space-4 14px; text-align: left; font-size: $font-size-sm; font-weight: $font-weight-semibold; @include text-uppercase($letter-spacing-wider); color: $text-2; border-bottom: 1px solid $border; background: $bg-3; } tbody { td { padding: $space-4 14px; font-size: $font-size-lg; border-bottom: 1px solid $border-subtle; max-width: 300px; @include text-truncate; } tr { cursor: pointer; transition: background $transition-fast; &:hover { background: $overlay-subtle; } &.row-selected { background: $info-bg-light; } &:last-child td { border-bottom: none; } } } } .sortable-header { cursor: pointer; user-select: none; transition: color $transition-base; &:hover { color: $accent-text; } } // Forms input[type='text'], textarea, select { @include input-base; &[type='number'] { width: 80px; padding: 6px $space-4; -moz-appearance: textfield; &::-webkit-outer-spin-button, &::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } } } textarea { min-height: 64px; resize: vertical; } select { appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'%3E%3Cpath fill='%236c6c84' d='M5 7L1 3h8z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right $space-4 center; padding-right: 26px; min-width: 100px; } .form-group { margin-bottom: $space-6; } .form-label { @include form-label; } .form-row { @include flex(row, flex-start, flex-end, $space-4); input[type='text'] { flex: 1; } } .form-label-row { @include flex(row, flex-start, center, 2px); margin-bottom: $space-2; .form-label { margin-bottom: 0; } } // Checkbox input[type='checkbox'] { appearance: none; -webkit-appearance: none; width: 16px; height: 16px; border: 1px solid $border-strong; border-radius: 3px; background: $bg-2; cursor: pointer; position: relative; flex-shrink: 0; transition: all $transition-slow ease; &:hover { border-color: $accent; background: $bg-3; } &:checked { background: $accent; border-color: $accent; &::after { content: ''; position: absolute; left: 5px; top: 2px; width: 4px; height: 8px; border: solid $bg-0; border-width: 0 2px 2px 0; transform: rotate(45deg); } } &:focus-visible { @include focus-outline; } } .checkbox-label { display: inline-flex; align-items: center; gap: $space-4; cursor: pointer; font-size: $font-size-lg; color: $text-1; user-select: none; &:hover { color: $text-0; } input[type='checkbox'] { margin: 0; } } // Toggle switch .toggle { @include flex(row, flex-start, center, $space-4); cursor: pointer; font-size: $font-size-lg; color: $text-0; &.disabled { opacity: 0.4; cursor: not-allowed; } } .toggle-track { width: 32px; height: 18px; border-radius: 9px; background: $bg-3; border: 1px solid $border; position: relative; transition: background $transition-slow; flex-shrink: 0; &.active { background: $accent; border-color: $accent; .toggle-thumb { transform: translateX(14px); } } } .toggle-thumb { width: 14px; height: 14px; border-radius: 50%; background: $text-0; position: absolute; top: 1px; left: 1px; transition: transform $transition-slow; } // Filter chips .filter-bar { @include flex(column, flex-start, stretch, 12px); padding: $space-6; background: $bg-0; border: 1px solid $border-subtle; border-radius: $radius; margin-bottom: $space-6; } .filter-row { display: flex; flex-wrap: wrap; align-items: center; gap: $space-4; } .filter-label { font-size: $font-size-base; font-weight: $font-weight-medium; color: $text-2; @include text-uppercase($letter-spacing-uppercase); margin-right: $space-2; } .filter-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px $space-5; background: $bg-2; border: 1px solid $border; border-radius: 14px; cursor: pointer; font-size: $font-size-base; color: $text-1; transition: all $transition-slow ease; user-select: none; &:hover { background: $bg-3; border-color: $border-strong; color: $text-0; } &.active { background: $accent-dim; border-color: $accent; color: $accent-text; } input[type='checkbox'] { width: 12px; height: 12px; margin: 0; &:checked::after { left: 3px; top: 1px; width: 3px; height: 6px; } } } .filter-group { display: flex; align-items: center; gap: 6px; label { display: flex; align-items: center; gap: 3px; cursor: pointer; color: $text-1; font-size: $font-size-base; white-space: nowrap; &:hover { color: $text-0; } } } .filter-separator { width: 1px; height: 20px; background: $border; flex-shrink: 0; } // View toggle .view-toggle { display: flex; border: 1px solid $border; border-radius: $radius-sm; overflow: hidden; } .view-btn { padding: $space-2 $space-5; background: $bg-2; border: none; color: $text-2; cursor: pointer; font-size: $font-size-4xl; line-height: 1; transition: background $transition-base, color $transition-base; &:first-child { border-right: 1px solid $border; } &:hover { color: $text-0; background: $bg-3; } &.active { background: $accent-dim; color: $accent-text; } } // Breadcrumb .breadcrumb { @include flex(row, flex-start, center, $space-2); padding: $space-5 16px; font-size: 0.85rem; color: $text-2; } .breadcrumb-sep { color: $text-2; opacity: 0.5; } .breadcrumb-link { color: $accent-text; text-decoration: none; cursor: pointer; &:hover { text-decoration: underline; } } .breadcrumb-current { color: $text-0; font-weight: $font-weight-medium; } // Progress bar .progress-bar { width: 100%; height: 8px; background: $bg-3; border-radius: 4px; overflow: hidden; margin-bottom: 6px; } .progress-fill { height: 100%; background: $accent; border-radius: 4px; transition: width 0.3s ease; &.indeterminate { width: 30%; animation: indeterminate 1.5s ease-in-out infinite; } } // Loading states .loading-overlay { @include flex-center; padding: 48px 16px; color: $text-2; font-size: $font-size-lg; gap: $space-5; } .spinner { width: 18px; height: 18px; border: 2px solid $border; border-top-color: $accent; border-radius: 50%; animation: spin 0.7s linear infinite; } .spinner-small { width: 14px; height: 14px; border: 2px solid $border; border-top-color: $accent; border-radius: 50%; animation: spin 0.7s linear infinite; } .spinner-tiny { width: 10px; height: 10px; border: 1.5px solid $border; border-top-color: $accent; border-radius: 50%; animation: spin 0.7s linear infinite; } // Modal .modal-overlay { position: fixed; inset: 0; background: $media-overlay-medium; @include flex-center; z-index: $z-modal-backdrop; @include fade-in; } .modal { background: $bg-2; border: 1px solid $border; border-radius: $radius-md; padding: 20px; min-width: 360px; max-width: 480px; box-shadow: $shadow-lg; &.wide { max-width: 600px; max-height: 70vh; overflow-y: auto; } &-title { font-size: $font-size-2xl; font-weight: $font-weight-semibold; margin-bottom: 6px; } &-body { font-size: $font-size-md; color: $text-1; margin-bottom: $space-8; line-height: $line-height-relaxed; } &-actions { @include flex(row, flex-end, center, 6px); } } // Tooltips .tooltip-trigger { @include tooltip-trigger; &:hover .tooltip-text { display: block; } } .tooltip-text { @include tooltip-content; } // Media player .media-player { position: relative; background: $bg-0; border-radius: $radius; overflow: hidden; &:focus { outline: none; } &-audio .player-artwork { @include flex(column, center, center, $space-4); padding: $space-12 $space-8 8px; } } .player-artwork { img { max-width: 200px; max-height: 200px; border-radius: $radius; object-fit: cover; } &-placeholder { width: 120px; height: 120px; @include flex-center; background: $bg-2; border-radius: $radius; font-size: 48px; opacity: 0.3; } } .player-title { font-size: $font-size-lg; font-weight: $font-weight-medium; color: $text-0; text-align: center; } .player-controls { @include flex(row, flex-start, center, $space-4); padding: $space-5 14px; background: $bg-2; } .media-player-video .player-controls { position: absolute; bottom: 0; left: 0; right: 0; background: $media-controls-bg; opacity: 0; transition: opacity $transition-slower; } .media-player-video:hover .player-controls { opacity: 1; } .play-btn, .mute-btn, .fullscreen-btn { background: none; border: none; color: $text-0; cursor: pointer; font-size: $font-size-4xl; padding: $space-2; line-height: 1; transition: color $transition-base; &:hover { color: $accent-text; } } .player-time { font-size: $font-size-base; color: $text-2; font-family: $font-family-mono; min-width: 36px; text-align: center; user-select: none; } .seek-bar { flex: 1; -webkit-appearance: none; appearance: none; height: 4px; border-radius: $space-2; background: $bg-3; outline: none; cursor: pointer; &::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 12px; height: 12px; border-radius: 50%; background: $accent; cursor: pointer; border: none; } &::-moz-range-thumb { width: 12px; height: 12px; border-radius: 50%; background: $accent; cursor: pointer; border: none; } } .volume-slider { width: 70px; -webkit-appearance: none; appearance: none; height: 4px; border-radius: $space-2; background: $bg-3; outline: none; cursor: pointer; &::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 10px; height: 10px; border-radius: 50%; background: $text-1; cursor: pointer; border: none; } &::-moz-range-thumb { width: 10px; height: 10px; border-radius: 50%; background: $text-1; cursor: pointer; border: none; } } // Image viewer .image-viewer-overlay { position: fixed; inset: 0; background: $media-overlay-bg; z-index: 150; @include flex(column); animation: fade-in 0.15s ease-out; &:focus { outline: none; } } .image-viewer-toolbar { @include flex-between; padding: $space-5 16px; background: $media-overlay-medium; border-bottom: 1px solid $image-viewer-border; z-index: 2; user-select: none; &-left, &-center, &-right { @include flex(row, flex-start, center, 6px); } } .iv-btn { background: $image-viewer-btn-bg; border: 1px solid $image-viewer-btn-border; color: $text-0; border-radius: $radius-sm; padding: $space-2 $space-5; font-size: $font-size-md; cursor: pointer; transition: background $transition-base; &:hover { background: $image-viewer-btn-hover; } &.iv-close { color: $error; font-weight: $font-weight-semibold; } } .iv-zoom-label { font-size: $font-size-base; color: $text-1; min-width: 40px; text-align: center; font-family: $font-family-mono; } .image-viewer-canvas { flex: 1; @include flex-center; overflow: hidden; position: relative; img { max-width: 100%; max-height: 100%; object-fit: contain; user-select: none; -webkit-user-drag: none; } } // PDF viewer .pdf-viewer { @include flex(column); height: 100%; min-height: 500px; background: $bg-0; border-radius: $radius; overflow: hidden; } .pdf-toolbar { @include flex(row, flex-start, center, $space-6); padding: $space-5 $space-6; background: $bg-1; border-bottom: 1px solid $border; &-group { @include flex(row, flex-start, center, $space-2); } } .pdf-toolbar-btn { @include flex-center; width: 28px; height: 28px; background: $bg-2; border: 1px solid $border; border-radius: $radius-sm; color: $text-1; font-size: 14px; cursor: pointer; transition: all $transition-slow; &:hover:not(:disabled) { background: $bg-3; color: $text-0; } &:disabled { opacity: 0.4; cursor: not-allowed; } } .pdf-zoom-label { min-width: 45px; text-align: center; font-size: $font-size-md; color: $text-1; } .pdf-container { flex: 1; position: relative; overflow: hidden; background: $bg-2; } .pdf-object { width: 100%; height: 100%; border: none; } .pdf-loading, .pdf-error { position: absolute; inset: 0; @include flex(column, center, center, 12px); background: $bg-1; color: $text-1; } .pdf-error { padding: $space-6; text-align: center; } .pdf-fallback { @include flex(column, center, center, $space-8); padding: 48px $space-6; text-align: center; color: $text-2; } // Markdown viewer .markdown-viewer { padding: $space-8; text-align: left; @include flex(column, flex-start, stretch, 12px); } .markdown-toolbar { @include flex(row, flex-start, center, $space-4); padding: $space-4; background: $bg-2; border-radius: $radius; border: 1px solid $border; } .toolbar-btn { padding: 6px $space-6; border: 1px solid $border; border-radius: $radius-sm; background: $bg-1; color: $text-1; font-size: $font-size-lg; font-weight: $font-weight-medium; cursor: pointer; transition: all $transition-slow; &:hover { background: $bg-3; border-color: $border-strong; } &.active { background: $accent; color: white; border-color: $accent; } } .markdown-source { max-width: 100%; background: $bg-3; border: 1px solid $border; border-radius: $radius; padding: $space-8; overflow-x: auto; font-family: $font-family-mono-alt; font-size: $font-size-lg; line-height: $line-height-loose; color: $text-0; white-space: pre-wrap; word-wrap: break-word; code { font-family: inherit; background: none; padding: 0; border: none; } } .markdown-content { max-width: 800px; color: $text-0; line-height: $line-height-loose; font-size: 14px; text-align: left; h1 { font-size: 1.8em; font-weight: $font-weight-bold; margin: 1em 0 0.5em; border-bottom: 1px solid $border-subtle; padding-bottom: 0.3em; } h2 { font-size: 1.5em; font-weight: $font-weight-semibold; margin: 0.8em 0 0.4em; border-bottom: 1px solid $border-subtle; padding-bottom: 0.2em; } h3 { font-size: 1.25em; font-weight: $font-weight-semibold; margin: 0.6em 0 0.3em; } h4 { font-size: 1.1em; font-weight: $font-weight-semibold; margin: 0.5em 0 0.25em; } h5, h6 { font-size: 1em; font-weight: $font-weight-semibold; margin: 0.4em 0 0.2em; color: $text-1; } p { margin: 0 0 1em; } a { color: $accent; text-decoration: none; &:hover { text-decoration: underline; } } pre { background: $bg-3; border: 1px solid $border; border-radius: $radius-sm; padding: $space-6 $space-8; overflow-x: auto; margin: 0 0 1em; font-family: $font-family-mono; font-size: $font-size-md; line-height: $line-height-relaxed; } code { background: $bg-3; padding: 1px 5px; border-radius: $radius-sm; font-family: $font-family-mono; font-size: 0.9em; } pre code { background: none; padding: 0; } blockquote { border-left: 3px solid $accent; padding: $space-2 $space-8; margin: 0 0 1em; color: $text-1; background: $purple-bg; } table { width: 100%; border-collapse: collapse; margin: 0 0 1em; } th, td { padding: 6px $space-6; border: 1px solid $border; font-size: $font-size-lg; } th { background: $bg-3; font-weight: $font-weight-semibold; text-align: left; } tr:nth-child(even) { background: $bg-2; } ul, ol { margin: 0 0 1em; padding-left: $space-8; } ul { list-style: disc; } ol { list-style: decimal; } li { padding: $space-1 0; font-size: 14px; color: $text-0; } hr { border: none; border-top: 1px solid $border; margin: 1.5em 0; } img { max-width: 100%; border-radius: $radius; } .footnote-definition { font-size: 0.85em; color: $text-1; margin-top: 0.5em; padding-left: 1.5em; sup { color: $accent; margin-right: $space-2; } } sup a { color: $accent; text-decoration: none; font-size: 0.8em; } } .wikilink { color: $accent-text; text-decoration: none; border-bottom: 1px dashed $accent; cursor: pointer; transition: border-color $transition-base, color $transition-base; &:hover { color: $accent; border-bottom-style: solid; } } .wikilink-embed { display: inline-block; padding: $space-1 $space-4; background: $purple-light; border: 1px dashed $purple-border; border-radius: $radius-sm; color: $type-audio-text; font-size: $font-size-md; cursor: default; }