mcpField
V
visual-redesign

visual-redesign

github.com/yu-369デザイン・UI99245 回インストール12 週間前に更新
リポジトリ

visual-redesign について

既存の React、HTML、CSS の画面を、アプリの動作を保ちながら視覚的に整えるスキルです。コードを監査してから CSS を中心に変更し、JavaScript のロジックや動作中の JSX 構造には手を加えません。

主な機能

  1. 01ファイルを監査しロジックと表示を分類
  2. 02状態、ハンドラー、API 呼び出しを維持
  3. 03具体的な視覚上の問題を特定
  4. 04既存のデザイントークンとスタイルを抽出
  5. 05動作中の JSX 構造を変更せずに調整

活用シーン

  1. 01既存の React 画面の見た目を更新
  2. 02業務ロジックを変えずにページを改善
  3. 03デザイン変更前にコードベースを監査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/yu-369/vibecurb --skill visual-redesign

インストール後、Claude Code で/visual-redesignを入力して読み込まれたか確認します。

詳細

ビジュアルの再設計:見た目を磨き上げる

ユーザーが既存の React/HTML/CSS コードを提示し、見た目の改善、デザインのアップグレード、美観の向上、プレミアム感の演出、Awwwards のような雰囲気の実現、あるいは「動くけれど見た目がひどい」といった要望をしたときに、このスキルが起動します。ユーザーのコードは機能しています。状態管理、API 呼び出し、イベントハンドラー、ビジネスロジックはすでに動作しています。あなたの仕事は、それらを壊さずにビジュアルレイヤーをアップグレードすることです。あなたは外科医であり、解体業者ではありません。正確に切り込み、患者を生かしたままにしてください。


絶対のルール — 最初に読むこと

JavaScript のロジックは神聖です。絶対に触れてはいけません。

これは、このスキルのあらゆる行に適用される、譲れない、破ることのできないルールです。

SACRED (never modify):
  ├── useState / useReducer declarations and updates
  ├── useEffect / useCallback / useMemo bodies
  ├── API calls (fetch, axios, SWR, React Query)
  ├── Event handler LOGIC (what happens onClick, not how the button looks)
  ├── Conditional rendering logic (ternaries, && chains, if blocks)
  ├── Router/navigation logic
  ├── Form validation logic
  ├── Context providers and consumers
  ├── Custom hook implementations
  ├── Data transformations (map, filter, reduce on data)
  ├── Error handling (try/catch, error boundaries)
  ├── Prop drilling / prop interfaces
  └── Third-party library integration logic

SLOP (upgrade aggressively):
  ├── className strings and CSS classes
  ├── Inline styles (style={{...}})
  ├── CSS/SCSS files
  ├── Tailwind utility classes
  ├── Bootstrap classes
  ├── Color values (hex, rgb, hsl)
  ├── Font families and sizes
  ├── Spacing values (padding, margin, gap)
  ├── Border-radius values
  ├── Shadow values
  ├── Transition/animation declarations
  ├── z-index values
  ├── Layout structure (flex/grid configuration)
  └── Wrapper div nesting (for layout, NOT for conditional logic)

⚠ 逸脱への警告: AI が「アプリを壊す」最大の原因は、見た目をすっきりさせようと JSX を再構成し、その結果、条件付きラッパーを誤って削除したり、key prop を移動したり、ref の割り当てを変更したり、DOM 上の位置に依存する子要素の順序を入れ替えたりすることです。既存の構造が機能しているなら、見た目のために JSX を再構成してはいけません。既存の構造に CSS を追加してください。CSS の好みに合わせて構造を作り変えてはいけません。

→ グレーゾーン

ロジックとスタイルの両方に関わる要素もあります。細心の注意を払って扱ってください。

要素絶対に触れてはいけないもの? それとも余計なもの?ルール
className={isActive ? 'active' : ''}両方 — ロジックは神聖ですが、クラス名は余計なものです三項演算子はそのままにします。クラス名の値だけを変更します:className={isActive ? 'nav-link--active' : 'nav-link'}
style={{ display: isOpen ? 'block' : 'none' }}神聖 — これは条件付き表示のロジックですCSS クラスに置き換えてはいけません。インラインスタイルは状態によって制御されています。そのまま残し、並行してスタイルを追加してください
{items.map((item) => <Card key={item.id} ... />)}神聖 — map、key、データフローはロジックですCard コンポーネントの内部にスタイルを適用してください。map の構造や key の割り当ては変更してはいけません
ref={containerRef}神聖 — ref の割り当ては JavaScript の動作を制御しますref を削除、移動、改名してはいけません
aria-* 属性神聖 — アクセシビリティ属性は機能の一部です削除してはいけません。不足している属性を追加することはできます
data-* 属性おそらく神聖 — JavaScript やテストで使われることがよくあります未使用と確認できない限り、削除してはいけません
id 属性おそらく神聖 — JavaScript のセレクターで使われている可能性があります未使用と確認できない限り、変更してはいけません
onClick={() => setOpen(!open)}神聖 — ハンドラーはロジックです要素にスタイルを適用してください。ハンドラーには触れてはいけません
条件付きコンテンツを囲む <div>神聖 — 描画上の理由から存在している可能性があります表示だけを目的としたものだと確認できない限り、「不要な」ラッパーの <div> を削除してはいけません

グレーゾーンの鉄則: あるものがロジックかスタイルか判断できない場合は、変更せず、並行してスタイルを追加してください。アプリを壊さない、多少洗練されていない CSS の解決策のほうが、バグを生む洗練されたリファクタリングより、はるかに優れています。


パイプライン

┌──────────────────────────────────────────────────────────────────────────┐
│                                                                          │
│   CODE IN ──→ Phase 1: Audit                                            │
│                 (read every file, classify Sacred vs Slop,              │
│                  identify the aesthetic crimes)                          │
│                                                                          │
│             ──→ Phase 2: Extraction                                     │
│                  (extract current design decisions across               │
│                   7 layers, build the Slop Sheet)                       │
│                                                                          │
│             ──→ Phase 3: Prescription                                   │
│                  (define target aesthetic, map every                    │
│                   slop item to its gold replacement)                    │
│                                                                          │
│             ──→ Phase 4: Surgery                                        │
│                  (execute replacements layer by layer:                  │
│                   tokens → typography → color → spacing →              │
│                   components → atmosphere → motion)                     │
│                                                                          │
│             ──→ Phase 5: Post-Op                                        │
│                  (verify nothing broke, visual diff,                    │
│                   responsive check, motion check)                       │
│                                                                          │
│   Each phase has a ✓ Quality Gate. Failing a gate blocks the next.     │
│                                                                          │
└──────────────────────────────────────────────────────────────────────────┘

フェーズ 1:監査

一文字でも変更する前に、コードベース全体を読みます。何があるのかを把握し、すべてを分類してください。

→ すべてのファイルを読み、監査テーブルに記入します
ファイル種類保護すべき要素問題のある要素リスクレベル
App.tsxルートコンポーネントルーターの設定、プロバイダー、グローバル状態ルートのclassName、グローバルなラッパースタイル低
Header.tsxUI コンポーネントナビゲーションの状態(モバイルメニューの切り替え)、認証状態すべてのclassName文字列、インラインスタイル、レイアウト中
Hero.tsxUI コンポーネントCTAのクリックハンドラー、アナリティクス呼び出しタイポグラフィ、色、余白、画像、レイアウト低
Features.tsxUI コンポーネントデータ配列、mapによる反復処理カードのスタイル、グリッドレイアウト、アイコン低
Dashboard.tsx複雑なコンポーネントすべての状態、エフェクト、API呼び出し、データ変換テーブルのスタイル、カードのスタイル、チャートのラッパースタイル高
Form.tsx複雑なコンポーネントバリデーション、送信処理、エラー処理、ref入力欄のスタイル、ボタンのスタイル、レイアウト高
index.cssスタイルシートなし(ただし重要なリセットが含まれている場合があります)すべて低

リスクレベル:

  • 低 - 大部分がプレゼンテーションです。大胆にスタイルを変更しても安全です。
  • 中 - ロジックとプレゼンテーションが混在しています。慎重にスタイルを変更し、その後テストしてください。
  • 高 - ロジックとプレゼンテーションが密接に絡み合っています。CSSクラスとスタイルのみ変更してください。変更のたびにテストしてください。
→ デザイン上の問題点を特定します

UIを確認し、見た目の問題をすべて記録してください。具体的に記述します。「見た目が悪い」だけでは診断になりません。

問題点場所深刻度例
汎用的なフォントスタックグローバル/body重大font-family: Arial, sans-serif またはブラウザーのデフォルト
デフォルトの影カード、ボタン大box-shadow: 0 2px 4px rgba(0,0,0,0.1) - Bootstrapのデフォルト
真っ白な背景に真っ黒な文字全体大color: #000; background: #fff - 温かみがなく、コントラストが強すぎます
余白の不統一セクション間大あるセクションのmargin-top: 20pxに対し、次のセクションはmargin-top: 50px
Bootstrapブルーのアクセントカラーボタン、リンク重大#0d6efd - 「デザインしていません」という印象を最も強く与える色
汎用的な角丸カード、ボタン中どこもborder-radius: 4pxで、角丸の使い分けがありません
表示時のアニメーションがないページ読み込み時中要素が静的で生気なく、ただ表示されます
ホバー状態がないボタン、カード、リンク大インタラクティブな要素から何のフィードバックもありません
パディングが窮屈カード、セクション大ゆとりを持たせるのに32px必要なカードのpadding: 16px
背景に雰囲気がない背景中単調なbackground: whiteまたはbackground: #f5f5f5で、奥行きがありません
角丸の使い分けが不統一コンポーネント全体中ボタンはrounded-full、カードは理由もなくrounded-smです
見出しに本文用フォントを使用H1-H3重大Inter/Roboto/Arialをfont-size: 24pxで使い、ディスプレイ見出しのように見せています
視覚的な階層がないコンテンツセクション大すべてが同じサイズ、太さ、色です
余白のシステムがないレイアウト大パターンもなく、mt-4、mt-6、mt-3をランダムに使用しています
→ 監査の概要を出力します

見つかった問題を3~5行で述べてください。

「監査の概要:8つのコンポーネントで構成されるReact SPAです。ルーター、認証状態、3つのAPI呼び出しは保護対象で、すべてDashboard.tsxとHeader.tsxにあります。ビジュアルレイヤー全体でBootstrap 5のデフォルトが使われています。#0d6efdの青いアクセントカラー、デフォルトの影、Arialのフォントスタック、すべてに適用された4pxの角丸、ホバー状態なし、表示時のアニメーションなし、カードの窮屈な16pxのパディング、真っ白な背景に真っ黒な文字が見られます。デザインシステムがなく、余白と色がコンポーネントごとに場当たり的です。問題の推定数:重大14件、大23件。全体のリスクは中、Dashboard.tsx(複雑な状態管理とテーブル描画)は高です。」

✓ 品質ゲート:監査

フェーズ 2 に進む前に、以下を確認してください:

  • すべてのファイルを読み込み、監査テーブルで分類している
  • すべてのファイルで、変更してはならない要素を特定している
  • ファイルごとにリスクレベルを割り当てている
  • デザイン上の問題を具体例とともに記録している
  • 監査の概要を作成している
  • 高リスク(JavaScript のロジックが多い)のファイルを把握している
  • コードをまだ一切変更していない

フェーズ 2:抽出

7 つのレイヤーにわたって、現在のデザイン上の決定事項を抽出します。これにより、「変更前」のスナップショットである Slop Sheet を作成します。

→ レイヤー 1:トークン(色、フォント、スペーシングスケール)
トークン現在の値(Slop)ソース
プライマリ背景#ffffff または whiteindex.css / インライン
セカンダリ背景#f5f5f5 または #f8f9faBootstrap gray-100
プライマリテキスト#000000 または #212529Bootstrap のデフォルト
セカンダリテキスト#6c757dBootstrap gray-600
アクセント/プライマリアクション#0d6efdBootstrap primary
アクセントのホバー時#0b5ed7Bootstrap primary hover
危険/エラー#dc3545Bootstrap danger
成功#198754Bootstrap success
枠線の色#dee2e6Bootstrap gray-300
表示用フォントsystem-ui または Arialブラウザーのデフォルト
本文フォント表示用フォントと同じ使い分けなし
等幅フォントなし未設定
基本スペーシングシステムなし(場当たり的)ランダムな px 値
デフォルトの角丸4px または 0.375remBootstrap のデフォルト
→ レイヤー 2:タイポグラフィ
要素現在の仕様(Slop)
H1font-size: 2rem; font-weight: bold; font-family: inherit
H2font-size: 1.5rem; font-weight: bold
H3font-size: 1.25rem; font-weight: bold
本文font-size: 1rem; line-height: 1.5
小さい文字/キャプションfont-size: 0.875rem
ボタンのテキストfont-size: 1rem; font-weight: 400
文字間隔未設定(ブラウザーのデフォルト:normal)
見出しの行の高さ1.2(Bootstrap のデフォルト。表示用としては広すぎる)
テキストの折り返し見出しに text-wrap: balance を設定していない
本文の最大幅なし(テキストが端から端まで続く)
→ レイヤー 3:スペーシング
測定項目現在の値(Slop)
セクションのパディング一貫性なし:py-3、py-4、py-5、ランダムな px 値
カードのパディングp-3(12px)または p-4(16px)。窮屈
グリッドの間隔gap-3(12px)または gap-4(16px)。狭い
見出しから本文までの間隔mb-2 または mb-3。狭すぎる
本文から CTA までの間隔mt-3。狭すぎる
ナビゲーションの高さpy-2(低く窮屈)または Bootstrap のデフォルトのナビゲーションの高さ
コンポーネントの間隔一貫したシステムなし。コンポーネントごとに異なる
→ レイヤー 4:色の使用方法
用途現在の値(Slop)問題
背景純粋な #fff または #f8f9fa単調で冷たく、温かみがない
テキスト純粋な #000 または #212529きつく、洗練されていない
アクセントBootstrap の #0d6efd「デザインされていない」印象が強い
枠線#dee2e6ありがちなグレー
影rgba(0,0,0,0.1)ありきたりで、差別化されていない
ホバー状態わずかに暗い色合い個性がない
アクティブ状態さらに暗い色合い機械的で、物理的な感触がない
エラーBootstrap の #dc3545ありきたりな赤
→ レイヤー 5:コンポーネント
コンポーネント現在の状態(Slop)
ボタンBootstrap の .btn.btn-primary。#0d6efd、角丸 4px、ありきたりなパディングで、ホバー時の物理的な感触がない
カード.card。1px solid #dee2e6、角丸 4px、デフォルトの影または影なし、窮屈なパディング
入力欄Bootstrap のフォームコントロール。枠線は #dee2e6、フォーカス時のグローなし、フローティングラベルなし
ナビゲーションBootstrap の navbar。情報量が多く、窮屈で、デフォルトのスタイル
テーブルBootstrap の .table。ゼブラストライプ、窮屈な行、洗練されていない
モーダルBootstrap のモーダル。ありきたりなオーバーレイで、表示時のアニメーションなし
バッジ/ピルBootstrap の .badge。小さく窮屈で、プライマリブルー
ドロップダウンBootstrap のドロップダウン。ありきたりな影で、アニメーションなし
→ レイヤー 6:雰囲気
プロパティ現在の状態(Slop)
背景のテクスチャなし - 単色でフラット
アンビエントグロー/グラデーションなし - 完全にフラット
粒子/ノイズなし
すりガラスなし
奥行きのシステムBootstrap のデフォルトのシャドウ、またはなし
視覚的な温かみゼロ - 冷たく無機質
→ レイヤー 7:モーション
プロパティ現在の状態(Slop)
ページ表示なし - 静的なマウントで、すべてが瞬時に表示される
スクロール時の表示なし - すべてがすぐに表示される
ホバー時のトランジションtransition: all 0.15s ease-in-out(Bootstrap のデフォルト)、またはなし
ページ遷移なし - 瞬時に切り替わる
マイクロインタラクションなし
読み込み状態スピナー、または「Loading...」のテキスト
イージングカーブCSS のキーワード ease-in-out、またはなし
✓ 品質ゲート:抽出

フェーズ 3 に進む前に、以下を確認してください。

  • 7 つの抽出レイヤーすべてに、コードベースから取得した実際の値が入力されている
  • 値は曖昧ではなく、具体的である(正確な 16 進数コード、正確な rem/px 値)
  • 現在の状態と目標の品質との差が把握できている
  • まだコードを一切変更していない

フェーズ 3:処方

フェーズ 2 で抽出した Slop の項目すべてについて、より優れた置き換えを処方します。これは変換マップ、つまり外科的な計画です。

→ トークンの処方
/* PRESCRIPTION: Design tokens - Slop → Gold
   WHY: Tokens are the foundation. Changing these first
   means every component that references them upgrades
   automatically. This is the highest-leverage change. */

:root {
  /* ── Colors ────────────────────────────────────── */

  /* Background: #ffffff → warm off-white
     WHY: Pure white is harsh and clinical. Off-white
     with a warm undertone feels premium and intentional.
     The difference is subtle but the eye registers it
     as "designed" vs "default." */
  --color-bg: #FAFAF9;        /* was: #ffffff */
  --color-surface: #FFFFFF;    /* was: #f8f9fa - cards sit ON the bg */
  --color-surface-2: #F5F4F2;  /* was: none - for alternating sections */

  /* Text: #000000 → warm near-black
     WHY: Pure black on warm off-white creates a jarring
     temperature clash. Near-black (#1a1a1a) matches the
     warmth of the background and reduces eye strain. */
  --color-text: #1A1A1A;       /* was: #000000 or #212529 */
  --color-text-2: #6B7280;     /* was: #6c757d - muted, for secondary */
  --color-text-3: #9CA3AF;     /* was: none - for captions, placeholders */

  /* Accent: #0d6efd → considered, non-Bootstrap hue
     WHY: Bootstrap blue is the single loudest "I didn't
     design this" signal on the web. ANY other considered
     hue immediately elevates the design. Pick based on
     brand context from the user's brief. */
  --color-accent: #____;       /* MUST be chosen based on brand context */
  --color-accent-hover: #____; /* 10-15% darker or more saturated */

  /* Borders and shadows: warm, not gray
     WHY: Cool gray borders (#dee2e6) clash with warm
     backgrounds. Use warm gray or very low-opacity black. */
  --color-border: rgba(0, 0, 0, 0.08);  /* was: #dee2e6 */
  --color-shadow: rgba(0, 0, 0, 0.04);  /* was: rgba(0,0,0,0.1) */

  /* ── Typography ────────────────────────────────── */

  /* Display font: Arial → a real display font
     WHY: Arial/system-ui as a heading font is the
     typographic equivalent of serving fine dining
     on paper plates. Display fonts have optical
     refinements for large sizes that body fonts lack. */
  --font-display: 'Outfit', system-ui, sans-serif;  /* was: Arial/system-ui */
  --font-body: 'Inter', system-ui, sans-serif;       /* was: same as display */
  --font-mono: 'JetBrains Mono', monospace;           /* was: none */

  /* ── Spacing ───────────────────────────────────── */

  /* Section spacing: random values → consistent scale
     WHY: A spacing system creates rhythm. Random spacing
     creates visual noise - the eye detects inconsistency
     even when the brain can't articulate it. */
  --space-section: clamp(5rem, 10vw, 8rem); /* was: random py values */
  --space-element: 1.5rem;                  /* was: 0.75rem–1rem */
  --space-component: 2rem;                  /* was: 1rem–1.5rem */

  /* ── Radius ────────────────────────────────────── */

  /* Radius: 4px everywhere → considered radius language
     WHY: A design system commits to a radius language.
     Pick ONE and apply consistently. */
  --radius-sm: 8px;          /* was: 4px (Bootstrap) - inputs, badges */
  --radius-md: 12px;         /* was: 4px - cards, containers */
  --radius-lg: 16px;         /* was: 4px - modals, large cards */
  --radius-full: 9999px;     /* was: 50% - pills, avatars */

  /* ── Easing ────────────────────────────────────── */

  /* Easing: ease-in-out → custom curves
     WHY: CSS keyword easings are the typographic
     equivalent of Comic Sans. Zero character,
     zero intentionality. Custom curves give
     every animation a deliberate feel. */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-snap: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
}
→ タイポグラフィの処方
/* PRESCRIPTION: Typography scale - Slop → Gold
   WHY: The heading is the first thing the eye hits.
   A display font with tight tracking and compressed
   line-height immediately signals "designed." The body
   font stays readable with comfortable line-height. */

/* Import the fonts - add to the top of your CSS or <head> */
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');

h1, h2, h3, h4 {
  font-family: var(--font-display);
  letter-spacing: -0.03em;   /* was: normal (too loose at display size) */
  line-height: 1.1;          /* was: 1.2 (Bootstrap) - tighten */
  text-wrap: balance;        /* prevents ugly orphan lines */
  color: var(--color-text);
}

h1 {
  font-size: clamp(2.25rem, 5vw, 3.75rem);  /* was: 2rem fixed */
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1.05;
}

h2 {
  font-size: clamp(1.75rem, 3.5vw, 2.75rem); /* was: 1.5rem fixed */
  font-weight: 600;
}

h3 {
  font-size: clamp(1.25rem, 2vw, 1.5rem);    /* was: 1.25rem fixed */
  font-weight: 600;
}

body, p, span, li {
  font-family: var(--font-body);
  font-size: clamp(0.9375rem, 1.1vw, 1.0625rem); /* was: 1rem fixed */
  line-height: 1.65;     /* was: 1.5 - slightly more generous */
  color: var(--color-text);
}

/* Body text max-width - prevent wall-to-wall text */
p {
  max-width: 65ch;  /* was: none - text ran edge to edge */
}

/* Muted secondary text */
.text-muted, .text-secondary {
  color: var(--color-text-2) !important; /* override Bootstrap's gray */
}

/* Eyebrow / label style - add where appropriate */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-3);
}
→ コンポーネントの処方
/* PRESCRIPTION: Button - Bootstrap → Premium
   WHY: The button is the most interactive element on the page.
   Its hover feel communicates the entire quality level of the site.
   A snappy cubic-bezier with a physical lift-and-shadow creates
   a tactile impression that Bootstrap's default cannot achieve. */

/* Strip Bootstrap button defaults */
.btn {
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.75rem 1.75rem;             /* was: py-2 px-3 - cramped */
  border-radius: var(--radius-full);     /* was: 4px - now pill */
  border: none;
  cursor: pointer;
  transition:
    transform 0.4s var(--ease-snap),
    box-shadow 0.4s var(--ease-snap),
    background-color 0.3s var(--ease-out);
}

.btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px var(--color-shadow);
}

.btn:active {
  transform: translateY(0) scale(0.98);
  transition-duration: 0.1s;
}

/* Primary button */
.btn-primary {
  background: var(--color-accent);
  color: #ffffff;
  border: none;
  box-shadow: 0 1px 3px var(--color-shadow);
}

.btn-primary:hover {
  background: var(--color-accent-hover);
}

/* Ghost / outline button */
.btn-outline-primary,
.btn-secondary,
.btn-outline-secondary {
  background: transparent;
  color: var(--color-text);
  border: 1px solid var(--color-border);
}

.btn-outline-primary:hover,
.btn-outline-secondary:hover {
  border-color: var(--color-text);
  background: rgba(0, 0, 0, 0.02);
}

/* PRESCRIPTION: Card - Bootstrap → Premium */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);        /* was: 4px */
  padding: var(--space-component);         /* was: 1rem - cramped */
  box-shadow: none;                        /* was: default Bootstrap shadow */
  transition:
    transform 0.4s var(--ease-snap),
    box-shadow 0.4s var(--ease-snap),
    border-color 0.3s var(--ease-snap);
}

.card:hover {
  transform: translateY(-4px);
  box-shadow:
    0 8px 24px rgba(0, 0, 0, 0.04),
    0 2px 8px rgba(0, 0, 0, 0.02);
  border-color: rgba(0, 0, 0, 0.12);
}

/* Reset Bootstrap card internals */
.card-body {
  padding: 0;  /* parent .card already has padding */
}

.card-title {
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: var(--space-element);
}

/* PRESCRIPTION: Input - Bootstrap → Premium */
.form-control,
input[type="text"],
input[type="email"],
input[type="password"],
textarea,
select {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  padding: 0.75rem 1rem;                  /* was: py-1.5 px-3 - cramped */
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  transition:
    border-color 0.3s var(--ease-snap),
    box-shadow 0.3s var(--ease-snap);
}

.form-control:focus,
input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(var(--color-accent-rgb), 0.15);
}

/* PRESCRIPTION: Navigation - Bootstrap → Premium */
.navbar, nav {
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  background: rgba(250, 250, 249, 0.85);  /* semi-transparent for frost */
  border-bottom: 1px solid var(--color-border);
  padding: 0 clamp(1.5rem, 5vw, 5rem);
  height: 64px;
  display: flex;
  align-items: center;
}

.nav-link, .navbar-nav .nav-link {
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-text-2);
  transition: color 0.3s var(--ease-snap);
  position: relative;
}

.nav-link:hover {
  color: var(--color-text);
}

/* Sliding underline on nav links */
.nav-link::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 100%;
  height: 1.5px;
  background: var(--color-text);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.3s var(--ease-snap);
}

.nav-link:hover::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* PRESCRIPTION: Table - Bootstrap → Premium */
.table, table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
}

.table th, table th {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-3);
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--color-border);
  text-align: left;
}

.table td, table td {
  font-size: 0.9375rem;
  padding: 1rem;
  border-bottom: 1px solid rgba(0, 0, 0, 0.04);
  color: var(--color-text);
}

.table tbody tr:hover, table tbody tr:hover {
  background: rgba(0, 0, 0, 0.015);
}

/* Kill Bootstrap zebra striping - it looks cheap */
.table-striped > tbody > tr:nth-of-type(odd) {
  background-color: transparent;
}
→ 雰囲気の処方
/* PRESCRIPTION: Atmosphere - Flat → Alive
   WHY: Flat backgrounds feel like nothing. A subtle
   radial gradient, grain texture, or warm tint gives
   the background depth without adding visual elements. */

/* Subtle warm radial on the body */
body {
  background:
    radial-gradient(ellipse at 30% 0%, rgba(250, 235, 215, 0.2) 0%, transparent 50%),
    var(--color-bg);
}

/* Noise grain overlay - felt, not seen */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: 0.025;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
}

/* Section dividers - subtle border instead of hard lines */
section + section {
  border-top: 1px solid var(--color-border);
}

/* Alternating section backgrounds for rhythm */
section:nth-child(even) {
  background-color: var(--color-surface-2);
}
→ モーションの処方
/* PRESCRIPTION: Motion - Static → Alive
   WHY: Every element that appears without animation
   feels like the page is broken. A staggered fade-up
   with deblur signals that the page loaded intentionally. */

/* Entry animation keyframe */
@keyframes enter-up {
  from {
    opacity: 0;
    transform: translateY(24px);
    filter: blur(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

/* Apply to major elements - use inline style for stagger:
   <h1 class="enter-up" style="--stagger: 0ms">
   <p class="enter-up" style="--stagger: 120ms">
   <button class="enter-up" style="--stagger: 240ms"> */
.enter-up {
  animation: enter-up 0.7s var(--ease-out) both;
  animation-delay: var(--stagger, 0ms);
}

/* Scroll reveal - elements below the fold */
[data-reveal] {
  opacity: 0;
  transform: translateY(30px);
  transition:
    opacity 0.8s var(--ease-out),
    transform 0.8s var(--ease-out);
}

[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Universal interactive transition - replaces Bootstrap's
   transition: all 0.15s ease-in-out on EVERY interactive element */
a, button, [role="button"],
input, select, textarea,
.card, .nav-link, .badge {
  transition: all 0.3s var(--ease-snap);
}

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  .enter-up {
    animation: none;
    opacity: 1;
    transform: none;
    filter: none;
  }

  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
→ スクロール時に表示する JavaScript(非破壊的)
/* PRESCRIPTION: Scroll reveal - add as a separate script
   WHY: This script observes [data-reveal] elements and
   adds .is-visible when they enter the viewport. It does
   NOT modify any existing JS - it's a new, separate file
   that runs independently.

   Add to the end of the page or import in main entry. */

class ScrollReveal {
  constructor() {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;

    this.observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            entry.target.classList.add('is-visible');
            this.observer.unobserve(entry.target);
          }
        });
      },
      { threshold: 0.15, rootMargin: '-50px 0px' }
    );

    document.querySelectorAll('[data-reveal]').forEach((el) => {
      this.observer.observe(el);
    });
  }
}

// Initialize after DOM ready
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', () => new ScrollReveal());
} else {
  new ScrollReveal();
}
✓ 品質ゲート:処方

フェーズ 4 に進む前に、以下を確認してください。

  • フェーズ 2 の Slop の項目すべてに、より優れた置き換えが処方されている
  • トークンの処方に一貫性がある(温かみのある背景には温かみのあるテキストを合わせ、温度感を混在させない)
  • アクセントカラーは、汎用的な別の青ではなく、ユーザーのブランドの文脈に基づいて選ばれている
  • タイポグラフィの処方では、見出しにディスプレイフォント、本文にボディフォントを使用している
  • コンポーネントの処方では、同じ DOM 構造(class の変更のみ)を維持している
  • 雰囲気の追加は控えめである(粒子の不透明度は 0.05 未満、グラデーションは 0.3 未満)
  • モーションの追加は非破壊的である(新しい CSS クラスと新しいスクリプトを追加し、既存の JS は変更しない)
  • アクセントカラーの #____ プレースホルダーに、実際の 16 進数値が入力されている

フェーズ 4:手術

処方を実行します。ここは手術室です。以下の正確な順序に従ってください。各レイヤーは前のレイヤーを基に構築します。

→ 手術の順序
Layer 1: Tokens     (CSS custom properties - the foundation)
Layer 2: Typography (font imports + heading/body styles)
Layer 3: Color      (replace all Bootstrap/generic color values)
Layer 4: Spacing    (padding, margins, gaps - breathing room)
Layer 5: Components (buttons, cards, inputs, nav, tables)
Layer 6: Atmosphere (grain, glow, section alternation)
Layer 7: Motion     (entry animations, hover states, scroll reveals)
→ 手術のルール
ルール理由
一度に 1 つのレイヤーだけ変更するトークン、タイポグラフィ、コンポーネントを同時に変更して問題が発生すると、原因を特定できません
各レイヤーの後にテストするアプリを実行してください。引き続き動作しますか?すべてのルートが読み込まれますか?フォームは送信されますか?API 呼び出しは応答を返しますか?問題がなければ、次のレイヤーに進みます
置き換えではなく CSS オーバーライドを使う既存のスタイルを上書きする新しいスタイルシート(例:gold.css)を追加してください。オーバーライドが正常に動作することを確認するまで、既存の CSS ファイルを削除してはいけません
className の変更は慎重に行うBootstrap のクラスをカスタムクラスに置き換える場合、削除する前に各クラスがコードベース全体で使われている箇所を検索してください。JS ロジック(document.querySelector('.btn-primary'))で使われているクラスは変更してはいけません
JSX の構造を書き換えないclassName と style の props は追加・変更できます。子要素の順序変更、ラッパー div の削除、コンポーネント階層の変更、または純粋に視覚的なものではない props の変更は禁止です
既存ファイルの変更より新規ファイルを優先する既存のスタイルシートを直接編集するより、gold.css を作成して既存のスタイルシートの後にインポートする(オーバーライドの優先順位を高める)方法を優先してください。これにより、簡単にロールバックできます
→ オーバーライド戦略

最も安全なアプローチは、既存のすべてのスタイルシートの後に読み込まれる、単一の新しいスタイルシートです:

/* gold.css - loaded LAST in the cascade
   WHY: By loading after Bootstrap/existing CSS, our rules
   override the defaults without deleting any existing code.
   If something breaks, the user can remove this one import
   to revert entirely. This is the safest surgery method.

   Import in main entry file:
   import './gold.css'  // AFTER all other CSS imports */

このファイルには、フェーズ 3 のすべての処方 - トークン、タイポグラフィ、コンポーネント、雰囲気、モーション - が 1 つのファイルにまとめられており、単一の単位として追加または削除できます。

⚠ ドリフト警告: Bootstrap のインポートを削除したり、古いスタイルシートを削除したりして、既存の CSS を「クリーンアップ」したくなる誘惑があります。ユーザーがゴールドオーバーライドが機能していることを確認するまでは、これをしないでください。古い CSS はセーフティネットです。患者が安定していることが確認されてから初めて削除してください。

→ 高リスクファイルの手術(ダッシュボード、フォーム、複雑なコンポーネント)

監査テーブルで 高 リスクとマークされたファイルの場合:

  1. まずファイル全体を読む - すべての状態変数、エフェクト、ハンドラーを理解する
  2. すべての className と style プロップをマッピングする - JS ロジックで参照されているものをメモする
  3. 変更するのは className の文字列値のみ - 属性はそのまま、値だけが変わる
  4. 状態を参照するインラインスタイルには絶対に触れない - style={{ display: isOpen ? 'block' : 'none' }} は神聖です
  5. 変更後すぐにテストする - アプリを実行し、すべての状態変化をトリガーし、すべてのフォームを送信し、すべての API 呼び出しを検証する
/* EXAMPLE: Safe className surgery on a complex component

   BEFORE (Bootstrap):
   <div className={`card ${isSelected ? 'border-primary' : ''}`}>

   AFTER (Gold):
   <div className={`card ${isSelected ? 'card--selected' : ''}`}>

   The ternary logic is IDENTICAL. Only the class name value changed.
   Then in gold.css:
   .card--selected {
     border-color: var(--color-accent);
     box-shadow: 0 0 0 2px rgba(var(--color-accent-rgb), 0.2);
   }
*/
→ data-reveal 属性の追加(非破壊的)

スクロールリビールアニメーションを追加するには、既存の JSX 要素に data-reveal 属性を追加します。data-* 属性は React のレンダリングロジックに影響しないため、これは安全です:

/* BEFORE: */
<section className="features">
  <h2>Features</h2>
  {features.map(f => <FeatureCard key={f.id} {...f} />)}
</section>

/* AFTER - added data-reveal, nothing else changed: */
<section className="features" data-reveal>
  <h2>Features</h2>
  {features.map(f => <FeatureCard key={f.id} {...f} />)}
</section>

/* The data-reveal attribute is inert until the ScrollReveal
   script observes it. It does not interfere with React's
   reconciliation, event handling, or state management. */
→ エントリーアニメーションクラスの追加(非破壊的)
/* BEFORE: */
<h1 className="hero-heading">Build faster.</h1>
<p className="hero-subtext">The platform for modern teams.</p>
<button className="btn btn-primary" onClick={handleSignup}>Get Started</button>

/* AFTER - added enter-up class and stagger variable: */
<h1 className="hero-heading enter-up" style={{ '--stagger': '0ms' } as React.CSSProperties}>Build faster.</h1>
<p className="hero-subtext enter-up" style={{ '--stagger': '120ms' } as React.CSSProperties}>The platform for modern teams.</p>
<button className="btn btn-primary enter-up" style={{ '--stagger': '240ms' } as React.CSSProperties} onClick={handleSignup}>Get Started</button>

/* onClick handler is UNTOUCHED. Only className and style were added.
   The style prop uses a CSS custom property for stagger delay.
   In TypeScript, cast as React.CSSProperties to avoid type errors. */
✓ 品質ゲート:手術

7 つのレイヤーをすべて適用した後、以下を確認します:

  • アプリがエラーなく実行される(コンソールがクリーン)
  • すべてのルートが正しく読み込まれる
  • すべてのフォームが正しく送信され、検証される
  • すべての API 呼び出しがデータを返し、正しくレンダリングされる
  • すべての状態変化が機能する(トグル、モーダル、ドロップダウン、選択)
  • すべてのイベントハンドラーが正しく発火する(クリック、送信、キー入力)
  • ref エラーや「undefined のプロパティを読み取れません」エラーがない
  • 新しい CSS インポートが既存のスタイルシートの後に読み込まれる
  • gold.css ファイルを削除すれば完全に元に戻せる

フェーズ 5:術後

手術が成功したことを検証します。すべてのチェックを順に確認します。FAIL があれば診断と修正が必要です。

機能チェック(神聖な整合性)
チェックPASS/FAIL
すべてのページ/ルートがエラーなく読み込まれる
すべてのフォームが正しく送信される
すべての API 呼び出しがデータを返し、レンダリングする
すべての状態トグルが機能する(開く/閉じる、表示/非表示、選択/選択解除)
すべてのイベントハンドラーが発火する(onClick、onSubmit、onChange、onKeyDown)
認証フローが機能する(ログイン、ログアウト、保護されたルート)
コンソールエラーがない
TypeScript エラーがない(TS プロジェクトの場合)
壊れた ref や undefined プロパティエラーがない
すべての条件付きレンダリングが機能する(ローディング状態、エラー状態、空状態)

⚠ いずれかの機能チェックが失敗した場合は、最後の手術レイヤーを元に戻して診断してください。すべての機能が合格するまで、視覚チェックに進まないでください。

視覚アップグレードチェック
チェックPASS/FAIL
どこにも Bootstrap ブルー(#0d6efd)が見えない
純白(#fff)背景に純黒(#000)テキストがない
見出しフォントがディスプレイフォント(Arial/system-ui ではない)
見出しのレタースペーシングが負(ゆるくなく、タイト)
見出しの行の高さが圧縮されている(< 1.15)
本文テキストに快適な最大幅がある(端から端までではない)
カードに十分なパディングがある(窮屈な 16px ではない)
ボタンがピル型、または規定の角丸を使用している
ボタンにホバーリフト + シャドウ拡張がある
ボタンにアクティブプレスフィードバックがある
ナビにフロステッドガラス処理がある
カラーパレットが暖かく一貫している(冷たいグレーと暖かいトーンが混在していない)
シャドウが繊細で暖かい(デフォルトの Bootstrap ではない)
同じコンポーネントタイプ間で border-radius が一貫している
雰囲気のチェック
チェック項目合格/不合格
背景にほのかな温かみがある(単調な白/グレーではない)
グレインのオーバーレイがあり、控えめである(目立たず、感じられる程度)
セクションの背景に変化があり、リズムが生まれている(すべて同じ背景ではない)
平坦で味気ない印象のセクションが残っていない
モーションのチェック
チェック項目合格/不合格
ページ読み込み時にヒーロー要素がアニメーションで表示される(フェードアップとぼかし解除を段階的に適用)
ファーストビューより下のセクションで、スクロール時に表示アニメーションが発火する
すべてのボタンにホバー時のトランジションがある(状態が瞬時に切り替わらない)
すべてのカードがホバー時に浮き上がる
ナビゲーションリンクにアニメーション付きの下線がある
入力欄のフォーカス時に、ボーダーがグローを伴ってトランジションする
CSS のキーワードによるイージング(ease、ease-in、ease-out、ease-in-out)を使ったアニメーションがない
prefers-reduced-motion が尊重される(動きを減らす設定ではモーションを適用しない)
レスポンシブのチェック
チェック項目合格/不合格
1440px(デスクトップ)でレイアウトが適切に表示される
768px(タブレット)でレイアウトが適切に表示される
375px(モバイル)でレイアウトが適切に表示される
どのビューポートでも横方向にはみ出さない
モバイルでタッチターゲットが最小 44px ある
どのビューポートでも見出しが 3 行を超えない
モバイルでカードが適切に縦積みされる(1 列)
ロールバックのチェック
チェック項目合格/不合格
gold.css のインポートを削除すると、すべての見た目の変更が問題なく元に戻る
既存の CSS ファイルが削除されておらず、フォールバックとしてそのまま残っている
JSX の構造に変更が加えられていない(className と data-* の追加のみ)
ユーザーがアップグレード全体をひとまとまりとして採用または却下できる

スロップカタログ - よくあるパターンと改善方法

よくある見た目の問題をすばやく確認できます。パターンを見つけたら、改善方法を適用してください。

スロップのパターン問題点改善方法
font-family: Arial, Helvetica, sans-serif本文用フォントを見出しにも使用している見出し用に Outfit/Satoshi/Cabinet Grotesk をインポートする
color: #000; background: #fff純粋な黒と白の組み合わせcolor: #1a1a1a; background: #FAFAF9
background: #0d6efdBootstrap のプライマリブルーブランドに合ったアクセントカラーを選ぶ
box-shadow: 0 2px 4px rgba(0,0,0,0.1)ありきたりなデフォルトのシャドウ通常時は box-shadow: 0 1px 3px rgba(0,0,0,0.04) にし、ホバー時に広げる
border-radius: 4pxBootstrap のデフォルトの角丸角丸の基準を統一する:8/12/16/9999
border: 1px solid #dee2e6冷たい印象のグレーのボーダーborder: 1px solid rgba(0,0,0,0.08) - 温かみがあり、控えめ
transition: all 0.15s ease-in-outBootstrap のデフォルトのトランジションtransition: all 0.3s cubic-bezier(0.22, 1, 0.36, 1)
カードの padding: 1rem余裕のないカードのパディング最低でも padding: 2rem - カードにはゆとりが必要
見出しと本文の間隔 margin-bottom: 0.5rem見出しとの間隔が窮屈margin-bottom: 1.5rem - 見出しをしっかり際立たせる
カードグリッドの gap: 1remグリッドの間隔が狭い最低でも gap: 1.5rem - カード同士に間隔を設ける
ボタンに :hover がない反応のない、操作感に乏しいボタンtranslateY(-2px) + シャドウの拡大 + カスタムイージング
カードに :hover がない静的で生気のないカードtranslateY(-4px) + シャドウの拡大 + ボーダーのグロー
表示時のアニメーションがない静的な状態で瞬時に表示されるファーストビュー内の要素に、フェードアップとぼかし解除を段階的に適用する
h1 { font-size: 2rem }見出しが小さすぎるfont-size: clamp(2.25rem, 5vw, 3.75rem)
見出しの line-height: 1.2見出しの行間が広すぎるline-height: 1.05 - 引き締まった構築的な印象にする
見出しに letter-spacing がない字間が広く、素人っぽい印象letter-spacing: -0.03em - 字間を詰める
セクションのパディングが py-3セクションが窮屈py-20 md:py-32 - セクションは段落ではなく章
ゼブラストライプのテーブル2010 年代の Bootstrap 風ストライプをなくし、ホバー時に行を控えめにハイライトする
.badge { font-size: 0.75em }バッジが小さく窮屈padding: 0.25rem 0.75rem; font-size: 0.75rem; border-radius: 9999px
入力欄に ::placeholder のスタイルがないデフォルトのグレーのプレースホルダーcolor: var(--color-text-3); opacity: 0.7

エッジケース

コードで CSS-in-JS(styled-components、Emotion)を使用している場合
  1. トークンの指定を CSS カスタムプロパティのレイヤー(:root 変数)として適用します
  2. トークンを参照するグローバルな createGlobalStyle で、styled-component のスタイルを上書きします
  3. コンポーネントレベルの上書きには、styled-component の上書きを記述した gold-overrides.ts ファイルを追加します
  4. 既存の styled-component の定義をインラインで変更してはいけません。代わりに上書き用のラッパーを作成します
コードで Tailwind CSS を使用している場合
  1. tailwind.config.js の theme をゴールドトークン(色、フォント、角丸、影)で上書きします
  2. 雰囲気や動きの追加には @layer utilities を使用します
  3. Tailwind のカラークラスを体系的に置き換えます。例:text-gray-900 → text-[#1a1a1a]、または設定ファイルでカスタムカラーを定義します
  4. shadow-sm / shadow-md を設定ファイルのカスタムシャドウ値に置き換えます
  5. rounded / rounded-md を設定ファイルのカスタム角丸に置き換えます
  6. Tailwind ではコンポーネントファイルごとに変更するのではなく、設定ファイルのレベルでデザインシステムを変更できるため、この方法が最も安全です
コードで Material UI / Chakra / Ant Design を使用している場合
  1. テーマプロバイダーの設定を上書きします。これらのライブラリはテーマのカスタマイズを前提に設計されています
  2. テーマオブジェクト(色、タイポグラフィ、間隔、角丸、影)を中心に調整します
  3. 雰囲気や動きの追加には、コンポーネントレベルの sx 上書きや styled() ラッパーを追加します
  4. コンポーネントライブラリの構造に逆らわず、テーマシステムの範囲内で作業します
コードがバニラ HTML/CSS(フレームワークなし)の場合
  1. <head> 内の最後のスタイルシートとして gold.css を追加します
  2. 既存のスタイルを編集せずに上書きできるよう、CSS の詳細度を利用します
  3. 既存のスタイルで !important が使われている場合は、上書きにも !important が必要になることがあります(残念ですが必要です)
  4. </body> の前に <script> として ScrollReveal スクリプトを追加します
ユーザーが「ヒーロー部分だけを見栄えよくして」と言った場合

サイト全体をアップグレードしてはいけません。次の手順をヒーローセクションだけに適用します。

  1. ヒーローコンポーネントを監査します
  2. 現在のデザイン上の判断を抽出します
  3. そのセクションに適用するゴールドへの置き換えを指定します
  4. そのセクションの CSS だけを外科的に変更します
  5. ほかの部分に問題がないことを確認します

ユーザーが指定した範囲を尊重してください。求められていない範囲までアップグレードすると、時間を浪費し、リスクを招きます。


中核となる原則

患者を生かさなければなりません。 動作しなくなった美しいアプリは、動作する見た目の悪いアプリよりも劣ります。変更のレイヤーごとにテストしてください。機能性は常に美しさより優先されます。

CSS の上書きを行い、JS を書き換えてはいけません。 使用するのは className の変更、新しい CSS ファイル、データ属性です。コンポーネントのロジックを書き換えたり、状態管理をリファクタリングしたり、JSX の階層を再構成したりしてはいけません。見た目のアップグレードに JS ロジックの変更が必要な場合は、CSS だけで実現する方法を探してください。

gold.css は単一のまとまりです。 ビジュアルアップグレード全体を含み、最後に読み込まれる 1 つのファイルです。ユーザーは 1 つのインポートを追加するだけでアップグレードでき、削除するだけで元に戻せます。これが外科的なアプローチです。導入も撤去も簡潔にします。

無機質さより温かみを。 プレミアムなデザインには、オフホワイトの背景、温かみのあるほぼ黒のテキスト、温かみのあるグレーの境界線など、温かい色調が使われています。冷たい中間色(純粋なグレー、純白、純黒)は、無機質で、デザインされていない印象を与えます。最も手早く効果が得られるのは、色温度を変えることです。

余白が秘訣です。 最も劇的な効果をもたらす変更は、セクションのパディング、カードのパディング、見出し間の間隔、グリッドの間隔を広げることです。窮屈な余白は素人っぽいデザインの特徴です。ゆとりのある余白は、プレミアムなデザインの特徴です。迷ったら、余白を増やしてください。

ディスプレイフォントが、素人とプロの差を生みます。 見出しのフォントを Arial/system-ui から適切なディスプレイフォント(Outfit、Satoshi、Cabinet Grotesk、Clash Display)に変えることは、単独で最も大きな効果をもたらす変更です。それ以外のすべては、この土台の上に成り立ちます。

コメント