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 .fork/customizations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,7 @@
- apps/web/src/custom/SidebarV2ChromeRows.tsx
- apps/web/src/custom/useScrollGutterWidth.ts
- apps/web/src/custom/SidebarStageDitherArt.tsx
- apps/web/src/custom/assets/sidebar-brand-mark.png
- apps/web/src/custom/assets/sidebar-brand-mark.svg
- apps/web/src/custom/assets/sidebar-stage-dither-dev.png
shadows: []
watch:
Expand Down
30 changes: 26 additions & 4 deletions apps/web/src/__fork_guards__/forkSidebarChrome.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,35 @@ describe("fork guard: fork-sidebar-chrome", () => {
expect(chrome).toMatch(/sidebar-brand[^"]*ml-auto/u);
expect(chrome).not.toContain("ml-[var(--workspace-titlebar-content-left)]");
expect(chrome).toMatch(/sidebar-brand[^"]*text-sidebar-foreground/u);
expect(chrome).toContain("size-6 shrink-0 [image-rendering:pixelated]");
expect(chrome).toContain("size-6 shrink-0");
Comment thread
NoahHendrickson marked this conversation as resolved.
expect(chrome).toContain("text-[0.875rem] leading-4 font-medium");
// The pixelated hack lived on the component, not the asset — a substring
// check on the class list would not notice it coming back beside it.
expect(chrome).not.toContain("image-rendering");
// The mark's art is a 23x23 pixel grid drawn at a 24px slot. A bitmap can
// only get there by resampling 23 cells onto 24 pixels, which blends every
// cell into its neighbours — the blur the vector mark replaced. Keep it
// vector, keep the viewBox on the 23-unit grid, and keep crispEdges so the
// cells stay hard-edged at every DPR instead of antialiasing back to mush.
const mark = NodeFS.readFileSync(
NodeURL.fileURLToPath(new URL("../custom/assets/sidebar-brand-mark.png", import.meta.url)),
NodeURL.fileURLToPath(new URL("../custom/assets/sidebar-brand-mark.svg", import.meta.url)),
"utf8",
);
expect(mark.readUInt32BE(16)).toBe(24);
expect(mark.readUInt32BE(20)).toBe(24);
expect(mark).toContain('viewBox="0 0 23 23"');
expect(mark).toContain('shape-rendering="crispEdges"');
expect(mark).not.toMatch(/image-rendering|<image\b/u);
// Every cell edge must land on the integer grid; a fractional coordinate is
// the same smearing defect re-entering through the asset. The count keeps
// the loop from passing vacuously, and the transform/<path> check pins the
// geometry to plain rect attributes — an svgo pass or Figma re-export that
// moves it into transforms or path data would otherwise hide fractional
// coordinates from this guard entirely.
const coords = [...mark.matchAll(/\s(?:x|y|width|height)="([^"]+)"/gu)];
expect(coords.length).toBeGreaterThan(100);
for (const coord of coords) {
expect(coord[1]).toMatch(/^\d+$/u);
}
expect(mark).not.toMatch(/transform=|<path\b/u);
});

it("keeps the flat header independent of identification mode and honors the pill", () => {
Expand Down
16 changes: 9 additions & 7 deletions apps/web/src/components/sidebar/SidebarChrome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from "../SidebarStageBackdrop";
import { Badge } from "../ui/badge";
/* fork:begin fork-sidebar-chrome — see .fork/customizations.yaml#fork-sidebar-chrome */
import sidebarBrandMarkUrl from "~/custom/assets/sidebar-brand-mark.png";
import sidebarBrandMarkUrl from "~/custom/assets/sidebar-brand-mark.svg";
/* fork:end fork-sidebar-chrome */
import {
SidebarFooter,
Expand Down Expand Up @@ -92,12 +92,14 @@ function SidebarBrand() {
{/* fork:begin fork-app-identity — see .fork/customizations.yaml#fork-app-identity
The borrowed T3 wordmark stays gone. The fork's own exported mark and
APP_BASE_NAME form the exact 24px / 4px / 14px lockup from the design,
while the injected desktop name and bridge-less fallback still agree. */}
<img
alt=""
className="size-6 shrink-0 [image-rendering:pixelated]"
src={sidebarBrandMarkUrl}
/>
while the injected desktop name and bridge-less fallback still agree.
The mark is vector: its art is a 23x23 pixel grid, which no bitmap can
resample into a 24px box without smearing every cell. crispEdges lives
in the asset, so cells stay hard-edged at every DPR. The 23-into-24 fit
still renders the center row and column of cells 2px at DPR 1 — one
heavy line, accepted over either blurring all of them or drawing the
art at 23px, which centers on a half-pixel. */}
<img alt="" className="size-6 shrink-0" src={sidebarBrandMarkUrl} />
Comment thread
NoahHendrickson marked this conversation as resolved.
<span className="truncate text-[0.875rem] leading-4 font-medium">{APP_BASE_NAME}</span>
{/* fork:end fork-app-identity */}
</Link>
Expand Down
Binary file removed apps/web/src/custom/assets/sidebar-brand-mark.png
Binary file not shown.
11 changes: 11 additions & 0 deletions apps/web/src/custom/assets/sidebar-brand-mark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading