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
8 changes: 7 additions & 1 deletion desktop/renderer/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,15 @@ const RAW: Record<string, string> = {
download: P("M12 4v9.5") + P("M8 10.5l4 4 4-4") + P("M5 18.5h14"),
};

// Action glyphs that read as "do something now" β€” they get the .ic-action hook
// so CSS can give them an extra spark on hover. Purely additive: behavior and
// default visual weight are unchanged.
const ACTION = new Set(["bolt", "spark", "refresh", "send", "plus", "download"]);

export function icon(name: keyof typeof RAW | string, size = 18, extraClass = ""): string {
const body = RAW[name] ?? RAW.info;
return `<svg class="ic ${extraClass}" viewBox="0 0 24 24" width="${size}" height="${size}" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${body}</svg>`;
const hook = ACTION.has(name as string) ? " ic-action" : "";
return `<svg class="ic${hook}${extraClass ? " " + extraClass : ""}" viewBox="0 0 24 24" width="${size}" height="${size}" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${body}</svg>`;
}

/** The LUCID wordmark Ο€ glyph used in the titlebar. */
Expand Down
40 changes: 40 additions & 0 deletions desktop/renderer/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -732,3 +732,43 @@ body.resizing .sidebar,body.resizing .inspector{transition:none}

/* P10.3 budget chip near-limit warning */
.statusbar .seg.warn{border-color:color-mix(in srgb,var(--red) 45%,var(--line));background:var(--red-dim)}

/* ───────────────────────── animated icons (unit #2) ─────────────────────────
Self-contained icon motion + glow. Scoped to `.ic` only β€” color stays owned
by parents (stroke=currentColor). Motion is GPU-friendly (transform/filter)
and globally gated by the prefers-reduced-motion reset near the top of this
file. Do not move color/layout ownership here. */
.ic{transition:transform var(--t) var(--ease-out),filter var(--t) var(--ease-out);
transform-origin:center;will-change:transform}

/* Hover lift + on-brand glow when an icon sits inside an interactive control.
Targets the .ic only β€” never the button body (owned elsewhere). */
.rail-btn:hover .ic,
.btn-mini:hover .ic,
.ws-recent-item:hover .ic,
.fb-item:hover .ic{
transform:translateY(-1px) scale(1.08);
filter:drop-shadow(0 0 5px rgba(198,75,214,.45));
}
/* Action icons get a touch more spark on hover. */
.btn-mini:hover .ic.ic-action{filter:drop-shadow(0 0 7px rgba(224,123,240,.6))}

/* Pressed state settles back down for tactile feedback. */
.rail-btn:active .ic,
.btn-mini:active .ic{transform:translateY(0) scale(.96);transition-duration:var(--t-fast)}

/* Spin utility β€” loading/refresh code opts in by adding `spin` via extraClass
(e.g. icon("refresh", 13, "spin")). Cubic, continuous, GPU-only. */
.ic.spin{animation:icSpin .9s linear infinite}
@keyframes icSpin{to{transform:rotate(360deg)}}

/* Soft draw/pulse for action glyphs (bolt, spark) β€” opt in with `ic-pulse`. */
.ic.ic-pulse{animation:icPulse 2.4s var(--ease) infinite}
@keyframes icPulse{
0%,100%{filter:drop-shadow(0 0 2px rgba(198,75,214,.25))}
50%{filter:drop-shadow(0 0 8px rgba(224,123,240,.7))}
}

/* One-shot pop for an icon that just appeared / activated β€” opt in with `ic-pop`. */
.ic.ic-pop{animation:icPop var(--t-slow) var(--ease-out)}
@keyframes icPop{0%{transform:scale(.6);opacity:.4}60%{transform:scale(1.12)}100%{transform:none;opacity:1}}