Skip to content

UI polish 2/12 — Animated SVG icons with hover lift + drop-shadow glow - #15

Merged
mlcyclops merged 1 commit into
masterfrom
polish/animated-icons
Jun 20, 2026
Merged

UI polish 2/12 — Animated SVG icons with hover lift + drop-shadow glow#15
mlcyclops merged 1 commit into
masterfrom
polish/animated-icons

Conversation

@mlcyclops

Copy link
Copy Markdown
Owner

Part of the Apple-level UI/UX polish batch. Independent, region-scoped slice (polish/animated-icons) so it merges on its own.

Gate per worker: desktop tsc --noEmit + bun build desktop/renderer/app.ts --target=browser + bun test harness (green) + /code-review.

🤖 Generated with Claude Code

…lities

Give icons tasteful life without changing their color or default weight.

- styles.css: isolated, clearly-commented `.ic` icon block (no :root/body/button
  edits). Base `.ic` gains a GPU-friendly transform/filter transition. Hover
  inside interactive controls (rail-btn, btn-mini, ws-recent-item, fb-item)
  gives a subtle 1px lift + 1.08 scale + on-brand drop-shadow glow; :active
  settles back for tactile feedback. Action icons get extra spark on hover.
- Three opt-in micro-interaction keyframes: `.ic.spin` (loading/refresh),
  `.ic.ic-pulse` (bolt/spark glow), `.ic.ic-pop` (one-shot appear). All motion
  is gated by the existing prefers-reduced-motion global reset.
- Excluded `.ctool` from the lift group — it has a deliberate color-only icon
  transition that would have made the lift snap without easing.
- icons.ts: signature/behavior unchanged. Action glyphs (bolt, spark, refresh,
  send, plus, download) auto-tag a `.ic-action` hook class; `extraClass` still
  works (e.g. icon("refresh", 13, "spin")). Backward-compatible — emits
  `class="ic"` cleanly instead of a trailing-space `class="ic "`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mlcyclops
mlcyclops merged commit f257ef9 into master Jun 20, 2026
5 checks passed
@mlcyclops
mlcyclops deleted the polish/animated-icons branch June 20, 2026 06:25
mlcyclops pushed a commit that referenced this pull request Jun 21, 2026
…-then-read (ADR-0025)

CodeQL alert #15 (js/file-system-race, High): loadExportText in
desktop/personal.ts checked then used — statSync(raw) to branch file/dir, then a
separate readFileSync(raw). The path can be swapped between the two, so the bytes
read need not be the bytes stat'd. The directory branch had the same existsSync-
then-readFileSync shape.

Replace with use-and-handle: read raw directly and let the error classify it —
EISDIR means a folder (fall through), ENOENT means missing. The folder branch
reads the listing once with readdirSync and selects from the names instead of a
per-file existsSync probe. No stat/exists precedes a read of the same path, so
there is no check/use window. statSync/existsSync dropped from the fs imports.
User-facing errors and ambiguous-folder rejection preserved.

loadExportText is exported solely for direct FS-branch testing. New
desktop/export_loader.test.ts: 6 tests (file, dir-with-conversations.json,
lone-json, missing→ENOENT, empty folder, ambiguous folder). desktop 33 pass
(+6), harness 194 pass, root + desktop tsc clean. ADR-0025 + PROGRESS recorded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FrTqRvkZBtq3NdEExxyCLG
mlcyclops added a commit that referenced this pull request Jun 21, 2026
sec(P11.6/SEC): TOCTOU-safe import reader — fix js/file-system-race (CodeQL #15, ADR-0025)
mlcyclops pushed a commit that referenced this pull request Jun 21, 2026
…s, dashboard escaping (ADR-0026)

Five real fixes from the open CodeQL alerts on master:

- #3/#4 js/stack-trace-exposure (desktop/dev.ts, tools/web/server.ts): the catch
  handlers returned String(err) to the client. Now they log the detail
  server-side and return a generic {ok:false,error:"internal error"}.
- #5 js/file-system-race (harness/memory/state.ts): existsSync-then-writeFileSync
  was a TOCTOU. Now a single writeFileSync(..., {flag:"wx"}) (create-or-fail,
  EEXIST-safe); existing files preserved. existsSync dropped from imports.
- #6 js/insecure-temporary-file (harness/personal/store.ts): the encrypted store
  was written then chmod'd, leaving a 0644 window. Now created owner-only via
  {mode:0o600}; chmod kept for the overwrite-existing case.
- #1 js/incomplete-html-attribute-sanitization (tools/web/index.html): the
  dashboard esc() escaped only &<> but its output lands in double-quoted
  attributes — a " could break out (attribute XSS). It now escapes " and ' too,
  matching the desktop renderer's esc.

The eight "File data in outbound network request" alerts (asksage, ratelimit_
probe) are intended API-key transmission to configured provider endpoints and
are dispositioned dismiss-as-by-design. #14/#15 were fixed by #41 (auto-close).

Tests: store-perms assertion (0600); state reopen/no-clobber already covered.
Verified live: a forced handler error returns the generic body with the real
SyntaxError only in the server log. harness 195 pass (+1), desktop 33, root +
desktop tsc clean. ADR-0026 + PROGRESS recorded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FrTqRvkZBtq3NdEExxyCLG
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant