fix(jetbrains): normalize icon canvas and stroke geometry - #12734
Conversation
| <path d="M5.00024 6.125C5.29925 6.12518 5.54126 6.36795 5.54126 6.66699C5.54108 6.96589 5.29914 7.20783 5.00024 7.20801C4.7012 7.20801 4.45843 6.966 4.45825 6.66699C4.45825 6.36784 4.70109 6.125 5.00024 6.125ZM7.91626 6.125C8.21541 6.125 8.45825 6.36784 8.45825 6.66699C8.45808 6.966 8.21531 7.20801 7.91626 7.20801C7.61736 7.20783 7.37542 6.96589 7.37524 6.66699C7.37524 6.36795 7.61726 6.12518 7.91626 6.125ZM10.8333 6.125C11.1324 6.125 11.3752 6.36784 11.3752 6.66699C11.3751 6.966 11.1323 7.20801 10.8333 7.20801C10.5342 7.20801 10.2914 6.966 10.2913 6.66699C10.2913 6.36784 10.5341 6.125 10.8333 6.125Z" fill="#6C707E" stroke="#6C707E" stroke-width="0.25" stroke-linecap="square"/> | ||
| <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <path d="M14.3333 8.3334V3H1.6666V13.6666H8.3333M14.3333 10.8718L9.3333 9.3334L10.8718 14.3334L12.0256 12.0257L14.3333 10.8718Z" stroke="#6C707E" stroke-width="1" stroke-linecap="round"/> | ||
| <path d="M4.0002 4.9C4.2394 4.9001 4.433 5.0944 4.433 5.3336C4.4329 5.5727 4.2393 5.7663 4.0002 5.7664C3.761 5.7664 3.5667 5.5728 3.5666 5.3336C3.5666 5.0943 3.7609 4.9 4.0002 4.9ZM6.333 4.9C6.5723 4.9 6.7666 5.0943 6.7666 5.3336C6.7665 5.5728 6.5722 5.7664 6.333 5.7664C6.0939 5.7663 5.9003 5.5727 5.9002 5.3336C5.9002 5.0944 6.0938 4.9001 6.333 4.9ZM8.6666 4.9C8.9059 4.9 9.1002 5.0943 9.1002 5.3336C9.1001 5.5728 8.9058 5.7664 8.6666 5.7664C8.4274 5.7664 8.2331 5.5728 8.233 5.3336C8.233 5.0943 8.4273 4.9 8.6666 4.9Z" fill="#6C707E" stroke="#6C707E" stroke-width="1" stroke-linecap="round"/> |
There was a problem hiding this comment.
WARNING: The three window dots grow ~75% — this stroke was a 0.25 hairline, not a real 1px stroke.
The original path used stroke-width="0.25" on the 20-unit grid (≈0.2px at 16px render) purely to fatten the filled dots slightly. Scaling the geometry by ×0.8 while forcing stroke-width="1" takes each dot from ≈1.07px to ≈1.87px diameter, so the dots will render noticeably heavier and blobbier than before. That contradicts the PR's "shapes are unchanged" claim for this icon.
Suggest scaling this decorative hairline like the geometry (0.25 × 0.8 = stroke-width="0.2") rather than normalizing it to 1. window-cursor_dark.svg:3 needs the same change.
Also worth a look: the frame path on line 2 went from stroke-width="1.07143" on the 20 grid (≈0.857px effective) to a full 1px, so the window outline gets ~17% heavier too.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| <path d="M7.9995 1.6656L13.6662 3.499V7.9405C13.6662 11.2555 10.6662 12.999 7.9995 14.4376C5.3328 12.999 2.3328 11.2555 2.3328 7.9405V3.499L7.9995 1.6656Z" fill="#6C707E"/> | ||
| <path d="M5.9995 7.499L7.3328 8.8323L9.9995 6.1656" stroke="#FFFFFF" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/> | ||
| <circle cx="12" cy="12" r="2" fill="#55A76A"/> | ||
| <circle cx="12" cy="12" r="2.4" stroke="#FFFFFF"/> |
There was a problem hiding this comment.
SUGGESTION: The white badge ring now overlaps the green fill.
Before, this ring was r="3" with an implicit stroke-width="1" on the 20-unit grid, so the stroke spanned r 2.5–3.5 and its inner edge sat exactly on the r="2.5" green fill edge. After scaling, the ring is r="2.4" but the stroke is still an unscaled 1, spanning r 1.9–2.9 — it now paints over 0.1 units of the r="2" green fill, shrinking the visible green badge.
Scaling the implicit stroke keeps the ring flush with the fill edge as designed. shield-filled_dark.svg:5 needs the same change.
| <circle cx="12" cy="12" r="2.4" stroke="#FFFFFF"/> | |
| <circle cx="12" cy="12" r="2.4" stroke="#FFFFFF" stroke-width="0.8"/> |
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| <svg width="16" height="16" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <path d="M0.416626 7.91667H1.66663M19.5833 7.91667H18.3333M11.866 7.57987C11.3165 7.26398 10.6793 7.08333 9.99996 7.08333C9.32061 7.08333 8.68344 7.26398 8.13389 7.57987M8.74996 10C8.74996 12.0711 7.07103 13.75 4.99996 13.75C2.92889 13.75 1.24996 12.0711 1.24996 10C1.24996 7.92893 2.92889 6.25 4.99996 6.25C7.07103 6.25 8.74996 7.92893 8.74996 10ZM18.75 10C18.75 12.0711 17.071 13.75 15 13.75C12.9289 13.75 11.25 12.0711 11.25 10C11.25 7.92893 12.9289 6.25 15 6.25C17.071 6.25 18.75 7.92893 18.75 10Z" stroke="#6C707E" stroke-linecap="square"/> | ||
| <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <path d="M0.3333 6.3333H1.3333M15.6666 6.3333H14.6666M9.4928 6.0639C9.0532 5.8112 8.5434 5.6667 8 5.6667C7.4565 5.6667 6.9468 5.8112 6.5071 6.0639M7 8C7 9.6569 5.6568 11 4 11C2.3431 11 1 9.6569 1 8C1 6.3431 2.3431 5 4 5C5.6568 5 7 6.3431 7 8ZM15 8C15 9.6569 13.6568 11 12 11C10.3431 11 9 9.6569 9 8C9 6.3431 10.3431 5 12 5C13.6568 5 15 6.3431 15 8Z" stroke="#6C707E" stroke-linecap="round"/> |
There was a problem hiding this comment.
SUGGESTION: Temple end caps are now clipped at both edges of the 16×16 canvas.
The two temple segments run from x=0.3333 and to x=15.6666. With a 1px round cap centered on those points the caps reach -0.167 and 16.167, so they're clipped by the viewBox. Previously the same geometry clipped by only ~0.07px of rendered output (0.4166 on a 20 grid with an effective 0.8px stroke), so this is roughly 2.5× worse.
Nudging both endpoints inward (0.5 and 15.5) would keep the caps inside the canvas. glasses_dark.svg:2 has the same geometry. views/mcp.svg has a milder version of this at the top of path 1 (y=0.4217 → -0.078).
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review SummaryStatus: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)SUGGESTION
Verification notesIncremental review of the single commit since I confirmed the new expectations match the assets at this HEAD: The two remaining stroke-weight suggestions from the previous revision ( In-IDE HiDPI visual QA is still not runnable in this environment. No changeset is expected — Files Reviewed (1 file)
Fix these issues in Kilo Cloud Previous Review Summaries (2 snapshots, latest commit 2f4ffc3)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 2f4ffc3)Status: 2 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)SUGGESTION
Previous issues resolved in this revisionAll three findings from the earlier review are fixed by scaling the stroke widths along with the geometry:
Verification notesIncremental review of the 8 files changed since For I could not run in-IDE HiDPI visual QA in this environment, so rendered-output impact is derived analytically. Files Reviewed (8 files)
Fix these issues in Kilo Cloud Previous review (commit b1911c5)Status: 3 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Verification notesI re-derived the coordinate transform by hand for a representative sample across both scale factors — The The issues above are all cases where geometry was scaled but a non-default I could not run visual QA in this environment, so the rendered-output impact is derived analytically rather than observed. Files Reviewed (66 files)All 66 SVG assets under
Reviewed by claude-opus-5 · Input: 34 · Output: 9.1K · Cached: 944.8K Review guidance: REVIEW.md from base branch |
| <svg width="16" height="16" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <path d="M0.416626 7.91667H1.66663M19.5833 7.91667H18.3333M11.866 7.57987C11.3165 7.26398 10.6793 7.08333 9.99996 7.08333C9.32061 7.08333 8.68344 7.26398 8.13389 7.57987M8.74996 10C8.74996 12.0711 7.07103 13.75 4.99996 13.75C2.92889 13.75 1.24996 12.0711 1.24996 10C1.24996 7.92893 2.92889 6.25 4.99996 6.25C7.07103 6.25 8.74996 7.92893 8.74996 10ZM18.75 10C18.75 12.0711 17.071 13.75 15 13.75C12.9289 13.75 11.25 12.0711 11.25 10C11.25 7.92893 12.9289 6.25 15 6.25C17.071 6.25 18.75 7.92893 18.75 10Z" stroke="#6C707E" stroke-linecap="square"/> | ||
| <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <path d="M0.3333 6.3333H1.3333M15.6666 6.3333H14.6666M9.4928 6.0639C9.0532 5.8112 8.5434 5.6667 8 5.6667C7.4565 5.6667 6.9468 5.8112 6.5071 6.0639M7 8C7 9.6569 5.6568 11 4 11C2.3431 11 1 9.6569 1 8C1 6.3431 2.3431 5 4 5C5.6568 5 7 6.3431 7 8ZM15 8C15 9.6569 13.6568 11 12 11C10.3431 11 9 9.6569 9 8C9 6.3431 10.3431 5 12 5C13.6568 5 15 6.3431 15 8Z" stroke="#6C707E" stroke-width="0.8" stroke-linecap="round"/> |
There was a problem hiding this comment.
SUGGESTION: Thinning the whole path to 0.8 fixes the clipping, but it also opts this icon out of the 1px normalization.
stroke-width="0.8" restores the exact pre-PR effective weight (0.8px at 16px), so the temple caps now land at -0.0667 / 16.0666 — identical to before, so no regression there. The tradeoff is that glasses now renders visibly lighter than its views/ neighbours (task, console, eye, brain, …) that this PR moved to a true 1px stroke.
An alternative that keeps both properties: leave stroke-width at 1 and inset just the two temple endpoints from 0.3333/15.6666 to 0.5/15.5, so the round caps sit flush inside the canvas. Same applies to glasses_dark.svg.
Either way, the PR description's "Strokes normalized to stroke-width="1"" is no longer accurate for this file and views/mcp.svg — worth a description tweak so future audits don't re-flag these.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| <path d="M7.42871 11.2747L13.7957 5.48643C14.9761 4.41338 16.8898 4.41338 18.0702 5.48643L18.1147 5.52688C19.2951 6.59993 19.2951 8.33966 18.1147 9.4127L10.3831 16.4414C9.98966 16.7991 9.98966 17.379 10.3831 17.7366L11.9707 19.1799" stroke="#6C707E" stroke-linecap="round"/> | ||
| <path d="M11.6587 3.54346L5.33619 9.29119C4.15584 10.3642 4.15584 12.1039 5.33619 13.177C6.51649 14.25 8.43019 14.25 9.61054 13.177L15.9331 7.42923" stroke="#6C707E" stroke-linecap="round"/> | ||
| <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
| <g stroke-width="0.8"> |
There was a problem hiding this comment.
SUGGESTION: Confirm this weight change is intentional and not a blanket revert.
stroke-width="0.8" on the <g> restores the pre-PR effective weight (0.8px at 16px) for all three inherited paths. Unlike views/glasses.svg, there is no clipping to avoid here: the extents are x ∈ [0.7781, 14.4918] and y ∈ [~0.636, 15.3439], so a 1px round cap (half-width 0.5) stays inside the 16×16 canvas on every side.
So the only effect is that mcp renders lighter than the other views/ icons this PR normalized to 1px. If the goal was pixel-identical output, that's fine — but it's a visible inconsistency inside the same tool window. Same in mcp_dark.svg.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| fun `test send icon matches scroll button theme colors`() { | ||
| assertTrue(resource("/icons/send.svg").contains("fill=\"#0066B8\"")) | ||
| assertTrue(resource("/icons/send_dark.svg").contains("fill=\"#0A7BD8\"")) | ||
| assertTrue(resource("/icons/send.svg").contains("fill=\"#3574F0\"")) |
There was a problem hiding this comment.
SUGGESTION: The values are correct, but the test duplicates the palette instead of asserting the parity its name claims.
I verified send.svg is #3574F0 and send_dark.svg is #548AF7 at this HEAD, matching scroll-bottom.svg / scroll-bottom_dark.svg, so this update is right. The test name is test send icon matches scroll button theme colors, yet nothing here reads the scroll button asset — the needing-to-edit-this-line-at-all is the drift the test was supposed to catch. If the scroll button palette moves again and send.svg is missed, this test keeps passing on a stale hardcoded hex.
Deriving the expectation from the scroll asset would make it self-maintaining, e.g. extract the fill="#......" from /icons/scroll-bottom.svg and assert /icons/send.svg contains the same value (and likewise for the _dark pair). Non-blocking — your call.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Context
Stacked on top of #12731 (palette fixes). The
icon-jetbrainsaudit found ~33 JetBrains plugin icons drawn on a 20-unit grid, plusbook-open-checkandwand-sparkleson a 24-unit grid, while declaringwidth/height="16". That mismatch meant the IDE rendered those assets as scaled-down 16px icons with inconsistent effective stroke weights, mixed square/round caps, and canvas geometry that did not match the intended IntelliJ action-icon size.This PR normalizes the affected icon assets to a native 16x16 coordinate grid and makes the stroke geometry explicit.
What changed
viewBox="0 0 16 16"for the affected SVGs, uniformly scaling geometry from 20x20 (x0.8) or 24x24 (x0.667) into the native IntelliJ action-icon canvas.glasses/mcpuse scaled 0.8px strokes to avoid cap clipping or unintended weight changes.book-open-checkwas scaled while preserving rotation and arc flags.Untouched: already-16 icons, the 20x20 (
plus,kilo@20x20) and 40x40 (scroll-*) icons whose canvas already matches their role, and the brand logos.Before and after
Scope note
This fixes the canvas-size and stroke-geometry mismatch. It does not attempt a full designer pixel-snapping pass: uniformly scaling existing paths preserves shape proportions but can leave fractional coordinates such as
5.3332. A future manual vector pass could snap individual curves/strokes to the pixel grid if we want sharper rasterization beyond this normalization.Some icons will look slightly heavier than before because they previously rendered a default
stroke-width="1"from a 20-unit viewBox at an effective ~0.8px. The normalized 16x16 assets intentionally render primary strokes at 1px. Secondary strokes that were decorative or would clip after the canvas change now use explicit scaled widths instead.How to Test
Automated/local verification
book-open-check.bun run typecheckfrompackages/kilo-jetbrains/successfully.@kilocode/kilo-jetbrains:typecheck, successfully.Reviewer test steps
./gradlew runIdefrompackages/kilo-jetbrains/.Blocked checks and substitute verification
Checklist