Communitygithub.com

aidan-neel/giga-ui

用於建構、重新設計或打磨任何使用者介面(元件、登陸頁、儀表板、應用程式畫面、行動 UI、引導流程或驗證流程),尤其適用於簡短或模糊的提示。提供完整的視覺語言、設計代碼、元件配方以及動畫與微互動系統,讓結果看起來和感覺起來都是高品質。風格靈感來自產品設計師 @marcelkargul。

giga-ui 是什麼?

GIGA UI 技能旨在將一行 UI 請求轉化為精緻、可投入生產的介面。其視覺語言深受設計師 @marcelkargul(Kargul Studio)公開作品的啟發,特點是沉穩、近乎單色、精確的排版、柔和的層疊陰影、單一的自信強調色,以及快速且物理性的動畫。此技能適用於任何編碼模型與技術棧,範例使用 React + Tailwind + Motion(motion/react),但也提供純 CSS 等價寫法。它提供完整的設計系統,包括排版規則(Inter 或 Geist 字體、最多兩種粗細、精確的字距)、色板(中性灰階搭配語意強調色)、形狀與間距(4px 網格與特定圓角半徑)、以及層疊陰影系統。除了靜態設計,GIGA UI 還提供一套互動與動畫配方,包含 CSS 變量(transition、scale、opacity)與 Motion 元件(AnimatedCounter、AnimatedNumber、FadeIn、StaggerFadeIn),確保動畫不淪為裝飾,而是產品體驗的一部分。最後,它包含一份詳盡的品質檢查清單,涵蓋邊緣情況、載入、空白、無障礙與暗色模式,幫助開發者打磨最後 10% 的細節。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/aidan-neel/design/tree/HEAD/skills/giga-ui

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

GIGA UI:沉穩、精確、有生命力

此技能可將一行 UI 請求轉化為精緻、可投入生產的介面。視覺語言靈感來自 @marcelkargul(Kargul Studio)的公開設計作品:沉穩、近乎單色的產品 UI、非常精確的排版、用柔和的層疊陰影取代厚重的邊框、一個自信的強調色,以及快速、物理性且絕不為裝飾而存在的動畫。

它適用於任何編碼模型與任何技術棧。範例使用 React + Tailwind + Motion(motion/react),每個範例都有純 CSS 等價寫法。

下方使用以下來源標記: [seen] 直接從他的貼文/圖片中觀察到,或在標題中陳述。 [inferred] 從觀察到的內容(從螢幕截圖測量或推斷)進行的合理推論。 [expert] 來自 Motion 文件、Emil Kowalski、Apple HIG 的一般動畫/UX 最佳實踐。非來自他的貼文。


1. 設計哲學

  1. 如果可以移除,就移除它。 [seen,標題:「每個畫面。每個元件。每個影格。如果它不需要存在,就不應該存在。簡單總是困難,但簡單總是勝利。」]
  2. 排版承擔了大部分的工作。 [seen:「只要精通排版,你就可以讓任何東西看起來好看。」] 使用一種字體家族(網頁默認 Inter,可選 Geist;iOS 風格的行動裝置使用 SF Pro Rounded),且最多使用兩種字重 [seen:「sf pro rounded,最多 2 種字重,保持簡單」]。
  3. 白色、黑色和陰影。 [seen:「沒有動畫,沒有漸層,沒有花俏效果。只有 FFFFFF、000000 和一些陰影。這就是設計的巔峰。」] 大部分色板是中性灰色。顏色僅用於表達意義,例如狀態、類別或唯一的主要操作。
  4. 深度來自柔和的層疊陰影和髮絲線,而不是厚重的邊框。 [seen:「這個按鈕只需要 3 個陰影!」以及 §3 中的次要按鈕配方]
  5. 動畫是產品的一部分,不是裝飾。 [seen:「貫穿始終的微互動」、「微妙的載入動畫。不過度,剛剛好」、「每個網站都需要這種層級的動畫」、「想法 → 設計 → 動畫」]。僅為解釋變更、確認操作或引導注意而進行動畫 [expert]。
  6. 手動打磨最後的 10%。 [seen:他的流程是「在 Figma 中設計,在 Claude 的幫助下建構,花費數小時手動修正小細節並改善程式碼品質」]。§9 中的 QA 檢查清單就是那最後的 10%。
  7. 乾淨勝過聰明。 他的標題反覆回歸到「乾淨」、「沉穩」和「簡單」這些詞(例如,「一個沉穩清單中的所有任務」)。即使資料量很大,畫面也應該感覺沉穩。

2. 觀察到的風格(他的作品實際上長怎樣)

2.1 排版

  • 字體家族: Inter(此技能的預設)和 Geist(可選替代方案)。[seen:「在試過數百種字體後,我意識到沒有什麼比得上 Inter 和 Geist。」;玩笑貼文:初級和高級設計師都使用「Inter, Geist」]。行動應用程式使用 SF Pro Rounded [seen,數篇貼文]。他也推薦 Google Sans Rounded 作為 SF Pro Rounded 的跨平台替代方案 [seen,回覆]。等寬字體(類似 Geist Mono)用於大數字、股票代碼和程式碼 [seen:加密貨幣應用程式餘額、Statsnap KPI 卡片、側邊欄導航變體]。品牌和行銷作品有時使用襯線展示字體(編輯過渡襯線,輕字重)[seen:金融科技登陸頁「Every payment protected…」,VC 登陸頁面]。
  • 字距(他的精確數字,使用 Geist 示範;同樣適用於 Inter,他也曾以 −6% 示範) [seen]:
    • 16px → 0%
    • 36px → −3%
    • 100px+ → −5% 到 −6%
    • 「永不負數規則適用於內文。在 100px+ 時,預設間距看起來太鬆散。」
    • SF Pro Rounded:+1% 字母間距 [seen,字體樣本]。
  • 字重: Regular (400) 和 Medium (500) 承擔了幾乎所有產品 UI。Semibold (600) 用於標題和數字。Bold/Black 僅用於大型展示標題 [inferred,從螢幕截圖推斷]。
  • 產品 UI 中的尺寸 [inferred,從 1× 螢幕截圖測量]:正文和表格文字 13–14px,次要/元資料 12–13px,章節標籤 11–12px 大寫或小型大寫灰色(例如「WORKSPACE」、「PINNED TOOLS」),頁面標題 18–24px Medium,KPI 數字 24–32px,英雄標題 48–72px 並帶有負字距。按鈕為 14px Medium [seen:「Geist/14/Medium」]。
  • 文字顏色: 主要近乎黑色(#171717–#1F1F1F),次要中灰色(#6B6B6B–#737373),三級/佔位符(#A3A3A3)。標籤使用深色調文字搭配淺色調背景,而非白色文字搭配飽和填充色 [seen:「Do / Don't」貼文:「深色文字極大地改善了整體可讀性。」]。

2.2 色彩

從螢幕截圖(近似值)取樣 [seen/inferred]:

角色亮色暗色
畫布 / 頁面#FFFFFF#0D0D0D–#121212
微妙表面(側邊欄、面板、行動背景)#F7F7F7 / #F4F4F4 / #FAFAFA#1A1A1A–#1E1E1E
展示背板(在 Mockup 後方)#E5E5E5–#EDEDED,中灰色 #8A8A8A#1F1F1F–#262626
髮絲邊框#ECECEC / #EBEBEBrgba(255,255,255,0.08)
主要文字#171717#FAFAFA
次要文字#737373#A1A1A1

強調色(每個產品使用一個,從不一次使用多種)[seen]:

  • 紫羅蘭色 #7B3AEC(Underlay 註冊、引導流程),也有靛藍色 #5B5BF0 變體
  • 藍色 #255CD1 / iOS 藍色 #2F7BF6(計算機、日曆、Statsnap)
  • 橙色 #FF5A1F / #F97316(Plunio、Nexora)
  • 藍綠色 #0F766E-ish(AI 管道、AIData)
  • 萊姆色 #B4F05A 搭配近乎黑色(程式碼編輯器「Start」按鈕、Soma 品牌)
  • 珊瑚紅 #F2435A(睡眠應用程式)
  • 純黑 #0A0A0A 作為中性應用程式的主要按鈕顏色(睡眠應用程式、計算機「=」、「Deploy v13」、「New event」)[seen]

語意色調 [seen]:綠色 #16A34A 文字搭配 #ECFDF3 背景;紅色 #DC2626 搭配 #FEF2F2 背景;琥珀色/橙色搭配 #FFF4E5 背景;藍色搭配 #EEF4FF 背景。頭像首字母位於帶有更深同色調文字的柔和圓圈上(「SW」、「AJ」、「MP」)。

漸層: 很少使用但用得恰到好處 [seen:「使用漸層的藝術」]。按鈕會有微妙的上到下漸層(次要按鈕為 #FFFFFF → #F7F7F7;主要按鈕頂部稍亮)。英雄插圖使用模糊的多彩色塊搭配 Plus-Darker 混合模式,再加上噪點/顆粒疊加 [seen:英雄插圖系列貼文]。

2.3 形狀、間距、深度

  • 圓角半徑 [seen and inferred]:小型控件和按鈕 8–10px [seen:「30px 高度,10px 半徑」];輸入框 10–12px;卡片 12–16px;模態視窗和命令面板 20–24px;行動表單和電話卡片 24–32px;藥丸狀和晶片完全圓角。行動按鈕通常是完整藥丸狀 [seen]。
  • 間距: 4px 基礎網格。常見間距為 4/8/12/16/24/32/48 [inferred]。內容周圍有大量留白;密集的表格行高仍約為 40–48px [inferred]。
  • 控件高度 [seen/inferred]:緊湊型桌面按鈕 30–32px,標準 36–40px,行動主要 CTA 48–56px。
  • 邊框: 1px 髮絲線,採用非常淺的灰色。邊框通常由一個 0 模糊 1px 擴散的陰影構成,而非 border [seen:次要按鈕配方]。
  • 陰影 [seen]:次要按鈕陰影 = 0 1px 2px rgba(40,40,40,.08), 0 0 0 1px #ECECEC。浮動表面(彈出視窗、面板、工具提示)使用一個大而非常柔和的環境陰影加上髮絲線。暗色工具提示置於亮色 UI 上 [seen:Statsnap 圖表工具提示、「Task completed · Undo」提示]。
  • 行動裝置: 畫板 430×932 [seen],頂部欄 40–44px 圓形圖示按鈕,在灰色畫布上分組的「嵌入」列表卡片,浮動藥丸狀標籤欄 [seen]。

2.4 佈局模式 [seen]

  • SaaS 應用程式外殼: 左側邊欄(220–260px)位於微妙灰色背景上,分組導航帶有小寫大寫灰色標籤,啟用項目 = 白色藥丸帶柔和陰影(亮色)或 #1E1E1E 填充(暗色);主要內容位於白色背景上,帶有細頂部欄(麵包屑 Home > Transaction,帶有 / 提示的搜尋框,圖示按鈕)。有時會有細長的圖示軌道(48–56px)代替。
  • 表格上方的篩選晶片行: Range Last 30 days ▾、Scope All tools ▾。標籤為灰色,值為深色。
  • 表格: 無斑馬紋,髮絲線行分隔線,小的灰色標題文字,色調狀態藥丸,頭像 + 名稱 + 電子郵件堆疊,右對齊數字,列表數字。
  • KPI 卡片: 標籤、大數字(通常為等寬)、Delta 藥丸(▲ +14.7% vs last year)。
  • 驗證/引導流程: 分割卡片。左側為表單(柔和圓圈中的 Logo、標題、副標題、Google 按鈕、「或」分隔線、輸入框、主要按鈕),右側為灰色面板中的產品預覽,帶有輪播點 [seen:「just designed the perfect signup page」]。
  • 命令面板: 24px 半徑,帶有 ESC 按鍵提示的搜尋行,篩選藥丸,分組結果,鍵盤圖例頁腳 [seen]。
  • 行動引導流程: 分段進度條 +「1/5」,置中粗體問題,帶有圓形勾選的可選選項行,黏性藥丸 CTA [seen]。
  • 登陸頁英雄: 浮動藥丸導航欄,小的「Backed with X」徽章,簡短有力的標題(有時是全大寫的無襯線字體,有時是襯線字體),深色主要 + 白色次要按鈕,下方為大型插圖 [seen]。

2.5 圖示與插圖 [seen]

  • 圖示:細線條輪廓圖示(類似 Lucide/Phosphor,~1.5px 線條粗細,UI 中 16–18px),預設為灰色,啟用時變深。
  • 小的彩色應用程式圖示磁貼(帶有漸層和字形的圓角正方形)用於功能卡片和分類。
  • 插圖風格:(a) 等距線條藝術,位於虛線網格上,單色;(b) 鮮豔的漸層帶/流,位於顆粒感粉彩背景上,帶有等距網格和浮動紙屑;(c) 友好的平面陰影點綴插圖和 3D 風格的表情符號圖示,適用於消費者和行動應用程式;(d) 擬物化點綴(一個縫合皮革錢包,裡面放著一張卡片)。
  • 他的動畫流程:「在 Figma 中繪製插圖 → 在 AE/Rive 中製作動畫 → 如果使用 AE 則導出到 Lottie → 在網站上實現」。在某個項目中,他使用了「Figma… Rive 用於動畫,Next.js + Sanity」。英雄區域通常需要「設計 + 插圖 + 動畫」[seen]。

2.6 暗色與亮色模式 [seen]

他兩種模式都使用,並提供匹配的組合(「亮色/暗色模式」、「figma tokens are so useful!」)。亮色是生產力 SaaS 的預設。暗色用於加密貨幣/交易、程式碼編輯器、側邊欄和行銷橫幅。暗色表面以 ~6–10 亮度增量逐步提高(#0D0D0D → #121212 → #1A1A1A → #222),而非到處都是純黑。


3. 設計代碼(CSS 變數)

將此貼到全域樣式表中。Tailwind 使用者可以在 @theme(v4)或 theme.extend(v3)中映射這些。

:root {
  /* 字體 */
  --font-sans: "Inter", "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, "Geist Mono", "SF Mono", Menlo, monospace;
  --font-rounded: "SF Pro Rounded", ui-rounded, "Google Sans Rounded", var(--font-sans);

  --text-xs: 12px;   --text-sm: 13px;  --text-base: 14px; --text-md: 16px;
  --text-lg: 18px;   --text-xl: 24px;  --text-2xl: 32px;  --text-3xl: 48px;
  --text-4xl: 64px;  --text-5xl: 96px;
  --tracking-body: 0;       /* <= 16px */
  --tracking-tight: -0.01em;/* 18–24px */
  --tracking-title: -0.03em;/* ~36px  (his rule) */
  --tracking-display: -0.055em; /* 100px+ (his rule: -5% to -6%) */
  --weight-regular: 400; --weight-medium: 500; --weight-semibold: 600;

  /* 中性色(亮色) */
  --bg: #ffffff;
  --bg-subtle: #f7f7f7;
  --bg-muted: #f0f0f0;
  --bg-backdrop: #e8e8e8;
  --border: #ececec;
  --border-strong: #e0e0e0;
  --fg: #171717;
  --fg-secondary: #737373;
  --fg-tertiary: #a3a3a3;
  --fg-inverse: #ffffff;

  /* 強調色:每個產品選擇一種 */
  --accent: #7b3aec;             /* 紫羅蘭色;替代方案:#255cd1 藍色、#ff5a1f 橙色、#0a0a0a 黑色 */
  --accent-hover: color-mix(in oklab, var(--accent), black 8%);
  --accent-soft: color-mix(in oklab, var(--accent), white 90%);
  --accent-fg: #ffffff;
  --ring: color-mix(in oklab, var(--accent), transparent 65%);

  /* 語意色(深色文字搭配柔色調) */
  --success: #16a34a; --success-soft: #ecfdf3;
  --danger:  #dc2626; --danger-soft:  #fef2f2;
  --warning: #d97706; --warning-soft: #fff7e6;
  --info:    #2563eb; --info-soft:    #eef4ff;

  /* 間距(4px 網格) */
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px;
  --space-12: 48px; --space-16: 64px; --space-24: 96px;

  /* 圓角 */
  --radius-xs: 6px; --radius-sm: 8px; --radius-md: 10px; --radius-lg: 12px;
  --radius-xl: 16px; --radius-2xl: 20px; --radius-3xl: 24px; --radius-full: 9999px;

  /* 高度 */
  --h-control-sm: 30px; --h-control: 36px; --h-control-lg: 44px; --h-cta-mobile: 52px;

  /* 陰影(分層、柔和;透過擴散產生髮絲線) */
  --hairline: 0 0 0 1px var(--border);
  --shadow-xs: 0 1px 2px rgb(40 40 40 / 0.08);
  --shadow-btn: 0 1px 2px rgb(40 40 40 / 0.08), 0 0 0 1px #ececec;     /* 他的次要按鈕 */
  --shadow-btn-primary: inset 0 1px 0 rgb(255 255 255 / 0.18), 0 1px 2px rgb(0 0 0 / 0.16), 0 0 0 1px color-mix(in oklab, var(--accent), black 12%);
  --shadow-card: 0 1px 2px rgb(0 0 0 / 0.04), 0 0 0 1px var(--border);
  --shadow-pop: 0 0 0 1px rgb(0 0 0 / 0.06), 0 8px 24px -4px rgb(0 0 0 / 0.10), 0 2px 6px rgb(0 0 0 / 0.04);
  --shadow-modal: 0 0 0 1px rgb(0 0 0 / 0.06), 0 24px 64px -12px rgb(0 0 0 / 0.18);
  --shadow-focus: 0 0 0 3px var(--ring);

  /* 動畫(參見 §5) */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);       /* 強緩出(Emil Kowalski) */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);   /* 用於螢幕上的移動 */
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);    /* 類似 iOS 的抽屜(Vaul) */
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --dur-instant: 100ms; --dur-fast: 150ms; --dur-base: 200ms;
  --dur-moderate: 250ms; --dur-slow: 350ms; --dur-page: 500ms;
}

[data-theme="dark"], .dark {
  --bg: #0d0d0d;
  --bg-subtle: #141414;
  --bg-muted: #1c1c1c;
  --bg-backdrop: #0a0a0a;
  --border: rgb(255 255 255 / 0.08);
  --border-strong: rgb(255 255 255 / 0.14);
  --fg: #fafafa;
  --fg-secondary: #a1a1a1;
  --fg-tertiary: #6b6b6b;
  --shadow-btn: inset 0 1px 0 rgb(255 255 255 / 0.06), 0 0 0 1px rgb(255 255 255 / 0.12);
  --shadow-btn-primary: inset 0 1px 0 rgb(255 255 255 / 0.10), 0 1px 2px rgb(0 0 0 / 0.24), 0 0 0 1px var(--accent);
  --shadow-card: 0 1px 2px rgb(0 0 0 / 0.08), 0 0 0 1px rgb(255 255 255 / 0.08);
  --shadow-pop: 0 0 0 1px rgb(255 255 255 / 0.08), 0 8px 24px -4px rgb(0 0 0 / 0.24), 0 2px 6px rgb(0 0 0 / 0.08);
  --shadow-modal: 0 0 0 1px rgb(255 255 255 / 0.06), 0 24px 64px -12px rgb(0 0 0 / 0.40);
}

4. 元件配方

備註: 這些是當前 UI 庫與框架的主流模式。

4.1 按鈕

主要按鈕

  • 14px Medium(桌面)或 16–18px(行動裝置),填充色為 var(--accent),白色文字,var(--radius-sm) 圓角。
  • 陰影:使用 var(--shadow-btn-primary),頂部有微妙的高光 inset。
  • 啟用懸停時:使用 var(--accent-hover) 背景。
  • 內邊距:水平 16px(桌面)/24px(行動裝置),上下 0 配合控制高度。

次要按鈕

  • var(--h-control) 高度,var(--radius-sm) 圓角。
  • 陰影:var(--shadow-btn)(0 1px 2px 擴散陰影 + 1px 髮絲線)。
  • 懸停時變深(0.5px 實色邊框或更深背景)。

幽靈/文字按鈕

  • 無背景或邊框,var(--fg-secondary) 文字。
  • 懸停時背景設為 var(--bg-subtle)。

圖示按鈕

  • 方形,邊長等於控制高度,var(--radius-sm)。
  • 所有樣式同文字按鈕或次要按鈕。

行動主要 CTA

  • 全寬 var(--h-cta-mobile) 高度,16–18px Medium,var(--radius-lg) 圓角。
  • 使用藥丸狀(--radius-full)作為明確的 iOS 風格。

4.2 輸入框

  • 標籤:var(--text-sm) var(--weight-medium),var(--fg)。12px 間距到輸入框。
  • 輸入框本體:var(--h-control) 高度,var(--text-base),var(--radius-md),內邊距 12px。
  • 邊框:使用 var(--hairline)。聚焦時:使用 var(--shadow-focus) 和 var(--accent) 邊框。
  • 狀態:錯誤 = var(--danger) 邊框 + var(--danger-soft) 背景。成功 = var(--success) 邊框。
  • 佔位符文字:var(--fg-tertiary)。
  • 描述/輔助文字:var(--text-sm) var(--fg-secondary),輸入框下方 4px。
  • 輸入框內圖示:保留 16px 空間,置於左/右內邊距。

4.3 卡片

  • var(--radius-xl) 圓角,var(--shadow-card) 陰影,12–16px 內邊距。
  • 無實色邊框。改用間距來建立分組。
  • 可選的頂部髮絲線用於堆疊中的區隔。

4.4 彈出視窗/工具提示

  • var(--radius-xl) 或 var(--radius-2xl) 圓角。
  • 陰影:var(--shadow-pop)。
  • 工具提示:11-12px 文字,深色背景(#1f1f1f),4px 內邊距,8px 圓角。

4.5 切換開關

  • 軌道:36×20px,var(--radius-full),var(--border)。
  • 啓用時:var(--accent) 軌道。14×14px 圓形白色拇指按鈕,從左側偏移 3px。

4.6 狀態標籤

  • var(--text-xs) var(--weight-medium),4px 水平內邊距,var(--radius-xs) 圓角。
  • 模式:純填充色(白色文字)或色調背景色(深色文字)。採用色調模式。
  • 中立:var(--bg-muted) var(--fg-secondary)。成功/錯誤/警告/資訊:使用語意色。

4.7 進度條

  • 容器:全寬 8px 高,var(--radius-full),var(--border) 背景。
  • 填充:var(--accent),動畫 width 搭配 var(--dur-moderate) 和 var(--ease-out)。
  • 可選:百分比標籤在進度條右側 4px。

4.8 前導圖示的列表項目

  • 佈局:圖示(24–28px,帶 var(--radius-sm) 圓角容器)→ 12px 間距 → 文字堆疊。
  • 文字:標題行 var(--text-base) var(--weight-medium),副標題行 var(--text-sm) var(--fg-secondary)。

5. 互動與動畫配方

5.1 通用 CSS 變數

.class {
  transition: all var(--dur-fast) var(--ease-out);
  /* 或針對特定屬性: */
  transition: transform var(--dur-fast) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}

5.2 懸停與按下效果

按鈕懸停:

  • translateY(-1px) 和增強陰影(var(--shadow-btn) → 更深,或者增大 y 偏移)。

按下(active):

  • scale(0.97) 搭配 var(--dur-instant)。

卡片懸停:

  • translateY(-2px),var(--shadow-pop),var(--dur-slow)。

輸入框聚焦:

  • var(--shadow-focus) 和邊框顏色為 var(--accent)。

連結懸停:

  • 文字顏色變為 var(--accent)。可選底線:background-size: 100% 1px。

5.3 進入/退出動畫

淡入(元件進入)

.fade-in {
  animation: fadeIn var(--dur-moderate) var(--ease-out) forwards;
}
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

縮放淡入(模態視窗、面板)

.scale-fade-in {
  animation: scaleFadeIn var(--dur-base) var(--ease-out) forwards;
}
@keyframes scaleFadeIn {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}

從下方滑入(選單、行動表單)

.slide-up {
  animation: slideUp var(--dur-moderate) var(--ease-drawer) forwards;
}
@keyframes slideUp {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

從側邊滑入(導航抽屜)

.slide-in-left {
  animation: slideInLeft 300ms var(--ease-drawer) forwards;
}
@keyframes slideInLeft {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}

Motion 元件版本(motion/react)

import { motion, AnimatePresence } from "motion/react";

<motion.div
  initial={{ opacity: 0, y: 8 }}
  animate={{ opacity: 1, y: 0 }}
  exit={{ opacity: 0, y: -8 }}
  transition={{ duration: 0.2, ease: [0.23, 1, 0.32, 1] }}
>
  {children}
</motion.div>
// 卡片的縮放淡入
<motion.div
  initial={{ opacity: 0, scale: 0.96 }}
  animate={{ opacity: 1, scale: 1 }}
  exit={{ opacity: 0, scale: 0.96 }}
  transition={{ duration: 0.15, ease: [0.23, 1, 0.32, 1] }}
/>

5.4 清單與疊代(Stagger)

<List>
  {items.map((item, i) => (
    <motion.li
      key={item.id}
      initial={{ opacity: 0, y: 8 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ delay: i * 0.04, duration: 0.2, ease: [0.23, 1, 0.32, 1] }}
    />
  ))}
</List>

5.5 數字動畫(計數器)

function AnimatedCounter({ value, duration = 0.5 }: { value: number; duration?: number }) {
  const [display, setDisplay] = useState(value);
  useEffect(() => {
    const start = display;
    const end = value;
    const startTime = performance.now();
    const animate = (now: number) => {
      const elapsed = now - startTime;
      const progress = Math.min(elapsed / (duration * 1000), 1);
      const eased = 1 - Math.pow(1 - progress, 3);
      setDisplay(Math.round(start + (end - start) * eased));
      if (progress < 1) requestAnimationFrame(animate);
    };
    requestAnimationFrame(animate);
  }, [value, duration]);
  return <span>{display.toLocaleString()}</span>;
}

5.6 載入狀態

骨架屏: 使用 var(--bg-subtle) 背景搭配脈衝動畫。

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}
.skeleton {
  background: var(--bg-muted);
  border-radius: var(--radius-sm);
  animation: pulse 1.5s var(--ease-in-out) infinite;
}

微調器: SVG 圓弧搭配旋轉動畫。

@keyframes spin {
  to { transform: rotate(360deg); }
}
.spinner {
  animation: spin 1s linear infinite;
}

5.7 頁面轉場

包裹路由內容。

<AnimatePresence mode="wait">
  <motion.div
    key={location.pathname}
    initial={{ opacity: 0 }}
    animate={{ opacity: 1 }}
    exit={{ opacity: 0 }}
    transition={{ duration: 0.15 }}
  >
    <Outlet />
  </motion.div>
</AnimatePresence>

6. 提示:如何引導 AI

要充分利用此技能:

  1. 將提示範圍縮小到一個畫面或元件。 不要在一個視窗中要求建立一個完整的應用程式。
  2. 指定上下文:「儀表板 KPI 卡片」、「設定頁面」、「登入畫面」、「個人資料表單」。
  3. 選擇你的強調色。 紫色、藍色、橙色、黑色。如果不指定,AI 會猜測(通常選藍色或紫色)。
  4. 選擇亮色或暗色模式。 如果不指定,AI 會輸出兩者,這可能不是你想要的。
  5. 如果你有 Logo 或品牌資產,請提供。 品牌顏色、商標表現方式、版權字體。
  6. 要求完成帶有所有互動和載入狀態的 React + Tailwind 或類似內容。
  7. 明確要求應對此任務! 好的提示開頭:「使用 GIGA UI 技能為財務應用程式設計一個 KPI 卡片行,採用亮色模式、紫色強調色、Inter 字體。」

7. 實作細節

7.1 函數

  • 建立一個 cn() 工具函數(使用 clsx 和 tailwind-merge)用於條件式 className 合併。
  • 建立一個 formatNumber() 工具函數用於數字格式化($、%、逗號、縮寫)。
  • 使用 useId() 鉤子獲取可訪問的 ID。

7.2 全局樣式

全局排版、CSS 變數和重置。Tailwind base 層是放置非 Tailwind 變數和基礎樣式的自然位置。

@layer base {
  * { box-sizing: border-box; }
  body {
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: 1.5;
    color: var(--fg);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
}

7.3 檔案結構(React 範例)

components/
  ui/
    button.tsx
    input.tsx
    card.tsx
  layout/
    sidebar.tsx
    topbar.tsx
    page.tsx
  features/
    kpi-card.tsx
    data-table.tsx
    auth-form.tsx

8. 檢測清單:辨識風格

測試你的 UI 是否處於 GIGA UI 語義空間:

  • 一個字體家族,最多兩種字重?
  • 幾乎沒有顏色(大面積白色/灰色,一個強調色)?
  • 沒有厚重的邊框(改為使用髮絲線或陰影)?
  • 非常精確的排版(尺寸、間距、字距)?
  • 內容周圍有空氣感(間距)?
  • 動畫是否服務於功能(解釋、確認、引導)?

9. 品質檢查清單

交付 UI 前請逐一檢查:

邊緣情況

  • 最小/最大內容測試(短名稱、長名稱、極短內容、極長內容)
  • 清空狀態(列表、表格、搜尋結果)
  • 錯誤狀態(表單驗證、API 錯誤)
  • 邊界值(輸入最大值、數字格式化)
  • 溢位(文字截斷、水平滾動)

載入

  • 骨架屏(不僅是旋轉器)用於內容區域
  • 按鈕具有載入微調器,同時保持寬度
  • 影像延遲載入
  • 無內容閃爍(使用最小高度)

空白與對齊

  • 一致的間距(4px 網格)
  • 文字、圖示、邊緣對齊
  • 影像無變形(保持長寬比)
  • 容器之間平衡的留白

可訪問性

  • 焦點狀態(:focus-visible 環)在鍵盤導航上清晰可見
  • 所有輸入框有標籤,圖示按鈕有 aria-label
  • 表單欄位有關聯的錯誤訊息
  • 顏色對比度(文字對背景)通過 WCAG AA 標準
  • 互動元素的角色和狀態
  • 不需要 JavaScript 也能閱讀內容

暗色模式

  • 所有顏色映射都已轉換
  • 無遺漏的硬編碼淺色值
  • 陰影感覺正確(在暗模式下,更像光源而非陰影)
  • color-scheme 設定正確
  • 影像在暗模式下不過曝

10. 來源

  • 公共作品: Marcel Kargul 的 Dribbble、Instagram、個人網站、Behance。
  • 他的動畫工具: Figma、Rive、AE、Lottie、Next.js + Sanity。
  • 相關設計典範: Emil Kowalski(vaul、cmdk、圍繞 dialog 標籤的 CSS 動畫)、Paco Coursey、Apple HIG、Linear 設計。

相關技能