PRODUCT NOTE / PLATFORM PRD
個人開発者 nzw のポートフォリオ兼 AI プラットフォーム。
この文書は、このサイトそのものをなぜ・誰のために・どんな思想で作っているかから記録した開発ノートです。
| ステータス | Active(継続運用・開発中) |
|---|---|
| ドメイン | nzw.jp(姉妹サイト zerohalf.jp と別ドメインで共存) |
| 運営 | nzw(Hidekazu Nozawa) — PM × 作家 × バイブコーダー |
| 載せているもの | 技術書 / モバイルアプリ / Web ゲーム / AI ツール / 開発ノート / グッズ |
| 最終更新 | 2026-08-15 |
| 技術構成 | FastAPI ・ Tailwind ・ Canvas ・ Flutter Web ・ Nginx ・ EC2 / Docker |
| 関連リンク | トップ ・ About(運営者) ・ グッズ ・ 開発ノート一覧 |
nzw.jp は、1 人の開発者がつくるアプリ・ゲーム・AI ツール・技術書・開発ノートを一元公開する場です。単なる作品展示場ではなく、「AI に任せる」ではなく「AI を使うことで、あなた自身が強くなる」という設計思想(zerohalf ミッション)を体現するプラットフォームを目指しています。
土台にあるのは zerohalf のミッション「AI が全てできる時代に、人間としての価値を育てる」。
そこで、理論(本)・実証(プロダクト)・記録(開発ノート)をひとつの場で束ねて見せるプラットフォームとして nzw.jp を運営している。
「PM × 作家 × バイブコーダー」を 1 人で横断する交差点そのものが参入障壁。汎用 AI が持てない「偏愛」と「積み重ねた文脈」で勝負する。
「思想とプロダクトが結びついて届く」状態かを見る。指標は仮置き
トップページには、ときどきブラックホールが現れて画面上をゆっくり横切る。Synapse Link の敵役をそのまま連れてきたもので、タップするとそのゲームが開く。絵の中身(6 層の重ね方・配色・脈動)は Synapse Link の開発ノートに書いたので、ここではサイトに載せるためにやったことを残す。
原典は Flutter の BlackHoleRenderer.draw()。層の順番・係数・色は一切変えず、API だけ差し替えた。数値を触らないと決めたので、見比べても違いが分からない状態を保てている。
| Flutter | Canvas 2D | 注意した点 |
|---|---|---|
| ui.Gradient.radial | ctx.createRadialGradient() | 停止位置の配列をそのまま addColorStop に写す |
| MaskFilter.blur | ctx.filter = 'blur(7px)' | 未対応環境があるので起動時に一度だけ判定し、駄目なら素の輪郭で描く |
| BlendMode.plus | globalCompositeOperation = 'lighter' | 降着円盤だけに掛け、save/restore で確実に戻す |
| HSLColor.fromAHSL | hsla(...) 文字列 | 色相は 0〜360 に丸めてから渡す |
| Color.lerp | 自前の lerpColor() | 危険度による紫 → 赤 → 金の補間で使う |
| 1 フレーム = 60fps 前提 | step = dt ÷ (1/60) | 原典の += 0.02 にこの係数を掛け、高リフレッシュレートでも速くならないようにした |
ゲーム内では重力計算で動くが、サイトには引き合う相手がいない。そこで移動だけを別に書いた。まっすぐ飛ばすと単なるスクリーンセーバーになるので、気まぐれさを足している。
当初は夜だけ必ず出していたが、必ず居るものは背景の一部になってしまう。朝・昼・夕は 3 回に 1 回、夜は 2 回に 1 回の抽選に変えた。大きさも blackHoleSizes の tiny / small / medium から等確率で引くので、出会えた日と、出会えた大きさが毎回違う。速度は原典の表どおり大きいほど遅く、tiny は 36px/秒、medium は 12px/秒。
ずっと手前にいると邪魔になり、ずっと奥だとほぼ見えない。そこで z-index を往復させている。
負の z-index は body の背景より上・コンテンツより下に入る。だから奥に回しても消えず、半透明のカード越しにぼんやり透ける。
z-index は補間できないので、0.45 秒かけて不透明度 0.08 まで落とし、いちばん薄いところで層を差し替えてから戻す。層が飛ぶ瞬間が見えない。pointer-events: none にし、本体に追従する丸いボタンだけを transform: translate3d() で毎フレーム動かす。全面を当たり判定にするとページ全体が操作不能になる。setTransform(dpr, 0, 0, dpr, 0, 0) で高精細に描きつつ、3 倍以上の端末で無駄に重くしない。visibilitychange でループを止め、戻ったときは前回時刻をリセットする。これを忘れると復帰の 1 フレームで大きく瞬間移動する(dt にも 0.05 秒の上限を置いた)。MutationObserver で監視するので、AUTO・手動・ランダムのどれでテーマが変わっても追従する。prefers-reduced-motion のときはキャンバスを非表示にし、スクリプト自体を起動しない。踏んだ罠 classList.remove() は消す対象が無くても class 属性を書き直す。後片付けを毎回無条件に呼んだ結果、MutationObserver → 後片付け → 属性の書き換え → MutationObserver …… とマイクロタスクが循環し、ページが完全に固まった。動作中かどうかのフラグを見て、必要なときだけ片付けるようにして解決。
サイトを支える判断を、決定・仮説・結果の 3 点で残す。
blackHoleSizes から tiny / small / medium を等確率で引き、速度は表どおり大きいほど遅くする。さらに z-index を 30 と -1 で往復させ、コンテンツの前後を行き来させた。classList.remove() が属性を無条件に書き直すことに起因する MutationObserver の無限ループを検出でき、公開前に潰せた。/goods/ を新設し、トップのヒーローと Labs & Prototypes の両方から導線を張った。EC・カート・価格表示は一切作らず、ステータスは「試作 / 構想」の 2 段階だけを持たせている。配布・販売の可能性は残すが、決まるまでは「未定」と明記する。.goods-card)を複製するだけで追加できる形に落ち着いた。販売を始める場合も、ステータスを差し替えて導線を足すだけで移行できる。/v1/content-cards API から公開中のものを動的注入。API 停止時は静かにスキップして静的閲覧を維持する。--nzw-* トークンに集約し、フレームワーク非依存の CSS で全ページ共通化した。Synapse Link の描画をトップページへ移植し徘徊させる/出現を時間帯ごとの抽選に変更/コンテンツの前後を天気に応じて往復
各プロダクトの Product Note(PRD / 設計ノート)を整備・公開
design-system.css で配色・トーンを標準化
『チームに溶け込む AI エージェント開発』を公開
Engly / DayGrid / LangBridge / Synapse Link を順次リリース、Flutter Web を同一オリジンに統合
FastAPI + 静的 HTML + DB コンテンツカードのハイブリッドとして運用開始
未決事項:MISSION(zerohalf 名義)と VISION(nzw.jp 名義)の主語の整理、B2B 導線の設計。