Files
beardrive/internal/webapp/static/style.css
T
Snow LeeandClaude Fable 5 927d77c22b design(round 2): 44px list rows, AA residuals, in-app modals
Closes the remaining design-review gaps (design-only; no flow changes).

Accessibility (the failing objective gate + residuals):
- Mobile 44px now reaches the PRIMARY tap targets: file tree rows,
  project rows, the org "Manage" button, new-project +, and folder-history
  all sized to 44px min (round 1 had only reached the header/sidebar icons).
- Residual sub-AA small text fixed: --text-faint #8a8a8a→#969696 (AA on the
  #262626 sidebar, measured 5.1); selected palette row's kind/icon lifted
  to #c4c4c4 (6.6); filled-button hover moved to --accent-press #5a3bc9 so
  white labels stay ≥4.5 on hover (7.2, was 2.9).
- Directory rows expose aria-expanded, updated on collapse toggle.

UX (the main remaining seam):
- Native prompt()/confirm() replaced with in-app modal components
  (modalPrompt / modalConfirm, destructive variant) for new project,
  rename, delete, remove member, and revoke invite/share — so every
  decision shares one visual language with the share modal and toasts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R7Q9ZKSZRTdvrSJkYLUmYs
2026-07-08 23:48:59 -07:00

425 lines
19 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Obsidian-inspired dark theme */
:root {
--bg: #1e1e1e;
--bg-side: #262626;
--bg-hover: #333333;
--bg-active: #3f3550;
--border: #363636;
--text: #dadada;
--text-dim: #a6a6a6; /* AA on --bg and --bg-side */
--text-faint: #969696; /* AA on both --bg (5.0) and --bg-side #262626 (4.6) */
--accent: #a882ff;
--accent-bright: #c9b3ff; /* accent text on the tinted --bg-active (AA) */
--accent-dim: #6a48e0; /* darker so white labels reach 4.5:1 */
--accent-press: #5a3bc9; /* button hover/press — white stays ≥4.5:1 */
--code-bg: #2a2a2a;
/* radius scale: controls / cards / overlays */
--r-ctl: 6px;
--r-card: 8px;
--r-over: 12px;
}
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
* { box-sizing: border-box; }
[hidden] { display: none !important; } /* explicit display rules must not override the hidden attribute */
html, body { height: 100%; margin: 0; }
#more-btn { display: none; } /* mobile-only; shown in the responsive block */
body {
display: flex;
background: var(--bg);
color: var(--text);
font: 15px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
/* ---- sidebar ---- */
#sidebar {
width: 280px;
min-width: 200px;
background: var(--bg-side);
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
overflow: hidden;
}
#vault {
padding: 14px 16px 10px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
}
#vault-name { font-weight: 600; font-size: 14px; }
#signout { color: var(--text-faint); text-decoration: none; font-size: 13px; }
#signout:hover { color: var(--text); }
#upload-btn {
border: none;
cursor: pointer;
font: inherit;
font-size: 12.5px;
}
#projects {
flex: none;
max-height: 30%;
overflow-y: auto;
padding: 8px 6px;
font-size: 13.5px;
border-bottom: 1px solid var(--border);
}
#projects ul { list-style: none; margin: 0; padding-left: 4px; }
#projects .row {
padding: 3px 8px;
border-radius: 5px;
cursor: pointer;
color: var(--text-dim);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#projects .row::before { content: "◇"; margin-right: 7px; color: var(--text-faint); }
#projects .row:hover { background: var(--bg-hover); color: var(--text); }
#projects .row.active { background: var(--bg-active); color: var(--accent-bright); box-shadow: inset 2px 0 0 var(--accent); }
#projects .row.active::before { color: var(--accent); }
#tree { flex: 1; overflow-y: auto; padding: 8px 6px 24px; font-size: 13.5px; }
#orgbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 9px 16px;
border-top: 1px solid var(--border);
font-size: 12.5px;
color: var(--text-dim);
}
#orgbar[hidden] { display: none; }
#org-name { cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#org-name::before { content: "◈"; margin-right: 7px; color: var(--text-faint); }
#org-name:hover { color: var(--text); }
#invite-btn {
border: none; cursor: pointer; font: inherit; font-size: 11.5px;
padding: 3px 10px; border-radius: var(--r-ctl);
background: var(--bg-active); color: var(--text);
}
#invite-btn:hover { color: #fff; background: var(--bg-hover); }
#tree ul { list-style: none; margin: 0; padding-left: 14px; }
#tree > ul { padding-left: 4px; }
#tree li > .row {
display: flex;
align-items: center;
gap: 5px;
padding: 2px 8px;
border-radius: 5px;
cursor: pointer;
color: var(--text-dim);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#tree li > .row:hover { background: var(--bg-hover); color: var(--text); }
#tree li > .row.active { background: var(--bg-active); color: var(--accent-bright); box-shadow: inset 2px 0 0 var(--accent); }
#tree li > .row .label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#tree .chev { width: 12px; flex: none; font-size: 10px; color: var(--text-faint); transition: transform .12s; }
#tree li.collapsed > ul { display: none; }
#tree li.collapsed > .row .chev { transform: rotate(-90deg); }
#tree .file .chev { visibility: hidden; }
/* ---- main pane ---- */
#main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
#topbar {
position: relative;
display: flex;
align-items: center;
gap: 12px;
padding: 10px 24px;
border-bottom: 1px solid var(--border);
min-height: 46px;
}
#crumb { font-size: 13px; color: var(--text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Single truncating line — never let author/time metadata wrap and shove
the action buttons around. */
#meta { flex: 1; min-width: 0; font-size: 12px; color: var(--text-faint); text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.btn {
flex: none;
padding: 5px 12px;
border-radius: var(--r-ctl);
background: var(--accent-dim);
color: #fff;
font-size: 12.5px;
text-decoration: none;
border: none; cursor: pointer; font-family: inherit;
}
.btn:hover { background: var(--accent-press); }
#content { flex: 1; overflow-y: auto; padding: 28px 48px 80px; }
#history-btn, #share-btn { border: none; cursor: pointer; font: inherit; font-size: 12.5px; background: var(--bg-active); color: var(--text); }
#history-btn:hover, #share-btn:hover { color: #fff; background: var(--bg-hover); }
.dir-history { margin-left: auto; padding: 0 4px; visibility: hidden; color: var(--text-faint); font-size: 11px; }
#tree li > .row:hover .dir-history { visibility: visible; }
.dir-history:hover { color: var(--text); }
.history { max-width: 860px; }
.hentry { padding: 10px 12px; border-bottom: 1px solid var(--border); }
.hentry .hline { display: flex; gap: 10px; align-items: baseline; }
.hkind { color: var(--accent); font-size: 11px; }
.hentry.delete .hkind { color: #ff7b72; }
.hpath { font-weight: 500; cursor: pointer; }
.hpath:hover { color: var(--accent); }
.htime { margin-left: auto; color: var(--text-faint); font-size: 12px; }
.hmeta { display: flex; gap: 16px; margin-top: 3px; font-size: 12px; color: var(--text-dim); }
.hdev, .hsize { color: var(--text-faint); }
.hact { margin-left: auto; }
.hact a { color: var(--accent); text-decoration: none; margin-left: 8px; }
.empty { color: var(--text-faint); text-align: center; margin-top: 20vh; }
.empty-hint { font-size: 12px; color: var(--text-faint); }
/* ---- command palette (⌘K) ---- */
#palette-overlay[hidden] { display: none; }
#palette-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, .45);
display: flex;
justify-content: center;
align-items: flex-start;
padding-top: 12vh;
z-index: 100;
}
#palette {
width: min(560px, 90vw);
background: var(--bg-side);
border: 1px solid var(--border);
border-radius: 12px;
box-shadow: 0 16px 48px rgba(0, 0, 0, .5);
overflow: hidden;
}
#palette-input {
width: 100%;
box-sizing: border-box;
padding: 14px 16px;
border: none;
border-bottom: 1px solid var(--border);
background: transparent;
color: var(--text);
font: inherit;
font-size: 15px;
outline: none;
}
#palette-results {
list-style: none;
margin: 0;
padding: 6px;
max-height: 46vh;
overflow-y: auto;
}
#palette-results li {
display: flex;
align-items: center;
gap: 10px;
padding: 7px 10px;
border-radius: 7px;
cursor: pointer;
color: var(--text-dim);
font-size: 13.5px;
}
#palette-results li.selected { background: var(--bg-active); color: var(--text); }
#palette-results li.selected .picon, #palette-results li.selected .pkind { color: #c4c4c4; }
#palette-results li .picon { width: 18px; flex: none; text-align: center; color: var(--text-faint); }
#palette-results li .plabel { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#palette-results li .plabel b { color: var(--accent); font-weight: 600; }
#palette-results li .pkind { flex: none; font-size: 11px; color: var(--text-faint); }
#palette-results .pempty { color: var(--text-faint); cursor: default; justify-content: center; }
#palette-hint {
padding: 7px 14px;
border-top: 1px solid var(--border);
font-size: 11px;
color: var(--text-faint);
}
/* ---- projects nav header + new-project ---- */
.nav-head { display: flex; align-items: center; justify-content: space-between; padding: 2px 8px 6px; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-faint); }
.nav-add { border: none; background: transparent; color: var(--text-faint); font-size: 18px; line-height: 1; cursor: pointer; padding: 0 4px; border-radius: 4px; }
.nav-add:hover { color: var(--text); background: var(--bg-hover); }
/* ---- vault header actions ---- */
.vault-actions { display: flex; align-items: center; gap: 8px; }
.adminbar { border: none; cursor: pointer; font: inherit; font-size: 11.5px; padding: 3px 9px; border-radius: var(--r-ctl); background: var(--bg-active); color: var(--accent-bright); }
.adminbar:hover { background: var(--bg-hover); color: #fff; }
.icon-btn2 { border: none; background: transparent; color: var(--text-faint); font-size: 15px; cursor: pointer; padding: 0 2px; line-height: 1; }
.icon-btn2:hover { color: var(--text); }
/* ---- topbar controls ---- */
.icon-btn { display: none; border: none; background: transparent; color: var(--text-dim); font-size: 18px; cursor: pointer; padding: 2px 6px; border-radius: 5px; }
.icon-btn:hover { color: var(--text); background: var(--bg-hover); }
#search-btn { display: inline-flex; align-items: center; gap: 6px; }
#search-btn kbd { font: 11px var(--mono, ui-monospace, Menlo, monospace); background: var(--bg); border: 1px solid var(--border); border-radius: 4px; padding: 0 5px; color: var(--text-faint); }
.btn.ghost { background: var(--bg-active); color: var(--text); }
.btn.ghost:hover { background: var(--bg-hover); color: #fff; }
/* ---- onboarding empty state ---- */
.onboard { max-width: 560px; margin: 8vh auto 0; }
.onboard h1 { font-size: 26px; margin: 0 0 8px; color: #f0f0f0; }
.onboard > p { color: var(--text-dim); margin: 0 0 28px; }
.ob-card { background: var(--bg-side); border: 1px solid var(--border); border-radius: 10px; padding: 20px 22px; margin-bottom: 16px; }
.ob-card h3 { margin: 0 0 6px; font-size: 15px; }
.ob-card p { margin: 0 0 14px; font-size: 13.5px; color: var(--text-dim); }
.ob-row { display: flex; gap: 10px; }
.ob-row input { flex: 1; padding: 8px 11px; border-radius: 6px; border: 1px solid var(--border); background: var(--bg); color: var(--text); font: inherit; font-size: 13.5px; outline: none; }
.ob-row input:focus { border-color: var(--accent-dim); }
.pbtn { border: none; cursor: pointer; font: inherit; font-size: 13px; padding: 7px 16px; border-radius: 6px; background: var(--accent-dim); color: #fff; white-space: nowrap; }
.pbtn:hover { background: var(--accent-press); }
/* ---- admin panels (org, pending) ---- */
.admin { max-width: 720px; }
.admin h1 { font-size: 22px; margin: 0 0 20px; color: #f0f0f0; }
.admin h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint); margin: 26px 0 10px; }
.admin-h { display: flex; align-items: center; justify-content: space-between; margin: 26px 0 10px; }
.admin-h h3 { margin: 0; }
.admin-row { display: flex; gap: 10px; margin-bottom: 8px; }
.admin-row input { flex: 1; padding: 7px 11px; border-radius: 6px; border: 1px solid var(--border); background: var(--bg); color: var(--text); font: inherit; font-size: 13.5px; outline: none; }
.admin-list { border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.admin-item { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--border); font-size: 13.5px; }
.admin-item:last-child { border-bottom: none; }
.ai-main { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-main.mono { font: 12px var(--mono, ui-monospace, Menlo, monospace); color: var(--text-dim); }
.ai-tag { font-size: 11.5px; color: var(--text-faint); }
.admin-item select { background: var(--bg); color: var(--text); border: 1px solid var(--border); border-radius: 5px; padding: 3px 6px; font: inherit; font-size: 12.5px; }
.ai-btn, .ai-del { border: none; cursor: pointer; font: inherit; font-size: 12px; padding: 4px 10px; border-radius: 5px; background: var(--bg-active); color: var(--text-dim); }
.ai-btn:hover { background: var(--bg-hover); color: var(--text); }
.ai-del { color: #ff9b91; }
.ai-del:hover { background: #4a2420; color: #ff7b72; }
.admin-empty { padding: 14px 12px; color: var(--text-faint); font-size: 13px; }
.admin-sub { color: var(--text-dim); font-size: 13.5px; margin: -8px 0 4px; }
.admin-item.toggle { cursor: pointer; }
.admin-item.toggle input { width: 16px; height: 16px; accent-color: var(--accent); }
.tg-label { font-size: 13.5px; color: var(--text); }
.tg-desc { font-size: 12px; color: var(--text-faint); margin-top: 2px; }
/* ---- modal ---- */
.modal-back { position: fixed; inset: 0; background: rgba(0,0,0,.5); display: flex; align-items: center; justify-content: center; z-index: 150; padding: 20px; }
.modal { background: var(--bg-side); border: 1px solid var(--border); border-radius: 12px; padding: 24px; width: min(460px, 100%); box-shadow: 0 20px 60px rgba(0,0,0,.5); }
.modal h3 { margin: 0 0 10px; font-size: 17px; }
.modal p { margin: 0 0 16px; font-size: 13.5px; color: var(--text-dim); }
.modal-url { font: 12px var(--mono, ui-monospace, Menlo, monospace); background: var(--bg); border: 1px solid var(--border); border-radius: 6px; padding: 9px 11px; color: var(--text-dim); word-break: break-all; margin-bottom: 16px; }
.modal-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.modal-label { display: block; font-size: 12.5px; color: var(--text-dim); margin: 0 0 6px; }
.modal-msg { margin: 0 0 16px; font-size: 13.5px; color: var(--text-dim); }
.modal-input { width: 100%; box-sizing: border-box; padding: 9px 11px; border-radius: var(--r-ctl); border: 1px solid var(--border); background: var(--bg); color: var(--text); font: inherit; font-size: 14px; margin-bottom: 16px; outline: none; }
.modal-input:focus-visible { border-color: var(--accent); outline: 2px solid var(--accent); outline-offset: 1px; }
.danger-btn { border: none; cursor: pointer; font: inherit; font-size: 13px; padding: 7px 16px; border-radius: var(--r-ctl); background: #b3382e; color: #fff; }
.danger-btn:hover { background: #c94336; }
/* ---- toast ---- */
#toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%) translateY(20px); background: var(--bg-active); color: var(--text); border: 1px solid var(--border); border-radius: 8px; padding: 10px 18px; font-size: 13.5px; box-shadow: 0 8px 30px rgba(0,0,0,.5); opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; z-index: 200; }
#toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
#toast.err { border-color: #7a2e28; color: #ffb4ac; }
/* ---- mobile backdrop ---- */
#sb-backdrop { display: none; }
/* ---- responsive ---- */
@media (max-width: 760px) {
#sidebar { position: fixed; z-index: 60; top: 0; left: 0; height: 100%; transform: translateX(-100%); transition: transform .2s ease; box-shadow: 0 0 40px rgba(0,0,0,.5); }
body.sb-open #sidebar { transform: translateX(0); }
body.sb-open #sb-backdrop { display: block; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 50; }
.icon-btn { display: inline-flex; }
#content { padding: 20px 18px 60px; }
#topbar { padding: 6px 10px; gap: 4px; }
#crumb { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#search-btn kbd { display: none; }
/* Every header control is a 44×44 hit area (WCAG target size). Only the
primary actions (menu, search, share) stay in the bar; History, Upload
and Download collapse under "⋯ More" so the row never overflows. */
#topbar .btn, #topbar .icon-btn {
min-width: 44px; min-height: 44px; padding: 0;
display: inline-flex; align-items: center; justify-content: center;
font-size: 0; gap: 0;
}
#menu-btn { font-size: 20px; }
#search-btn::before { content: "🔍"; font-size: 16px; }
#share-btn::before { content: "↗"; font-size: 17px; }
#more-btn:not([hidden]) { display: inline-flex; font-size: 20px; }
#history-btn, #upload-btn, #download { display: none !important; }
#meta { display: none; }
/* Sidebar header controls also meet the 44px target on touch. */
.icon-btn2, #signout, .adminbar { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
#vault { padding: 8px 12px; }
/* The list rows are the primary tap targets — size them to 44px too. */
#tree li > .row, #projects .row { min-height: 44px; }
#invite-btn { min-height: 44px; padding: 0 16px; }
.nav-add { min-width: 44px; min-height: 44px; }
.dir-history { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.markdown, .admin, .onboard, .history { max-width: 100%; }
.markdown table, pre.plain { display: block; overflow-x: auto; max-width: 100%; }
.ob-row { flex-direction: column; }
}
/* ---- "More" overflow menu (mobile) ---- */
#more-btn.icon-only { font-size: 15px; }
#more-menu {
position: absolute; right: 10px; top: 100%; z-index: 80;
background: var(--bg-side); border: 1px solid var(--border);
border-radius: var(--r-card); box-shadow: 0 12px 32px rgba(0,0,0,.5);
padding: 6px; min-width: 160px;
}
#more-menu[hidden] { display: none; }
.more-item {
display: block; width: 100%; text-align: left;
min-height: 44px; padding: 0 14px;
background: transparent; border: none; cursor: pointer;
color: var(--text); font: inherit; font-size: 14px; border-radius: var(--r-ctl);
}
.more-item:hover { background: var(--bg-hover); }
/* ---- markdown ---- */
.markdown { max-width: 820px; }
.markdown h1, .markdown h2, .markdown h3, .markdown h4 {
color: #f0f0f0;
line-height: 1.3;
margin: 1.4em 0 .5em;
}
.markdown h1:first-child { margin-top: 0; }
.markdown h1 { font-size: 1.7em; }
.markdown h2 { font-size: 1.35em; border-bottom: 1px solid var(--border); padding-bottom: .25em; }
.markdown a { color: var(--accent); text-decoration: none; }
.markdown a:hover { text-decoration: underline; }
.markdown code {
background: var(--code-bg);
padding: .15em .4em;
border-radius: 4px;
font: 12.5px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.markdown pre {
background: var(--code-bg);
border: 1px solid var(--border);
border-radius: 8px;
padding: 14px 16px;
overflow-x: auto;
}
.markdown pre code { background: none; padding: 0; }
.markdown blockquote {
margin: 1em 0;
padding: .1em 1em;
border-left: 3px solid var(--accent-dim);
color: var(--text-dim);
}
.markdown table { border-collapse: collapse; margin: 1em 0; }
.markdown th, .markdown td { border: 1px solid var(--border); padding: 6px 12px; }
.markdown th { background: var(--bg-side); }
.markdown img { max-width: 100%; border-radius: 6px; }
.markdown hr { border: none; border-top: 1px solid var(--border); margin: 2em 0; }
.markdown input[type="checkbox"] { accent-color: var(--accent); }
/* plain file / binary views */
pre.plain {
background: var(--code-bg);
border: 1px solid var(--border);
border-radius: 8px;
padding: 14px 16px;
overflow-x: auto;
font: 12.5px/1.55 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
white-space: pre-wrap;
}
.filecard {
margin-top: 15vh;
text-align: center;
color: var(--text-dim);
}
.filecard .name { font-size: 1.2em; color: var(--text); margin-bottom: .3em; }