diff --git a/AMICODE-PATCHES.md b/AMICODE-PATCHES.md index 0834bb663e..0a839a745e 100644 --- a/AMICODE-PATCHES.md +++ b/AMICODE-PATCHES.md @@ -245,3 +245,16 @@ Rebuilt with the exact T3 recipe (`OPENCODE_VERSION=1.17.3 bun run script/build. reuses any server on port 3000 (`reuseExistingServer`) — run with `PLAYWRIGHT_PORT=` if something else (e.g. the harmoniqs website dev server) holds 3000. - Checks: `tsgo -b` clean; `bun run test:unit` 376 pass / 0 fail. + +15. (mark drift fix, synced to amicode PR #99 final) — amicode: consolidated the fork's brand mark to ONE geometry, matching amicode's redesigned mark. The "kept in sync manually" cross-repo promise from patch #8 had already silently failed. + +- Trigger: amicode's mark was redesigned (PR #99) without a corresponding update here — the fork still rendered the OLD "digi" pixel-accented H-robot everywhere. PR #99 went through several iterations before landing on its final geometry; this entry tracks that FINAL state (square viewBox `0 0 3600 3600`), not the intermediate "hackathon mark" (viewBox `116 287 3377 3035`) an earlier draft of this fork PR had copied — that intermediate geometry is now itself stale and was replaced here. +- Two copies of near-identical geometry lived in THIS repo (logo.tsx's `Robot` used by `Mark`/`Splash`, and spinner.tsx's `AmicoSpinner`), plus a third in favicon/amico.svg. Consolidated to a single `MARK_PATH` exported from logo.tsx. +- Geometry now mirrors amicode PR #99's two authored SVGs (amicode:`packages/extension/media/amico{,_reduced}.svg`), both square `0 0 3600 3600`: + - `MARK_PATH` = amico_reduced.svg's outer-bracket path (fill-rule evenodd screen knockout). Used by `Mark`, `Splash`, `AmicoSpinner`, and mirrored as a literal in favicon/amico.svg — every SMALL context, matching amicode's own "small → reduced" rule. + - `MarkDetailed` = amico.svg's full detailed mark (bracket path + internal circuit-pattern rects/polygons). Used ONLY by the Meet Amico home card (`w-12`/48px), large enough for the detail to resolve. + - `Mark`/`Splash`/`MarkDetailed` viewBox `0 0 64 56`/`116 287 3377 3035` → `0 0 3600 3600`; logo.css aspect-ratio `8/7` → `1/1` (the mark is square now). +- Still theme-adaptive via currentColor + var(--icon-strong-base) — this is a live webview DOM, so currentColor resolves (unlike amicode's native VS Code tab icon, which needs committed {light,dark} files; see amicode PR #99). +- NOT a re-established cross-repo sync promise — `MARK_PATH` is the single source of truth WITHIN this repo; it happens to match amicode's current geometry, kept aligned by hand when the mark changes. +- Tests: ui `bun test src/amicode` green; typecheck green ui + app. +- NOT done this round: full native `bun run script/build.ts` compile + vendored-binary swap — this patch only touches the embedded web UI. Deferred to the next amicode.N release tag, same split as patches #8/#11. diff --git a/packages/app/src/components/session/session-new-design-view.tsx b/packages/app/src/components/session/session-new-design-view.tsx index 5cb67750e6..aa9bbb621c 100644 --- a/packages/app/src/components/session/session-new-design-view.tsx +++ b/packages/app/src/components/session/session-new-design-view.tsx @@ -1,17 +1,18 @@ import { Show, type JSX } from "solid-js" -import { Logo, Mark } from "@opencode-ai/ui/logo" +import { Logo, MarkDetailed } from "@opencode-ai/ui/logo" import { NEW_SESSION_CONTENT_WIDTH } from "@/pages/session/new-session-layout" // amicode: new-session start screen, top→bottom — H-bot mark (hero), the AMICODE // wordmark, tagline + how-it-works + starter chips, then the composer. Sizing // mirrors the classic NewSessionView (Mark w-36 / Logo w-72); keeps the session // tabs and centered composer. The chips are the one-tap path to the next task. +// The hero uses the DETAILED mark (144px, well above where the accents resolve). export function NewSessionDesignView(props: { children: JSX.Element; gettingStarted?: JSX.Element }) { return (
- +
{props.gettingStarted}
diff --git a/packages/app/src/components/session/session-new-view.tsx b/packages/app/src/components/session/session-new-view.tsx index b70f8fb9ab..b0df2b278d 100644 --- a/packages/app/src/components/session/session-new-view.tsx +++ b/packages/app/src/components/session/session-new-view.tsx @@ -10,7 +10,7 @@ import { amicodeGet } from "@/utils/amicode-fetch" import { parseProblemsResponse } from "@opencode-ai/ui/amicode-problem-switcher" import { Icon } from "@opencode-ai/ui/icon" import { AmicodeGettingStarted } from "@opencode-ai/ui/amicode-getting-started" -import { Mark } from "@opencode-ai/ui/logo" +import { MarkDetailed } from "@opencode-ai/ui/logo" import { getDirectory, getFilename } from "@opencode-ai/core/util/path" const MAIN_WORKTREE = "main" @@ -78,7 +78,7 @@ export function NewSessionView(props: NewSessionViewProps) {
- + {/* amicode: straight wordmark (the Logo's Racing Sans One face reads as italic); byline keeps the brand attribution. */}
void }) { data-slot="amicode-meet-identity" style={{ display: "flex", gap: "12px", "align-items": "center", "margin-top": "10px" }} > - +
Amico
diff --git a/packages/ui/src/amicode/onboarding-wizard.tsx b/packages/ui/src/amicode/onboarding-wizard.tsx index bf36a0bdbc..cc8b7c298b 100644 --- a/packages/ui/src/amicode/onboarding-wizard.tsx +++ b/packages/ui/src/amicode/onboarding-wizard.tsx @@ -1,5 +1,5 @@ import { For, Show, createSignal, onCleanup } from "solid-js" -import { Mark } from "../components/logo" +import { Mark, MarkDetailed } from "../components/logo" import { institutionLogoUrl, suggestInstitutions, @@ -236,7 +236,7 @@ export function AmicodeOnboardingWizard(props: { padding: "14px 0 4px", }} > - +
Welcome to Amicode diff --git a/packages/ui/src/amicode/run-card.tsx b/packages/ui/src/amicode/run-card.tsx index 38f74daa56..d7e9c22f82 100644 --- a/packages/ui/src/amicode/run-card.tsx +++ b/packages/ui/src/amicode/run-card.tsx @@ -6,6 +6,12 @@ // trading card, not UI panel. Pure string-SVG so the same markup drives both // the in-app gallery (innerHTML) and the PNG export (SVG → Image → canvas). +// The mark geometry lives in ONE place — logo.tsx's MARK_PATH (a plain string +// const). Importing it here keeps this card from drifting into a private copy +// of the glyph, which is what this consolidation fixes. The mark is square +// (viewBox 0 0 3600 3600). +import { MARK_PATH } from "../components/logo" + export type RunCardData = { slug: string problem: string @@ -129,14 +135,13 @@ export function renderRunCardSvg(d: RunCardData): string { } } - const MARK = "M2 2h16v14h28V2h16v52H46V40H18v14H2Z M9 19h46v18H9Z" const mono = "ui-monospace, SFMono-Regular, Menlo, monospace" const sans = "-apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif" return ` - + AMICODE SOLVED PULSE diff --git a/packages/ui/src/amicode/spinner.tsx b/packages/ui/src/amicode/spinner.tsx index eac03cab83..a836b2d1f1 100644 --- a/packages/ui/src/amicode/spinner.tsx +++ b/packages/ui/src/amicode/spinner.tsx @@ -1,4 +1,5 @@ import { type ComponentProps } from "solid-js" +import { MARK_PATH } from "../components/logo" // AMICODE: working/thinking spinner — the Harmoniqs H-robot silhouette as a // small monochrome glyph (H body with the screen slit knocked out via @@ -10,6 +11,12 @@ import { type ComponentProps } from "solid-js" // matches the stock spinner's own animation language. prefers-reduced-motion: // static glyph, no animation (matchMedia guard; inline animations don't // inherit the CSS-file media-query pattern used elsewhere). +// +// Path comes from logo.tsx's MARK_PATH (Mark/Splash now render the same +// glyph) instead of its own copy — this file used to carry an independent +// literal that happened to already match Mark/Splash's silhouette variant; +// consolidated so there's one geometry in this repo, not a second one that +// could quietly drift the way Mark/Splash's OWN old copy did. const reducedMotion = () => typeof window !== "undefined" && !!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches @@ -22,7 +29,7 @@ export function AmicoSpinner(props: { return ( - - - - - - - - - - - - - - - - - - - - + + + + diff --git a/packages/ui/src/components/logo.css b/packages/ui/src/components/logo.css index 6891ec3d64..1eaa2eba8d 100644 --- a/packages/ui/src/components/logo.css +++ b/packages/ui/src/components/logo.css @@ -1,4 +1,4 @@ [data-component="logo-mark"] { width: 16px; - aspect-ratio: 8/7; + aspect-ratio: 1/1; /* mark viewBox is square (0 0 3600 3600) */ } diff --git a/packages/ui/src/components/logo.tsx b/packages/ui/src/components/logo.tsx index 8250cdad1c..f0d1b7b5a5 100644 --- a/packages/ui/src/components/logo.tsx +++ b/packages/ui/src/components/logo.tsx @@ -1,48 +1,35 @@ import { type ComponentProps } from "solid-js" -// AMICODE branding v2: Mark/Splash render the "digi" Harmoniqs H-robot -// (canonical source also lives at amicode:packages/extension/media/amico.svg, -// kept in sync manually); Logo renders the AMICODE wordmark. Component names, -// props, and data-component hooks are kept identical to stock. The robot body -// follows currentColor; the display rect + glyphs are fixed brand colors. -// viewBox is 64:56 (8:7, not square) — see logo.css aspect-ratio. +// AMICODE branding: Mark/Splash render the Harmoniqs H-robot mark; Logo +// renders the AMICODE wordmark. Component names, props, and data-component +// hooks are kept identical to stock. The mark is square (viewBox 0 0 3600 +// 3600) — see logo.css aspect-ratio 1/1. +// +// Geometry mirrors amicode PR #99's two authored SVGs (amicode: +// packages/extension/media/amico{,_reduced}.svg), both square 0 0 3600 3600: +// MARK_PATH → amico_reduced.svg — the outer bracket (fill-rule evenodd +// knocks out the screen). The SMALL-size mark: Mark, Splash, +// AmicoSpinner (../amicode/spinner.tsx, imports MARK_PATH), +// and favicon/amico.svg (mirrors it as a literal — a static +// SVG can't import a TS module; keep its +// byte-identical to this constant). +// MarkDetailed → amico.svg — the full mark WITH the internal circuit-pattern +// accents, for LARGE contexts only (the Meet Amico card). +// This matches amicode's own "small → reduced, large → detailed" split, so +// the fork and the extension render the same brand mark. MARK_PATH is the +// single source of truth for the glyph within this repo; it is kept aligned +// with amicode's geometry by hand when the mark changes (no build-time link). +export const MARK_PATH = + "M2279.19,374.09v622.56h-958.38V374.09H202.07v2851.83h1118.74v-520.15h958.38v520.15h1118.74V374.09h-1118.74ZM3165.55,2523.71H478.91v-1338.38h2686.65v1338.38Z" -const Robot = () => ( - <> - - - - - - - - - - - - - - - - - - - - - - - - - - -) +const Robot = () => export const Mark = (props: { class?: string }) => { return ( @@ -57,7 +44,7 @@ export const Splash = (props: Pick, "ref" | "class">) => { ref={props.ref} data-component="logo-splash" classList={{ [props.class ?? ""]: !!props.class }} - viewBox="0 0 64 56" + viewBox="0 0 3600 3600" xmlns="http://www.w3.org/2000/svg" style={{ color: "var(--icon-strong-base)" }} > @@ -66,6 +53,47 @@ export const Splash = (props: Pick, "ref" | "class">) => { ) } +// Detailed mark (amicode PR #99's amico.svg) — the full H-robot WITH the +// internal circuit-pattern accents, used ONLY where it renders large enough to +// resolve (the Meet Amico card, ~48px). currentColor + var(--icon-strong-base), +// same convention as Mark/Splash, so it stays theme-adaptive here — unlike +// amicode's native VS Code chat-tab icon, which needs committed light/dark SVG +// files because a native tab icon has no live CSS context for currentColor. +// Geometry mirrors amicode:packages/extension/media/amico.svg (viewBox +// 0 0 3600 3600); keep in sync by hand if that mark changes. +export const MarkDetailed = (props: { class?: string }) => { + return ( + + + + + + + + + + + + + + + + + + + + + + ) +} + export const Logo = (props: { class?: string }) => { return (