Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion entrypoints/sidepanel/components/ActiveConversation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export default function ActiveConversation({ conv, health }: Props) {

<div className="lco-dash-active-stats">
<span>{conv.turnCount} turn{conv.turnCount === 1 ? '' : 's'}</span>
<span>{formatTokens(conv.totalInputTokens + conv.totalOutputTokens)} tokens</span>
<span>{formatTokens(conv.totalInputTokens + conv.totalOutputTokens)} tok</span>
{showDelta
? <span>{totalDelta.toFixed(1)}% of session</span>
: <span>{formatCost(conv.estimatedCost)}</span>
Expand Down
22 changes: 5 additions & 17 deletions entrypoints/sidepanel/components/TodayCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// entrypoints/sidepanel/components/TodayCard.tsx
// Today's aggregate stats in a 2x2 grid.
// Today's aggregate stats as a single dense row matching overlay typography.

import React from 'react';
import type { DailySummary } from '../../../lib/conversation-store';
Expand All @@ -18,22 +18,10 @@ export default function TodayCard({ summary }: Props) {

return (
<div className={`lco-dash-today ${isEmpty ? 'lco-dash-today--empty' : ''}`}>
<div className="lco-dash-metric">
<span className="lco-dash-metric-value">{conversations}</span>
<span className="lco-dash-metric-label">Conversations</span>
</div>
<div className="lco-dash-metric">
<span className="lco-dash-metric-value">{turns}</span>
<span className="lco-dash-metric-label">Turns</span>
</div>
<div className="lco-dash-metric">
<span className="lco-dash-metric-value">{formatTokens(tokens)}</span>
<span className="lco-dash-metric-label">Tokens</span>
</div>
<div className="lco-dash-metric">
<span className="lco-dash-metric-value">{formatCost(cost)}</span>
<span className="lco-dash-metric-label">Cost</span>
</div>
<span className="lco-dash-today-label">today</span>
<span className="lco-dash-today-stats">
{conversations} conv · {turns} turn{turns !== 1 ? 's' : ''} · {formatTokens(tokens)} tok · {formatCost(cost)}
</span>
</div>
);
}
105 changes: 51 additions & 54 deletions entrypoints/sidepanel/dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

body {
font-family: var(--lco-font);
font-size: 13px;
font-size: 11px;
line-height: 1.5;
color: var(--lco-text);
background: var(--lco-bg);
Expand All @@ -64,6 +64,12 @@ body {
max-width: 400px;
margin: 0 auto;
padding: 16px 12px;
/* Flex column + min-height keeps the feedback widget pinned to the viewport
bottom when sections are collapsed. When History is tall, the panel scrolls
and the widget sits naturally at the end of content (no overlap, no stickiness). */
min-height: 100vh;
display: flex;
flex-direction: column;
}

.lco-dash-loading {
Expand Down Expand Up @@ -208,66 +214,41 @@ body {
/* ── Today card ─────────────────────────────────────────────────────────────── */

.lco-dash-today {
display: grid;
grid-template-columns: 1fr 1fr;
display: flex;
align-items: baseline;
gap: 8px;
padding: 2px 0;
}

.lco-dash-today--empty {
opacity: 0.5;
}

.lco-dash-metric {
background: var(--lco-bg-card);
border: 1px solid var(--lco-border);
border-radius: var(--lco-radius);
padding: 12px;
display: flex;
flex-direction: column;
gap: 2px;
transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.lco-dash-metric:hover {
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

@media (prefers-color-scheme: dark) {
.lco-dash-metric:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}
}

.lco-dash-metric-value {
font-size: 20px;
font-weight: 700;
font-family: var(--lco-font-mono);
letter-spacing: -0.02em;
color: var(--lco-text);
.lco-dash-today-label {
font-size: 10px;
color: var(--lco-text-muted);
flex-shrink: 0;
}

.lco-dash-metric-label {
.lco-dash-today-stats {
font-size: 11px;
color: var(--lco-text-secondary);
text-transform: uppercase;
letter-spacing: 0.04em;
font-variant-numeric: tabular-nums;
}

/* ── Active conversation ────────────────────────────────────────────────────── */

.lco-dash-active {
background: var(--lco-bg-card);
border: 1px solid var(--lco-border);
border-radius: var(--lco-radius);
padding: 12px;
padding: 8px 0;
/* GPU-accelerated: only transform + opacity for 60/120fps compositing. */
will-change: transform, opacity;
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.25s ease;
}

.lco-dash-active--empty {
border-style: dashed;
border: 1px dashed var(--lco-border);
border-radius: var(--lco-radius);
padding: 8px;
}

.lco-dash-active--hidden {
Expand Down Expand Up @@ -296,25 +277,25 @@ body {
}

.lco-dash-health-dot {
width: 8px;
height: 8px;
width: 6px;
height: 6px;
border-radius: 50%;
flex-shrink: 0;
/* No transition: health state changes snap instantly (rare, not per-frame). */
}

.lco-dash-health-dot--healthy { background: var(--lco-health-green); box-shadow: 0 0 4px rgba(76, 175, 80, 0.4); }
.lco-dash-health-dot--degrading { background: var(--lco-health-yellow); box-shadow: 0 0 4px rgba(245, 166, 35, 0.4); }
.lco-dash-health-dot--critical { background: var(--lco-health-red); box-shadow: 0 0 4px rgba(229, 57, 53, 0.4); }
.lco-dash-health-dot--critical { background: var(--lco-health-red); animation: lco-dot-pulse 2s ease-in-out infinite; }
Comment thread
DevanshuNEU marked this conversation as resolved.

.lco-dash-health-label {
font-size: 12px;
font-size: 10px;
font-weight: 500;
color: var(--lco-text-secondary);
}

.lco-dash-active-subject {
font-size: 14px;
font-size: 12px;
font-weight: 500;
color: var(--lco-text);
margin-bottom: 10px;
Expand All @@ -330,9 +311,9 @@ body {

.lco-dash-context-bar {
flex: 1;
height: 6px;
height: 4px;
background: var(--lco-context-track);
border-radius: 3px;
border-radius: 2px;
overflow: hidden;
}

Expand Down Expand Up @@ -360,9 +341,15 @@ body {

.lco-dash-active-stats {
display: flex;
gap: 12px;
font-size: 12px;
font-size: 11px;
color: var(--lco-text-secondary);
font-variant-numeric: tabular-nums;
}

/* Dot separators between stat spans; avoids hardcoding · in JSX. */
.lco-dash-active-stats > span + span::before {
content: ' · ';
color: var(--lco-text-muted);
}

/* ── Non-Claude tab banner ──────────────────────────────────────────────────── */
Expand Down Expand Up @@ -418,14 +405,14 @@ body {
.lco-dash-budget-dot--critical { background: var(--lco-health-red); box-shadow: 0 0 4px rgba(229, 57, 53, 0.4); }

.lco-dash-budget-zone-label {
font-size: 12px;
font-size: 10px;
font-weight: 500;
color: var(--lco-text-secondary);
}

/* Primary status line: "11% used; resets in 53 min" */
.lco-dash-budget-status {
font-size: 13px;
font-size: 11px;
font-weight: 500;
color: var(--lco-text);
margin-bottom: 10px;
Expand Down Expand Up @@ -475,6 +462,7 @@ body {
font-size: 11px;
color: var(--lco-text-muted);
font-family: var(--lco-font-mono);
font-variant-numeric: tabular-nums;
width: 28px; /* Fixed width so the percentage numbers don't shift layout */
text-align: right;
flex-shrink: 0;
Expand Down Expand Up @@ -532,7 +520,7 @@ body {
}

.lco-dash-conv-subject {
font-size: 13px;
font-size: 12px;
font-weight: 500;
color: var(--lco-text);
flex: 1;
Expand Down Expand Up @@ -568,6 +556,7 @@ body {
.lco-dash-conv-turns,
.lco-dash-conv-cost {
font-family: var(--lco-font-mono);
font-variant-numeric: tabular-nums;
font-size: 11px;
}

Expand All @@ -576,7 +565,10 @@ body {
/* Open: textarea + cancel/send. Sent: green confirmation, auto-resets in 4s. */

.lco-dash-feedback {
margin-top: 12px;
/* margin-top: auto fills available flex space, pushing the widget to the
viewport bottom when content is short. Collapses to 0 when content fills
the panel, so History (if expanded) still has border-top separation below it. */
margin-top: auto;
padding-top: 12px;
border-top: 1px solid var(--lco-border);
padding-bottom: 4px;
Expand Down Expand Up @@ -699,6 +691,11 @@ body {

/* ── Animations ─────────────────────────────────────────────────────────────── */

@keyframes lco-dot-pulse {
0%, 100% { box-shadow: 0 0 4px rgba(229, 57, 53, 0.4); }
50% { box-shadow: 0 0 10px rgba(229, 57, 53, 0.7); }
}

@keyframes lco-dash-slide-in {
from {
opacity: 0;
Expand Down Expand Up @@ -727,8 +724,8 @@ body {
.lco-dash-budget-fill {
transition: none;
}
.lco-dash-metric {
transition: none;
.lco-dash-health-dot--critical {
animation: none;
}
.lco-dash-skeleton {
animation: none;
Expand Down
Loading