Files
Harbor/harbor/web/harbor.css
T
KeelrLeek dbfd1720c5 Harbor as of 2026-10-05: the coordination hub for the Open Sea's decomp team
Messages, threads, acknowledgements, claims, bands, tasks, review items and
stop flags for a team of AI agents; the chat page and board; host hooks and
MCP server; autopilot; tools/watch.py. Put under version control after the
weekend's changes so they have history and can be rolled back. Local only.
2026-10-05 10:44:23 -05:00

351 lines
24 KiB
CSS

/* Harbor design system: tokens, themes and components shared by the chat page and the board. The colour themes
from BroadWorks Enhancer live in themes.css and override these tokens; this file is Harbor's own default look. */
@font-face {
font-family: "Inter"; src: url("InterVariable.woff2") format("woff2"); /* OFL, Inter-OFL.txt */
font-weight: 100 900; font-style: normal; font-display: swap;
}
:root {
--font: "Inter", "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
--font-display: "Inter", "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
--mono: "Cascadia Code", "Cascadia Mono", ui-monospace, "SF Mono", Consolas, monospace;
--bg: #f2f4f8;
--bg-tint: radial-gradient(1200px 600px at 100% -10%, #e6ebff 0%, transparent 60%), radial-gradient(900px 500px at -10% 110%, #e8f6f1 0%, transparent 55%);
--surface: #ffffff;
--surface-2: #f7f9fc;
--surface-3: #eef2f8;
--text: #111a2c;
--text-2: #364259;
--muted: #687489;
--faint: #9aa4b6;
--line: #e3e8f0;
--line-2: #d2d9e5;
--accent: #4361ee;
--accent-2: #3650d6;
--accent-soft: #edf0ff;
--accent-ink: #2c3fb5;
--action: #4361ee; --action-2: #3650d6; --on-action: #ffffff; /* filled buttons, the send button, your bubbles */
--on-green: #ffffff; --on-red: #ffffff;
--green: #097a5a; --green-soft: #e3f5ee;
--amber: #b97710; --amber-soft: #fcf1de;
--red: #d63f36; --red-soft: #fdebea;
--violet: #7356f0; --violet-soft: #f0ecff;
--blue: #2a78e4; --blue-soft: #e6f0fd;
--shadow-1: 0 1px 2px rgba(17, 26, 44, .05);
--shadow-2: 0 1px 2px rgba(17, 26, 44, .04), 0 8px 24px -10px rgba(17, 26, 44, .14);
--shadow-3: 0 24px 60px -16px rgba(17, 26, 44, .32);
--ring: 0 0 0 3px rgba(67, 97, 238, .28);
--r-1: 8px; --r-2: 12px; --r-3: 16px; --r-4: 22px;
--green-ink: color-mix(in oklab, var(--green) 66%, var(--text)); --red-ink: color-mix(in oklab, var(--red) 66%, var(--text));
--amber-ink: color-mix(in oklab, var(--amber) 66%, var(--text)); --violet-ink: color-mix(in oklab, var(--violet) 66%, var(--text));
--blue-ink: color-mix(in oklab, var(--blue) 66%, var(--text));
/* the top bar and the sidebar; a theme can colour them apart from the page */
--header: color-mix(in srgb, var(--surface) 58%, transparent);
--side: color-mix(in srgb, var(--surface) 72%, transparent); --side-solid: var(--surface);
--side-text: var(--text); --side-muted: var(--muted); --side-hover: var(--surface-3); --side-line: var(--line);
--side-active: var(--accent-soft); --side-active-text: var(--accent-ink); --side-accent: var(--accent);
--side-green: color-mix(in oklab, var(--green) 34%, var(--side-text));
--side-green-soft: color-mix(in srgb, var(--side-green) 16%, var(--side-solid));
--ease: cubic-bezier(.2, .8, .2, 1);
color-scheme: light;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #0b0f17;
--bg-tint: radial-gradient(1200px 600px at 100% -10%, rgba(76, 99, 230, .16) 0%, transparent 60%), radial-gradient(900px 500px at -10% 110%, rgba(30, 160, 120, .08) 0%, transparent 55%);
--surface: #121825; --surface-2: #161d2b; --surface-3: #1c2435;
--text: #e9eef7; --text-2: #c3cbdb; --muted: #8b96ac; --faint: #5d687e;
--line: #222b3c; --line-2: #2c374a;
--accent: #7189ff; --accent-2: #8a9dff; --accent-soft: rgba(113, 137, 255, .14); --accent-ink: #b9c5ff;
--action: #4f6af0; --action-2: #6079f5; --on-green: #0b0f17; --on-red: #0b0f17;
--green: #33c995; --green-soft: rgba(51, 201, 149, .13);
--amber: #f1b44c; --amber-soft: rgba(241, 180, 76, .13);
--red: #ff6b61; --red-soft: rgba(255, 107, 97, .13);
--violet: #a68cff; --violet-soft: rgba(166, 140, 255, .14);
--blue: #5ba3ff; --blue-soft: rgba(91, 163, 255, .13);
--shadow-1: 0 1px 2px rgba(0, 0, 0, .35);
--shadow-2: 0 1px 2px rgba(0, 0, 0, .3), 0 10px 30px -12px rgba(0, 0, 0, .55);
--shadow-3: 0 30px 70px -20px rgba(0, 0, 0, .7);
--ring: 0 0 0 3px rgba(113, 137, 255, .35);
color-scheme: dark;
}
}
:root[data-theme="dark"] {
--bg: #0b0f17;
--bg-tint: radial-gradient(1200px 600px at 100% -10%, rgba(76, 99, 230, .16) 0%, transparent 60%), radial-gradient(900px 500px at -10% 110%, rgba(30, 160, 120, .08) 0%, transparent 55%);
--surface: #121825; --surface-2: #161d2b; --surface-3: #1c2435;
--text: #e9eef7; --text-2: #c3cbdb; --muted: #8b96ac; --faint: #5d687e;
--line: #222b3c; --line-2: #2c374a;
--accent: #7189ff; --accent-2: #8a9dff; --accent-soft: rgba(113, 137, 255, .14); --accent-ink: #b9c5ff;
--action: #4f6af0; --action-2: #6079f5; --on-green: #0b0f17; --on-red: #0b0f17;
--green: #33c995; --green-soft: rgba(51, 201, 149, .13);
--amber: #f1b44c; --amber-soft: rgba(241, 180, 76, .13);
--red: #ff6b61; --red-soft: rgba(255, 107, 97, .13);
--violet: #a68cff; --violet-soft: rgba(166, 140, 255, .14);
--blue: #5ba3ff; --blue-soft: rgba(91, 163, 255, .13);
--shadow-1: 0 1px 2px rgba(0, 0, 0, .35);
--shadow-2: 0 1px 2px rgba(0, 0, 0, .3), 0 10px 30px -12px rgba(0, 0, 0, .55);
--shadow-3: 0 30px 70px -20px rgba(0, 0, 0, .7);
--ring: 0 0 0 3px rgba(113, 137, 255, .35);
color-scheme: dark;
}
/* ------------------------------------------------------------------------------------------------ base */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
font: 14px/1.5 var(--font); color: var(--text); font-feature-settings: "cv11", "ss03";
background-color: var(--bg); background-image: var(--bg-tint); background-attachment: fixed;
-webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
code, .mono { font-family: var(--mono); font-size: .92em; }
code { background: var(--surface-3); padding: 1px 5px; border-radius: 5px; }
::selection { background: var(--accent-soft); }
:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r-1); }
* { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
[hidden] { display: none !important; }
svg.i { width: 16px; height: 16px; flex-shrink: 0; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
svg.i.lg { width: 20px; height: 20px; }
svg.i.sm { width: 14px; height: 14px; }
svg.i { pointer-events: none; }
.muted { color: var(--muted); } .faint { color: var(--faint); }
.note { font-size: 12px; color: var(--muted); }
.err { color: var(--red); }
.grow { flex: 1; min-width: 0; }
.row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.stack-v { display: flex; flex-direction: column; gap: 4px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* ------------------------------------------------------------------------------------------------ buttons */
.btn {
display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 34px; padding: 0 13px;
border: 1px solid var(--line-2); background: var(--surface); color: var(--text-2); border-radius: var(--r-1);
font-size: 13px; font-weight: 600; white-space: nowrap; box-shadow: var(--shadow-1);
transition: background .15s, border-color .15s, color .15s, transform .08s, box-shadow .15s;
}
.btn:hover { background: var(--surface-2); border-color: var(--faint); color: var(--text); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: default; transform: none; }
.btn.small, .btn.sm { height: 28px; padding: 0 10px; font-size: 12px; border-radius: 7px; }
.btn.primary { background: var(--action); border-color: var(--action); color: var(--on-action); }
.btn.primary:hover { background: var(--action-2); border-color: var(--action-2); color: var(--on-action); }
.btn.go { background: var(--green); border-color: var(--green); color: var(--on-green); }
.btn.go:hover { background: var(--green); filter: brightness(1.07); border-color: var(--green); color: var(--on-green); }
.btn.stop, .btn.danger { background: var(--red); border-color: var(--red); color: var(--on-red); }
.btn.stop:hover, .btn.danger:hover { background: var(--red); filter: brightness(1.07); border-color: var(--red); color: var(--on-red); }
.btn.ghost { background: transparent; border-color: transparent; box-shadow: none; color: var(--muted); }
.btn.ghost:hover { background: var(--surface-3); color: var(--text); }
.btn.icon { width: 34px; padding: 0; }
.btn.icon.sm { width: 28px; }
.btn[aria-pressed="true"] { background: var(--accent-soft); border-color: transparent; color: var(--accent-ink); }
/* ------------------------------------------------------------------------------------------------ tags and pills */
.tag {
display: inline-flex; align-items: center; gap: 5px; height: 21px; padding: 0 8px; border-radius: 999px;
font-size: 11px; font-weight: 650; letter-spacing: .1px; white-space: nowrap; border: 0;
background: var(--surface-3); color: var(--muted);
}
.tag.green { background: var(--green-soft); color: var(--green-ink); }
.tag.red { background: var(--red-soft); color: var(--red-ink); }
.tag.amber { background: var(--amber-soft); color: var(--amber-ink); }
.tag.violet { background: var(--violet-soft); color: var(--violet-ink); }
.tag.blue { background: var(--blue-soft); color: var(--blue-ink); }
.tag.solid-red { background: var(--red); color: var(--on-red); }
.tag .dot, .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; display: inline-block; flex-shrink: 0; }
button.tag { cursor: pointer; }
button.tag:hover { filter: brightness(.96); color: var(--accent); }
.count-badge {
min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px; display: inline-grid; place-items: center;
font-size: 11px; font-weight: 700; background: var(--surface-3); color: var(--muted);
}
.count-badge.hot { background: var(--red); color: var(--on-red); }
.count-badge.accent { background: var(--action); color: var(--on-action); }
.count-badge.green { background: var(--green-soft); color: var(--green-ink); }
a.tag:hover { text-decoration: none; filter: brightness(.96); }
/* ------------------------------------------------------------------------------------------------ live dot */
.live { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--muted); white-space: nowrap; }
.live .dot { width: 8px; height: 8px; background: var(--amber); box-shadow: 0 0 0 3px var(--amber-soft); }
.live.ok .dot, .connection.connected .dot { background: var(--green); box-shadow: 0 0 0 3px var(--green-soft); animation: breathe 2.4s ease-in-out infinite; }
.live.bad .dot, .connection.failed .dot { background: var(--red); box-shadow: 0 0 0 3px var(--red-soft); }
@keyframes breathe { 0%, 100% { box-shadow: 0 0 0 3px var(--green-soft); } 50% { box-shadow: 0 0 0 6px transparent; } }
@keyframes pulse { 0% { opacity: 1; } 50% { opacity: .35; } 100% { opacity: 1; } }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
/* ------------------------------------------------------------------------------------------------ avatars */
.avatar {
--avatar: #7b8797; position: relative; width: 36px; height: 36px; flex-shrink: 0; display: grid; place-items: center;
border-radius: 12px; font-size: 11.5px; font-weight: 750; letter-spacing: .2px; color: #fff;
background: linear-gradient(145deg, color-mix(in srgb, var(--avatar) 82%, #fff 18%), var(--avatar));
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14), var(--shadow-1);
}
.avatar.sm { width: 28px; height: 28px; border-radius: 9px; font-size: 10px; }
.avatar.lg { width: 44px; height: 44px; border-radius: 14px; font-size: 13px; }
.avatar.xs { width: 22px; height: 22px; border-radius: 7px; font-size: 8.5px; letter-spacing: 0; }
.avatar.xs[data-state]::after { width: 8px; height: 8px; border-width: 2px; right: -2px; bottom: -2px; }
.avatar[data-state]::after {
content: ""; position: absolute; right: -3px; bottom: -3px; width: 12px; height: 12px; border-radius: 50%;
border: 2.5px solid var(--surface); background: var(--faint);
}
.avatar[data-state="working"]::after { background: var(--green); animation: pulse 1.6s infinite; }
.avatar[data-state="online"]::after { background: var(--green); }
.avatar[data-state="stopped"]::after { background: var(--red); }
.avatar[data-state="trial"]::after { background: var(--amber); }
.claude { --avatar: #cc8a65; } .codex { --avatar: #4688e6; } .deepseek { --avatar: #8071ce; }
.opencode { --avatar: #39a48d; } .kimi { --avatar: #b45b9b; } .user { --avatar: #536070; }
/* ------------------------------------------------------------------------------------------------ cards */
.card {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-3); box-shadow: var(--shadow-2);
min-width: 0; animation: rise .35s var(--ease) both;
}
.card > header {
display: flex; align-items: center; gap: 10px; padding: 14px 18px 12px; border-bottom: 1px solid var(--line);
}
.card > header h2 { margin: 0; font: 650 13.5px/1.3 var(--font-display); letter-spacing: -.1px; display: flex; align-items: center; gap: 8px; }
.card > header h2 svg.i { color: var(--muted); }
.card > header .count { font-size: 12px; color: var(--muted); }
.card .body { padding: 14px 18px 16px; }
.card .body.flush { padding: 0; }
.scroll { overflow-x: auto; }
/* ------------------------------------------------------------------------------------------------ forms */
input[type=text], input[type=search], select, textarea {
background: var(--surface-2); border: 1px solid var(--line-2); border-radius: var(--r-1); padding: 7px 10px;
font-size: 13px; min-width: 0; color: var(--text); transition: border-color .15s, box-shadow .15s, background .15s;
}
input[type=text]:focus, input[type=search]:focus, select:focus, textarea:focus {
outline: none; border-color: var(--accent); box-shadow: var(--ring); background: var(--surface);
}
select { padding-right: 26px; appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: calc(100% - 14px) 52%, calc(100% - 9px) 52%; background-size: 5px 5px; background-repeat: no-repeat; }
textarea { width: 100%; resize: vertical; min-height: 72px; line-height: 1.5; }
input::placeholder, textarea::placeholder { color: var(--faint); }
.check { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text-2); cursor: pointer; user-select: none; }
.check input { accent-color: var(--action); width: 15px; height: 15px; margin: 0; }
.switch { position: relative; display: inline-flex; align-items: center; gap: 9px; cursor: pointer; font-size: 12.5px; color: var(--text-2); user-select: none; }
.switch input { appearance: none; width: 34px; height: 20px; border-radius: 999px; background: var(--line-2); position: relative; margin: 0; cursor: pointer; transition: background .2s; }
.switch input::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: var(--shadow-1); transition: transform .2s var(--ease); }
.switch input:checked { background: var(--action); }
.switch input:checked::after { transform: translateX(14px); }
.toggle-chip { position: relative; display: inline-flex; }
.toggle-chip input { position: absolute; opacity: 0; inset: 0; cursor: pointer; margin: 0; }
.toggle-chip span { display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 10px; border-radius: 999px; border: 1px solid var(--line-2); font-size: 11.5px; font-weight: 600; color: var(--muted); background: var(--surface); transition: all .15s; }
.toggle-chip input:checked + span { background: var(--accent-soft); color: var(--accent-ink); border-color: transparent; }
.toggle-chip input:focus-visible + span { box-shadow: var(--ring); }
.toggle-chip.danger input:checked + span { background: var(--red-soft); color: var(--red); }
/* ------------------------------------------------------------------------------------------------ tables */
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .7px; color: var(--faint); font-weight: 650; padding: 8px 12px; border-bottom: 1px solid var(--line); background: var(--surface-2); }
td { padding: 10px 12px; border-top: 1px solid var(--line); vertical-align: top; overflow-wrap: anywhere; }
tbody tr:first-child td { border-top: 0; }
tr.click { cursor: pointer; }
tr.click:hover td, tbody tr:hover td { background: var(--surface-2); }
td.mono { white-space: nowrap; color: var(--muted); }
/* ------------------------------------------------------------------------------------------------ empty states */
.empty { display: grid; justify-items: center; gap: 6px; text-align: center; color: var(--muted); padding: 22px 12px; font-size: 13px; }
.empty strong { color: var(--text-2); font-size: 14px; }
.empty svg.i { width: 26px; height: 26px; color: var(--faint); stroke-width: 1.5; }
/* ------------------------------------------------------------------------------------------------ dialogs */
dialog {
border: 1px solid var(--line); border-radius: var(--r-4); background: var(--surface); color: var(--text);
padding: 0; width: min(760px, calc(100vw - 32px)); box-shadow: var(--shadow-3); max-height: 86vh;
}
dialog[open] { animation: rise .25s var(--ease); }
dialog::backdrop { background: rgba(8, 12, 20, .5); backdrop-filter: blur(3px); }
dialog > header, dialog form > header { display: flex; align-items: center; gap: 10px; padding: 16px 20px; border-bottom: 1px solid var(--line); }
dialog h2 { margin: 0; font: 650 15px/1.3 var(--font-display); flex: 1; min-width: 0; overflow-wrap: anywhere; }
dialog .body { padding: 16px 20px 20px; overflow: auto; }
dialog footer { display: flex; justify-content: flex-end; gap: 8px; padding: 14px 20px; border-top: 1px solid var(--line); background: var(--surface-2); border-radius: 0 0 var(--r-4) var(--r-4); }
/* ------------------------------------------------------------------------------------------------ segmented radio */
.segmented { display: inline-flex; padding: 3px; background: var(--surface-3); border-radius: 10px; gap: 2px; }
.segmented label { position: relative; }
.segmented input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.segmented span { display: flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 8px; font-size: 12.5px; font-weight: 600; color: var(--muted); transition: all .15s; }
.segmented input:checked + span { background: var(--surface); color: var(--text); box-shadow: var(--shadow-1); }
.segmented input:focus-visible + span { box-shadow: var(--ring); }
/* ------------------------------------------------------------------------------------------------ availability pill */
.avail {
display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 14px 0 12px; border-radius: 999px; white-space: nowrap;
border: 1px solid var(--line-2); background: var(--surface); color: var(--text-2); font-size: 12.5px; font-weight: 650; box-shadow: var(--shadow-1);
transition: background .15s, border-color .15s;
}
.avail::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 3px var(--green-soft); flex-shrink: 0; }
.avail:hover { background: var(--surface-2); border-color: var(--faint); }
.avail.away { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 45%, var(--line-2)); }
.avail.away::before { background: var(--amber); box-shadow: 0 0 0 3px var(--amber-soft); }
.avail.dnd { color: var(--red); border-color: color-mix(in srgb, var(--red) 45%, var(--line-2)); }
.avail.dnd::before { background: var(--red); box-shadow: 0 0 0 3px var(--red-soft); }
/* ------------------------------------------------------------------------------------------------ misc shared */
.working { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--green); font-weight: 650; }
.working::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--green); animation: pulse 1.4s infinite; }
.kbd { font: 600 11px var(--mono); padding: 1px 6px; border: 1px solid var(--line-2); border-bottom-width: 2px; border-radius: 5px; color: var(--muted); background: var(--surface); }
.divider { height: 1px; background: var(--line); margin: 12px 0; }
/* ------------------------------------------------------------------------------------------------ the sidebar's colours */
/* Inside a sidebar the general tokens point at the theme's side colours, so everything in it follows the theme. */
.side, .sidebar {
--text: var(--side-text); --text-2: var(--side-text); --muted: var(--side-muted); --faint: var(--side-muted);
--line: var(--side-line); --line-2: var(--side-line);
--surface: var(--side-solid); --surface-2: var(--side-hover); --surface-3: var(--side-hover);
--accent: var(--side-accent); --accent-soft: var(--side-active); --accent-ink: var(--side-active-text);
--green: var(--side-green); --green-soft: var(--side-green-soft);
color: var(--text); background: var(--side);
}
.side .segmented input:checked + span, .sidebar .segmented input:checked + span { background: var(--side-active); color: var(--side-active-text); box-shadow: none; }
.theme-btn {
display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 11px; min-width: 0; border-radius: 9px;
border: 1px solid var(--line-2); background: var(--surface-2); color: var(--text-2); font-size: 12.5px; font-weight: 600;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: background .15s, border-color .15s;
}
.theme-btn:hover { background: var(--surface-3); border-color: var(--accent); }
.theme-btn svg.i { color: var(--accent); }
/* ------------------------------------------------------------------------------------------------ the theme picker */
.theme-dialog { width: min(860px, calc(100vw - 32px)); }
.theme-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
.theme-row .field-label { margin: 0; }
.theme-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 172px), 1fr)); gap: 12px; }
.tcard {
display: flex; flex-direction: column; gap: 9px; padding: 8px 8px 10px; text-align: left; color: var(--text);
border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface-2);
transition: border-color .15s, transform .15s var(--ease), box-shadow .15s;
}
.tcard:hover { border-color: var(--line-2); transform: translateY(-2px); box-shadow: var(--shadow-2); }
.tcard[aria-pressed="true"] { border-color: var(--accent); box-shadow: var(--ring); }
.tname { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; padding: 0 3px; font-size: 13px; font-weight: 650; }
.tprev {
display: grid; grid-template-columns: 24% 1fr; grid-template-rows: 13px 1fr; height: 82px; overflow: hidden;
border-radius: 8px; border: 1px solid var(--p-line); background: var(--p-bg);
}
.tprev i, .tprev b, .tprev em { display: block; font-style: normal; }
.tprev .ps { grid-row: 1 / 3; background: var(--p-side); padding: 16px 6px 0; display: flex; flex-direction: column; gap: 6px; }
.tprev .ps b { height: 4px; border-radius: 2px; background: var(--p-side-accent); opacity: .45; }
.tprev .ps b:first-child { opacity: 1; }
.tprev .ph { background: var(--p-header); border-bottom: 1px solid var(--p-line); }
.tprev .pb { padding: 8px; display: flex; }
.tprev .pc { flex: 1; display: flex; flex-direction: column; gap: 5px; padding: 7px; border-radius: 6px; background: var(--p-surface); border: 1px solid var(--p-line); }
.tprev .pc b { height: 4px; width: 78%; border-radius: 2px; background: var(--p-text); opacity: .75; }
.tprev .pc b + b { width: 52%; opacity: .4; }
.tprev .pc em { margin-top: auto; height: 10px; width: 40%; border-radius: 5px; background: var(--p-action); }
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
}