TATSUYA HORIKAWA
July 6, 2026·Engineering·6 min read

「AIが作った風」のデザインから抜け出す — このサイトを計器盤に作り替えた記録

クリーム地にセリフ体、中央寄せ、角丸カード。生成AIに任せると出てくる「どこかで見た見た目」を捨て、このポートフォリオに固有のデザインを与えるまで。トークンの一点書き換えで全ページを揃える方法と、夜モードで本文が消えたバグの話。

「AIが作った風」のデザインから抜け出す — このサイトを計器盤に作り替えた記録

このサイトは、少し前まで「生成AIに作らせたまま」の見た目をしていた。 クリーム色の背景に上品なセリフ体、ふわっとした角丸カード、なんとなく中央寄せ。 悪くはない。悪くはないのだが、どこかで見たことがある

問題は、それが自分のサイトに見えないことだった。誰のポートフォリオに置いても 成立してしまう匿名性。せっかく自分でコードを書けるのに、 「AIのデフォルト」をそのまま公開している状態がずっと気になっていた。

なので一度、デザインを一から作り替えた。この記事は、その作業で使った考え方と、 途中で踏んだ技術的な罠の記録だ。

まず「何がAIっぽいのか」を言語化する

抜け出すには、まず敵の輪郭をはっきりさせる必要がある。 いま生成AIが吐くデザインは、いくつかの型に集中している。

  • 温かいクリーム色(#F4F1EA あたり)にセリフ見出し、アクセントはテラコッタ
  • ほぼ黒の背景に、差し色でアシッドグリーンかバーミリオンを一点
  • InterSpace Grotesk を「無難だから」で選ぶ
  • 見出しの前に絵文字、要素はとりあえず中央寄せ、カードは全部 rounded-lg

自分のサイトは、見事にこの一つ目のど真ん中にいた。 「無難で上品」は、量産されると匿名になる。 ここを起点にすると決めた。

アイデンティティを一つに絞る

新しい方向は「エンジニアド・エディトリアル(計器盤)」と名付けた。 図面や計測機器の質感を、読み物の骨格に持ち込む。抽象的な気分で決めず、 色・書体・素材の三つを具体的な値まで落とす。

  • 配色:骨のような生成り(bone #E7E3D8)/インク(#15130F)/コバルト(#2B39D6)の3色
  • 書体:見出しは Bricolage Grotesque、ラベルと数値は JetBrains Mono、日本語本文は Zen Kaku Gothic New
  • 素材:座標表記、四隅のトンボ(レジストレーションマーク)、ヘアライン、方眼のブループリント背景

ポイントは、装飾を「気分」ではなく意味のある構造として使うこと。 座標もトンボも罫線も、図面という世界観から借りてきた語彙で統一する。 番号や記号を飾りで足さない。

トークンを一点だけ書き換えて全ページに波及させる

配色と書体を決めても、それを全ページに手で反映するのは骨が折れる。 このサイトは既に多くの箇所で font-serif(旧デザインのセリフ体)を使っていた。 これを一つずつ書き換えるのは事故のもとだ。

そこで、クラスには触らず Tailwind のトークンの向き先だけを変えた。

// tailwind.config.ts
fontFamily: {
  // serif トークンの実体を Bricolage に差し替える。
  // 既存の font-serif が全ページで自動的に新書体を採用する。
  serif: ["var(--font-bricolage)", "var(--font-zen-kaku)", "sans-serif"],
}

font-serif という名前は残したまま、指す先だけを新書体にする。 これで、ブログ・プロダクト・問い合わせ・404 まで、一箇所の変更が全ページに波及する。 命名を過去に縛られず、実体を差し替えるだけで足りる場面は意外と多い。

「昼夜で色が反転する」を透明度ごと成立させる

記事ページには昼/夜の切り替えを付けた。ここで一番大きな罠を踏んだ。

夜モードにすると、本文が完全に消えた。 背景だけ暗くなり、文字が見えない。 コントラスト比を測ると 1.00。真っ黒の上に真っ黒を書いていた。

原因はトークンの持ち方だった。背景色は CSS 変数(夜で反転する)で塗っていたのに、 本文は Tailwind の text-text/85 を使っていて、この色トークンが固定の16進数だった。 背景だけ夜色に変わり、文字はインクのまま——だから消えた。

直し方は、色トークンを RGB チャンネルの変数にして、透明度指定ごと反転させること。

:root {
  --rgb-text: 21 19 15;        /* インク */
}
html[data-reading="night"] {
  --rgb-text: 231 227 216;     /* 夜は骨色に反転 */
}
// tailwind.config.ts — <alpha-value> を使うと /85 などの不透明度が生きる
colors: {
  text: "rgb(var(--rgb-text) / <alpha-value>)",
}

こうすると text-text/85rgb(var(--rgb-text) / 0.85) に展開され、 昼は骨の上のインク、夜は闇の上の骨色に、透明度を保ったまま反転する。 副産物として、記事だけのつもりだった夜モードがサイト全体で破綻しなくなり、 そのまま一貫したダークテーマに昇格した。本文のコントラストは 14.5:1 まで戻った。

「動いて見える」を疑う

このバグは、ビルドを通しただけでは絶対に見つからない。 next build は緑で通る。型も構文も正しい。それでも本文は見えていなかった。

同じ作業でもう一つ、コードのシンタックスハイライトが昼モードだけ無色になる罠も踏んだ。 Shiki の色変数のうち夜用(--shiki-dark)にしか CSS を当てておらず、 昼はトークンが全部同じ黒だった。これも画面では気づきにくい。

結局どちらも、実際にブラウザで開いて、色の数とコントラスト比を測って初めて分かった。 「ビルドが通った=完成」ではない。完了と言う前に、対象を一度は本当に動かす。 これは AI と組んで開発するときにも、そのまま効くルールだった。

まとめ

  • 抜け出す前に「何がAIっぽいのか」を型として言語化する
  • アイデンティティは気分でなく、色・書体・素材の具体値まで落とす
  • 命名は残して実体(トークン)だけ差し替えると、一点の変更が全ページに波及する
  • 色は16進数で固定せず RGB チャンネル変数にすると、透明度ごとテーマを反転できる
  • ビルドの緑を信じない。色数とコントラストは測って確かめる

固有のデザインは、奇抜さではなく一貫した制約から立ち上がる。 そして一貫性は、手作業の徹底ではなく、変数の設計で担保するのが一番強い。

Thanks for reading.

読んでくれてありがとう。感想や反論、どちらも歓迎します。

SharePost