Files
brittle/brittle-ui/style.css

409 lines
9.7 KiB
CSS

/* ── Reset / base ─────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #1d2021;
--bg-surface: #282828;
--bg-overlay: #3c3836;
--border: #504945;
--accent: #d79921;
--accent-dim: #b57614;
--text: #ebdbb2;
--text-muted: #a89984;
--text-subtle: #928374;
--cursor-bg: #504945;
--cursor-fg: #ebdbb2;
--focused-ring: #d79921;
--font-mono: "JetBrains Mono", "Fira Code", "Cascadia Code", monospace;
--font-ui: system-ui, -apple-system, "Segoe UI", sans-serif;
--radius: 4px;
--tab-h: 32px;
--cmd-h: 28px;
}
[data-theme="dark"] {
--bg: #1d2021;
--bg-surface: #282828;
--bg-overlay: #3c3836;
--border: #504945;
--accent: #d79921;
--accent-dim: #b57614;
--text: #ebdbb2;
--text-muted: #a89984;
--text-subtle: #928374;
--cursor-bg: #504945;
--cursor-fg: #ebdbb2;
--focused-ring: #d79921;
}
html, body {
height: 100%;
background: var(--bg);
color: var(--text);
font-family: var(--font-ui);
font-size: 13px;
line-height: 1.5;
overflow: hidden;
}
ul { list-style: none; }
/* ── App shell ────────────────────────────────────────────────────────────── */
.app {
display: flex;
flex-direction: column;
height: 100vh;
}
.app-body {
flex: 1;
overflow: hidden;
position: relative;
}
/* ── Tab bar ──────────────────────────────────────────────────────────────── */
.tab-bar {
display: flex;
align-items: stretch;
height: var(--tab-h);
background: var(--bg-surface);
border-bottom: 1px solid var(--border);
padding: 0 4px;
gap: 2px;
flex-shrink: 0;
}
.tab {
display: inline-flex;
align-items: center;
padding: 0 12px;
background: transparent;
border: none;
border-bottom: 2px solid transparent;
color: var(--text-muted);
cursor: pointer;
font: inherit;
font-size: 12px;
white-space: nowrap;
user-select: none;
border-radius: var(--radius) var(--radius) 0 0;
gap: 6px;
}
.tab:hover { color: var(--text); background: var(--bg-overlay); }
.tab.tab-active {
color: var(--text);
border-bottom-color: var(--accent);
}
.tab-pdf { cursor: pointer; }
.tab-label { pointer-events: none; }
.tab-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
background: transparent;
border: none;
border-radius: 2px;
color: var(--text-muted);
font-size: 14px;
line-height: 1;
cursor: pointer;
padding: 0;
opacity: 0;
transition: opacity 0.1s, background 0.1s;
}
.tab-pdf:hover .tab-close { opacity: 1; }
.tab-close:hover { background: var(--bg-overlay); color: var(--text); }
/* ── Three-pane library layout ────────────────────────────────────────────── */
.lib-tab {
display: flex;
height: 100%;
}
.resizer {
width: 2px;
background: var(--border);
cursor: col-resize;
flex-shrink: 0;
transition: background 0.2s;
z-index: 10;
position: relative;
}
.resizer::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: -4px;
right: -4px;
}
.resizer:hover, .resizer.resizing {
background: var(--accent);
}
.pane {
display: flex;
flex-direction: column;
overflow: hidden;
}
.pane-left { flex-shrink: 0; }
.pane-center { flex: 1; min-width: 0; }
.pane-right { flex-shrink: 0; }
.pane-focused { outline: 1px solid var(--focused-ring); outline-offset: -1px; }
/* ── Library tree pane ────────────────────────────────────────────────────── */
.tree-pane {
height: 100%;
overflow-y: auto;
padding: 4px 0;
}
.tree-list { padding: 0; }
.tree-item {
display: flex;
align-items: center;
gap: 2px;
padding: 3px 8px;
cursor: pointer;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border-radius: 0;
}
.tree-item:hover { background: var(--bg-overlay); }
.tree-item.tree-cursor {
background: var(--cursor-bg);
color: var(--cursor-fg);
}
.tree-icon {
color: var(--text-muted);
font-size: 11px;
width: 14px;
flex-shrink: 0;
}
.tree-name {
overflow: hidden;
text-overflow: ellipsis;
}
/* ── Publication list pane ────────────────────────────────────────────────── */
.pub-list-pane {
height: 100%;
overflow-y: auto;
}
.pub-list { padding: 4px 0; }
.pub-item {
display: flex;
flex-direction: column;
padding: 6px 10px;
cursor: pointer;
border-bottom: 1px solid var(--border);
gap: 1px;
}
.pub-item:hover { background: var(--bg-overlay); }
.pub-item.pub-cursor {
background: var(--cursor-bg);
color: var(--cursor-fg);
}
.pub-item.pub-cursor .pub-meta { color: var(--text-muted); opacity: 0.8; }
.pub-item.pub-cursor .pub-type { color: var(--accent); }
.pub-type {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--accent);
font-weight: 600;
}
.pub-title {
font-size: 12px;
font-weight: 500;
line-height: 1.4;
}
.pub-meta {
font-size: 11px;
color: var(--text-muted);
}
/* ── Publication detail pane ──────────────────────────────────────────────── */
.pub-detail-pane {
height: 100%;
overflow-y: auto;
padding: 12px;
}
.detail-title {
font-size: 14px;
font-weight: 600;
line-height: 1.4;
margin-bottom: 10px;
color: var(--text);
}
.detail-fields {
display: grid;
grid-template-columns: auto 1fr;
gap: 4px 12px;
align-items: baseline;
}
.detail-fields dt {
color: var(--text-muted);
font-size: 11px;
white-space: nowrap;
text-align: right;
}
.detail-fields dd {
color: var(--text);
font-size: 12px;
word-break: break-word;
min-width: 0;
}
.detail-timestamps {
margin-top: 12px;
font-size: 10px;
color: var(--text-subtle);
}
.mono {
font-family: var(--font-mono);
font-size: 11px;
}
/* ── Empty state ──────────────────────────────────────────────────────────── */
.empty-state {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: var(--text-subtle);
font-size: 12px;
padding: 24px;
text-align: center;
}
/* ── Command / search bar ─────────────────────────────────────────────────── */
.command-bar {
display: flex;
align-items: center;
height: var(--cmd-h);
background: var(--bg-surface);
border-top: 1px solid var(--border);
padding: 0 8px;
gap: 4px;
flex-shrink: 0;
}
.command-prefix {
color: var(--accent);
font-family: var(--font-mono);
font-size: 14px;
font-weight: bold;
line-height: 1;
}
.command-input {
flex: 1;
background: transparent;
border: none;
outline: none;
color: var(--text);
font: inherit;
font-family: var(--font-mono);
font-size: 12px;
caret-color: var(--accent);
}
.command-status {
color: #fb4934;
font-size: 12px;
}
/* ── PDF viewer frame ─────────────────────────────────────────────────────── */
.pdf-frame {
width: 100%;
height: 100%;
border: none;
display: block;
}
/* ── Drag-and-drop ────────────────────────────────────────────────────────── */
/* Suppress pointer events on text spans inside tree rows so that
dragleave / dragover never fire on child elements — avoids highlight flicker
when the cursor moves between the icon and the label inside one row. */
.tree-icon,
.tree-name { pointer-events: none; }
/* Publication items are drag sources. */
.pub-item[draggable="true"] { cursor: grab; }
.pub-item[draggable="true"]:active { cursor: grabbing; }
/* Library tree rows highlighted as drop targets. */
.tree-item.tree-drop-target {
background: var(--accent-dim);
color: var(--cursor-fg);
outline: 1px dashed var(--accent);
outline-offset: -1px;
}
/* ── Light theme (Gruvbox Light) ─────────────────────────────────────────── */
[data-theme="light"] {
--bg: #f9f5d7;
--bg-surface: #fbf1c7;
--bg-overlay: #ebdbb2;
--border: #d5c4a1;
--accent: #af3a03;
--accent-dim: #d65d0e;
--text: #3c3836;
--text-muted: #7c6f64;
--text-subtle: #928374;
--cursor-bg: #d5c4a1;
--cursor-fg: #3c3836;
--focused-ring: #af3a03;
}
/* ── Scrollbar (WebKit) ───────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-subtle); }